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>
133 lines
4.3 KiB
C
133 lines
4.3 KiB
C
/* ec_dh.c - TinyCrypt implementation of EC-DH */
|
|
|
|
/*
|
|
* Copyright (C) 2015 by Intel Corporation, All Rights Reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* - Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* - Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* - Neither the name of Intel Corporation nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
#include <tinycrypt/constants.h>
|
|
#include <tinycrypt/ecc.h>
|
|
|
|
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 * 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_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_safe(&P, &curve_G, p_privateKey);
|
|
EccPoint_toAffine(p_publicKey, &P);
|
|
|
|
return TC_CRYPTO_SUCCESS;
|
|
}
|
|
|
|
/* Compute p_result = x^3 - 3x + b */
|
|
static void curve_x_side(uint32_t p_result[NUM_ECC_DIGITS],
|
|
uint32_t x[NUM_ECC_DIGITS])
|
|
{
|
|
|
|
uint32_t _3[NUM_ECC_DIGITS] = {3}; /* -a = 3 */
|
|
|
|
vli_modSquare_fast(p_result, x); /* r = x^2 */
|
|
vli_modSub(p_result, p_result, _3, curve_p); /* r = x^2 - 3 */
|
|
vli_modMult_fast(p_result, p_result, x); /* r = x^3 - 3x */
|
|
vli_modAdd(p_result, p_result, curve_b, curve_p); /* r = x^3 - 3x + b */
|
|
|
|
}
|
|
|
|
int32_t ecc_valid_public_key(EccPoint *p_publicKey)
|
|
{
|
|
uint32_t l_tmp1[NUM_ECC_DIGITS];
|
|
uint32_t l_tmp2[NUM_ECC_DIGITS];
|
|
|
|
if (EccPoint_isZero(p_publicKey)) {
|
|
return -1;
|
|
}
|
|
|
|
if ((vli_cmp(curve_p, p_publicKey->x, NUM_ECC_DIGITS) != 1) ||
|
|
(vli_cmp(curve_p, p_publicKey->y, NUM_ECC_DIGITS) != 1)) {
|
|
return -2;
|
|
}
|
|
|
|
vli_modSquare_fast(l_tmp1, p_publicKey->y); /* tmp1 = y^2 */
|
|
|
|
curve_x_side(l_tmp2, p_publicKey->x); /* tmp2 = x^3 - 3x + b */
|
|
|
|
/* Make sure that y^2 == x^3 + ax + b */
|
|
if (vli_cmp(l_tmp1, l_tmp2, NUM_ECC_DIGITS) != 0) {
|
|
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;
|
|
}
|
|
|
|
int32_t ecdh_shared_secret(uint32_t p_secret[NUM_ECC_DIGITS],
|
|
EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS])
|
|
{
|
|
|
|
EccPoint p_point;
|
|
EccPointJacobi P;
|
|
|
|
EccPoint_mult_safe(&P, p_publicKey, p_privateKey);
|
|
if (EccPointJacobi_isZero(&P)) {
|
|
return TC_CRYPTO_FAIL;
|
|
}
|
|
EccPoint_toAffine(&p_point, &P);
|
|
vli_set(p_secret, p_point.x);
|
|
|
|
return TC_CRYPTO_SUCCESS;
|
|
}
|