// 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_PBES

static const char * const _oid_pbes2 =  "1.2.840.113549.1.5.13";
static const char * const _oid_pbkdf2 = "1.2.840.113549.1.5.12";

typedef struct {
   const char *oid;
   const char *id;
} oid_id_st;

static const oid_id_st _hmac_oid_names[] = {
   { "1.2.840.113549.2.7",  "sha1" },
   { "1.2.840.113549.2.8",  "sha224" },
   { "1.2.840.113549.2.9",  "sha256" },
   { "1.2.840.113549.2.10", "sha384" },
   { "1.2.840.113549.2.11", "sha512" },
   { "1.2.840.113549.2.12", "sha512-224" },
   { "1.2.840.113549.2.13", "sha512-256" },
};

static const pbes_properties _pbes2_default_types[] = {
   { pkcs_5_alg2, "sha1",   "des",   8, 0 },
   { pkcs_5_alg2, "sha1",   "rc2",   4, 0 },
   { pkcs_5_alg2, "sha1",   "3des", 24, 0 },
   { pkcs_5_alg2, "sha1",   "aes",  16, 0 },
   { pkcs_5_alg2, "sha1",   "aes",  24, 0 },
   { pkcs_5_alg2, "sha1",   "aes",  32, 0 },
};

typedef struct {
   const pbes_properties *data;
   const char* oid;
} oid_to_pbes;

static const oid_to_pbes _pbes2_list[] = {
   { &_pbes2_default_types[0], "1.3.14.3.2.7"            },  /* http://www.oid-info.com/get/1.3.14.3.2.7            desCBC */
   { &_pbes2_default_types[1], "1.2.840.113549.3.2"      },  /* http://www.oid-info.com/get/1.2.840.113549.3.2      rc2CBC */
   { &_pbes2_default_types[2], "1.2.840.113549.3.7"      },  /* http://www.oid-info.com/get/1.2.840.113549.3.7      des-EDE3-CBC */
   { &_pbes2_default_types[3], "2.16.840.1.101.3.4.1.2"  },  /* http://www.oid-info.com/get/2.16.840.1.101.3.4.1.2  aes128-CBC */
   { &_pbes2_default_types[4], "2.16.840.1.101.3.4.1.22" },  /* http://www.oid-info.com/get/2.16.840.1.101.3.4.1.22 aes192-CBC */
   { &_pbes2_default_types[5], "2.16.840.1.101.3.4.1.42" },  /* http://www.oid-info.com/get/2.16.840.1.101.3.4.1.42 aes256-CBC */
};

static int _pbes2_from_oid(const ltc_asn1_list *cipher_oid, const ltc_asn1_list *hmac_oid, pbes_properties *res)
{
   unsigned int i;
   for (i = 0; i < sizeof(_pbes2_list)/sizeof(_pbes2_list[0]); ++i) {
      if (pk_oid_cmp_with_asn1(_pbes2_list[i].oid, cipher_oid) == CRYPT_OK) {
         *res = *_pbes2_list[i].data;
         break;
      }
   }
   if (res->c == NULL) return CRYPT_INVALID_CIPHER;
   if (hmac_oid != NULL) {
      for (i = 0; i < sizeof(_hmac_oid_names)/sizeof(_hmac_oid_names[0]); ++i) {
         if (pk_oid_cmp_with_asn1(_hmac_oid_names[i].oid, hmac_oid) == CRYPT_OK) {
            res->h = _hmac_oid_names[i].id;
            return CRYPT_OK;
         }
      }
      return CRYPT_INVALID_HASH;
   }
   return CRYPT_OK;
}


/**
   Extract PBES2 parameters

   @param s     The start of the sequence with potential PBES2 parameters
   @param res   Pointer to where the extracted parameters should be stored
   @return CRYPT_OK on success
*/
int pbes2_extract(const ltc_asn1_list *s, pbes_arg *res)
{
   unsigned long klen;
   ltc_asn1_list *lkdf, *lenc, *loptseq, *liter, *lhmac;
   int err;

   LTC_ARGCHK(s   != NULL);
   LTC_ARGCHK(res != NULL);

   if ((err = pk_oid_cmp_with_asn1(_oid_pbes2, s)) != CRYPT_OK) return err;

   if (!LTC_ASN1_IS_TYPE(s->next, LTC_ASN1_SEQUENCE) ||
       !LTC_ASN1_IS_TYPE(s->next->child, LTC_ASN1_SEQUENCE) ||
       !LTC_ASN1_IS_TYPE(s->next->child->child, LTC_ASN1_OBJECT_IDENTIFIER) ||
       !LTC_ASN1_IS_TYPE(s->next->child->child->next, LTC_ASN1_SEQUENCE) ||
       !LTC_ASN1_IS_TYPE(s->next->child->next, LTC_ASN1_SEQUENCE) ||
       !LTC_ASN1_IS_TYPE(s->next->child->next->child, LTC_ASN1_OBJECT_IDENTIFIER)) {
      return CRYPT_INVALID_PACKET;
   }
   /* PBES2: encrypted pkcs8 - PBES2+PBKDF2+des-ede3-cbc:
    *  0:d=0  hl=4 l= 380 cons: SEQUENCE
    *  4:d=1  hl=2 l=  78 cons:   SEQUENCE
    *  6:d=2  hl=2 l=   9 prim:     OBJECT             :PBES2 (== 1.2.840.113549.1.5.13) (== *s)
    * 17:d=2  hl=2 l=  65 cons:     SEQUENCE
    * 19:d=3  hl=2 l=  41 cons:       SEQUENCE
    * 21:d=4  hl=2 l=   9 prim:         OBJECT         :PBKDF2 (== *lkdf)
    * 32:d=4  hl=2 l=  28 cons:         SEQUENCE
    * 34:d=5  hl=2 l=   8 prim:           OCTET STRING [HEX DUMP]:28BA4ABF6AA76A3D (== res->salt)
    * 44:d=5  hl=2 l=   2 prim:           INTEGER      :0800 (== res->iterations, *liter)
    * 48:d=5  hl=2 l=  12 cons:           SEQUENCE     (== *loptseq   - this sequence is optional, may be missing)
    * 50:d=6  hl=2 l=   8 prim:             OBJECT     :hmacWithSHA256 (== *lhmac)
    * 60:d=6  hl=2 l=   0 prim:             NULL
    * 62:d=3  hl=2 l=  20 cons:       SEQUENCE
    * 64:d=4  hl=2 l=   8 prim:         OBJECT         :des-ede3-cbc (== *lenc)
    * 74:d=4  hl=2 l=   8 prim:         OCTET STRING   [HEX DUMP]:B1404C4688DC9A5A
    * 84:d=1  hl=4 l= 296 prim:   OCTET STRING         :bytes (== encrypted data)
    */
   lkdf = s->next->child->child;
   lenc = s->next->child->next->child;

   if ((err = pk_oid_cmp_with_asn1(_oid_pbkdf2, lkdf)) != CRYPT_OK) return err;

   if (!LTC_ASN1_IS_TYPE(lkdf->next, LTC_ASN1_SEQUENCE) ||
       !LTC_ASN1_IS_TYPE(lkdf->next->child, LTC_ASN1_OCTET_STRING) ||
       !LTC_ASN1_IS_TYPE(lkdf->next->child->next, LTC_ASN1_INTEGER)) {
      return CRYPT_INVALID_PACKET;
   }

   liter = lkdf->next->child->next;
   loptseq = liter->next;
   res->salt = lkdf->next->child;
   res->iterations = mp_get_int(liter->data);

   /* There's an optional INTEGER keyLength after the iterations, skip that if it's there.
    * c.f. RFC 2898 A.2 PBKDF2 */
   if(LTC_ASN1_IS_TYPE(loptseq, LTC_ASN1_INTEGER)) {
      loptseq = loptseq->next;
   }

   /* this sequence is optional */
   lhmac = NULL;
   if (LTC_ASN1_IS_TYPE(loptseq, LTC_ASN1_SEQUENCE) &&
       LTC_ASN1_IS_TYPE(loptseq->child, LTC_ASN1_OBJECT_IDENTIFIER)) {
      lhmac = loptseq->child;
   }
   if ((err = _pbes2_from_oid(lenc, lhmac, &res->type)) != CRYPT_OK) return err;

   if (LTC_ASN1_IS_TYPE(lenc->next, LTC_ASN1_OCTET_STRING)) {
      /* 'NON-RC2'-CBC */
      res->iv = lenc->next;
   } else if (LTC_ASN1_IS_TYPE(lenc->next, LTC_ASN1_SEQUENCE)) {
      /* RC2-CBC is a bit special ...
       *
       * RC2-CBC-Parameter ::= SEQUENCE {
       *     rc2ParameterVersion INTEGER OPTIONAL,
       *     iv OCTET STRING (SIZE(8)) }
       */
      if (LTC_ASN1_IS_TYPE(lenc->next->child, LTC_ASN1_INTEGER) &&
          LTC_ASN1_IS_TYPE(lenc->next->child->next, LTC_ASN1_OCTET_STRING)) {
         klen = mp_get_int(lenc->next->child->data);
         res->iv   = lenc->next->child->next;
         /*
          * Effective Key Bits         Encoding
          *         40                    160
          *         64                    120
          *        128                     58
          *       b >= 256                  b
          */
         switch (klen) {
            case 160:
               res->key_bits = 40;
               break;
            case 120:
               res->key_bits = 64;
               break;
            case 58:
               res->key_bits = 128;
               break;
            default:
               /* We don't handle undefined Key Bits */
               if (klen < 256) return CRYPT_INVALID_KEYSIZE;

               res->key_bits = klen;
               break;
         }
      } else if (LTC_ASN1_IS_TYPE(lenc->next->child, LTC_ASN1_OCTET_STRING)) {
         res->iv   = lenc->next->child;
         /*
          * If the rc2ParameterVersion field is omitted, the "effective key bits"
          * defaults to 32.
          */
         res->key_bits = 32;
      } else {
         return CRYPT_INVALID_PACKET;
      }
   }

   return CRYPT_OK;
}

#endif

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