summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavio Santes <flavio.santes@intel.com>2017-03-10 20:08:21 -0600
committerAnas Nashif <anas.nashif@intel.com>2017-04-19 18:44:06 -0400
commitc6588695ee74374439aeefede137dd40b33d43e8 (patch)
tree29a89f479d243ab75143855da666ec7ce4ec77c9
parent2421e11f25a297f3bf86a72d9cdf14a6927bdeaf (diff)
ext/lib/crypto: Update TinyCrypt to version 0.2.6
Update TinyCrypt to version 0.2.6. Origin: https://github.com/01org/tinycrypt/releases/tag/v0.2.6 Jira: ZEP-749 Change-Id: I62be0c134236d4a5dcae14bee86692c0fd6dc381 Signed-off-by: Flavio Santes <flavio.santes@intel.com>
-rw-r--r--ext/lib/crypto/tinycrypt/include/tinycrypt/constants.h4
-rw-r--r--ext/lib/crypto/tinycrypt/include/tinycrypt/ecc.h41
-rw-r--r--ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dh.h20
-rw-r--r--ext/lib/crypto/tinycrypt/include/tinycrypt/hmac.h1
-rw-r--r--ext/lib/crypto/tinycrypt/source/ecc.c27
-rw-r--r--ext/lib/crypto/tinycrypt/source/ecc_dh.c19
-rw-r--r--ext/lib/crypto/tinycrypt/source/ecc_dsa.c14
-rw-r--r--ext/lib/crypto/tinycrypt/source/utils.c7
8 files changed, 96 insertions, 37 deletions
diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/constants.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/constants.h
index 25f03616c..1a7c9df36 100644
--- a/ext/lib/crypto/tinycrypt/include/tinycrypt/constants.h
+++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/constants.h
@@ -47,10 +47,6 @@ extern "C" {
#define NULL ((void *)0)
#endif
-#ifndef bool
-enum {false, true} bool;
-#endif
-
#define TC_CRYPTO_SUCCESS 1
#define TC_CRYPTO_FAIL 0
diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc.h
index 71194758c..74324f91b 100644
--- a/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc.h
+++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc.h
@@ -79,10 +79,12 @@
extern "C" {
#endif
+/* Word size (4 bytes considering 32-bits architectures) */
+#define WORD_SIZE 4
/* Number of words of 32 bits to represent an element of the the curve p-256: */
#define NUM_ECC_DIGITS 8
/* Number of bytes to represent an element of the the curve p-256: */
-#define NUM_ECC_BYTES (4*NUM_ECC_DIGITS)
+#define NUM_ECC_BYTES (WORD_SIZE*NUM_ECC_DIGITS)
/* struct to represent a point of the curve (uses X and Y coordinates): */
typedef struct EccPoint {
@@ -218,6 +220,8 @@ void vli_modSquare_fast(uint32_t *p_result, uint32_t *p_left);
* @param p_right IN -- buffer p_right in (p_left * p_right) % p_mod.
* @param p_mod IN -- module.
* @param p_barrett IN -- used for Barrett reduction.
+ * @note Side-channel countermeasure: algorithm strengthened against timing
+ * attack.
*/
void vli_modMult(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right,
uint32_t *p_mod, uint32_t *p_barrett);
@@ -229,11 +233,28 @@ void vli_modMult(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right,
* @param p_input IN -- buffer p_input in (1/p_intput) % p_mod.
* @param p_mod IN -- module.
* @param p_barrett IN -- used for Barrett reduction.
+ * @note Side-channel countermeasure: algorithm strengthened against timing
+ * attack.
*/
void vli_modInv(uint32_t *p_result, uint32_t *p_input,
uint32_t *p_mod, uint32_t *p_barrett);
/*
+ * @brief modular reduction based on Barrett's method
+ * @param p_result OUT -- p_product % p_mod.
+ * @param p_product IN -- buffer p_product in (p_product % p_mod).
+ * @param p_mod IN -- buffer p_mod in (p_product % p_mod).
+ * @param p_barrett -- used for Barrett reduction.
+ * @note Side-channel countermeasure: algorithm strengthened against timing
+ * attack.
+ */
+void vli_mmod_barrett(
+ uint32_t *p_result,
+ uint32_t *p_product,
+ uint32_t *p_mod,
+ uint32_t *p_barrett);
+
+/*
* @brief Check if a point is zero.
* @return Returns 1 if p_point is the point at infinity, 0 otherwise.
*
@@ -271,11 +292,27 @@ void EccPoint_add(EccPointJacobi *P1, EccPointJacobi *P2);
* @param p_result OUT -- Product of p_point by p_scalar.
* @param p_point IN -- Elliptic curve point
* @param p_scalar IN -- Scalar integer
+ * @note Side-channel countermeasure: algorithm strengthened against timing
+ * attack.
*/
-void EccPoint_mult(EccPointJacobi *p_result, EccPoint *p_point,
+void EccPoint_mult_safe(EccPointJacobi *p_result, EccPoint *p_point,
uint32_t *p_scalar);
/*
+ * @brief Fast elliptic curve scalar multiplication with result in Jacobi
+ * coordinates
+ * @note non constant time
+ * @param p_result OUT -- Product of p_point by p_scalar.
+ * @param p_point IN -- Elliptic curve point
+ * @param p_scalar IN -- Scalar integer
+ * @note algorithm NOT strengthened against timing attack.
+ */
+void EccPoint_mult_unsafe(
+ EccPointJacobi *p_result,
+ EccPoint *p_point,
+ uint32_t *p_scalar);
+
+/*
* @brief Convert an integer in standard octet representation to native format.
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dh.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dh.h
index b31477b1f..778fee272 100644
--- a/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dh.h
+++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dh.h
@@ -80,7 +80,7 @@ extern "C" {
/**
* @brief Create a public/private key pair.
- * @return returns TC_CRYPTO_SUCCESS (1) if the key pair was generated successfully
+ * @return returns TC_CRYPTO_SUCCESS (1) if key pair was generated successfully
* returns TC_CRYPTO_FAIL (0) if:
* the private key is 0
*
@@ -90,13 +90,15 @@ extern "C" {
*
* @note You must use a new non-predictable random number to generate each
* new key pair.
+ * @note p_random must have NUM_ECC_DIGITS*2 bits of entropy to eliminate
+ * bias in keys.
*
* @note side-channel countermeasure: algorithm strengthened against timing
* attack.
*/
int32_t ecc_make_key(EccPoint *p_publicKey,
uint32_t p_privateKey[NUM_ECC_DIGITS],
- uint32_t p_random[NUM_ECC_DIGITS]);
+ uint32_t p_random[2 * NUM_ECC_DIGITS]);
/**
* @brief Determine whether or not a given point is on the chosen elliptic curve
@@ -106,7 +108,8 @@ int32_t ecc_make_key(EccPoint *p_publicKey,
* returns -2 if: curve_p - p_publicKey->x != 1 or
* curve_p - p_publicKey->y != 1
* returns -3 if: y^2 != x^3 + ax + b
-
+ * returns -4 if: public key is the group generator
+ *
* @param p_publicKey IN -- The point to be checked.
*/
int32_t ecc_valid_public_key(EccPoint *p_publicKey);
@@ -114,7 +117,7 @@ int32_t ecc_valid_public_key(EccPoint *p_publicKey);
/**
* @brief Compute a shared secret given your secret key and someone else's
* public key.
- * @return returns TC_CRYPTO_SUCCESS (1) if the shared secret was computed successfully
+ * @return returns TC_CRYPTO_SUCCESS (1) if the secret was computed successfully
* returns TC_CRYPTO_FAIL (0) otherwise
*
* @param p_secret OUT -- The shared secret value.
@@ -125,12 +128,9 @@ int32_t ecc_valid_public_key(EccPoint *p_publicKey);
* attacks. The random multiplier should probably be different for each
* invocation of ecdh_shared_secret().
*
- * @note It is recommended that you hash the result of ecdh_shared_secret before
- * using it for symmetric encryption or HMAC. If you do not hash the shared
- * secret, you must call ecc_valid_public_key() to verify that the remote side's
- * public key is valid. If this is not done, an attacker could create a public
- * key that would cause your use of the shared secret to leak information about
- * the private key.
+ * @warning It is recommended to use the output of ecdh_shared_secret() as the
+ * input of a recommended Key Derivation Function (see NIST SP 800-108) in
+ * order to produce a symmetric key.
*/
int32_t ecdh_shared_secret(uint32_t p_secret[NUM_ECC_DIGITS], EccPoint *p_publicKey,
uint32_t p_privateKey[NUM_ECC_DIGITS]);
diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/hmac.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/hmac.h
index 41e712a39..26f6cfe68 100644
--- a/ext/lib/crypto/tinycrypt/include/tinycrypt/hmac.h
+++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/hmac.h
@@ -125,6 +125,7 @@ int32_t tc_hmac_update(TCHmacState_t ctx,
* ctx == NULL or
* key == NULL or
* taglen != TC_SHA256_DIGEST_SIZE
+ * @note 'ctx' is erased before exiting (this must never be changed/removed).
* @note Assumes the tag bufer is at least sizeof(hmac_tag_size(state)) bytes
* state has been initialized by tc_hmac_init
* @param tag IN/OUT -- buffer to receive computed HMAC tag
diff --git a/ext/lib/crypto/tinycrypt/source/ecc.c b/ext/lib/crypto/tinycrypt/source/ecc.c
index 357139b9b..bfe6c5f13 100644
--- a/ext/lib/crypto/tinycrypt/source/ecc.c
+++ b/ext/lib/crypto/tinycrypt/source/ecc.c
@@ -97,7 +97,9 @@ static void vli_clear(uint32_t *p_vli)
}
}
-/* Returns nonzero if bit p_bit of p_vli is set. */
+/* Returns nonzero if bit p_bit of p_vli is set.
+ * It is assumed that the value provided in 'bit' is within
+ * the boundaries of the word-array 'p_vli'.*/
static uint32_t vli_testBit(uint32_t *p_vli, uint32_t p_bit)
{
return (p_vli[p_bit / 32] & (1 << (p_bit % 32)));
@@ -235,7 +237,7 @@ static void vli_square(uint32_t *p_result, uint32_t *p_left)
}
/* Computes p_result = p_product % curve_p using Barrett reduction. */
-static void vli_mmod_barrett(uint32_t *p_result, uint32_t *p_product,
+void vli_mmod_barrett(uint32_t *p_result, uint32_t *p_product,
uint32_t *p_mod, uint32_t *p_barrett)
{
uint32_t i;
@@ -547,7 +549,7 @@ void EccPoint_add(EccPointJacobi *P1, EccPointJacobi *P2)
*
* p_result = p_scalar * p_point.
*/
-void EccPoint_mult(EccPointJacobi *p_result, EccPoint *p_point, uint32_t *p_scalar)
+void EccPoint_mult_safe(EccPointJacobi *p_result, EccPoint *p_point, uint32_t *p_scalar)
{
int32_t i;
@@ -568,6 +570,25 @@ void EccPoint_mult(EccPointJacobi *p_result, EccPoint *p_point, uint32_t *p_scal
}
}
+/* Ellptic curve scalar multiplication with result in Jacobi coordinates */
+/* p_result = p_scalar * p_point */
+void EccPoint_mult_unsafe(EccPointJacobi *p_result, EccPoint *p_point, uint32_t *p_scalar)
+{
+ int i;
+ EccPointJacobi p_point_jacobi;
+ EccPoint_fromAffine(p_result, p_point);
+ EccPoint_fromAffine(&p_point_jacobi, p_point);
+
+ for(i = vli_numBits(p_scalar) - 2; i >= 0; i--)
+ {
+ EccPoint_double(p_result);
+ if (vli_testBit(p_scalar, i))
+ {
+ EccPoint_add(p_result, &p_point_jacobi);
+ }
+ }
+}
+
/* -------- Conversions between big endian and little endian: -------- */
void ecc_bytes2native(uint32_t p_native[NUM_ECC_DIGITS],
diff --git a/ext/lib/crypto/tinycrypt/source/ecc_dh.c b/ext/lib/crypto/tinycrypt/source/ecc_dh.c
index 965394b23..861001d43 100644
--- a/ext/lib/crypto/tinycrypt/source/ecc_dh.c
+++ b/ext/lib/crypto/tinycrypt/source/ecc_dh.c
@@ -35,31 +35,36 @@
extern uint32_t curve_p[NUM_ECC_DIGITS];
extern uint32_t curve_b[NUM_ECC_DIGITS];
extern uint32_t curve_n[NUM_ECC_DIGITS];
+extern uint32_t curve_pb[NUM_ECC_DIGITS + 1];
extern EccPoint curve_G;
int32_t ecc_make_key(EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS],
- uint32_t p_random[NUM_ECC_DIGITS])
+ uint32_t p_random[NUM_ECC_DIGITS * 2])
{
+ /* computing modular reduction of p_random (see FIPS 186.4 B.4.1): */
+ vli_mmod_barrett(p_privateKey, p_random, curve_p, curve_pb);
/* Make sure the private key is in the range [1, n-1].
* For the supported curve, n is always large enough
* that we only need to subtract once at most.
*/
uint32_t p_tmp[NUM_ECC_DIGITS];
-
- vli_set(p_privateKey, p_random);
vli_sub(p_tmp, p_privateKey, curve_n, NUM_ECC_DIGITS);
vli_cond_set(p_privateKey, p_privateKey, p_tmp,
vli_cmp(curve_n, p_privateKey, NUM_ECC_DIGITS) == 1);
+ /* erasing temporary buffer used to store secret: */
+ for (uint32_t i = 0; i < NUM_ECC_DIGITS; i++)
+ p_tmp[i] = 0;
+
if (vli_isZero(p_privateKey)) {
return TC_CRYPTO_FAIL; /* The private key cannot be 0 (mod p). */
}
EccPointJacobi P;
- EccPoint_mult(&P, &curve_G, p_privateKey);
+ EccPoint_mult_safe(&P, &curve_G, p_privateKey);
EccPoint_toAffine(p_publicKey, &P);
return TC_CRYPTO_SUCCESS;
@@ -102,6 +107,10 @@ int32_t ecc_valid_public_key(EccPoint *p_publicKey)
return -3;
}
+ if (vli_cmp(p_publicKey->x, curve_G.x, NUM_ECC_DIGITS) == 0 &&
+ vli_cmp(p_publicKey->y, curve_G.y, NUM_ECC_DIGITS) == 0 )
+ return -4;
+
return 0;
}
@@ -112,7 +121,7 @@ int32_t ecdh_shared_secret(uint32_t p_secret[NUM_ECC_DIGITS],
EccPoint p_point;
EccPointJacobi P;
- EccPoint_mult(&P, p_publicKey, p_privateKey);
+ EccPoint_mult_safe(&P, p_publicKey, p_privateKey);
if (EccPointJacobi_isZero(&P)) {
return TC_CRYPTO_FAIL;
}
diff --git a/ext/lib/crypto/tinycrypt/source/ecc_dsa.c b/ext/lib/crypto/tinycrypt/source/ecc_dsa.c
index 8636fa18e..dd84a1834 100644
--- a/ext/lib/crypto/tinycrypt/source/ecc_dsa.c
+++ b/ext/lib/crypto/tinycrypt/source/ecc_dsa.c
@@ -56,7 +56,7 @@ int32_t ecdsa_sign(uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS],
vli_cond_set(k, k, tmp, vli_cmp(curve_n, k, NUM_ECC_DIGITS) == 1);
/* tmp = k * G */
- EccPoint_mult(&P, &curve_G, k);
+ EccPoint_mult_safe(&P, &curve_G, k);
EccPoint_toAffine(&p_point, &P);
/* r = x1 (mod n) */
@@ -101,17 +101,15 @@ int32_t ecdsa_verify(EccPoint *p_publicKey, uint32_t p_hash[NUM_ECC_DIGITS],
vli_modMult(u2, r, z, curve_n, curve_nb); /* u2 = r/s */
/* calculate P = u1*G + u2*Q */
- EccPoint_mult(&P, &curve_G, u1);
- EccPoint_mult(&R, p_publicKey, u2);
+ EccPoint_mult_unsafe(&P, &curve_G, u1);
+ EccPoint_mult_unsafe(&R, p_publicKey, u2);
EccPoint_add(&P, &R);
EccPoint_toAffine(&p_point, &P);
/* Accept only if P.x == r. */
- vli_cond_set(
- p_point.x,
- p_point.x,
- z,
- vli_sub(z, p_point.x, curve_n, NUM_ECC_DIGITS));
+ if (!vli_sub(z, p_point.x, curve_n, NUM_ECC_DIGITS)) {
+ vli_set(p_point.x, z);
+ }
return (vli_cmp(p_point.x, r, NUM_ECC_DIGITS) == 0);
}
diff --git a/ext/lib/crypto/tinycrypt/source/utils.c b/ext/lib/crypto/tinycrypt/source/utils.c
index 3338e0ca4..147d8d407 100644
--- a/ext/lib/crypto/tinycrypt/source/utils.c
+++ b/ext/lib/crypto/tinycrypt/source/utils.c
@@ -55,14 +55,11 @@ void _set(void *to, uint8_t val, uint32_t len)
}
/*
- * Doubles the value of a byte for values up to 127. Original 'return
- * ((a<<1) ^ ((a>>7) * 0x1b))' re-written to avoid extra multiplication which
- * the compiler won't be able to optimize
+ * Doubles the value of a byte for values up to 127.
*/
uint8_t _double_byte(uint8_t a)
{
- return (a & MASK_MOST_SIG_BIT) ?
- ((a << 1) ^ MASK_TWENTY_SEVEN) : (a << 1);
+ return ((a<<1) ^ ((a>>7) * MASK_TWENTY_SEVEN));
}
int32_t _compare(const uint8_t *a, const uint8_t *b, size_t size)