Add integrity check for curve parameters

We don't really need a secure hash for that, something like CRC32 would
probably be enough - but we have SHA-256 handy, not CRC32, so use that for the
sake of simplicity.
This commit is contained in:
Manuel Pégourié-Gonnard 2019-11-21 13:37:00 +01:00
parent 1a5337179f
commit 2b90961b8d
3 changed files with 84 additions and 0 deletions

View file

@ -110,6 +110,10 @@
#error "MBEDTLS_USE_TINYCRYPT defined, but it cannot be defined with MBEDTLS_NO_64BIT_MULTIPLICATION"
#endif
#if defined(MBEDTLS_USE_TINYCRYPT) && !defined(MBEDTLS_SHA256_C)
#error "MBEDTLS_USE_TINYCRYPT defined, but not MBEDTLS_SHA256_C"
#endif
#if defined(MBEDTLS_USE_TINYCRYPT) && \
!( defined(MBEDTLS_SSL_CONF_SINGLE_EC) && \
MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID == 23 && \

View file

@ -2649,6 +2649,7 @@
* MBEDTLS_SSL_CONF_SINGLE_EC
* MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID == 23
* MBEDTLS_SSL_CONF_SINGLE_UECC_GRP_ID == MBEDTLS_UECC_DP_SECP256R1
* MBEDTLS_SHA256_C
*
* \see MBEDTLS_SSL_CONF_RNG
*

View file

@ -66,6 +66,7 @@
#if defined(MBEDTLS_USE_TINYCRYPT)
#include <tinycrypt/ecc.h>
#include "mbedtls/platform_util.h"
#include "mbedtls/sha256.h"
#include <string.h>
/* Parameters for curve NIST P-256 aka secp256r1 */
@ -98,6 +99,73 @@ const uECC_word_t curve_b[NUM_ECC_WORDS] = {
BYTES_TO_WORDS_8(E7, 93, 3A, AA, D8, 35, C6, 5A)
};
static int uECC_update_param_sha256(mbedtls_sha256_context *ctx,
const uECC_word_t val[NUM_ECC_WORDS])
{
uint8_t bytes[NUM_ECC_BYTES];
uECC_vli_nativeToBytes(bytes, NUM_ECC_BYTES, val);
return mbedtls_sha256_update_ret(ctx, bytes, NUM_ECC_BYTES);
}
static int uECC_compute_param_sha256(unsigned char output[32])
{
int ret = UECC_FAILURE;
mbedtls_sha256_context ctx;
mbedtls_sha256_init( &ctx );
if (mbedtls_sha256_starts_ret(&ctx, 0) != 0) {
goto exit;
}
if (uECC_update_param_sha256(&ctx, curve_p) != 0 ||
uECC_update_param_sha256(&ctx, curve_n) != 0 ||
uECC_update_param_sha256(&ctx, curve_G) != 0 ||
uECC_update_param_sha256(&ctx, curve_G + NUM_ECC_WORDS) != 0 ||
uECC_update_param_sha256(&ctx, curve_b) != 0)
{
goto exit;
}
if (mbedtls_sha256_finish_ret(&ctx, output) != 0) {
goto exit;
}
ret = UECC_SUCCESS;
exit:
mbedtls_sha256_free( &ctx );
return ret;
}
/*
* Check integrity of curve parameters.
* Return 0 if everything's OK, non-zero otherwise.
*/
static int uECC_check_curve_integrity(void)
{
unsigned char computed[32];
unsigned char reference[32] = {
0x2d, 0xa1, 0xa4, 0x64, 0x45, 0x28, 0x0d, 0xe1,
0x93, 0xf9, 0x29, 0x2f, 0xac, 0x3e, 0xe2, 0x92,
0x76, 0x0a, 0xe2, 0xbc, 0xce, 0x2a, 0xa2, 0xc6,
0x38, 0xf2, 0x19, 0x1d, 0x76, 0x72, 0x93, 0x49,
};
volatile unsigned char diff = 0;
unsigned char i;
if (uECC_compute_param_sha256(computed) != UECC_SUCCESS) {
return UECC_FAILURE;
}
for (i = 0; i < 32; i++)
diff |= computed[i] ^ reference[i];
return diff;
}
/* IMPORTANT: Make sure a cryptographically-secure PRNG is set and the platform
* has access to enough entropy in order to feed the PRNG regularly. */
#if default_RNG_defined
@ -955,6 +1023,11 @@ int EccPoint_mult_safer(uECC_word_t * result, const uECC_word_t * point,
uECC_word_t *initial_Z = 0;
int r;
/* Protect against faults modifying curve paremeters in flash */
if (uECC_check_curve_integrity() != 0) {
return 0;
}
/* Protects against invalid curves attacks */
if (uECC_valid_point(point) != 0 ) {
return 0;
@ -983,6 +1056,12 @@ int EccPoint_mult_safer(uECC_word_t * result, const uECC_word_t * point,
goto clear_and_out;
}
/* Protect against faults modifying curve paremeters in flash */
if (uECC_check_curve_integrity() != 0) {
r = 0;
goto clear_and_out;
}
r = 1;
clear_and_out: