/*
 * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/*
 * ECDH and ECDSA low level APIs are deprecated for public use, but still ok
 * for internal use.
 */
#include "internal/deprecated.h"

#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/x509.h>
#include <openssl/ec.h>
#include <openssl/bn.h>
#include <openssl/asn1t.h>
#include "crypto/asn1.h"
#include "crypto/evp.h"
#include "crypto/x509.h"
#include <openssl/core_names.h>
#include <openssl/param_build.h>
#include "ec_local.h"

static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key)
{
    const EC_GROUP *group;
    int nid;

    if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
        ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS);
        return 0;
    }
    if (EC_GROUP_get_asn1_flag(group)
        && (nid = EC_GROUP_get_curve_name(group)))
        /* we have a 'named curve' => just set the OID */
    {
        ASN1_OBJECT *asn1obj = OBJ_nid2obj(nid);

        if (asn1obj == NULL || OBJ_length(asn1obj) == 0) {
            ASN1_OBJECT_free(asn1obj);
            ERR_raise(ERR_LIB_EC, EC_R_MISSING_OID);
            return 0;
        }
        *ppval = asn1obj;
        *pptype = V_ASN1_OBJECT;
    } else {                    /* explicit parameters */

        ASN1_STRING *pstr = NULL;
        pstr = ASN1_STRING_new();
        if (pstr == NULL)
            return 0;
        pstr->length = i2d_ECParameters(ec_key, &pstr->data);
        if (pstr->length <= 0) {
            ASN1_STRING_free(pstr);
            ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
            return 0;
        }
        *ppval = pstr;
        *pptype = V_ASN1_SEQUENCE;
    }
    return 1;
}

static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
{
    const EC_KEY *ec_key = pkey->pkey.ec;
    void *pval = NULL;
    int ptype;
    unsigned char *penc = NULL, *p;
    int penclen;

    if (!eckey_param2type(&ptype, &pval, ec_key)) {
        ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
        return 0;
    }
    penclen = i2o_ECPublicKey(ec_key, NULL);
    if (penclen <= 0)
        goto err;
    penc = OPENSSL_malloc(penclen);
    if (penc == NULL)
        goto err;
    p = penc;
    penclen = i2o_ECPublicKey(ec_key, &p);
    if (penclen <= 0)
        goto err;
    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
                               ptype, pval, penc, penclen))
        return 1;
 err:
    if (ptype == V_ASN1_OBJECT)
        ASN1_OBJECT_free(pval);
    else
        ASN1_STRING_free(pval);
    OPENSSL_free(penc);
    return 0;
}

static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
{
    const unsigned char *p = NULL;
    int pklen;
    EC_KEY *eckey = NULL;
    X509_ALGOR *palg;
    OSSL_LIB_CTX *libctx = NULL;
    const char *propq = NULL;

    if (!ossl_x509_PUBKEY_get0_libctx(&libctx, &propq, pubkey)
        || !X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
        return 0;
    eckey = ossl_ec_key_param_from_x509_algor(palg, libctx, propq);

    if (!eckey)
        return 0;

    /* We have parameters now set public key */
    if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
        ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR);
        goto ecerr;
    }

    EVP_PKEY_assign_EC_KEY(pkey, eckey);
    return 1;

 ecerr:
    EC_KEY_free(eckey);
    return 0;
}

static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
{
    int r;
    const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
    const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
        *pb = EC_KEY_get0_public_key(b->pkey.ec);

    if (group == NULL || pa == NULL || pb == NULL)
        return -2;
    r = EC_POINT_cmp(group, pa, pb, NULL);
    if (r == 0)
        return 1;
    if (r == 1)
        return 0;
    return -2;
}

static int eckey_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8,
                                OSSL_LIB_CTX *libctx, const char *propq)
{
    int ret = 0;
    EC_KEY *eckey = ossl_ec_key_from_pkcs8(p8, libctx, propq);

    if (eckey != NULL) {
        ret = 1;
        EVP_PKEY_assign_EC_KEY(pkey, eckey);
    }

    return ret;
}

static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
{
    EC_KEY ec_key = *(pkey->pkey.ec);
    unsigned char *ep, *p;
    int eplen, ptype;
    void *pval;
    unsigned int old_flags;

    if (!eckey_param2type(&ptype, &pval, &ec_key)) {
        ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR);
        return 0;
    }

    /* set the private key */

    /*
     * do not include the parameters in the SEC1 private key see PKCS#11
     * 12.11
     */
    old_flags = EC_KEY_get_enc_flags(&ec_key);
    EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS);

    eplen = i2d_ECPrivateKey(&ec_key, NULL);
    if (!eplen) {
        ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
        return 0;
    }
    ep = OPENSSL_malloc(eplen);
    if (ep == NULL) {
        ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    p = ep;
    if (!i2d_ECPrivateKey(&ec_key, &p)) {
        OPENSSL_free(ep);
        ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
        return 0;
    }

    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
                         ptype, pval, ep, eplen)) {
        OPENSSL_free(ep);
        return 0;
    }

    return 1;
}

static int int_ec_size(const EVP_PKEY *pkey)
{
    return ECDSA_size(pkey->pkey.ec);
}

static int ec_bits(const EVP_PKEY *pkey)
{
    return EC_GROUP_order_bits(EC_KEY_get0_group(pkey->pkey.ec));
}

static int ec_security_bits(const EVP_PKEY *pkey)
{
    int ecbits = ec_bits(pkey);

    if (ecbits >= 512)
        return 256;
    if (ecbits >= 384)
        return 192;
    if (ecbits >= 256)
        return 128;
    if (ecbits >= 224)
        return 112;
    if (ecbits >= 160)
        return 80;
    return ecbits / 2;
}

static int ec_missing_parameters(const EVP_PKEY *pkey)
{
    if (pkey->pkey.ec == NULL || EC_KEY_get0_group(pkey->pkey.ec) == NULL)
        return 1;
    return 0;
}

static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
{
    EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));

    if (group == NULL)
        return 0;
    if (to->pkey.ec == NULL) {
        to->pkey.ec = EC_KEY_new();
        if (to->pkey.ec == NULL)
            goto err;
    }
    if (EC_KEY_set_group(to->pkey.ec, group) == 0)
        goto err;
    EC_GROUP_free(group);
    return 1;
 err:
    EC_GROUP_free(group);
    return 0;
}

static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
{
    const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
        *group_b = EC_KEY_get0_group(b->pkey.ec);

    if (group_a == NULL || group_b == NULL)
        return -2;
    if (EC_GROUP_cmp(group_a, group_b, NULL))
        return 0;
    else
        return 1;
}

static void int_ec_free(EVP_PKEY *pkey)
{
    EC_KEY_free(pkey->pkey.ec);
}

typedef enum {
    EC_KEY_PRINT_PRIVATE,
    EC_KEY_PRINT_PUBLIC,
    EC_KEY_PRINT_PARAM
} ec_print_t;

static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype)
{
    const char *ecstr;
    unsigned char *priv = NULL, *pub = NULL;
    size_t privlen = 0, publen = 0;
    int ret = 0;
    const EC_GROUP *group;

    if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
        ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (ktype != EC_KEY_PRINT_PARAM && EC_KEY_get0_public_key(x) != NULL) {
        publen = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL);
        if (publen == 0)
            goto err;
    }

    if (ktype == EC_KEY_PRINT_PRIVATE && EC_KEY_get0_private_key(x) != NULL) {
        privlen = EC_KEY_priv2buf(x, &priv);
        if (privlen == 0)
            goto err;
    }

    if (ktype == EC_KEY_PRINT_PRIVATE)
        ecstr = "Private-Key";
    else if (ktype == EC_KEY_PRINT_PUBLIC)
        ecstr = "Public-Key";
    else
        ecstr = "ECDSA-Parameters";

    if (!BIO_indent(bp, off, 128))
        goto err;
    if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
                   EC_GROUP_order_bits(group)) <= 0)
        goto err;

    if (privlen != 0) {
        if (BIO_printf(bp, "%*spriv:\n", off, "") <= 0)
            goto err;
        if (ASN1_buf_print(bp, priv, privlen, off + 4) == 0)
            goto err;
    }

    if (publen != 0) {
        if (BIO_printf(bp, "%*spub:\n", off, "") <= 0)
            goto err;
        if (ASN1_buf_print(bp, pub, publen, off + 4) == 0)
            goto err;
    }

    if (!ECPKParameters_print(bp, group, off))
        goto err;
    ret = 1;
 err:
    if (!ret)
        ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
    OPENSSL_clear_free(priv, privlen);
    OPENSSL_free(pub);
    return ret;
}

static int eckey_param_decode(EVP_PKEY *pkey,
                              const unsigned char **pder, int derlen)
{
    EC_KEY *eckey;

    if ((eckey = d2i_ECParameters(NULL, pder, derlen)) == NULL)
        return 0;
    EVP_PKEY_assign_EC_KEY(pkey, eckey);
    return 1;
}

static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
{
    return i2d_ECParameters(pkey->pkey.ec, pder);
}

static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
                             ASN1_PCTX *ctx)
{
    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PARAM);
}

static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
                           ASN1_PCTX *ctx)
{
    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PUBLIC);
}

static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
                            ASN1_PCTX *ctx)
{
    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PRIVATE);
}

static int old_ec_priv_decode(EVP_PKEY *pkey,
                              const unsigned char **pder, int derlen)
{
    EC_KEY *ec;

    if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL)
        return 0;
    EVP_PKEY_assign_EC_KEY(pkey, ec);
    return 1;
}

static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
{
    return i2d_ECPrivateKey(pkey->pkey.ec, pder);
}

static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
{
    switch (op) {
    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
        if (EVP_PKEY_get_id(pkey) == EVP_PKEY_SM2) {
            /* For SM2, the only valid digest-alg is SM3 */
            *(int *)arg2 = NID_sm3;
            return 2;            /* Make it mandatory */
        }
        *(int *)arg2 = NID_sha256;
        return 1;

    case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
        /* We should only be here if we have a legacy key */
        if (!ossl_assert(evp_pkey_is_legacy(pkey)))
            return 0;
        return EC_KEY_oct2key(evp_pkey_get0_EC_KEY_int(pkey), arg2, arg1, NULL);

    case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
        return EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(pkey),
                              POINT_CONVERSION_UNCOMPRESSED, arg2, NULL);

    default:
        return -2;
    }
}

static int ec_pkey_check(const EVP_PKEY *pkey)
{
    EC_KEY *eckey = pkey->pkey.ec;

    /* stay consistent to what EVP_PKEY_check demands */
    if (eckey->priv_key == NULL) {
        ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY);
        return 0;
    }

    return EC_KEY_check_key(eckey);
}

static int ec_pkey_public_check(const EVP_PKEY *pkey)
{
    EC_KEY *eckey = pkey->pkey.ec;

    /*
     * Note: it unnecessary to check eckey->pub_key here since
     * it will be checked in EC_KEY_check_key(). In fact, the
     * EC_KEY_check_key() mainly checks the public key, and checks
     * the private key optionally (only if there is one). So if
     * someone passes a whole EC key (public + private), this
     * will also work...
     */

    return EC_KEY_check_key(eckey);
}

static int ec_pkey_param_check(const EVP_PKEY *pkey)
{
    EC_KEY *eckey = pkey->pkey.ec;

    /* stay consistent to what EVP_PKEY_check demands */
    if (eckey->group == NULL) {
        ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS);
        return 0;
    }

    return EC_GROUP_check(eckey->group, NULL);
}

static
size_t ec_pkey_dirty_cnt(const EVP_PKEY *pkey)
{
    return pkey->pkey.ec->dirty_cnt;
}

static
int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
                      OSSL_FUNC_keymgmt_import_fn *importer,
                      OSSL_LIB_CTX *libctx, const char *propq)
{
    const EC_KEY *eckey = NULL;
    const EC_GROUP *ecg = NULL;
    unsigned char *pub_key_buf = NULL, *gen_buf = NULL;
    size_t pub_key_buflen;
    OSSL_PARAM_BLD *tmpl;
    OSSL_PARAM *params = NULL;
    const BIGNUM *priv_key = NULL;
    const EC_POINT *pub_point = NULL;
    int selection = 0;
    int rv = 0;
    BN_CTX *bnctx = NULL;

    if (from == NULL
            || (eckey = from->pkey.ec) == NULL
            || (ecg = EC_KEY_get0_group(eckey)) == NULL)
        return 0;

    tmpl = OSSL_PARAM_BLD_new();
    if (tmpl == NULL)
        return 0;

    /*
     * EC_POINT_point2buf() can generate random numbers in some
     * implementations so we need to ensure we use the correct libctx.
     */
    bnctx = BN_CTX_new_ex(libctx);
    if (bnctx == NULL)
        goto err;
    BN_CTX_start(bnctx);

    /* export the domain parameters */
    if (!ossl_ec_group_todata(ecg, tmpl, NULL, libctx, propq, bnctx, &gen_buf))
        goto err;
    selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;

    priv_key = EC_KEY_get0_private_key(eckey);
    pub_point = EC_KEY_get0_public_key(eckey);

    if (pub_point != NULL) {
        /* convert pub_point to a octet string according to the SECG standard */
        if ((pub_key_buflen = EC_POINT_point2buf(ecg, pub_point,
                                                 POINT_CONVERSION_COMPRESSED,
                                                 &pub_key_buf, bnctx)) == 0
            || !OSSL_PARAM_BLD_push_octet_string(tmpl,
                                                 OSSL_PKEY_PARAM_PUB_KEY,
                                                 pub_key_buf,
                                                 pub_key_buflen))
            goto err;
        selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
    }

    if (priv_key != NULL) {
        size_t sz;
        int ecbits;
        int ecdh_cofactor_mode;

        /*
         * Key import/export should never leak the bit length of the secret
         * scalar in the key.
         *
         * For this reason, on export we use padded BIGNUMs with fixed length.
         *
         * When importing we also should make sure that, even if short lived,
         * the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as
         * soon as possible, so that any processing of this BIGNUM might opt for
         * constant time implementations in the backend.
         *
         * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
         * to preallocate the BIGNUM internal buffer to a fixed public size big
         * enough that operations performed during the processing never trigger
         * a realloc which would leak the size of the scalar through memory
         * accesses.
         *
         * Fixed Length
         * ------------
         *
         * The order of the large prime subgroup of the curve is our choice for
         * a fixed public size, as that is generally the upper bound for
         * generating a private key in EC cryptosystems and should fit all valid
         * secret scalars.
         *
         * For padding on export we just use the bit length of the order
         * converted to bytes (rounding up).
         *
         * For preallocating the BIGNUM storage we look at the number of "words"
         * required for the internal representation of the order, and we
         * preallocate 2 extra "words" in case any of the subsequent processing
         * might temporarily overflow the order length.
         */
        ecbits = EC_GROUP_order_bits(ecg);
        if (ecbits <= 0)
            goto err;

        sz = (ecbits + 7) / 8;
        if (!OSSL_PARAM_BLD_push_BN_pad(tmpl,
                                        OSSL_PKEY_PARAM_PRIV_KEY,
                                        priv_key, sz))
            goto err;
        selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;

        /*
         * The ECDH Cofactor Mode is defined only if the EC_KEY actually
         * contains a private key, so we check for the flag and export it only
         * in this case.
         */
        ecdh_cofactor_mode =
            (EC_KEY_get_flags(eckey) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;

        /* Export the ECDH_COFACTOR_MODE parameter */
        if (!OSSL_PARAM_BLD_push_int(tmpl,
                                     OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
                                     ecdh_cofactor_mode))
            goto err;
        selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS;
    }

    params = OSSL_PARAM_BLD_to_param(tmpl);

    /* We export, the provider imports */
    rv = importer(to_keydata, selection, params);

 err:
    OSSL_PARAM_BLD_free(tmpl);
    OSSL_PARAM_free(params);
    OPENSSL_free(pub_key_buf);
    OPENSSL_free(gen_buf);
    BN_CTX_end(bnctx);
    BN_CTX_free(bnctx);
    return rv;
}

static int ec_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
{
    EVP_PKEY_CTX *pctx = vpctx;
    EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
    EC_KEY *ec = EC_KEY_new_ex(pctx->libctx, pctx->propquery);

    if (ec == NULL) {
        ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    if (!ossl_ec_group_fromdata(ec, params)
        || !ossl_ec_key_otherparams_fromdata(ec, params)
        || !ossl_ec_key_fromdata(ec, params, 1)
        || !EVP_PKEY_assign_EC_KEY(pkey, ec)) {
        EC_KEY_free(ec);
        return 0;
    }
    return 1;
}

static int ec_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
{
    EC_KEY *eckey = from->pkey.ec;
    EC_KEY *dupkey = NULL;
    int ret;

    if (eckey != NULL) {
        dupkey = EC_KEY_dup(eckey);
        if (dupkey == NULL)
            return 0;
    } else {
        /* necessary to properly copy empty SM2 keys */
        return EVP_PKEY_set_type(to, from->type);
    }

    ret = EVP_PKEY_assign_EC_KEY(to, dupkey);
    if (!ret)
        EC_KEY_free(dupkey);
    return ret;
}

const EVP_PKEY_ASN1_METHOD ossl_eckey_asn1_meth = {
    EVP_PKEY_EC,
    EVP_PKEY_EC,
    0,
    "EC",
    "OpenSSL EC algorithm",

    eckey_pub_decode,
    eckey_pub_encode,
    eckey_pub_cmp,
    eckey_pub_print,

    NULL,
    eckey_priv_encode,
    eckey_priv_print,

    int_ec_size,
    ec_bits,
    ec_security_bits,

    eckey_param_decode,
    eckey_param_encode,
    ec_missing_parameters,
    ec_copy_parameters,
    ec_cmp_parameters,
    eckey_param_print,
    0,

    int_ec_free,
    ec_pkey_ctrl,
    old_ec_priv_decode,
    old_ec_priv_encode,

    0, 0, 0,

    ec_pkey_check,
    ec_pkey_public_check,
    ec_pkey_param_check,

    0, /* set_priv_key */
    0, /* set_pub_key */
    0, /* get_priv_key */
    0, /* get_pub_key */

    ec_pkey_dirty_cnt,
    ec_pkey_export_to,
    ec_pkey_import_from,
    ec_pkey_copy,
    eckey_priv_decode_ex
};

#if !defined(OPENSSL_NO_SM2)
const EVP_PKEY_ASN1_METHOD ossl_sm2_asn1_meth = {
   EVP_PKEY_SM2,
   EVP_PKEY_EC,
   ASN1_PKEY_ALIAS
};
#endif

int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
{
    int private = EC_KEY_get0_private_key(x) != NULL;

    return do_EC_KEY_print(bp, x, off,
                private ? EC_KEY_PRINT_PRIVATE : EC_KEY_PRINT_PUBLIC);
}

int ECParameters_print(BIO *bp, const EC_KEY *x)
{
    return do_EC_KEY_print(bp, x, 4, EC_KEY_PRINT_PARAM);
}
