lkml.org 
[lkml]   [2024]   [Feb]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 01/14] crypto: ecdsa - Convert byte arrays with key coordinates to digits
    Date
    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(-)

    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
    *
    --
    2.43.0

    \
     
     \ /
      Last update: 2024-05-27 15:05    [W:4.065 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site