Path: blob/main/crypto/libecc/src/sig/ecdsa_common.c
39534 views
/*1* Copyright (C) 2017 - This file is part of libecc project2*3* Authors:4* Ryad BENADJILA <[email protected]>5* Arnaud EBALARD <[email protected]>6* Jean-Pierre FLORI <[email protected]>7*8* Contributors:9* Nicolas VIVET <[email protected]>10* Karim KHALFALLAH <[email protected]>11*12* This software is licensed under a dual BSD and GPL v2 license.13* See LICENSE file at the root folder of the project.14*/15#include <libecc/lib_ecc_config.h>16#if defined(WITH_SIG_ECDSA) || defined(WITH_SIG_DECDSA)1718#include <libecc/nn/nn_rand.h>19#include <libecc/nn/nn_mul_public.h>20#include <libecc/nn/nn_logical.h>2122#include <libecc/sig/sig_algs_internal.h>23#include <libecc/sig/ec_key.h>24#include <libecc/utils/utils.h>25#ifdef VERBOSE_INNER_VALUES26#define EC_SIG_ALG "ECDSA"27#endif28#include <libecc/utils/dbg_sig.h>293031#if defined(WITH_SIG_DECDSA)32#include <libecc/hash/hmac.h>3334/*35* Deterministic nonce generation function for deterministic ECDSA, as36* described in RFC6979.37* NOTE: Deterministic nonce generation for ECDSA is useful against attackers38* in contexts where only poor RNG/entropy are available, or when nonce bits39* leaking can be possible through side-channel attacks.40* However, in contexts where fault attacks are easy to mount, deterministic41* ECDSA can bring more security risks than regular ECDSA.42*43* Depending on the context where you use the library, choose carefully if44* you want to use the deterministic version or not.45*46*/47ATTRIBUTE_WARN_UNUSED_RET static int __ecdsa_rfc6979_nonce(nn_t k, nn_src_t q, bitcnt_t q_bit_len,48nn_src_t x, const u8 *hash, u8 hsize,49hash_alg_type hash_type)50{51int ret, cmp;52u8 V[MAX_DIGEST_SIZE];53u8 K[MAX_DIGEST_SIZE];54u8 T[BYTECEIL(CURVES_MAX_Q_BIT_LEN) + MAX_DIGEST_SIZE];55u8 priv_key_buff[EC_PRIV_KEY_MAX_SIZE];56hmac_context hmac_ctx;57bitcnt_t t_bit_len;58u8 q_len;59u8 hmac_size;60u8 tmp;6162/* Sanity checks */63MUST_HAVE((k != NULL), ret, err);64MUST_HAVE((hash != NULL), ret, err);65ret = nn_check_initialized(q); EG(ret, err);66ret = nn_check_initialized(x); EG(ret, err);6768q_len = (u8)BYTECEIL(q_bit_len);6970MUST_HAVE((q_len <= EC_PRIV_KEY_MAX_SIZE) && (hsize <= MAX_BLOCK_SIZE), ret, err);7172/* Steps b. and c.: set V = 0x01 ... 0x01 and K = 0x00 ... 0x00 */73ret = local_memset(V, 0x01, hsize); EG(ret, err);74ret = local_memset(K, 0x00, hsize); EG(ret, err);75/* Export our private key in a buffer */76ret = nn_export_to_buf(priv_key_buff, q_len, x); EG(ret, err);77/* Step d.: set K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1))78* where x is the private key and h1 the message hash.79*/80ret = hmac_init(&hmac_ctx, K, hsize, hash_type); EG(ret, err);81ret = hmac_update(&hmac_ctx, V, hsize); EG(ret, err);8283tmp = 0x00;84ret = hmac_update(&hmac_ctx, &tmp, 1); EG(ret, err);85ret = hmac_update(&hmac_ctx, priv_key_buff, q_len); EG(ret, err);8687/* We compute bits2octets(hash) here */88ret = nn_init_from_buf(k, hash, hsize); EG(ret, err);89if((8 * hsize) > q_bit_len){90ret = nn_rshift(k, k, (bitcnt_t)((8 * hsize) - q_bit_len)); EG(ret, err);91}92ret = nn_mod(k, k, q); EG(ret, err);93ret = nn_export_to_buf(T, q_len, k); EG(ret, err);94ret = hmac_update(&hmac_ctx, T, q_len); EG(ret, err);95hmac_size = sizeof(K);96ret = hmac_finalize(&hmac_ctx, K, &hmac_size); EG(ret, err);9798/* Step e.: set V = HMAC_K(V) */99hmac_size = sizeof(V);100ret = hmac(K, hsize, hash_type, V, hsize, V, &hmac_size); EG(ret, err);101/* Step f.: K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1)) */102ret = hmac_init(&hmac_ctx, K, hsize, hash_type); EG(ret, err);103ret = hmac_update(&hmac_ctx, V, hsize); EG(ret, err);104105tmp = 0x01;106ret = hmac_update(&hmac_ctx, &tmp, 1); EG(ret, err);107ret = hmac_update(&hmac_ctx, priv_key_buff, q_len); EG(ret, err);108109/* We compute bits2octets(hash) here */110ret = hmac_update(&hmac_ctx, T, q_len); EG(ret, err);111hmac_size = sizeof(K);112ret = hmac_finalize(&hmac_ctx, K, &hmac_size); EG(ret, err);113/* Step g.: set V = HMAC_K(V)*/114hmac_size = sizeof(V);115ret = hmac(K, hsize, hash_type, V, hsize, V, &hmac_size); EG(ret, err);116117/* Step h. now apply the generation algorithm until we get118* a proper nonce value:119* 1. Set T to the empty sequence. The length of T (in bits) is120* denoted tlen; thus, at that point, tlen = 0.121* 2. While tlen < qlen, do the following:122* V = HMAC_K(V)123* T = T || V124* 3. Compute:125* k = bits2int(T)126* If that value of k is within the [1,q-1] range, and is127* suitable for DSA or ECDSA (i.e., it results in an r value128* that is not 0; see Section 3.4), then the generation of k is129* finished. The obtained value of k is used in DSA or ECDSA.130* Otherwise, compute:131* K = HMAC_K(V || 0x00)132* V = HMAC_K(V)133* and loop (try to generate a new T, and so on).134*/135restart:136t_bit_len = 0;137while(t_bit_len < q_bit_len){138/* V = HMAC_K(V) */139hmac_size = sizeof(V);140ret = hmac(K, hsize, hash_type, V, hsize, V, &hmac_size); EG(ret, err);141ret = local_memcpy(&T[BYTECEIL(t_bit_len)], V, hmac_size); EG(ret, err);142t_bit_len = (bitcnt_t)(t_bit_len + (8 * hmac_size));143}144ret = nn_init_from_buf(k, T, q_len); EG(ret, err);145if((8 * q_len) > q_bit_len){146ret = nn_rshift(k, k, (bitcnt_t)((8 * q_len) - q_bit_len)); EG(ret, err);147}148ret = nn_cmp(k, q, &cmp); EG(ret, err);149if(cmp >= 0){150/* K = HMAC_K(V || 0x00) */151ret = hmac_init(&hmac_ctx, K, hsize, hash_type); EG(ret, err);152ret = hmac_update(&hmac_ctx, V, hsize); EG(ret, err);153154tmp = 0x00;155ret = hmac_update(&hmac_ctx, &tmp, 1); EG(ret, err);156157hmac_size = sizeof(K);158ret = hmac_finalize(&hmac_ctx, K, &hmac_size); EG(ret, err);159/* V = HMAC_K(V) */160hmac_size = sizeof(V);161ret = hmac(K, hsize, hash_type, V, hsize, V, &hmac_size); EG(ret, err);162163goto restart;164}165166err:167return ret;168}169#endif170171int __ecdsa_init_pub_key(ec_pub_key *out_pub, const ec_priv_key *in_priv,172ec_alg_type key_type)173{174prj_pt_src_t G;175int ret, cmp;176nn_src_t q;177178MUST_HAVE((out_pub != NULL), ret, err);179180/* Zero init public key to be generated */181ret = local_memset(out_pub, 0, sizeof(ec_pub_key)); EG(ret, err);182183ret = priv_key_check_initialized_and_type(in_priv, key_type); EG(ret, err);184q = &(in_priv->params->ec_gen_order);185186/* Sanity check on key compliance */187MUST_HAVE((!nn_cmp(&(in_priv->x), q, &cmp)) && (cmp < 0), ret, err);188189/* Y = xG */190G = &(in_priv->params->ec_gen);191/* Use blinding when computing point scalar multiplication */192ret = prj_pt_mul_blind(&(out_pub->y), &(in_priv->x), G); EG(ret, err);193194out_pub->key_type = key_type;195out_pub->params = in_priv->params;196out_pub->magic = PUB_KEY_MAGIC;197198err:199return ret;200}201202int __ecdsa_siglen(u16 p_bit_len, u16 q_bit_len, u8 hsize, u8 blocksize, u8 *siglen)203{204int ret;205206MUST_HAVE(siglen != NULL, ret, err);207MUST_HAVE((p_bit_len <= CURVES_MAX_P_BIT_LEN) &&208(q_bit_len <= CURVES_MAX_Q_BIT_LEN) &&209(hsize <= MAX_DIGEST_SIZE) && (blocksize <= MAX_BLOCK_SIZE), ret, err);210(*siglen) = (u8)ECDSA_SIGLEN(q_bit_len);211ret = 0;212213err:214return ret;215}216217/*218* Generic *internal* ECDSA signature functions (init, update and finalize).219* Their purpose is to allow passing a specific hash function (along with220* its output size) and the random ephemeral key k, so that compliance221* tests against test vectors can be made without ugly hack in the code222* itself.223*224* Global EC-DSA signature process is as follows (I,U,F provides225* information in which function(s) (init(), update() or finalize())226* a specific step is performed):227*228*| IUF - ECDSA signature229*|230*| UF 1. Compute h = H(m)231*| F 2. If |h| > bitlen(q), set h to bitlen(q)232*| leftmost (most significant) bits of h233*| F 3. e = OS2I(h) mod q234*| F 4. Get a random value k in ]0,q[235*| F 5. Compute W = (W_x,W_y) = kG236*| F 6. Compute r = W_x mod q237*| F 7. If r is 0, restart the process at step 4.238*| F 8. If e == rx, restart the process at step 4.239*| F 9. Compute s = k^-1 * (xr + e) mod q240*| F 10. If s is 0, restart the process at step 4.241*| F 11. Return (r,s)242*243* Implementation notes:244*245* a) Usually (this is for instance the case in ISO 14888-3 and X9.62), the246* process starts with steps 4 to 7 and is followed by steps 1 to 3.247* The order is modified here w/o impact on the result and the security248* in order to allow the algorithm to be compatible with an249* init/update/finish API. More explicitly, the generation of k, which250* may later result in a (unlikely) restart of the whole process is251* postponed until the hash of the message has been computed.252* b) sig is built as the concatenation of r and s. Both r and s are253* encoded on ceil(bitlen(q)/8) bytes.254* c) in EC-DSA, the public part of the key is not needed per se during the255* signature but - as it is needed in other signature algs implemented256* in the library - the whole key pair is passed instead of just the257* private key.258*/259260#define ECDSA_SIGN_MAGIC ((word_t)(0x80299a2bf630945bULL))261#define ECDSA_SIGN_CHECK_INITIALIZED(A, ret, err) \262MUST_HAVE((((void *)(A)) != NULL) && ((A)->magic == ECDSA_SIGN_MAGIC), ret, err)263264int __ecdsa_sign_init(struct ec_sign_context *ctx, ec_alg_type key_type)265{266int ret;267268/* First, verify context has been initialized */269ret = sig_sign_check_initialized(ctx); EG(ret, err);270271/* Additional sanity checks on input params from context */272ret = key_pair_check_initialized_and_type(ctx->key_pair, key_type); EG(ret, err);273274MUST_HAVE((ctx->h != NULL) && (ctx->h->digest_size <= MAX_DIGEST_SIZE) &&275(ctx->h->block_size <= MAX_BLOCK_SIZE), ret, err);276277/*278* Initialize hash context stored in our private part of context279* and record data init has been done280*/281/* Since we call a callback, sanity check our mapping */282ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);283ret = ctx->h->hfunc_init(&(ctx->sign_data.ecdsa.h_ctx)); EG(ret, err);284285ctx->sign_data.ecdsa.magic = ECDSA_SIGN_MAGIC;286287err:288return ret;289}290291int __ecdsa_sign_update(struct ec_sign_context *ctx,292const u8 *chunk, u32 chunklen, ec_alg_type key_type)293{294int ret;295296/*297* First, verify context has been initialized and private298* part too. This guarantees the context is an ECDSA299* signature one and we do not update() or finalize()300* before init().301*/302ret = sig_sign_check_initialized(ctx); EG(ret, err);303ECDSA_SIGN_CHECK_INITIALIZED(&(ctx->sign_data.ecdsa), ret, err);304305/* Additional sanity checks on input params from context */306ret = key_pair_check_initialized_and_type(ctx->key_pair, key_type); EG(ret, err);307308/* 1. Compute h = H(m) */309/* Since we call a callback, sanity check our mapping */310ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);311ret = ctx->h->hfunc_update(&(ctx->sign_data.ecdsa.h_ctx), chunk, chunklen);312313err:314return ret;315}316317int __ecdsa_sign_finalize(struct ec_sign_context *ctx, u8 *sig, u8 siglen,318ec_alg_type key_type)319{320int ret, iszero, cmp;321const ec_priv_key *priv_key;322prj_pt_src_t G;323u8 hash[MAX_DIGEST_SIZE];324bitcnt_t rshift, q_bit_len;325prj_pt kG;326nn_src_t q, x;327u8 hsize, q_len;328nn k, r, e, tmp, s, kinv;329#ifdef USE_SIG_BLINDING330/* b is the blinding mask */331nn b;332b.magic = WORD(0);333#endif334335k.magic = r.magic = e.magic = WORD(0);336tmp.magic = s.magic = kinv.magic = WORD(0);337kG.magic = WORD(0);338339/*340* First, verify context has been initialized and private341* part too. This guarantees the context is an ECDSA342* signature one and we do not finalize() before init().343*/344ret = sig_sign_check_initialized(ctx); EG(ret, err);345ECDSA_SIGN_CHECK_INITIALIZED(&(ctx->sign_data.ecdsa), ret, err);346MUST_HAVE((sig != NULL), ret, err);347348/* Additional sanity checks on input params from context */349ret = key_pair_check_initialized_and_type(ctx->key_pair, key_type); EG(ret, err);350351/* Zero init out point */352ret = local_memset(&kG, 0, sizeof(prj_pt)); EG(ret, err);353354/* Make things more readable */355priv_key = &(ctx->key_pair->priv_key);356q = &(priv_key->params->ec_gen_order);357q_bit_len = priv_key->params->ec_gen_order_bitlen;358G = &(priv_key->params->ec_gen);359q_len = (u8)BYTECEIL(q_bit_len);360x = &(priv_key->x);361hsize = ctx->h->digest_size;362363MUST_HAVE((priv_key->key_type == key_type), ret, err);364365/* Sanity check */366ret = nn_cmp(x, q, &cmp); EG(ret, err);367/* This should not happen and means that our368* private key is not compliant!369*/370MUST_HAVE((cmp < 0), ret, err);371372dbg_nn_print("p", &(priv_key->params->ec_fp.p));373dbg_nn_print("q", &(priv_key->params->ec_gen_order));374dbg_priv_key_print("x", priv_key);375dbg_ec_point_print("G", &(priv_key->params->ec_gen));376dbg_pub_key_print("Y", &(ctx->key_pair->pub_key));377378/* Check given signature buffer length has the expected size */379MUST_HAVE((siglen == ECDSA_SIGLEN(q_bit_len)), ret, err);380381/* 1. Compute h = H(m) */382ret = local_memset(hash, 0, hsize); EG(ret, err);383/* Since we call a callback, sanity check our mapping */384ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);385ret = ctx->h->hfunc_finalize(&(ctx->sign_data.ecdsa.h_ctx), hash); EG(ret, err);386dbg_buf_print("h", hash, hsize);387388/*389* 2. If |h| > bitlen(q), set h to bitlen(q)390* leftmost bits of h.391*392* Note that it's easier to check if the truncation has393* to be done here but only implement it using a logical394* shift at the beginning of step 3. below once the hash395* has been converted to an integer.396*/397rshift = 0;398if ((hsize * 8) > q_bit_len) {399rshift = (bitcnt_t)((hsize * 8) - q_bit_len);400}401402/*403* 3. Compute e = OS2I(h) mod q, i.e. by converting h to an404* integer and reducing it mod q405*/406ret = nn_init_from_buf(&e, hash, hsize); EG(ret, err);407dbg_nn_print("h initial import as nn", &e);408if (rshift) {409ret = nn_rshift_fixedlen(&e, &e, rshift); EG(ret, err);410}411dbg_nn_print("h final import as nn", &e);412ret = nn_mod(&e, &e, q); EG(ret, err);413dbg_nn_print("e", &e);414415restart:416/* 4. get a random value k in ]0,q[ */417#ifdef NO_KNOWN_VECTORS418/* NOTE: when we do not need self tests for known vectors,419* we can be strict about random function handler!420* This allows us to avoid the corruption of such a pointer.421*/422/* Sanity check on the handler before calling it */423if(ctx->rand != nn_get_random_mod){424#ifdef WITH_SIG_DECDSA425/* In deterministic ECDSA, nevermind! */426if(key_type != DECDSA)427#endif428{429ret = -1;430goto err;431}432}433#endif434if(ctx->rand != NULL){435/* Non-deterministic generation, or deterministic with436* test vectors.437*/438ret = ctx->rand(&k, q);439}440else441#if defined(WITH_SIG_DECDSA)442{443/* Only applies for DETERMINISTIC ECDSA */444if(key_type != DECDSA){445ret = -1;446goto err;447}448/* Deterministically generate k as RFC6979 mandates */449ret = __ecdsa_rfc6979_nonce(&k, q, q_bit_len, &(priv_key->x),450hash, hsize, ctx->h->type);451}452#else453{454/* NULL rand function is not accepted for regular ECDSA */455ret = -1;456goto err;457}458#endif459if (ret) {460ret = -1;461goto err;462}463dbg_nn_print("k", &k);464465#ifdef USE_SIG_BLINDING466/* Note: if we use blinding, r and e are multiplied by467* a random value b in ]0,q[ */468ret = nn_get_random_mod(&b, q); EG(ret, err);469470dbg_nn_print("b", &b);471#endif /* USE_SIG_BLINDING */472473474/* 5. Compute W = (W_x,W_y) = kG */475#ifdef USE_SIG_BLINDING476ret = prj_pt_mul_blind(&kG, &k, G); EG(ret, err);477#else478ret = prj_pt_mul(&kG, &k, G); EG(ret, err);479#endif /* USE_SIG_BLINDING */480ret = prj_pt_unique(&kG, &kG); EG(ret, err);481482dbg_nn_print("W_x", &(kG.X.fp_val));483dbg_nn_print("W_y", &(kG.Y.fp_val));484485/* 6. Compute r = W_x mod q */486ret = nn_mod(&r, &(kG.X.fp_val), q); EG(ret, err);487dbg_nn_print("r", &r);488489/* 7. If r is 0, restart the process at step 4. */490ret = nn_iszero(&r, &iszero); EG(ret, err);491if (iszero) {492goto restart;493}494495/* Clean hash buffer as we do not need it anymore */496ret = local_memset(hash, 0, hsize); EG(ret, err);497498/* Export r */499ret = nn_export_to_buf(sig, q_len, &r); EG(ret, err);500501#ifdef USE_SIG_BLINDING502/* Blind r with b */503ret = nn_mod_mul(&r, &r, &b, q); EG(ret, err);504505/* Blind the message e */506ret = nn_mod_mul(&e, &e, &b, q); EG(ret, err);507#endif /* USE_SIG_BLINDING */508509/* tmp = xr mod q */510ret = nn_mod_mul(&tmp, x, &r, q); EG(ret, err);511dbg_nn_print("x*r mod q", &tmp);512513/* 8. If e == rx, restart the process at step 4. */514ret = nn_cmp(&e, &tmp, &cmp); EG(ret, err);515if (!cmp) {516goto restart;517}518519/* 9. Compute s = k^-1 * (xr + e) mod q */520521/* tmp = (e + xr) mod q */522ret = nn_mod_add(&tmp, &tmp, &e, q); EG(ret, err);523dbg_nn_print("(xr + e) mod q", &tmp);524525#ifdef USE_SIG_BLINDING526/*527* In case of blinding, we compute (b*k)^-1, and b^-1 will528* automatically unblind (r*x) in the following.529*/530ret = nn_mod_mul(&k, &k, &b, q); EG(ret, err);531#endif532/* Compute k^-1 mod q */533/* NOTE: we use Fermat's little theorem inversion for534* constant time here. This is possible since q is prime.535*/536ret = nn_modinv_fermat(&kinv, &k, q); EG(ret, err);537538dbg_nn_print("k^-1 mod q", &kinv);539540/* s = k^-1 * tmp2 mod q */541ret = nn_mod_mul(&s, &tmp, &kinv, q); EG(ret, err);542543dbg_nn_print("s", &s);544545/* 10. If s is 0, restart the process at step 4. */546ret = nn_iszero(&s, &iszero); EG(ret, err);547if (iszero) {548goto restart;549}550551/* 11. return (r,s) */552ret = nn_export_to_buf(sig + q_len, q_len, &s);553554err:555nn_uninit(&k);556nn_uninit(&r);557nn_uninit(&e);558nn_uninit(&tmp);559nn_uninit(&s);560nn_uninit(&kinv);561prj_pt_uninit(&kG);562#ifdef USE_SIG_BLINDING563nn_uninit(&b);564#endif565566/*567* We can now clear data part of the context. This will clear568* magic and avoid further reuse of the whole context.569*/570if(ctx != NULL){571IGNORE_RET_VAL(local_memset(&(ctx->sign_data.ecdsa), 0, sizeof(ecdsa_sign_data)));572}573574/* Clean what remains on the stack */575PTR_NULLIFY(priv_key);576PTR_NULLIFY(G);577PTR_NULLIFY(q);578PTR_NULLIFY(x);579VAR_ZEROIFY(q_len);580VAR_ZEROIFY(q_bit_len);581VAR_ZEROIFY(rshift);582VAR_ZEROIFY(hsize);583584return ret;585}586587/*588* Generic *internal* ECDSA verification functions (init, update and finalize).589* Their purpose is to allow passing a specific hash function (along with590* its output size) and the random ephemeral key k, so that compliance591* tests against test vectors can be made without ugly hack in the code592* itself.593*594* Global ECDSA verification process is as follows (I,U,F provides595* information in which function(s) (init(), update() or finalize())596* a specific step is performed):597*598*| IUF - ECDSA verification599*|600*| I 1. Reject the signature if r or s is 0.601*| UF 2. Compute h = H(m)602*| F 3. If |h| > bitlen(q), set h to bitlen(q)603*| leftmost (most significant) bits of h604*| F 4. Compute e = OS2I(h) mod q605*| F 5. Compute u = (s^-1)e mod q606*| F 6. Compute v = (s^-1)r mod q607*| F 7. Compute W' = uG + vY608*| F 8. If W' is the point at infinity, reject the signature.609*| F 9. Compute r' = W'_x mod q610*| F 10. Accept the signature if and only if r equals r'611*612*/613614#define ECDSA_VERIFY_MAGIC ((word_t)(0x5155fe73e7fd51beULL))615#define ECDSA_VERIFY_CHECK_INITIALIZED(A, ret, err) \616MUST_HAVE((((void *)(A)) != NULL) && ((A)->magic == ECDSA_VERIFY_MAGIC), ret, err)617618int __ecdsa_verify_init(struct ec_verify_context *ctx, const u8 *sig, u8 siglen,619ec_alg_type key_type)620{621bitcnt_t q_bit_len;622u8 q_len;623nn_src_t q;624nn *r, *s;625int ret, cmp1, cmp2, iszero1, iszero2;626627/* First, verify context has been initialized */628ret = sig_verify_check_initialized(ctx); EG(ret, err);629630/* Do some sanity checks on input params */631ret = pub_key_check_initialized_and_type(ctx->pub_key, key_type); EG(ret, err);632MUST_HAVE((ctx->h != NULL) && (ctx->h->digest_size <= MAX_DIGEST_SIZE) &&633(ctx->h->block_size <= MAX_BLOCK_SIZE), ret, err);634MUST_HAVE((sig != NULL), ret, err);635636/* Make things more readable */637q = &(ctx->pub_key->params->ec_gen_order);638q_bit_len = ctx->pub_key->params->ec_gen_order_bitlen;639q_len = (u8)BYTECEIL(q_bit_len);640r = &(ctx->verify_data.ecdsa.r);641s = &(ctx->verify_data.ecdsa.s);642643/* Check given signature length is the expected one */644MUST_HAVE((siglen == ECDSA_SIGLEN(q_bit_len)), ret, err);645646/* Import r and s values from signature buffer */647ret = nn_init_from_buf(r, sig, q_len); EG(ret, err);648ret = nn_init_from_buf(s, sig + q_len, q_len); EG(ret, err);649dbg_nn_print("r", r);650dbg_nn_print("s", s);651652/* 1. Reject the signature if r or s is 0. */653ret = nn_iszero(r, &iszero1); EG(ret, err);654ret = nn_iszero(s, &iszero2); EG(ret, err);655ret = nn_cmp(r, q, &cmp1); EG(ret, err);656ret = nn_cmp(s, q, &cmp2); EG(ret, err);657MUST_HAVE(((!iszero1) && (cmp1 < 0) && !iszero2 && (cmp2 < 0)), ret, err);658659/* Initialize the remaining of verify context. */660/* Since we call a callback, sanity check our mapping */661ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);662ret = ctx->h->hfunc_init(&(ctx->verify_data.ecdsa.h_ctx)); EG(ret, err);663664ctx->verify_data.ecdsa.magic = ECDSA_VERIFY_MAGIC;665666err:667VAR_ZEROIFY(q_len);668VAR_ZEROIFY(q_bit_len);669PTR_NULLIFY(q);670PTR_NULLIFY(r);671PTR_NULLIFY(s);672673return ret;674}675676int __ecdsa_verify_update(struct ec_verify_context *ctx,677const u8 *chunk, u32 chunklen, ec_alg_type key_type)678{679int ret;680681/*682* First, verify context has been initialized and public683* part too. This guarantees the context is an ECDSA684* verification one and we do not update() or finalize()685* before init().686*/687ret = sig_verify_check_initialized(ctx); EG(ret, err);688ECDSA_VERIFY_CHECK_INITIALIZED(&(ctx->verify_data.ecdsa), ret, err);689/* Do some sanity checks on input params */690ret = pub_key_check_initialized_and_type(ctx->pub_key, key_type); EG(ret, err);691692/* 2. Compute h = H(m) */693/* Since we call a callback, sanity check our mapping */694ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);695ret = ctx->h->hfunc_update(&(ctx->verify_data.ecdsa.h_ctx), chunk, chunklen);696697err:698return ret;699}700701int __ecdsa_verify_finalize(struct ec_verify_context *ctx,702ec_alg_type key_type)703{704prj_pt uG, vY;705prj_pt_t W_prime;706nn e, sinv, uv, r_prime;707prj_pt_src_t G, Y;708u8 hash[MAX_DIGEST_SIZE];709bitcnt_t rshift, q_bit_len;710nn_src_t q;711nn *s, *r;712u8 hsize;713int ret, iszero, cmp;714715uG.magic = vY.magic = WORD(0);716e.magic = sinv.magic = uv.magic = r_prime.magic = WORD(0);717718/* NOTE: we reuse uG for W_prime to optimize local variables */719W_prime = &uG;720721/*722* First, verify context has been initialized and public723* part too. This guarantees the context is an ECDSA724* verification one and we do not finalize() before init().725*/726ret = sig_verify_check_initialized(ctx); EG(ret, err);727ECDSA_VERIFY_CHECK_INITIALIZED(&(ctx->verify_data.ecdsa), ret, err);728/* Do some sanity checks on input params */729ret = pub_key_check_initialized_and_type(ctx->pub_key, key_type); EG(ret, err);730731/* Zero init points */732ret = local_memset(&uG, 0, sizeof(prj_pt)); EG(ret, err);733ret = local_memset(&vY, 0, sizeof(prj_pt)); EG(ret, err);734735/* Make things more readable */736G = &(ctx->pub_key->params->ec_gen);737Y = &(ctx->pub_key->y);738q = &(ctx->pub_key->params->ec_gen_order);739q_bit_len = ctx->pub_key->params->ec_gen_order_bitlen;740hsize = ctx->h->digest_size;741r = &(ctx->verify_data.ecdsa.r);742s = &(ctx->verify_data.ecdsa.s);743744/* 2. Compute h = H(m) */745/* Since we call a callback, sanity check our mapping */746ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);747ret = ctx->h->hfunc_finalize(&(ctx->verify_data.ecdsa.h_ctx), hash); EG(ret, err);748dbg_buf_print("h = H(m)", hash, hsize);749750/*751* 3. If |h| > bitlen(q), set h to bitlen(q)752* leftmost bits of h.753*754* Note that it's easier to check here if the truncation755* needs to be done but implement it using a logical756* shift at the beginning of step 3. below once the hash757* has been converted to an integer.758*/759rshift = 0;760if ((hsize * 8) > q_bit_len) {761rshift = (bitcnt_t)((hsize * 8) - q_bit_len);762}763764/*765* 4. Compute e = OS2I(h) mod q, by converting h to an integer766* and reducing it mod q767*/768ret = nn_init_from_buf(&e, hash, hsize); EG(ret, err);769ret = local_memset(hash, 0, hsize); EG(ret, err);770dbg_nn_print("h initial import as nn", &e);771if (rshift) {772ret = nn_rshift_fixedlen(&e, &e, rshift); EG(ret, err);773}774dbg_nn_print("h final import as nn", &e);775776ret = nn_mod(&e, &e, q); EG(ret, err);777dbg_nn_print("e", &e);778779/* Compute s^-1 mod q */780ret = nn_modinv(&sinv, s, q); EG(ret, err);781dbg_nn_print("s", s);782dbg_nn_print("sinv", &sinv);783784/* 5. Compute u = (s^-1)e mod q */785ret = nn_mod_mul(&uv, &e, &sinv, q); EG(ret, err);786dbg_nn_print("u = (s^-1)e mod q", &uv);787ret = prj_pt_mul(&uG, &uv, G); EG(ret, err);788789/* 6. Compute v = (s^-1)r mod q */790ret = nn_mod_mul(&uv, r, &sinv, q); EG(ret, err);791dbg_nn_print("v = (s^-1)r mod q", &uv);792ret = prj_pt_mul(&vY, &uv, Y); EG(ret, err);793794/* 7. Compute W' = uG + vY */795ret = prj_pt_add(W_prime, &uG, &vY); EG(ret, err);796797/* 8. If W' is the point at infinity, reject the signature. */798ret = prj_pt_iszero(W_prime, &iszero); EG(ret, err);799MUST_HAVE(!iszero, ret, err);800801/* 9. Compute r' = W'_x mod q */802ret = prj_pt_unique(W_prime, W_prime); EG(ret, err);803dbg_nn_print("W'_x", &(W_prime->X.fp_val));804dbg_nn_print("W'_y", &(W_prime->Y.fp_val));805ret = nn_mod(&r_prime, &(W_prime->X.fp_val), q); EG(ret, err);806807/* 10. Accept the signature if and only if r equals r' */808ret = nn_cmp(&r_prime, r, &cmp); EG(ret, err);809ret = (cmp != 0) ? -1 : 0;810811err:812prj_pt_uninit(&uG);813prj_pt_uninit(&vY);814nn_uninit(&e);815nn_uninit(&sinv);816nn_uninit(&uv);817nn_uninit(&r_prime);818819/*820* We can now clear data part of the context. This will clear821* magic and avoid further reuse of the whole context.822*/823if(ctx != NULL){824IGNORE_RET_VAL(local_memset(&(ctx->verify_data.ecdsa), 0, sizeof(ecdsa_verify_data)));825}826827/* Clean what remains on the stack */828PTR_NULLIFY(W_prime);829PTR_NULLIFY(G);830PTR_NULLIFY(Y);831VAR_ZEROIFY(rshift);832VAR_ZEROIFY(q_bit_len);833PTR_NULLIFY(q);834PTR_NULLIFY(s);835PTR_NULLIFY(r);836VAR_ZEROIFY(hsize);837838return ret;839}840841/* Public key recovery from a signature.842* For ECDSA, it is possible to recover two possible public keys from843* a signature and a digest.844*845* Please note that this recovery is not perfect as some information is846* lost when reducing Rx modulo the order q during the signature. Hence,847* a few possible R points can provide the same r. The following algorithm848* assumes that Rx == r, i.e. Rx is < q and already reduced. This should849* happen with a probability q / p, and "bad" cases with probability850* (p - q) / p. Actually, some small multiples of r are also tested,851* but we give up after 10 tries as this can be very time consuming.852*853* With usual curve parameters, this last probability is negligible if854* everything is random (which should be the case for a "regular" signature855* algorithm) for curves with cofactor = 1. However, an adversary could856* willingly choose a Rx > q and the following algorithm will most certainly857* fail.858*859* For curves with cofactor > 1, q is usually some orders of magnitudes860* smaller than p and this function will certainly fail.861*862* Please use the resulting public keys with care and with all these863* warnings in mind!864*865*/866int __ecdsa_public_key_from_sig(ec_pub_key *out_pub1, ec_pub_key *out_pub2, const ec_params *params,867const u8 *sig, u8 siglen, const u8 *hash, u8 hsize,868ec_alg_type key_type)869{870int ret, iszero1, iszero2, cmp1, cmp2;871prj_pt uG;872prj_pt_t Y1, Y2;873prj_pt_src_t G;874nn u, v, e, r, s;875nn_src_t q, p;876bitcnt_t rshift, q_bit_len;877u8 q_len;878word_t order_multiplier = WORD(1);879880uG.magic = WORD(0);881u.magic = v.magic = e.magic = r.magic = s.magic = WORD(0);882883/* Zero init points */884ret = local_memset(&uG, 0, sizeof(prj_pt)); EG(ret, err);885886/* Sanity checks */887MUST_HAVE((params != NULL) && (sig != NULL) && (hash != NULL) && (out_pub1 != NULL) && (out_pub2 != NULL), ret, err);888889/* Import our params */890G = &(params->ec_gen);891p = &(params->ec_fp.p);892q = &(params->ec_gen_order);893q_bit_len = params->ec_gen_order_bitlen;894q_len = (u8)BYTECEIL(q_bit_len);895Y1 = &(out_pub1->y);896Y2 = &(out_pub2->y);897898/* Check given signature length is the expected one */899MUST_HAVE((siglen == ECDSA_SIGLEN(q_bit_len)), ret, err);900901restart:902/* Import r and s values from signature buffer */903ret = nn_init_from_buf(&r, sig, q_len); EG(ret, err);904ret = nn_init_from_buf(&s, sig + q_len, q_len); EG(ret, err);905906/* Reject the signature if r or s is 0. */907ret = nn_iszero(&r, &iszero1); EG(ret, err);908ret = nn_iszero(&s, &iszero2); EG(ret, err);909ret = nn_cmp(&r, q, &cmp1); EG(ret, err);910ret = nn_cmp(&s, q, &cmp2); EG(ret, err);911MUST_HAVE(((!iszero1) && (cmp1 < 0) && !iszero2 && (cmp2 < 0)), ret, err);912913/* Add a multiple of the order to r using our current order multiplier */914if(order_multiplier > 1){915int cmp;916ret = nn_init(&u, 0);917ret = nn_mul_word(&u, q, order_multiplier); EG(ret, err);918ret = nn_add(&r, &r, &u); EG(ret, err);919/* If we have reached > p, leave with an error */920ret = nn_cmp(&r, p, &cmp); EG(ret, err);921/* NOTE: we do not use a MUST_HAVE macro here since922* this condition can nominally happen, and we do not want923* a MUST_HAVE in debug mode (i.e. with an assert) to break924* the execution flow.925*/926if(cmp < 0){927ret = -1;928goto err;929}930}931932/*933* Compute e.934* If |h| > bitlen(q), set h to bitlen(q)935* leftmost bits of h.936*937* Note that it's easier to check here if the truncation938* needs to be done but implement it using a logical939* shift.940*/941rshift = 0;942if ((hsize * 8) > q_bit_len) {943rshift = (bitcnt_t)((hsize * 8) - q_bit_len);944}945ret = nn_init_from_buf(&e, hash, hsize); EG(ret, err);946if (rshift) {947ret = nn_rshift_fixedlen(&e, &e, rshift); EG(ret, err);948}949ret = nn_mod(&e, &e, q); EG(ret, err);950951/* Now to find the y coordinate by solving the curve equation.952* NOTE: we use uG as temporary storage.953*/954ret = fp_init(&(uG.X), &(params->ec_fp)); EG(ret, err);955ret = fp_init(&(uG.Y), &(params->ec_fp)); EG(ret, err);956ret = fp_init(&(uG.Z), &(params->ec_fp)); EG(ret, err);957ret = fp_set_nn(&(uG.Z), &r); EG(ret, err);958ret = aff_pt_y_from_x(&(uG.X), &(uG.Y), &(uG.Z), &(params->ec_curve));959if(ret){960/* If we have failed here, this means that our r has certainly been961* reduced. Increment our multiplier and restart the process.962*/963order_multiplier = (word_t)(order_multiplier + 1);964if(order_multiplier > 10){965/* Too much tries, leave ... */966ret = -1;967goto err;968}969goto restart;970}971972/* Initialize Y1 and Y2 */973ret = fp_init(&(Y2->Z), &(params->ec_fp)); EG(ret, err);974ret = fp_one(&(Y2->Z)); EG(ret, err);975/* Y1 */976ret = prj_pt_init_from_coords(Y1, &(params->ec_curve), &(uG.Z), &(uG.X), &(Y2->Z)); EG(ret, err);977/* Y2 */978ret = prj_pt_init_from_coords(Y2, &(params->ec_curve), &(uG.Z), &(uG.Y), &(Y1->Z)); EG(ret, err);979980/* Now compute u = (-e r^-1) mod q, and v = (s r^-1) mod q */981ret = nn_init(&u, 0); EG(ret, err);982ret = nn_init(&v, 0); EG(ret, err);983ret = nn_modinv(&r, &r, q); EG(ret, err);984/* u */985ret = nn_mod_mul(&u, &e, &r, q); EG(ret, err);986/* NOTE: -x mod q is (q - x) mod q, i.e. (q - x) when x is reduced, except for 0 */987ret = nn_mod_neg(&u, &u, q); EG(ret, err);988/* v */989ret = nn_mod_mul(&v, &s, &r, q); EG(ret, err);990991/* Compute uG */992ret = prj_pt_mul(&uG, &u, G); EG(ret, err);993/* Compute vR1 and possible Y1 */994ret = prj_pt_mul(Y1, &v, Y1); EG(ret, err);995ret = prj_pt_add(Y1, Y1, &uG); EG(ret, err);996/* Compute vR2 and possible Y2 */997ret = prj_pt_mul(Y2, &v, Y2); EG(ret, err);998ret = prj_pt_add(Y2, Y2, &uG); EG(ret, err);9991000/* Now initialize our two public keys */1001/* out_pub1 */1002out_pub1->key_type = key_type;1003out_pub1->params = params;1004out_pub1->magic = PUB_KEY_MAGIC;1005/* out_pub2 */1006out_pub2->key_type = key_type;1007out_pub2->params = params;1008out_pub2->magic = PUB_KEY_MAGIC;10091010ret = 0;10111012err:1013prj_pt_uninit(&uG);1014nn_uninit(&r);1015nn_uninit(&s);1016nn_uninit(&u);1017nn_uninit(&v);1018nn_uninit(&e);10191020/* Clean what remains on the stack */1021PTR_NULLIFY(G);1022PTR_NULLIFY(Y1);1023PTR_NULLIFY(Y2);1024VAR_ZEROIFY(rshift);1025VAR_ZEROIFY(q_bit_len);1026PTR_NULLIFY(q);1027PTR_NULLIFY(p);10281029return ret;1030}10311032#else /* defined(WITH_SIG_ECDSA) || defined(WITH_SIG_DECDSA) */10331034/*1035* Dummy definition to avoid the empty translation unit ISO C warning1036*/1037typedef int dummy;1038#endif /* WITH_SIG_ECDSA */103910401041