// SPDX-License-Identifier: BSD-2-Clause
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
 *
 * LibTomCrypt is a library that provides various cryptographic
 * algorithms in a highly modular and flexible manner.
 *
 * The library is free for all purposes without any express
 * guarantee it works.
 */

#include "tomcrypt_private.h"

#ifdef LTC_MECC

typedef struct {
   ltc_asn1_type t;
   ltc_asn1_list **pp;
} der_flexi_check;

#define LTC_SET_DER_FLEXI_CHECK(list, index, Type, P)    \
   do {                                         \
      int LTC_SDFC_temp##__LINE__ = (index);   \
      list[LTC_SDFC_temp##__LINE__].t = Type;  \
      list[LTC_SDFC_temp##__LINE__].pp = P;    \
   } while (0)

static int _der_flexi_sequence_cmp(const ltc_asn1_list *flexi, der_flexi_check *check)
{
   const ltc_asn1_list *cur;
   if (flexi->type != LTC_ASN1_SEQUENCE) {
      return CRYPT_INVALID_PACKET;
   }
   cur = flexi->child;
   while(check->t != LTC_ASN1_EOL) {
      if (!LTC_ASN1_IS_TYPE(cur, check->t)) {
         return CRYPT_INVALID_PACKET;
      }
      if (check->pp != NULL) *check->pp = (ltc_asn1_list*)cur;
      cur = cur->next;
      check++;
   }
   return CRYPT_OK;
}

/* NOTE: _der_decode_pkcs8_flexi & related stuff can be shared with rsa_import_pkcs8() */

int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen,
                     const void *pwd, unsigned long pwdlen,
                     ecc_key *key)
{
   void          *a, *b, *gx, *gy;
   unsigned long len, cofactor, n;
   const char    *pka_ec_oid;
   int           err;
   char          OID[256];
   const ltc_ecc_curve *curve;
   ltc_asn1_list *p = NULL, *l = NULL;
   der_flexi_check flexi_should[7];
   ltc_asn1_list *seq, *priv_key;

   LTC_ARGCHK(in          != NULL);
   LTC_ARGCHK(key         != NULL);
   LTC_ARGCHK(ltc_mp.name != NULL);

   /* get EC alg oid */
   err = pk_get_oid(PKA_EC, &pka_ec_oid);
   if (err != CRYPT_OK) return err;

   /* init key */
   err = mp_init_multi(&a, &b, &gx, &gy, NULL);
   if (err != CRYPT_OK) return err;


   if ((err = pkcs8_decode_flexi(in, inlen, pwd, pwdlen, &l)) == CRYPT_OK) {

      /* Setup for basic structure */
      n=0;
      LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_INTEGER, NULL);
      LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, &seq);
      LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_OCTET_STRING, &priv_key);
      LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL);

      if (((err = _der_flexi_sequence_cmp(l, flexi_should)) == CRYPT_OK) &&
            (pk_oid_cmp_with_asn1(pka_ec_oid, seq->child) == CRYPT_OK)) {
         ltc_asn1_list *version, *field, *point, *point_g, *order, *p_cofactor;

         /* Setup for CASE 2 */
         n=0;
         LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_INTEGER, &version);
         LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, &field);
         LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, &point);
         LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_OCTET_STRING, &point_g);
         LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_INTEGER, &order);
         LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_INTEGER, &p_cofactor);
         LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL);

         if (LTC_ASN1_IS_TYPE(seq->child->next, LTC_ASN1_OBJECT_IDENTIFIER)) {
            /* CASE 1: curve by OID (AKA short variant):
             *   0:d=0  hl=2 l= 100 cons: SEQUENCE
             *   2:d=1  hl=2 l=   1 prim:   INTEGER        :00
             *   5:d=1  hl=2 l=  16 cons:   SEQUENCE       (== *seq)
             *   7:d=2  hl=2 l=   7 prim:     OBJECT       :id-ecPublicKey
             *  16:d=2  hl=2 l=   5 prim:     OBJECT       :(== *curve_oid (e.g. secp256k1 (== 1.3.132.0.10)))
             *  23:d=1  hl=2 l=  77 prim:   OCTET STRING   :bytes (== *priv_key)
             */
            ltc_asn1_list *curve_oid = seq->child->next;
            len = sizeof(OID);
            if ((err = pk_oid_num_to_str(curve_oid->data, curve_oid->size, OID, &len)) != CRYPT_OK) { goto LBL_DONE; }
            if ((err = ecc_find_curve(OID, &curve)) != CRYPT_OK)                          { goto LBL_DONE; }
            if ((err = ecc_set_curve(curve, key)) != CRYPT_OK)                            { goto LBL_DONE; }
         }
         else if ((err = _der_flexi_sequence_cmp(seq->child->next, flexi_should)) == CRYPT_OK) {
            /* CASE 2: explicit curve parameters (AKA long variant):
             *   0:d=0  hl=3 l= 227 cons: SEQUENCE
             *   3:d=1  hl=2 l=   1 prim:   INTEGER              :00
             *   6:d=1  hl=3 l= 142 cons:   SEQUENCE             (== *seq)
             *   9:d=2  hl=2 l=   7 prim:     OBJECT             :id-ecPublicKey
             *  18:d=2  hl=3 l= 130 cons:     SEQUENCE
             *  21:d=3  hl=2 l=   1 prim:       INTEGER          :01
             *  24:d=3  hl=2 l=  44 cons:       SEQUENCE         (== *field)
             *  26:d=4  hl=2 l=   7 prim:         OBJECT         :prime-field
             *  35:d=4  hl=2 l=  33 prim:         INTEGER        :(== *prime / curve.prime)
             *  70:d=3  hl=2 l=   6 cons:       SEQUENCE         (== *point)
             *  72:d=4  hl=2 l=   1 prim:         OCTET STRING   :bytes (== curve.A)
             *  75:d=4  hl=2 l=   1 prim:         OCTET STRING   :bytes (== curve.B)
             *  78:d=3  hl=2 l=  33 prim:       OCTET STRING     :bytes (== *g_point / curve.G-point)
             * 113:d=3  hl=2 l=  33 prim:       INTEGER          :(== *order / curve.order)
             * 148:d=3  hl=2 l=   1 prim:       INTEGER          :(== curve.cofactor)
             * 151:d=1  hl=2 l=  77 prim:   OCTET STRING         :bytes (== *priv_key)
             */

            if (mp_get_int(version->data) != 1) {
               goto LBL_DONE;
            }
            cofactor = mp_get_int(p_cofactor->data);

            if (LTC_ASN1_IS_TYPE(field->child, LTC_ASN1_OBJECT_IDENTIFIER) &&
                LTC_ASN1_IS_TYPE(field->child->next, LTC_ASN1_INTEGER) &&
                LTC_ASN1_IS_TYPE(point->child, LTC_ASN1_OCTET_STRING) &&
                LTC_ASN1_IS_TYPE(point->child->next, LTC_ASN1_OCTET_STRING)) {

               ltc_asn1_list *prime = field->child->next;
               if ((err = mp_read_unsigned_bin(a, point->child->data, point->child->size)) != CRYPT_OK) {
                  goto LBL_DONE;
               }
               if ((err = mp_read_unsigned_bin(b, point->child->next->data, point->child->next->size)) != CRYPT_OK) {
                  goto LBL_DONE;
               }
               if ((err = ltc_ecc_import_point(point_g->data, point_g->size, prime->data, a, b, gx, gy)) != CRYPT_OK) {
                  goto LBL_DONE;
               }
               if ((err = ecc_set_curve_from_mpis(a, b, prime->data, order->data, gx, gy, cofactor, key)) != CRYPT_OK) {
                  goto LBL_DONE;
               }
            }
         }
         else {
            err = CRYPT_INVALID_PACKET;
            goto LBL_DONE;
         }

         /* load private key value 'k' */
         len = priv_key->size;
         if ((err = der_decode_sequence_flexi(priv_key->data, &len, &p)) == CRYPT_OK) {
            if (p->type == LTC_ASN1_SEQUENCE &&
                LTC_ASN1_IS_TYPE(p->child, LTC_ASN1_INTEGER) &&
                LTC_ASN1_IS_TYPE(p->child->next, LTC_ASN1_OCTET_STRING)) {
               ltc_asn1_list *lk = p->child->next;
               if (mp_cmp_d(p->child->data, 1) != LTC_MP_EQ) {
                  err = CRYPT_INVALID_PACKET;
                  goto LBL_ECCFREE;
               }
               if ((err = ecc_set_key(lk->data, lk->size, PK_PRIVATE, key)) != CRYPT_OK) {
                  goto LBL_ECCFREE;
               }
               goto LBL_DONE; /* success */
            }
         }
      }
   }
   err = CRYPT_INVALID_PACKET;
   goto LBL_DONE;

LBL_ECCFREE:
   ecc_free(key);
LBL_DONE:
   mp_clear_multi(a, b, gx, gy, NULL);
   if (l) der_free_sequence_flexi(l);
   if (p) der_free_sequence_flexi(p);
   return err;
}

#endif

/* ref:         $Format:%D$ */
/* git commit:  $Format:%H$ */
/* commit time: $Format:%ai$ */
