Skip to content

Commit

Permalink
core: libmbedtls: add fault mitigation in crypto_acipher_rsassa_verify()
Browse files Browse the repository at this point in the history
Adds fault mitigations in crypto_acipher_rsassa_verify() by checking
that the internal call to memcmp() when verifying the hash in the RSA
signature was called and was successful.

The internal call to memcmp() records the result of the comparison if
successful. This is double checked against the normal return value from
the called pk_info->verify_func().

If the normal return value is OK then the recorded return value must
match or we're likely subject to a fault injection attack and we're
triggering a panic.

If the normal return value isn't OK we don't care about the recorded
value, it's overridden by a new error code. In this case we don't know
if we're subject to a fault injection attack or not, the important thing
to make sure that the calling function doesn't miss the error.

This fault mitigation is only enabled with the calling function enabled
fault mitigations and CFG_CORE_FAULT_MITIGATION is 'y'.

Acked-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
  • Loading branch information
jenswi-linaro authored and jforissier committed Nov 25, 2022
1 parent 06de608 commit 98ada65
Showing 1 changed file with 20 additions and 0 deletions.
20 changes: 20 additions & 0 deletions lib/libmbedtls/core/rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <string.h>
#include <tee/tee_cryp_utl.h>
#include <utee_defines.h>
#include <fault_mitigation.h>

#include "mbed_helpers.h"

Expand Down Expand Up @@ -680,6 +681,14 @@ TEE_Result sw_crypto_acipher_rsassa_verify(uint32_t algo,
mbedtls_rsa_context rsa;
const mbedtls_pk_info_t *pk_info = NULL;
uint32_t md_algo = 0;
struct ftmn ftmn = { };
unsigned long arg_hash = 0;

/*
* The caller expects to call crypto_acipher_rsassa_verify(),
* update the hash as needed.
*/
FTMN_CALLEE_SWAP_HASH(FTMN_FUNC_HASH("crypto_acipher_rsassa_verify"));

memset(&rsa, 0, sizeof(rsa));
mbedtls_rsa_init(&rsa, 0, 0);
Expand Down Expand Up @@ -712,13 +721,15 @@ TEE_Result sw_crypto_acipher_rsassa_verify(uint32_t algo,
case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
arg_hash = FTMN_FUNC_HASH("mbedtls_rsa_rsassa_pkcs1_v15_verify");
lmd_padding = MBEDTLS_RSA_PKCS_V15;
break;
case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
arg_hash = FTMN_FUNC_HASH("mbedtls_rsa_rsassa_pss_verify_ext");
lmd_padding = MBEDTLS_RSA_PKCS_V21;
break;
default:
Expand All @@ -740,15 +751,24 @@ TEE_Result sw_crypto_acipher_rsassa_verify(uint32_t algo,

mbedtls_rsa_set_padding(&rsa, lmd_padding, md_algo);

FTMN_PUSH_LINKED_CALL(&ftmn, arg_hash);
lmd_res = pk_info->verify_func(&rsa, md_algo, msg, msg_len,
sig, sig_len);
if (!lmd_res)
FTMN_SET_CHECK_RES_FROM_CALL(&ftmn, FTMN_INCR0, lmd_res);
FTMN_POP_LINKED_CALL(&ftmn);
if (lmd_res != 0) {
FMSG("verify_func failed, returned 0x%x", -lmd_res);
res = TEE_ERROR_SIGNATURE_INVALID;
goto err;
}
res = TEE_SUCCESS;
goto out;

err:
FTMN_SET_CHECK_RES_NOT_ZERO(&ftmn, FTMN_INCR0, res);
out:
FTMN_CALLEE_DONE_CHECK(&ftmn, FTMN_INCR0, FTMN_STEP_COUNT(1), res);
/* Reset mpi to skip freeing here, those mpis will be freed with key */
mbedtls_mpi_init(&rsa.E);
mbedtls_mpi_init(&rsa.N);
Expand Down

0 comments on commit 98ada65

Please sign in to comment.