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.
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index fe9c594..ce348d9 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -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 &&                      \
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 87012da..dbb84b4 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -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
  *
diff --git a/tinycrypt/ecc.c b/tinycrypt/ecc.c
index 62517df..381beff 100644
--- a/tinycrypt/ecc.c
+++ b/tinycrypt/ecc.c
@@ -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 @@
 	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 @@
 	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 @@
 		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: