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>
This commit is contained in:
parent
381df63fe8
commit
c2cc5f90e2
|
@ -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
|
||||
|
||||
|
|
|
@ -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,10 +233,27 @@ 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,10 +292,26 @@ 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)
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue