Message ID | 20240301022007.344948-2-stefanb@linux.ibm.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-87829-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2097:b0:108:e6aa:91d0 with SMTP id gs23csp813637dyb; Thu, 29 Feb 2024 18:23:27 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVp+X2eSDb3bzGUGToGAwuQ4lzi2mUYNTOyVrtm22eDJqJz7PEjafV34A/Kc/iSaJdYzmf62oLNdSybNMejegzvkO5e/g== X-Google-Smtp-Source: AGHT+IE+fuDBKqx2Ib8MBWmhiVpYFgUB59cNbWHHH1Gq7vhHDh3pPfpuN2rE48NeMZFBzI5hlEEs X-Received: by 2002:ac8:7d44:0:b0:42e:b6ed:7048 with SMTP id h4-20020ac87d44000000b0042eb6ed7048mr450017qtb.11.1709259806987; Thu, 29 Feb 2024 18:23:26 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709259806; cv=pass; d=google.com; s=arc-20160816; b=NQrjyr9gs45Q59qtpEc5xU8LCmMpinYVm8nDZ9I6GXrqvxJJEQYay/n/izl593uzW9 sg3wzm654py9GBkHGY0f8DSOVErDsufsnUCSVVdWvuImmvsY9lDg4P+5WRF+AUw1tyzm s1dlFAVHZqtMZy1l1mWwOxBIbYKAGDN2wcC9xh+o2bmLatlryyutJV8zlDXUiCeNgUtm qHpOJGm1JKHfqjvyvbZ/m9MMDkleijk6m/xKjsuO2GEpqRK9ILPRZShh5ppZKndYNywl jVcnS+d38Fzfu4NnN0UUE94jspRdZtdrUQhrp1rbIwf4UHmTZP/kHLNgsihWp46v6wrg cOkg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=jyCSD/SD6Do0oEV7VM7M2eWAjErVj5gVDWzEBgNvx6k=; fh=rcM6ok5GFu5IIT2QdH7dFGIfgvD+dlFEBXZav0jM/0I=; b=joxp6A53vNYTsmOMnT9qYZneCObWUJHJGUtuW6tvqc0f6DS+rEVOVNa5OEDNo4jkOb pL5N9LIyx9YeiFgroeNBARcbRcj66tG3M4W6Lzot91R6Ek0pgxiGMnhbvFY/goe+7dac ldywYe2X4qofTIUW4GeI99y3lc4KUbyYNLAekiI1TpJPjw8krQPZ68TJeJsS/kQdQans d4zpP4b1U2tM8znjVie0nsh/NyA3cVsWkwPBp0CDSjTNrqVI/aCzbbgOIeqDiHw4S6GB ALg9PW9EgSj4E5UL07KtUnMllTWGq5hhn8XlJXYf/do2IV/niLb4jQL91ike42T6OB0+ hLZQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@ibm.com header.s=pp1 header.b=nKTsHlky; arc=pass (i=1 spf=pass spfdomain=linux.ibm.com dkim=pass dkdomain=ibm.com dmarc=pass fromdomain=linux.ibm.com); spf=pass (google.com: domain of linux-kernel+bounces-87829-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-87829-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=NONE dis=NONE) header.from=ibm.com Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id d3-20020ac851c3000000b0042e8a92fe4bsi2478476qtn.547.2024.02.29.18.23.26 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Feb 2024 18:23:26 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-87829-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@ibm.com header.s=pp1 header.b=nKTsHlky; arc=pass (i=1 spf=pass spfdomain=linux.ibm.com dkim=pass dkdomain=ibm.com dmarc=pass fromdomain=linux.ibm.com); spf=pass (google.com: domain of linux-kernel+bounces-87829-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-87829-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=NONE dis=NONE) header.from=ibm.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id BE5BB1C22AFD for <ouuuleilei@gmail.com>; Fri, 1 Mar 2024 02:23:26 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BC35C3EA95; Fri, 1 Mar 2024 02:20:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="nKTsHlky" Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 88B1E3A8C7; Fri, 1 Mar 2024 02:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709259623; cv=none; b=FCcWsdYfsDGcTfTMoeXphuWCHCiazj8fCTMpgWyutbVvntkw+TKRqIA6jCxIpQnNCiarqZiSrViwCRTOVrX4dxBHQKYWJ9WQGa58vl3VfvmzMPj5+OElQ/UohsTzpsve7osYIqNTy2zntnkAiZItoecWEf/BkH8aJdqrps3Bm1A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709259623; c=relaxed/simple; bh=sFcvSdKygidwLtw/uzuN+NfCipI2tHKBw5kMEwhOhRU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JOiWfgfbiEznnM76ppL/NdQy5colWO5BLEx5cRtiJ5knMKn7jfZDNCfLSp8mgip8Qqc6aoqQyqiKXvGXo+p5yhcq3tu4KwmloyKIYT+4ZOB+r6ttYGT7XzMDeLfCbzW29BbA9iLAvo9RiEtqLpPPljKxltmvzvmtyVG5PcuaJsc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=nKTsHlky; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 4212HfYU024976; Fri, 1 Mar 2024 02:20:13 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=jyCSD/SD6Do0oEV7VM7M2eWAjErVj5gVDWzEBgNvx6k=; b=nKTsHlkyNIi7LIfNZ7KbnBEcGeo755HE9uUB7pukjjGpx1Q1gYjZ/JWfRaBx7RVlEsCY 9KNFwqW1+gNiTNANSYIHpYi4QNOGuX8+PsqjJS8e3erocqjEB3lwBSh5La38mCR+CjGh Py4dCxKBWqtQG0IRSXY44F1WL/fNjZN3PSA8XViBidNOTFsatAB7dyYK+9XBKlkpuRcY I5E81vpkxYrP2aG4T5yjaKDXe4M6Lwe0vqmm06J99pou7fEoC1ofBdvBNspY0hWBLLJ8 bUjrXoG3I0pi8KoHv4ul3Qz1/e/0ywJioRbwqZZUBPxsF+BAxJkKPxGX+zAz747RbaN3 lA== Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3wk63qg1vm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 01 Mar 2024 02:20:13 +0000 Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 41TNwnoB008827; Fri, 1 Mar 2024 02:20:12 GMT Received: from smtprelay05.dal12v.mail.ibm.com ([172.16.1.7]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 3wftsu1w62-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 01 Mar 2024 02:20:12 +0000 Received: from smtpav05.dal12v.mail.ibm.com (smtpav05.dal12v.mail.ibm.com [10.241.53.104]) by smtprelay05.dal12v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 4212KAM740042974 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 1 Mar 2024 02:20:12 GMT Received: from smtpav05.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 133115805D; Fri, 1 Mar 2024 02:20:10 +0000 (GMT) Received: from smtpav05.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9192058069; Fri, 1 Mar 2024 02:20:09 +0000 (GMT) Received: from sbct-3.pok.ibm.com (unknown [9.47.158.153]) by smtpav05.dal12v.mail.ibm.com (Postfix) with ESMTP; Fri, 1 Mar 2024 02:20:09 +0000 (GMT) From: Stefan Berger <stefanb@linux.ibm.com> To: keyrings@vger.kernel.org, linux-crypto@vger.kernel.org, herbert@gondor.apana.org.au, davem@davemloft.net Cc: linux-kernel@vger.kernel.org, saulo.alessandre@tse.jus.br, lukas@wunner.de, Stefan Berger <stefanb@linux.ibm.com> Subject: [PATCH v4 01/12] crypto: ecdsa - Convert byte arrays with key coordinates to digits Date: Thu, 29 Feb 2024 21:19:56 -0500 Message-ID: <20240301022007.344948-2-stefanb@linux.ibm.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240301022007.344948-1-stefanb@linux.ibm.com> References: <20240301022007.344948-1-stefanb@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: Mg0t73Q_vcJOM8BCzjgSpJ3JThHjHUaj X-Proofpoint-GUID: Mg0t73Q_vcJOM8BCzjgSpJ3JThHjHUaj X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-29_08,2024-02-29_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 priorityscore=1501 adultscore=0 impostorscore=0 bulkscore=0 phishscore=0 mlxscore=0 malwarescore=0 clxscore=1015 spamscore=0 suspectscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311290000 definitions=main-2403010018 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1792288811311966858 X-GMAIL-MSGID: 1792288811311966858 |
Series |
Add support for NIST P521 to ecdsa
|
|
Commit Message
Stefan Berger
March 1, 2024, 2:19 a.m. UTC
For NIST P192/256/384 the public key's x and y parameters could be copied
directly from a given array since both parameters filled 'ndigits' of
digits (a 'digit' is a u64). For support of NIST P521 the key parameters
need to have leading zeros prepended to the most significant digit since
only 2 bytes of the most significant digit are provided.
Therefore, implement ecc_digits_from_bytes to convert a byte array into an
array of digits and use this function in ecdsa_set_pub_key where an input
byte array needs to be converted into digits.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
crypto/ecdsa.c | 14 +++++++++-----
include/crypto/internal/ecc.h | 25 +++++++++++++++++++++++++
2 files changed, 34 insertions(+), 5 deletions(-)
Comments
On Fri Mar 1, 2024 at 4:19 AM EET, Stefan Berger wrote: > For NIST P192/256/384 the public key's x and y parameters could be copied > directly from a given array since both parameters filled 'ndigits' of > digits (a 'digit' is a u64). For support of NIST P521 the key parameters > need to have leading zeros prepended to the most significant digit since > only 2 bytes of the most significant digit are provided. > > Therefore, implement ecc_digits_from_bytes to convert a byte array into an > array of digits and use this function in ecdsa_set_pub_key where an input > byte array needs to be converted into digits. > > Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> > --- > crypto/ecdsa.c | 14 +++++++++----- > include/crypto/internal/ecc.h | 25 +++++++++++++++++++++++++ > 2 files changed, 34 insertions(+), 5 deletions(-) > > diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c > index fbd76498aba8..6653dec17327 100644 > --- a/crypto/ecdsa.c > +++ b/crypto/ecdsa.c > @@ -222,9 +222,8 @@ static int ecdsa_ecc_ctx_reset(struct ecc_ctx *ctx) > static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) > { > struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); > + unsigned int digitlen, ndigits; > const unsigned char *d = key; > - const u64 *digits = (const u64 *)&d[1]; > - unsigned int ndigits; > int ret; > > ret = ecdsa_ecc_ctx_reset(ctx); > @@ -238,12 +237,17 @@ static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsig > return -EINVAL; > > keylen--; > - ndigits = (keylen >> 1) / sizeof(u64); > + digitlen = keylen >> 1; > + > + ndigits = DIV_ROUND_UP(digitlen, sizeof(u64)); > if (ndigits != ctx->curve->g.ndigits) > return -EINVAL; > > - ecc_swap_digits(digits, ctx->pub_key.x, ndigits); > - ecc_swap_digits(&digits[ndigits], ctx->pub_key.y, ndigits); > + d++; > + > + ecc_digits_from_bytes(d, digitlen, ctx->pub_key.x, ndigits); > + ecc_digits_from_bytes(&d[digitlen], digitlen, ctx->pub_key.y, ndigits); > + > ret = ecc_is_pubkey_valid_full(ctx->curve, &ctx->pub_key); > > ctx->pub_key_set = ret == 0; > diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h > index 4f6c1a68882f..48a04605da7f 100644 > --- a/include/crypto/internal/ecc.h > +++ b/include/crypto/internal/ecc.h > @@ -56,6 +56,31 @@ static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigit > out[i] = get_unaligned_be64(&src[ndigits - 1 - i]); > } > > +/** > + * ecc_digits_from_bytes() - Create ndigits-sized digits array from byte array > + * @in: Input byte array > + * @nbytes Size of input byte array > + * @out Output digits array > + * @ndigits: Number of digits to create from byte array > + */ > +static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, > + u64 *out, unsigned int ndigits) > +{ > + unsigned int o = nbytes & 7; > + u64 msd = 0; > + size_t i; > + > + if (o == 0) { > + ecc_swap_digits(in, out, ndigits); > + } else { > + /* if key length is not a multiple of 64 bits (NIST P521) */ > + for (i = 0; i < o; i++) > + msd = (msd << 8) | in[i]; > + out[ndigits - 1] = msd; > + ecc_swap_digits(&in[o], out, (nbytes - o) >> 3); > + } https://lore.kernel.org/keyrings/CZIOY02QS2QC.LV0A0HNT7VKM@suppilovahvero/ BR, Jarkko
On Sat, 2024-03-02 at 22:34 +0100, Lukas Wunner wrote: > On Thu, Feb 29, 2024 at 09:19:56PM -0500, Stefan Berger wrote: [...] > > @@ -238,12 +237,17 @@ static int ecdsa_set_pub_key(struct > > crypto_akcipher *tfm, const void *key, unsig > > return -EINVAL; > > > > keylen--; > > - ndigits = (keylen >> 1) / sizeof(u64); > > + digitlen = keylen >> 1; > > + > > + ndigits = DIV_ROUND_UP(digitlen, sizeof(u64)); > > Instead of introducing an additional digitlen variable, you could > just use keylen. It seems it's not used in the remainder of the > function, so modifying it is harmless: > > keylen--; > + keylen >>= 1; > - ndigits = (keylen >> 1) / sizeof(u64); > + ndigits = DIV_ROUND_UP(digitlen, sizeof(u64)); > > Just a suggestion. The compiler will optimize the variables like this anyway (reuse registers or frames after a current consumer becomes unused) so there's no requirement to do this for efficiency, the only real question is whether using digitlen is clearer than reusing keylen, which I'll leave to the author. James
On 3/2/24 16:34, Lukas Wunner wrote: > On Thu, Feb 29, 2024 at 09:19:56PM -0500, Stefan Berger wrote: >> --- a/crypto/ecdsa.c >> +++ b/crypto/ecdsa.c >> @@ -222,9 +222,8 @@ static int ecdsa_ecc_ctx_reset(struct ecc_ctx *ctx) >> static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) >> { >> struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); >> + unsigned int digitlen, ndigits; >> const unsigned char *d = key; >> - const u64 *digits = (const u64 *)&d[1]; >> - unsigned int ndigits; >> int ret; >> >> ret = ecdsa_ecc_ctx_reset(ctx); > > Hm, the removal of digits isn't strictly necessary. If you would keep it, > the patch would become simpler (fewer lines changes). > > >> @@ -238,12 +237,17 @@ static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsig >> return -EINVAL; >> >> keylen--; >> - ndigits = (keylen >> 1) / sizeof(u64); >> + digitlen = keylen >> 1; >> + >> + ndigits = DIV_ROUND_UP(digitlen, sizeof(u64)); > > Instead of introducing an additional digitlen variable, you could just > use keylen. It seems it's not used in the remainder of the function, > so modifying it is harmless: > > keylen--; > + keylen >>= 1; > - ndigits = (keylen >> 1) / sizeof(u64); > + ndigits = DIV_ROUND_UP(digitlen, sizeof(u64)); > > Just a suggestion. I would prefer 'digitlen' rather than repurposing keylen and giving it a different meaning... Stefan > > Thanks, > > Lukas
diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c index fbd76498aba8..6653dec17327 100644 --- a/crypto/ecdsa.c +++ b/crypto/ecdsa.c @@ -222,9 +222,8 @@ static int ecdsa_ecc_ctx_reset(struct ecc_ctx *ctx) static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) { struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); + unsigned int digitlen, ndigits; const unsigned char *d = key; - const u64 *digits = (const u64 *)&d[1]; - unsigned int ndigits; int ret; ret = ecdsa_ecc_ctx_reset(ctx); @@ -238,12 +237,17 @@ static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsig return -EINVAL; keylen--; - ndigits = (keylen >> 1) / sizeof(u64); + digitlen = keylen >> 1; + + ndigits = DIV_ROUND_UP(digitlen, sizeof(u64)); if (ndigits != ctx->curve->g.ndigits) return -EINVAL; - ecc_swap_digits(digits, ctx->pub_key.x, ndigits); - ecc_swap_digits(&digits[ndigits], ctx->pub_key.y, ndigits); + d++; + + ecc_digits_from_bytes(d, digitlen, ctx->pub_key.x, ndigits); + ecc_digits_from_bytes(&d[digitlen], digitlen, ctx->pub_key.y, ndigits); + ret = ecc_is_pubkey_valid_full(ctx->curve, &ctx->pub_key); ctx->pub_key_set = ret == 0; diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h index 4f6c1a68882f..48a04605da7f 100644 --- a/include/crypto/internal/ecc.h +++ b/include/crypto/internal/ecc.h @@ -56,6 +56,31 @@ static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigit out[i] = get_unaligned_be64(&src[ndigits - 1 - i]); } +/** + * ecc_digits_from_bytes() - Create ndigits-sized digits array from byte array + * @in: Input byte array + * @nbytes Size of input byte array + * @out Output digits array + * @ndigits: Number of digits to create from byte array + */ +static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, + u64 *out, unsigned int ndigits) +{ + unsigned int o = nbytes & 7; + u64 msd = 0; + size_t i; + + if (o == 0) { + ecc_swap_digits(in, out, ndigits); + } else { + /* if key length is not a multiple of 64 bits (NIST P521) */ + for (i = 0; i < o; i++) + msd = (msd << 8) | in[i]; + out[ndigits - 1] = msd; + ecc_swap_digits(&in[o], out, (nbytes - o) >> 3); + } +} + /** * ecc_is_key_valid() - Validate a given ECDH private key *