Message ID | 20240223204149.4055630-2-stefanb@linux.ibm.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Add support for NIST P521 to ecdsa | expand |
On Fri, Feb 23, 2024 at 03:41:40PM -0500, Stefan Berger wrote: > +static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, > + u64 *out, unsigned int ndigits) > +{ > + unsigned int sz = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; > + u8 tmp[ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT]; > + unsigned int o = sz - nbytes; > + > + memset(tmp, 0, o); > + memcpy(&tmp[o], in, nbytes); > + ecc_swap_digits(tmp, out, ndigits); > +} Copying the whole key into tmp seems inefficient. You only need special handling for the first few bytes of "in" (6 bytes in the P521 case) and could use ecc_swap_digits() to convert the rest of "in" directly to "out" without using tmp. So it would be sufficient to allocate the first digit on the stack, memset + memcpy, then convert that to native byte order into "in[0]" and use ecc_swap_digits() for the rest. And the special handling would be conditional on "!o", so is skipped for existing curves. Thanks, Lukas
On 2/29/24 04:11, Lukas Wunner wrote: > On Fri, Feb 23, 2024 at 03:41:40PM -0500, Stefan Berger wrote: >> +static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, >> + u64 *out, unsigned int ndigits) >> +{ >> + unsigned int sz = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; >> + u8 tmp[ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT]; >> + unsigned int o = sz - nbytes; >> + >> + memset(tmp, 0, o); >> + memcpy(&tmp[o], in, nbytes); >> + ecc_swap_digits(tmp, out, ndigits); >> +} > > Copying the whole key into tmp seems inefficient. You only need > special handling for the first few bytes of "in" (6 bytes in the > P521 case) and could use ecc_swap_digits() to convert the rest > of "in" directly to "out" without using tmp. > > So it would be sufficient to allocate the first digit on the stack, > memset + memcpy, then convert that to native byte order into "in[0]" > and use ecc_swap_digits() for the rest. > > And the special handling would be conditional on "!o", so is skipped > for existing curves. Thanks. It looks like this now: 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 { for (i = 0; i < o; i++) msd = (msd << 8) | in[i]; out[ndigits - 1] = msd; ecc_swap_digits(&in[o], out, ndigits - 1); } } Stefan > > Thanks, > > Lukas
On Thu, Feb 29, 2024 at 09:57:30AM -0500, Stefan Berger wrote: > 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 { > for (i = 0; i < o; i++) > msd = (msd << 8) | in[i]; > out[ndigits - 1] = msd; > ecc_swap_digits(&in[o], out, ndigits - 1); > } > } Might be beneficial to add a code comment explaining the else-branch is for curves with key length not a multiple of 64 bits (such as NIST P521). Otherwise LGTM, thanks! Lukas
On 2/29/24 11:48, Lukas Wunner wrote: > On Thu, Feb 29, 2024 at 09:57:30AM -0500, Stefan Berger wrote: >> 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 { >> for (i = 0; i < o; i++) >> msd = (msd << 8) | in[i]; >> out[ndigits - 1] = msd; >> ecc_swap_digits(&in[o], out, ndigits - 1); >> } >> } > > Might be beneficial to add a code comment explaining the else-branch > is for curves with key length not a multiple of 64 bits (such as NIST P521). Will do. I am also using this here now since it's safer: ecc_swap_digits(&in[o], out, (nbytes - o) >> 3); Stefan > > Otherwise LGTM, thanks! > > Lukas
On Thu Feb 29, 2024 at 4:57 PM EET, Stefan Berger wrote: > > > On 2/29/24 04:11, Lukas Wunner wrote: > > On Fri, Feb 23, 2024 at 03:41:40PM -0500, Stefan Berger wrote: > >> +static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, > >> + u64 *out, unsigned int ndigits) > >> +{ > >> + unsigned int sz = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; > >> + u8 tmp[ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT]; > >> + unsigned int o = sz - nbytes; > >> + > >> + memset(tmp, 0, o); > >> + memcpy(&tmp[o], in, nbytes); > >> + ecc_swap_digits(tmp, out, ndigits); > >> +} > > > > Copying the whole key into tmp seems inefficient. You only need > > special handling for the first few bytes of "in" (6 bytes in the > > P521 case) and could use ecc_swap_digits() to convert the rest > > of "in" directly to "out" without using tmp. > > > > So it would be sufficient to allocate the first digit on the stack, > > memset + memcpy, then convert that to native byte order into "in[0]" > > and use ecc_swap_digits() for the rest. > > > > And the special handling would be conditional on "!o", so is skipped > > for existing curves. > > Thanks. It looks like this now: > > 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 { > for (i = 0; i < o; i++) > msd = (msd << 8) | in[i]; > out[ndigits - 1] = msd; > ecc_swap_digits(&in[o], out, ndigits - 1); This would be more stream-lined IMHO: unsigned int o = nbytes & 7; unsigned int n = ndigits; u64 msd = 0; size_t i; if (o != 0) { for (i = 0; i < o; i++) msd = (msd << 8) | in[i]; out[--n] = msd; } ecc_swap_digits(in, out, n); BR, Jarkko
On 3/1/24 15:26, Jarkko Sakkinen wrote: > On Thu Feb 29, 2024 at 4:57 PM EET, Stefan Berger wrote: >> >> >> On 2/29/24 04:11, Lukas Wunner wrote: >>> On Fri, Feb 23, 2024 at 03:41:40PM -0500, Stefan Berger wrote: >>>> +static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, >>>> + u64 *out, unsigned int ndigits) >>>> +{ >>>> + unsigned int sz = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; >>>> + u8 tmp[ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT]; >>>> + unsigned int o = sz - nbytes; >>>> + >>>> + memset(tmp, 0, o); >>>> + memcpy(&tmp[o], in, nbytes); >>>> + ecc_swap_digits(tmp, out, ndigits); >>>> +} >>> >>> Copying the whole key into tmp seems inefficient. You only need >>> special handling for the first few bytes of "in" (6 bytes in the >>> P521 case) and could use ecc_swap_digits() to convert the rest >>> of "in" directly to "out" without using tmp. >>> >>> So it would be sufficient to allocate the first digit on the stack, >>> memset + memcpy, then convert that to native byte order into "in[0]" >>> and use ecc_swap_digits() for the rest. >>> >>> And the special handling would be conditional on "!o", so is skipped >>> for existing curves. >> >> Thanks. It looks like this now: >> >> 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 { >> for (i = 0; i < o; i++) >> msd = (msd << 8) | in[i]; >> out[ndigits - 1] = msd; >> ecc_swap_digits(&in[o], out, ndigits - 1); > > This would be more stream-lined IMHO: > > unsigned int o = nbytes & 7; > unsigned int n = ndigits; > u64 msd = 0; > size_t i; > > if (o != 0) { > for (i = 0; i < o; i++) > msd = (msd << 8) | in[i]; > > out[--n] = msd; > } > > ecc_swap_digits(in, out, n); You forgot to advance 'in'. > > BR, Jarkko >
On Fri Mar 1, 2024 at 10:48 PM EET, Stefan Berger wrote: > > > On 3/1/24 15:26, Jarkko Sakkinen wrote: > > On Thu Feb 29, 2024 at 4:57 PM EET, Stefan Berger wrote: > >> > >> > >> On 2/29/24 04:11, Lukas Wunner wrote: > >>> On Fri, Feb 23, 2024 at 03:41:40PM -0500, Stefan Berger wrote: > >>>> +static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, > >>>> + u64 *out, unsigned int ndigits) > >>>> +{ > >>>> + unsigned int sz = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; > >>>> + u8 tmp[ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT]; > >>>> + unsigned int o = sz - nbytes; > >>>> + > >>>> + memset(tmp, 0, o); > >>>> + memcpy(&tmp[o], in, nbytes); > >>>> + ecc_swap_digits(tmp, out, ndigits); > >>>> +} > >>> > >>> Copying the whole key into tmp seems inefficient. You only need > >>> special handling for the first few bytes of "in" (6 bytes in the > >>> P521 case) and could use ecc_swap_digits() to convert the rest > >>> of "in" directly to "out" without using tmp. > >>> > >>> So it would be sufficient to allocate the first digit on the stack, > >>> memset + memcpy, then convert that to native byte order into "in[0]" > >>> and use ecc_swap_digits() for the rest. > >>> > >>> And the special handling would be conditional on "!o", so is skipped > >>> for existing curves. > >> > >> Thanks. It looks like this now: > >> > >> 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 { > >> for (i = 0; i < o; i++) > >> msd = (msd << 8) | in[i]; > >> out[ndigits - 1] = msd; > >> ecc_swap_digits(&in[o], out, ndigits - 1); > > > > This would be more stream-lined IMHO: > > > > unsigned int o = nbytes & 7; > > unsigned int n = ndigits; > > u64 msd = 0; > > size_t i; > > > > if (o != 0) { > > for (i = 0; i < o; i++) > > msd = (msd << 8) | in[i]; > > > > out[--n] = msd; > > } > > > > ecc_swap_digits(in, out, n); > > You forgot to advance 'in'. yeah, pointing out that two call sites is unnecessary complexity, that's all BR, Jarkko
On Fri, Mar 01, 2024 at 10:26:29PM +0200, Jarkko Sakkinen wrote: > On Thu Feb 29, 2024 at 4:57 PM EET, Stefan Berger wrote: > > > > > > On 2/29/24 04:11, Lukas Wunner wrote: > > > On Fri, Feb 23, 2024 at 03:41:40PM -0500, Stefan Berger wrote: > > >> +static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, > > >> + u64 *out, unsigned int ndigits) > > >> +{ > > >> + unsigned int sz = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; > > >> + u8 tmp[ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT]; > > >> + unsigned int o = sz - nbytes; > > >> + > > >> + memset(tmp, 0, o); > > >> + memcpy(&tmp[o], in, nbytes); > > >> + ecc_swap_digits(tmp, out, ndigits); > > >> +} > > > > > > Copying the whole key into tmp seems inefficient. You only need > > > special handling for the first few bytes of "in" (6 bytes in the > > > P521 case) and could use ecc_swap_digits() to convert the rest > > > of "in" directly to "out" without using tmp. > > > > > > So it would be sufficient to allocate the first digit on the stack, > > > memset + memcpy, then convert that to native byte order into "in[0]" > > > and use ecc_swap_digits() for the rest. > > > > > > And the special handling would be conditional on "!o", so is skipped > > > for existing curves. > > > > Thanks. It looks like this now: > > > > 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 { > > for (i = 0; i < o; i++) > > msd = (msd << 8) | in[i]; > > out[ndigits - 1] = msd; > > ecc_swap_digits(&in[o], out, ndigits - 1); > > This would be more stream-lined IMHO: > > unsigned int o = nbytes & 7; > unsigned int n = ndigits; > u64 msd = 0; > size_t i; > > if (o != 0) { > for (i = 0; i < o; i++) > msd = (msd << 8) | in[i]; > > out[--n] = msd; > } > > ecc_swap_digits(in, out, n); Maybe eliminate the for-loop as well? unsigned int o = nbytes & 7; u64 msd = 0; if (o != 0) { /* if key length is not a multiple of 64 bits (NIST P521) */ memcpy((u8 *)&msd + sizeof(msd) - o, in, o); out[--ndigits] = be64_to_cpu(msd); in += o; } ecc_swap_digits(in, out, ndigits);
On 3/2/24 09:00, Lukas Wunner wrote: > On Fri, Mar 01, 2024 at 10:26:29PM +0200, Jarkko Sakkinen wrote: >> On Thu Feb 29, 2024 at 4:57 PM EET, Stefan Berger wrote: >>> >>> >>> On 2/29/24 04:11, Lukas Wunner wrote: >>>> On Fri, Feb 23, 2024 at 03:41:40PM -0500, Stefan Berger wrote: >>>>> +static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, >>>>> + u64 *out, unsigned int ndigits) >>>>> +{ >>>>> + unsigned int sz = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; >>>>> + u8 tmp[ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT]; >>>>> + unsigned int o = sz - nbytes; >>>>> + >>>>> + memset(tmp, 0, o); >>>>> + memcpy(&tmp[o], in, nbytes); >>>>> + ecc_swap_digits(tmp, out, ndigits); >>>>> +} >>>> >>>> Copying the whole key into tmp seems inefficient. You only need >>>> special handling for the first few bytes of "in" (6 bytes in the >>>> P521 case) and could use ecc_swap_digits() to convert the rest >>>> of "in" directly to "out" without using tmp. >>>> >>>> So it would be sufficient to allocate the first digit on the stack, >>>> memset + memcpy, then convert that to native byte order into "in[0]" >>>> and use ecc_swap_digits() for the rest. >>>> >>>> And the special handling would be conditional on "!o", so is skipped >>>> for existing curves. >>> >>> Thanks. It looks like this now: >>> >>> 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 { >>> for (i = 0; i < o; i++) >>> msd = (msd << 8) | in[i]; >>> out[ndigits - 1] = msd; >>> ecc_swap_digits(&in[o], out, ndigits - 1); >> >> This would be more stream-lined IMHO: >> >> unsigned int o = nbytes & 7; >> unsigned int n = ndigits; >> u64 msd = 0; >> size_t i; >> >> if (o != 0) { >> for (i = 0; i < o; i++) >> msd = (msd << 8) | in[i]; >> >> out[--n] = msd; >> } >> >> ecc_swap_digits(in, out, n); > > Maybe eliminate the for-loop as well? > > unsigned int o = nbytes & 7; > u64 msd = 0; > > if (o != 0) { > /* if key length is not a multiple of 64 bits (NIST P521) */ > memcpy((u8 *)&msd + sizeof(msd) - o, in, o); > out[--ndigits] = be64_to_cpu(msd); > in += o; > } > > ecc_swap_digits(in, out, ndigits); > Will take this for v5 with your Suggested-by:, ok? Stefan
On Sat, Mar 02, 2024 at 04:19:49PM -0500, Stefan Berger wrote: > On 3/2/24 09:00, Lukas Wunner wrote: > > Maybe eliminate the for-loop as well? > > > > unsigned int o = nbytes & 7; > > u64 msd = 0; > > > > if (o != 0) { > > /* if key length is not a multiple of 64 bits (NIST P521) */ > > memcpy((u8 *)&msd + sizeof(msd) - o, in, o); > > out[--ndigits] = be64_to_cpu(msd); > > in += o; > > } > > > > ecc_swap_digits(in, out, ndigits); > > Will take this for v5 with your Suggested-by:, ok? Sure, feel free to, but better test it because I haven't. :-) I'll look through the rest of the series tomorrow. %-) Thanks, Lukas
On Sat Mar 2, 2024 at 4:00 PM EET, Lukas Wunner wrote: > On Fri, Mar 01, 2024 at 10:26:29PM +0200, Jarkko Sakkinen wrote: > > On Thu Feb 29, 2024 at 4:57 PM EET, Stefan Berger wrote: > > > > > > > > > On 2/29/24 04:11, Lukas Wunner wrote: > > > > On Fri, Feb 23, 2024 at 03:41:40PM -0500, Stefan Berger wrote: > > > >> +static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, > > > >> + u64 *out, unsigned int ndigits) > > > >> +{ > > > >> + unsigned int sz = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; > > > >> + u8 tmp[ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT]; > > > >> + unsigned int o = sz - nbytes; > > > >> + > > > >> + memset(tmp, 0, o); > > > >> + memcpy(&tmp[o], in, nbytes); > > > >> + ecc_swap_digits(tmp, out, ndigits); > > > >> +} > > > > > > > > Copying the whole key into tmp seems inefficient. You only need > > > > special handling for the first few bytes of "in" (6 bytes in the > > > > P521 case) and could use ecc_swap_digits() to convert the rest > > > > of "in" directly to "out" without using tmp. > > > > > > > > So it would be sufficient to allocate the first digit on the stack, > > > > memset + memcpy, then convert that to native byte order into "in[0]" > > > > and use ecc_swap_digits() for the rest. > > > > > > > > And the special handling would be conditional on "!o", so is skipped > > > > for existing curves. > > > > > > Thanks. It looks like this now: > > > > > > 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 { > > > for (i = 0; i < o; i++) > > > msd = (msd << 8) | in[i]; > > > out[ndigits - 1] = msd; > > > ecc_swap_digits(&in[o], out, ndigits - 1); > > > > This would be more stream-lined IMHO: > > > > unsigned int o = nbytes & 7; > > unsigned int n = ndigits; > > u64 msd = 0; > > size_t i; > > > > if (o != 0) { > > for (i = 0; i < o; i++) > > msd = (msd << 8) | in[i]; > > > > out[--n] = msd; > > } > > > > ecc_swap_digits(in, out, n); > > Maybe eliminate the for-loop as well? > > unsigned int o = nbytes & 7; > u64 msd = 0; > > if (o != 0) { > /* if key length is not a multiple of 64 bits (NIST P521) */ > memcpy((u8 *)&msd + sizeof(msd) - o, in, o); > out[--ndigits] = be64_to_cpu(msd); > in += o; > } > > ecc_swap_digits(in, out, ndigits); +1 BR, Jarkko
diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c index fbd76498aba8..ba8fb76fd165 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 = 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..bee3329af7de 100644 --- a/include/crypto/internal/ecc.h +++ b/include/crypto/internal/ecc.h @@ -56,6 +56,25 @@ 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 sz = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; + u8 tmp[ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT]; + unsigned int o = sz - nbytes; + + memset(tmp, 0, o); + memcpy(&tmp[o], in, nbytes); + ecc_swap_digits(tmp, out, ndigits); +} + /** * ecc_is_key_valid() - Validate a given ECDH private key *
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 first have to be copied into a temporary byte array with leading zeros and can then be copied into the final digit array using ecc_swap_digits. 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 | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-)