Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,15 @@ jobs:

- name: Setup Ubuntu MbedTLS
if: matrix.os == 'ubuntu-latest' && matrix.crypto == 'mbedtls'
run: sudo apt-get install libmbedtls-dev
run: |
git clone https://github.com/Mbed-TLS/mbedtls.git
cd mbedtls
git checkout mbedtls-4.0.0
git submodule update --init --recursive
cmake -S . -B build
cmake --build build
sudo cmake --install build
cd ..

- name: Setup macOS OpenSSL
if: matrix.os == 'macos-latest' && matrix.crypto == 'openssl'
Expand Down
12 changes: 10 additions & 2 deletions .github/workflows/meson.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,15 @@ jobs:

- name: Setup Ubuntu MbedTLS
if: matrix.os == 'ubuntu-latest' && matrix.crypto == 'mbedtls'
run: sudo apt-get install libmbedtls-dev
run: |
git clone https://github.com/Mbed-TLS/mbedtls.git
cd mbedtls
git checkout mbedtls-4.0.0
git submodule update --init --recursive
cmake -S . -B build
cmake --build build
sudo cmake --install build
cd ..

- name: Setup macOS OpenSSL
if: matrix.os == 'macos-latest' && matrix.crypto == 'openssl'
Expand Down Expand Up @@ -128,7 +136,7 @@ jobs:
- uses: actions/checkout@v2

- name: Create Build Environment
run: meson setup ${{github.workspace}}/build ${{ matrix.meson-crypto-enable }}
run: meson setup ${{github.workspace}}/build -Ddefault_library=static ${{ matrix.meson-crypto-enable }}

- name: Build
working-directory: ${{github.workspace}}/build
Expand Down
79 changes: 49 additions & 30 deletions crypto/cipher/aes_gcm_mbedtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <mbedtls/gcm.h>

#include <psa/crypto.h>
#include "aes_gcm.h"
#include "alloc.h"
#include "err.h" /* for srtp_debug */
Expand Down Expand Up @@ -198,7 +199,6 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_alloc(srtp_cipher_t **c,
if (tlen != GCM_AUTH_TAG_LEN && tlen != GCM_AUTH_TAG_LEN_8) {
return (srtp_err_status_bad_param);
}

/* allocate memory a cipher of type aes_gcm */
*c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
if (*c == NULL) {
Expand All @@ -212,15 +212,15 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_alloc(srtp_cipher_t **c,
return (srtp_err_status_alloc_fail);
}

gcm->ctx =
(mbedtls_gcm_context *)srtp_crypto_alloc(sizeof(mbedtls_gcm_context));
gcm->ctx = (psa_gcm_context *)srtp_crypto_alloc(sizeof(psa_gcm_context));

if (gcm->ctx == NULL) {
srtp_crypto_free(gcm);
srtp_crypto_free(*c);
*c = NULL;
return srtp_err_status_alloc_fail;
}
mbedtls_gcm_init(gcm->ctx);
gcm->ctx->op = psa_aead_operation_init();

/* set pointers */
(*c)->state = gcm;
Expand Down Expand Up @@ -256,7 +256,7 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_dealloc(srtp_cipher_t *c)
FUNC_ENTRY();
ctx = (srtp_aes_gcm_ctx_t *)c->state;
if (ctx) {
mbedtls_gcm_free(ctx->ctx);
psa_destroy_key(ctx->ctx->key_id);
srtp_crypto_free(ctx->ctx);
/* zeroize the key material */
octet_string_set_to_zero(ctx, sizeof(srtp_aes_gcm_ctx_t));
Expand All @@ -275,7 +275,7 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_context_init(void *cv,
FUNC_ENTRY();
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
uint32_t key_len_in_bits;
int errCode = 0;
psa_status_t status = PSA_SUCCESS;
c->dir = srtp_direction_any;
c->aad_size = 0;

Expand All @@ -291,10 +291,20 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_context_init(void *cv,
break;
}

errCode =
mbedtls_gcm_setkey(c->ctx, MBEDTLS_CIPHER_ID_AES, key, key_len_in_bits);
if (errCode != 0) {
debug_print(srtp_mod_aes_gcm, "mbedtls error code: %d", errCode);
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;

psa_set_key_usage_flags(&attr,
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(
&attr, PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, c->tag_len));
psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attr, key_len_in_bits);

status = psa_import_key(&attr, key, key_len_in_bits / 8, &c->ctx->key_id);

if (status != PSA_SUCCESS) {
debug_print(srtp_mod_aes_gcm, "mbedtls error code: %d", status);
psa_destroy_key(c->ctx->key_id);
return srtp_err_status_init_fail;
}

Expand Down Expand Up @@ -366,7 +376,8 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_encrypt(void *cv,
{
FUNC_ENTRY();
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
int errCode = 0;

psa_status_t status = PSA_SUCCESS;

if (c->dir != srtp_direction_encrypt) {
return srtp_err_status_bad_param;
Expand All @@ -376,13 +387,24 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_encrypt(void *cv,
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, dst + src_len);
/*
There are tests that check a buffer is only written too as mush as needed
even if there is space in buffer. psa_aead_encrypt uses that extra space,
probable for performance reasons. For adjust the dst_len to be only what
is required to avoid the tests failing. The tests should be changed as
there is nothing wrong with using the free buffer space.
*/
*dst_len = src_len + c->tag_len;

size_t out_len = 0;
status = psa_aead_encrypt(
c->ctx->key_id,
PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, c->tag_len), c->iv,
c->iv_len, c->aad, c->aad_size, src, src_len, dst, *dst_len, &out_len);

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

Expand All @@ -407,7 +429,8 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_decrypt(void *cv,
{
FUNC_ENTRY();
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
int errCode = 0;

psa_status_t status = PSA_SUCCESS;

if (c->dir != srtp_direction_decrypt) {
return srtp_err_status_bad_param;
Expand All @@ -417,26 +440,22 @@ static srtp_err_status_t srtp_aes_gcm_mbedtls_decrypt(void *cv,
return srtp_err_status_bad_param;
}

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

debug_print(srtp_mod_aes_gcm, "AAD: %s",
srtp_octet_string_hex_string(c->aad, c->aad_size));

errCode = mbedtls_gcm_auth_decrypt(
c->ctx, (src_len - c->tag_len), c->iv, c->iv_len, c->aad, c->aad_size,
src + (src_len - c->tag_len), c->tag_len, src, dst);
size_t out_len = 0;
status = psa_aead_decrypt(
c->ctx->key_id,
PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, c->tag_len), c->iv,
c->iv_len, c->aad, c->aad_size, src, src_len, dst, *dst_len, &out_len);
*dst_len = out_len;
c->aad_size = 0;
if (errCode != 0) {
if (status != PSA_SUCCESS) {
return srtp_err_status_auth_fail;
}

/*
* Reduce the buffer size by the tag length since the tag
* is not part of the original payload
*/
*dst_len = (src_len - c->tag_len);

return srtp_err_status_ok;
}
91 changes: 72 additions & 19 deletions crypto/cipher/aes_icm_mbedtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <mbedtls/aes.h>
#include <psa/crypto_types.h>
#include <psa/crypto.h>

#include "aes_icm_ext.h"
#include "crypto_types.h"
#include "err.h" /* for srtp_debug */
Expand Down Expand Up @@ -230,15 +232,17 @@ static srtp_err_status_t srtp_aes_icm_mbedtls_alloc(srtp_cipher_t **c,
}

icm->ctx =
(mbedtls_aes_context *)srtp_crypto_alloc(sizeof(mbedtls_aes_context));
(psa_aes_icm_ctx_t *)srtp_crypto_alloc(sizeof(psa_aes_icm_ctx_t));

if (icm->ctx == NULL) {
srtp_crypto_free(icm);
srtp_crypto_free(*c);
*c = NULL;
return srtp_err_status_alloc_fail;
}

mbedtls_aes_init(icm->ctx);
((icm->ctx))->key_id = PSA_KEY_ID_NULL;
((icm->ctx)->op) = psa_cipher_operation_init();

/* set pointers */
(*c)->state = icm;
Expand Down Expand Up @@ -284,7 +288,7 @@ static srtp_err_status_t srtp_aes_icm_mbedtls_dealloc(srtp_cipher_t *c)
*/
ctx = (srtp_aes_icm_ctx_t *)c->state;
if (ctx != NULL) {
mbedtls_aes_free(ctx->ctx);
psa_destroy_key(ctx->ctx->key_id);
srtp_crypto_free(ctx->ctx);
/* zeroize the key material */
octet_string_set_to_zero(ctx, sizeof(srtp_aes_icm_ctx_t));
Expand All @@ -302,7 +306,9 @@ static srtp_err_status_t srtp_aes_icm_mbedtls_context_init(void *cv,
{
srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
uint32_t key_size_in_bits = (c->key_size << 3);
int errcode = 0;
psa_status_t status = PSA_SUCCESS;

status = psa_crypto_init();

/*
* set counter and initial values to 'offset' value, being careful not to
Expand Down Expand Up @@ -330,9 +336,25 @@ static srtp_err_status_t srtp_aes_icm_mbedtls_context_init(void *cv,
break;
}

errcode = mbedtls_aes_setkey_enc(c->ctx, key, key_size_in_bits);
if (errcode != 0) {
debug_print(srtp_mod_aes_icm, "errCode: %d", errcode);
/* Set key attributes */
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;

psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attr, key_size_in_bits);
psa_set_key_usage_flags(&attr,
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(&attr, PSA_ALG_CTR);

if (c->ctx->key_id != PSA_KEY_ID_NULL) {
c->ctx->key_id = PSA_KEY_ID_NULL;
}

status =
psa_import_key(&attr, key, key_size_in_bits / 8, &(c->ctx->key_id));

if (status != PSA_SUCCESS) {
psa_destroy_key(c->ctx->key_id);
debug_print(srtp_mod_aes_icm, "status: %d", status);
}

return srtp_err_status_ok;
Expand All @@ -349,6 +371,8 @@ static srtp_err_status_t srtp_aes_icm_mbedtls_set_iv(
{
srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
v128_t nonce;
psa_status_t status = PSA_SUCCESS;

(void)dir;

c->nc_off = 0;
Expand All @@ -362,16 +386,40 @@ static srtp_err_status_t srtp_aes_icm_mbedtls_set_iv(
debug_print(srtp_mod_aes_icm, "set_counter: %s",
v128_hex_string(&c->counter));

status = psa_cipher_abort(&c->ctx->op);
if (status != PSA_SUCCESS) {
debug_print(srtp_mod_aes_icm, "abort error: %d", status);
return srtp_err_status_cipher_fail;
}

status =
psa_cipher_encrypt_setup(&(c->ctx->op), c->ctx->key_id, PSA_ALG_CTR);
if (status != PSA_SUCCESS) {
psa_cipher_abort(&c->ctx->op);
debug_print(srtp_mod_aes_icm, "setup error: %d", status);
return srtp_err_status_cipher_fail;
}

status = psa_cipher_set_iv(&c->ctx->op, c->counter.v8, 16);
if (status != PSA_SUCCESS) {
debug_print(srtp_mod_aes_icm, "set iv error: %d", status);
psa_cipher_abort(&c->ctx->op);
return srtp_err_status_cipher_fail;
}

return srtp_err_status_ok;
}

/*
* This function encrypts a buffer using AES CTR mode
*
* Parameters:
* c Crypto context
* buf data to encrypt
* enc_len length of encrypt buffer
* cv Crypto contexts
* src plaintext buffer
* src_len length of plaintext
* dst encrypted data buffer
* dst_len At the begining of function, length of encrypted data buffer.
* des_len At the end of function, length of the actual encrypted data.
*/
static srtp_err_status_t srtp_aes_icm_mbedtls_encrypt(void *cv,
const uint8_t *src,
Expand All @@ -381,22 +429,27 @@ static srtp_err_status_t srtp_aes_icm_mbedtls_encrypt(void *cv,
{
srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;

int errCode = 0;
psa_status_t status = PSA_SUCCESS;
size_t out_len = 0;

debug_print(srtp_mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter));
debug_print(srtp_mod_aes_icm, "source: %s",
srtp_octet_string_hex_string(src, src_len));

if (*dst_len < src_len) {
return srtp_err_status_buffer_small;
}
status =
psa_cipher_update(&(c->ctx->op), src, src_len, dst, *dst_len, &out_len);

errCode =
mbedtls_aes_crypt_ctr(c->ctx, src_len, &(c->nc_off), c->counter.v8,
c->stream_block.v8, src, dst);
if (errCode != 0) {
debug_print(srtp_mod_aes_icm, "encrypt error: %d", errCode);
if (status != PSA_SUCCESS) {
debug_print(srtp_mod_aes_icm, "encrypt error: %d", status);
psa_cipher_abort(&c->ctx->op);
return srtp_err_status_cipher_fail;
}

*dst_len = src_len;
*dst_len = out_len;
debug_print(srtp_mod_aes_icm, "encrypted: %s",
srtp_octet_string_hex_string(dst, *dst_len));
Comment thread
pabuhler marked this conversation as resolved.

return srtp_err_status_ok;
}
Loading
Loading