Skip to content

Commit 3426508

Browse files
1010101001010101nashif
authored andcommitted
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 <[email protected]> Signed-off-by: Anas Nashif <[email protected]>
1 parent 00fa999 commit 3426508

File tree

9 files changed

+97
-38
lines changed

9 files changed

+97
-38
lines changed

ext/lib/crypto/tinycrypt/README

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ open source project. The original upstream code can be found at:
33

44
https://github.com/01org/tinycrypt
55

6-
At revision c7b1dca2b27070dfb5f92e56dab7a91a7afee18c, version 0.2.5
6+
At revision e6cffb820b91578d9816fc0bcc8f72f32f6ee76b, version 0.2.6
77

88
Any changes to the local version should include Zephyr's TinyCrypt
99
maintainer in the review. That can be found via the git history.

ext/lib/crypto/tinycrypt/include/tinycrypt/constants.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,6 @@ extern "C" {
4747
#define NULL ((void *)0)
4848
#endif
4949

50-
#ifndef bool
51-
enum {false, true} bool;
52-
#endif
53-
5450
#define TC_CRYPTO_SUCCESS 1
5551
#define TC_CRYPTO_FAIL 0
5652

ext/lib/crypto/tinycrypt/include/tinycrypt/ecc.h

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,12 @@
7979
extern "C" {
8080
#endif
8181

82+
/* Word size (4 bytes considering 32-bits architectures) */
83+
#define WORD_SIZE 4
8284
/* Number of words of 32 bits to represent an element of the the curve p-256: */
8385
#define NUM_ECC_DIGITS 8
8486
/* Number of bytes to represent an element of the the curve p-256: */
85-
#define NUM_ECC_BYTES (4*NUM_ECC_DIGITS)
87+
#define NUM_ECC_BYTES (WORD_SIZE*NUM_ECC_DIGITS)
8688

8789
/* struct to represent a point of the curve (uses X and Y coordinates): */
8890
typedef struct EccPoint {
@@ -218,6 +220,8 @@ void vli_modSquare_fast(uint32_t *p_result, uint32_t *p_left);
218220
* @param p_right IN -- buffer p_right in (p_left * p_right) % p_mod.
219221
* @param p_mod IN -- module.
220222
* @param p_barrett IN -- used for Barrett reduction.
223+
* @note Side-channel countermeasure: algorithm strengthened against timing
224+
* attack.
221225
*/
222226
void vli_modMult(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right,
223227
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,
229233
* @param p_input IN -- buffer p_input in (1/p_intput) % p_mod.
230234
* @param p_mod IN -- module.
231235
* @param p_barrett IN -- used for Barrett reduction.
236+
* @note Side-channel countermeasure: algorithm strengthened against timing
237+
* attack.
232238
*/
233239
void vli_modInv(uint32_t *p_result, uint32_t *p_input,
234240
uint32_t *p_mod, uint32_t *p_barrett);
235241

242+
/*
243+
* @brief modular reduction based on Barrett's method
244+
* @param p_result OUT -- p_product % p_mod.
245+
* @param p_product IN -- buffer p_product in (p_product % p_mod).
246+
* @param p_mod IN -- buffer p_mod in (p_product % p_mod).
247+
* @param p_barrett -- used for Barrett reduction.
248+
* @note Side-channel countermeasure: algorithm strengthened against timing
249+
* attack.
250+
*/
251+
void vli_mmod_barrett(
252+
uint32_t *p_result,
253+
uint32_t *p_product,
254+
uint32_t *p_mod,
255+
uint32_t *p_barrett);
256+
236257
/*
237258
* @brief Check if a point is zero.
238259
* @return Returns 1 if p_point is the point at infinity, 0 otherwise.
@@ -271,10 +292,26 @@ void EccPoint_add(EccPointJacobi *P1, EccPointJacobi *P2);
271292
* @param p_result OUT -- Product of p_point by p_scalar.
272293
* @param p_point IN -- Elliptic curve point
273294
* @param p_scalar IN -- Scalar integer
295+
* @note Side-channel countermeasure: algorithm strengthened against timing
296+
* attack.
274297
*/
275-
void EccPoint_mult(EccPointJacobi *p_result, EccPoint *p_point,
298+
void EccPoint_mult_safe(EccPointJacobi *p_result, EccPoint *p_point,
276299
uint32_t *p_scalar);
277300

301+
/*
302+
* @brief Fast elliptic curve scalar multiplication with result in Jacobi
303+
* coordinates
304+
* @note non constant time
305+
* @param p_result OUT -- Product of p_point by p_scalar.
306+
* @param p_point IN -- Elliptic curve point
307+
* @param p_scalar IN -- Scalar integer
308+
* @note algorithm NOT strengthened against timing attack.
309+
*/
310+
void EccPoint_mult_unsafe(
311+
EccPointJacobi *p_result,
312+
EccPoint *p_point,
313+
uint32_t *p_scalar);
314+
278315
/*
279316
* @brief Convert an integer in standard octet representation to native format.
280317
* @return returns TC_CRYPTO_SUCCESS (1)

ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dh.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ extern "C" {
8080

8181
/**
8282
* @brief Create a public/private key pair.
83-
* @return returns TC_CRYPTO_SUCCESS (1) if the key pair was generated successfully
83+
* @return returns TC_CRYPTO_SUCCESS (1) if key pair was generated successfully
8484
* returns TC_CRYPTO_FAIL (0) if:
8585
* the private key is 0
8686
*
@@ -90,13 +90,15 @@ extern "C" {
9090
*
9191
* @note You must use a new non-predictable random number to generate each
9292
* new key pair.
93+
* @note p_random must have NUM_ECC_DIGITS*2 bits of entropy to eliminate
94+
* bias in keys.
9395
*
9496
* @note side-channel countermeasure: algorithm strengthened against timing
9597
* attack.
9698
*/
9799
int32_t ecc_make_key(EccPoint *p_publicKey,
98100
uint32_t p_privateKey[NUM_ECC_DIGITS],
99-
uint32_t p_random[NUM_ECC_DIGITS]);
101+
uint32_t p_random[2 * NUM_ECC_DIGITS]);
100102

101103
/**
102104
* @brief Determine whether or not a given point is on the chosen elliptic curve
@@ -106,15 +108,16 @@ int32_t ecc_make_key(EccPoint *p_publicKey,
106108
* returns -2 if: curve_p - p_publicKey->x != 1 or
107109
* curve_p - p_publicKey->y != 1
108110
* returns -3 if: y^2 != x^3 + ax + b
109-
111+
* returns -4 if: public key is the group generator
112+
*
110113
* @param p_publicKey IN -- The point to be checked.
111114
*/
112115
int32_t ecc_valid_public_key(EccPoint *p_publicKey);
113116

114117
/**
115118
* @brief Compute a shared secret given your secret key and someone else's
116119
* public key.
117-
* @return returns TC_CRYPTO_SUCCESS (1) if the shared secret was computed successfully
120+
* @return returns TC_CRYPTO_SUCCESS (1) if the secret was computed successfully
118121
* returns TC_CRYPTO_FAIL (0) otherwise
119122
*
120123
* @param p_secret OUT -- The shared secret value.
@@ -125,12 +128,9 @@ int32_t ecc_valid_public_key(EccPoint *p_publicKey);
125128
* attacks. The random multiplier should probably be different for each
126129
* invocation of ecdh_shared_secret().
127130
*
128-
* @note It is recommended that you hash the result of ecdh_shared_secret before
129-
* using it for symmetric encryption or HMAC. If you do not hash the shared
130-
* secret, you must call ecc_valid_public_key() to verify that the remote side's
131-
* public key is valid. If this is not done, an attacker could create a public
132-
* key that would cause your use of the shared secret to leak information about
133-
* the private key.
131+
* @warning It is recommended to use the output of ecdh_shared_secret() as the
132+
* input of a recommended Key Derivation Function (see NIST SP 800-108) in
133+
* order to produce a symmetric key.
134134
*/
135135
int32_t ecdh_shared_secret(uint32_t p_secret[NUM_ECC_DIGITS], EccPoint *p_publicKey,
136136
uint32_t p_privateKey[NUM_ECC_DIGITS]);

ext/lib/crypto/tinycrypt/include/tinycrypt/hmac.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ int32_t tc_hmac_update(TCHmacState_t ctx,
125125
* ctx == NULL or
126126
* key == NULL or
127127
* taglen != TC_SHA256_DIGEST_SIZE
128+
* @note 'ctx' is erased before exiting (this must never be changed/removed).
128129
* @note Assumes the tag bufer is at least sizeof(hmac_tag_size(state)) bytes
129130
* state has been initialized by tc_hmac_init
130131
* @param tag IN/OUT -- buffer to receive computed HMAC tag

ext/lib/crypto/tinycrypt/source/ecc.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ static void vli_clear(uint32_t *p_vli)
9797
}
9898
}
9999

100-
/* Returns nonzero if bit p_bit of p_vli is set. */
100+
/* Returns nonzero if bit p_bit of p_vli is set.
101+
* It is assumed that the value provided in 'bit' is within
102+
* the boundaries of the word-array 'p_vli'.*/
101103
static uint32_t vli_testBit(uint32_t *p_vli, uint32_t p_bit)
102104
{
103105
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)
235237
}
236238

237239
/* Computes p_result = p_product % curve_p using Barrett reduction. */
238-
static void vli_mmod_barrett(uint32_t *p_result, uint32_t *p_product,
240+
void vli_mmod_barrett(uint32_t *p_result, uint32_t *p_product,
239241
uint32_t *p_mod, uint32_t *p_barrett)
240242
{
241243
uint32_t i;
@@ -547,7 +549,7 @@ void EccPoint_add(EccPointJacobi *P1, EccPointJacobi *P2)
547549
*
548550
* p_result = p_scalar * p_point.
549551
*/
550-
void EccPoint_mult(EccPointJacobi *p_result, EccPoint *p_point, uint32_t *p_scalar)
552+
void EccPoint_mult_safe(EccPointJacobi *p_result, EccPoint *p_point, uint32_t *p_scalar)
551553
{
552554

553555
int32_t i;
@@ -568,6 +570,25 @@ void EccPoint_mult(EccPointJacobi *p_result, EccPoint *p_point, uint32_t *p_scal
568570
}
569571
}
570572

573+
/* Ellptic curve scalar multiplication with result in Jacobi coordinates */
574+
/* p_result = p_scalar * p_point */
575+
void EccPoint_mult_unsafe(EccPointJacobi *p_result, EccPoint *p_point, uint32_t *p_scalar)
576+
{
577+
int i;
578+
EccPointJacobi p_point_jacobi;
579+
EccPoint_fromAffine(p_result, p_point);
580+
EccPoint_fromAffine(&p_point_jacobi, p_point);
581+
582+
for(i = vli_numBits(p_scalar) - 2; i >= 0; i--)
583+
{
584+
EccPoint_double(p_result);
585+
if (vli_testBit(p_scalar, i))
586+
{
587+
EccPoint_add(p_result, &p_point_jacobi);
588+
}
589+
}
590+
}
591+
571592
/* -------- Conversions between big endian and little endian: -------- */
572593

573594
void ecc_bytes2native(uint32_t p_native[NUM_ECC_DIGITS],

ext/lib/crypto/tinycrypt/source/ecc_dh.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,31 +35,36 @@
3535
extern uint32_t curve_p[NUM_ECC_DIGITS];
3636
extern uint32_t curve_b[NUM_ECC_DIGITS];
3737
extern uint32_t curve_n[NUM_ECC_DIGITS];
38+
extern uint32_t curve_pb[NUM_ECC_DIGITS + 1];
3839
extern EccPoint curve_G;
3940

4041
int32_t ecc_make_key(EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS],
41-
uint32_t p_random[NUM_ECC_DIGITS])
42+
uint32_t p_random[NUM_ECC_DIGITS * 2])
4243
{
44+
/* computing modular reduction of p_random (see FIPS 186.4 B.4.1): */
45+
vli_mmod_barrett(p_privateKey, p_random, curve_p, curve_pb);
4346

4447
/* Make sure the private key is in the range [1, n-1].
4548
* For the supported curve, n is always large enough
4649
* that we only need to subtract once at most.
4750
*/
4851
uint32_t p_tmp[NUM_ECC_DIGITS];
49-
50-
vli_set(p_privateKey, p_random);
5152
vli_sub(p_tmp, p_privateKey, curve_n, NUM_ECC_DIGITS);
5253

5354
vli_cond_set(p_privateKey, p_privateKey, p_tmp,
5455
vli_cmp(curve_n, p_privateKey, NUM_ECC_DIGITS) == 1);
5556

57+
/* erasing temporary buffer used to store secret: */
58+
for (uint32_t i = 0; i < NUM_ECC_DIGITS; i++)
59+
p_tmp[i] = 0;
60+
5661
if (vli_isZero(p_privateKey)) {
5762
return TC_CRYPTO_FAIL; /* The private key cannot be 0 (mod p). */
5863
}
5964

6065
EccPointJacobi P;
6166

62-
EccPoint_mult(&P, &curve_G, p_privateKey);
67+
EccPoint_mult_safe(&P, &curve_G, p_privateKey);
6368
EccPoint_toAffine(p_publicKey, &P);
6469

6570
return TC_CRYPTO_SUCCESS;
@@ -102,6 +107,10 @@ int32_t ecc_valid_public_key(EccPoint *p_publicKey)
102107
return -3;
103108
}
104109

110+
if (vli_cmp(p_publicKey->x, curve_G.x, NUM_ECC_DIGITS) == 0 &&
111+
vli_cmp(p_publicKey->y, curve_G.y, NUM_ECC_DIGITS) == 0 )
112+
return -4;
113+
105114
return 0;
106115
}
107116

@@ -112,7 +121,7 @@ int32_t ecdh_shared_secret(uint32_t p_secret[NUM_ECC_DIGITS],
112121
EccPoint p_point;
113122
EccPointJacobi P;
114123

115-
EccPoint_mult(&P, p_publicKey, p_privateKey);
124+
EccPoint_mult_safe(&P, p_publicKey, p_privateKey);
116125
if (EccPointJacobi_isZero(&P)) {
117126
return TC_CRYPTO_FAIL;
118127
}

ext/lib/crypto/tinycrypt/source/ecc_dsa.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ int32_t ecdsa_sign(uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS],
5656
vli_cond_set(k, k, tmp, vli_cmp(curve_n, k, NUM_ECC_DIGITS) == 1);
5757

5858
/* tmp = k * G */
59-
EccPoint_mult(&P, &curve_G, k);
59+
EccPoint_mult_safe(&P, &curve_G, k);
6060
EccPoint_toAffine(&p_point, &P);
6161

6262
/* r = x1 (mod n) */
@@ -101,17 +101,15 @@ int32_t ecdsa_verify(EccPoint *p_publicKey, uint32_t p_hash[NUM_ECC_DIGITS],
101101
vli_modMult(u2, r, z, curve_n, curve_nb); /* u2 = r/s */
102102

103103
/* calculate P = u1*G + u2*Q */
104-
EccPoint_mult(&P, &curve_G, u1);
105-
EccPoint_mult(&R, p_publicKey, u2);
104+
EccPoint_mult_unsafe(&P, &curve_G, u1);
105+
EccPoint_mult_unsafe(&R, p_publicKey, u2);
106106
EccPoint_add(&P, &R);
107107
EccPoint_toAffine(&p_point, &P);
108108

109109
/* Accept only if P.x == r. */
110-
vli_cond_set(
111-
p_point.x,
112-
p_point.x,
113-
z,
114-
vli_sub(z, p_point.x, curve_n, NUM_ECC_DIGITS));
110+
if (!vli_sub(z, p_point.x, curve_n, NUM_ECC_DIGITS)) {
111+
vli_set(p_point.x, z);
112+
}
115113

116114
return (vli_cmp(p_point.x, r, NUM_ECC_DIGITS) == 0);
117115
}

ext/lib/crypto/tinycrypt/source/utils.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,11 @@ void _set(void *to, uint8_t val, uint32_t len)
5555
}
5656

5757
/*
58-
* Doubles the value of a byte for values up to 127. Original 'return
59-
* ((a<<1) ^ ((a>>7) * 0x1b))' re-written to avoid extra multiplication which
60-
* the compiler won't be able to optimize
58+
* Doubles the value of a byte for values up to 127.
6159
*/
6260
uint8_t _double_byte(uint8_t a)
6361
{
64-
return (a & MASK_MOST_SIG_BIT) ?
65-
((a << 1) ^ MASK_TWENTY_SEVEN) : (a << 1);
62+
return ((a<<1) ^ ((a>>7) * MASK_TWENTY_SEVEN));
6663
}
6764

6865
int32_t _compare(const uint8_t *a, const uint8_t *b, size_t size)

0 commit comments

Comments
 (0)