Browse Source

add ecc_import_pkcs8

Karel Miko 7 years ago
parent
commit
bf04bf18a4
3 changed files with 1116 additions and 0 deletions
  1. 1 0
      src/headers/tomcrypt_pk.h
  2. 609 0
      src/pk/ecc/ecc_import_pkcs8.c
  3. 506 0
      tests/ecc_test.c

+ 1 - 0
src/headers/tomcrypt_pk.h

@@ -282,6 +282,7 @@ int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_ke
 
 int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, const ecc_key *key);
 int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *key);
+int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, const void *pwd, unsigned long pwdlen, ecc_key *key);
 int ecc_import_x509(const unsigned char *in, unsigned long inlen, ecc_key *key);
 
 int  ecc_shared_secret(const ecc_key *private_key, const ecc_key *public_key,

+ 609 - 0
src/pk/ecc/ecc_import_pkcs8.c

@@ -0,0 +1,609 @@
+/* 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
+
+enum algorithm_oid {
+   PBE_MD2_DES,         /* 0 */
+   PBE_MD2_RC2,
+   PBE_MD5_DES,
+   PBE_MD5_RC2,
+   PBE_SHA1_DES,
+   PBE_SHA1_RC2,        /* 5 */
+   PBES2,
+   PBKDF2,
+   DES_CBC,
+   RC2_CBC,
+   DES_EDE3_CBC,        /* 10 */
+   HMAC_WITH_SHA1,
+   HMAC_WITH_SHA224,
+   HMAC_WITH_SHA256,
+   HMAC_WITH_SHA384,
+   HMAC_WITH_SHA512,    /* 15 */
+   PBE_SHA1_3DES
+};
+
+static const oid_st oid_list[] = {
+   { { 1,2,840,113549,1,5,1     }, 7 }, /* [0]  http://www.oid-info.com/get/1.2.840.113549.1.5.1    pbeWithMD2AndDES-CBC */
+   { { 1,2,840,113549,1,5,4     }, 7 }, /* [1]  http://www.oid-info.com/get/1.2.840.113549.1.5.4    pbeWithMD2AndRC2-CBC */
+   { { 1,2,840,113549,1,5,3     }, 7 }, /* [2]  http://www.oid-info.com/get/1.2.840.113549.1.5.3    pbeWithMD5AndDES-CBC */
+   { { 1,2,840,113549,1,5,6     }, 7 }, /* [3]  http://www.oid-info.com/get/1.2.840.113549.1.5.6    pbeWithMD5AndRC2-CBC */
+   { { 1,2,840,113549,1,5,10    }, 7 }, /* [4]  http://www.oid-info.com/get/1.2.840.113549.1.5.10   pbeWithSHA1AndDES-CBC */
+   { { 1,2,840,113549,1,5,11    }, 7 }, /* [5]  http://www.oid-info.com/get/1.2.840.113549.1.5.11   pbeWithSHA1AndRC2-CBC */
+   { { 1,2,840,113549,1,5,13    }, 7 }, /* [6]  http://www.oid-info.com/get/1.2.840.113549.1.5.13   pbes2 */
+   { { 1,2,840,113549,1,5,12    }, 7 }, /* [7]  http://www.oid-info.com/get/1.2.840.113549.1.5.12   pBKDF2 */
+   { { 1,3,14,3,2,7             }, 6 }, /* [8]  http://www.oid-info.com/get/1.3.14.3.2.7            desCBC */
+   { { 1,2,840,113549,3,2       }, 6 }, /* [9]  http://www.oid-info.com/get/1.2.840.113549.3.2      rc2CBC */
+   { { 1,2,840,113549,3,7       }, 6 }, /* [10] http://www.oid-info.com/get/1.2.840.113549.3.7      des-EDE3-CBC */
+   { { 1,2,840,113549,2,7       }, 6 }, /* [11] http://www.oid-info.com/get/1.2.840.113549.2.7      hmacWithSHA1 */
+   { { 1,2,840,113549,2,8       }, 6 }, /* [12] http://www.oid-info.com/get/1.2.840.113549.2.8      hmacWithSHA224 */
+   { { 1,2,840,113549,2,9       }, 6 }, /* [13] http://www.oid-info.com/get/1.2.840.113549.2.9      hmacWithSHA256 */
+   { { 1,2,840,113549,2,10      }, 6 }, /* [14] http://www.oid-info.com/get/1.2.840.113549.2.10     hmacWithSHA384 */
+   { { 1,2,840,113549,2,11      }, 6 }, /* [15] http://www.oid-info.com/get/1.2.840.113549.2.11     hmacWithSHA512 */
+   { { 1,2,840,113549,1,12,1,3  }, 8 }, /* [16] http://www.oid-info.com/get/1.2.840.113549.1.12.1.3 pbeWithSHAAnd3-KeyTripleDES-CBC */
+   { { 0 }, 0 },
+};
+
+static int _simple_utf8_to_utf16(const unsigned char *in, unsigned long inlen,
+                                 unsigned char *out, unsigned long *outlen) {
+   unsigned long len = 0;
+   const unsigned char* in_end = in + inlen;
+   const ulong32 offset[6] = {
+      0x00000000UL, 0x00003080UL, 0x000E2080UL,
+      0x03C82080UL, 0xFA082080UL, 0x82082080UL
+   };
+   int err = CRYPT_ERROR;
+
+   while (in < in_end) {
+      ulong32 ch = 0;
+      unsigned short extra = 0; /* 0 */
+      if (*in >= 192) extra++;  /* 1 */
+      if (*in >= 224) extra++;  /* 2 */
+      if (*in >= 240) extra++;  /* 3 */
+      if (*in >= 248) extra++;  /* 4 */
+      if (*in >= 252) extra++;  /* 5 */
+      if (in + extra >= in_end) goto ERROR;
+      switch (extra) {
+         case 5: ch += *in++; ch <<= 6;
+         case 4: ch += *in++; ch <<= 6;
+         case 3: ch += *in++; ch <<= 6;
+         case 2: ch += *in++; ch <<= 6;
+         case 1: ch += *in++; ch <<= 6;
+         case 0: ch += *in++;
+      }
+      ch -= offset[extra];
+      if (ch > 0xFFFF) goto ERROR;
+      if (*outlen >= len + 2) {
+         out[len] = (unsigned short)((ch >> 8) & 0xFF);
+         out[len + 1] = (unsigned char)(ch & 0xFF);
+      }
+      len += 2;
+   }
+
+   err = len > *outlen ? CRYPT_BUFFER_OVERFLOW : CRYPT_OK;
+   *outlen = len;
+ERROR:
+   return err;
+}
+
+static int _kdf_pkcs12(int hash_id, const unsigned char *pw, unsigned long pwlen,
+                                    const unsigned char *salt, unsigned long saltlen,
+                                    unsigned int iterations, unsigned char purpose,
+                                    unsigned char *out, unsigned long outlen)
+{
+   unsigned long u = hash_descriptor[hash_id].hashsize;
+   unsigned long v = hash_descriptor[hash_id].blocksize;
+   unsigned long c = (outlen + u - 1) / u;
+   unsigned long Slen = ((saltlen + v - 1) / v) * v;
+   unsigned long Plen = ((pwlen + v - 1) / v) * v;
+   unsigned long k = (Plen + Slen) / v;
+   unsigned long Alen, keylen = 0;
+   unsigned int tmp, i, j, n;
+   unsigned char ch;
+   unsigned char D[MAXBLOCKSIZE], A[MAXBLOCKSIZE], B[MAXBLOCKSIZE];
+   unsigned char *I = NULL, *key = NULL;
+   int err = CRYPT_ERROR;
+
+   key = XMALLOC(u * c);
+   I   = XMALLOC(Plen + Slen);
+   if (key == NULL || I == NULL) goto DONE;
+   zeromem(key, u * c);
+
+   for (i = 0; i < v;    i++) D[i] = purpose;              /* D - diversifier */
+   for (i = 0; i < Slen; i++) I[i] = salt[i % saltlen];
+   for (i = 0; i < Plen; i++) I[Slen + i] = pw[i % pwlen]; /* I = Salt || Pass */
+
+   for (i = 0; i < c; i++) {
+      Alen = u; /* hash size */
+      err = hash_memory_multi(hash_id, A, &Alen, D, v, I, Slen + Plen, NULL); /* A = HASH(D || I) */
+      if (err != CRYPT_OK) goto DONE;
+      for (j = 1; j < iterations; j++) {
+         err = hash_memory(hash_id, A, Alen, A, &Alen); /* A = HASH(A) */
+         if (err != CRYPT_OK) goto DONE;
+      }
+      /* fill buffer B with A */
+      for (j = 0; j < v; j++) B[j] = A[j % Alen];
+      /* B += 1 */
+      for (j = v; j > 0; j--) {
+         if (++B[j - 1] != 0) break;
+      }
+      /* I_n += B */
+      for (n = 0; n < k; n++) {
+         ch = 0;
+         for (j = v; j > 0; j--) {
+            tmp = I[n * v + j - 1] + B[j - 1] + ch;
+            ch = (unsigned char)((tmp >> 8) & 0xFF);
+            I[n * v + j - 1] = (unsigned char)(tmp & 0xFF);
+         }
+      }
+      /* store derived key block */
+      for (j = 0; j < Alen; j++) key[keylen++] = A[j];
+   }
+
+   for (i = 0; i < outlen; i++) out[i] = key[i];
+   err = CRYPT_OK;
+DONE:
+   if (I) XFREE(I);
+   if (key) XFREE(key);
+   return err;
+}
+
+static int _oid_to_id(const unsigned long *oid, unsigned long oid_size)
+{
+   int i, j;
+   for (j = 0; oid_list[j].OIDlen > 0; j++) {
+     int match = 1;
+     if (oid_list[j].OIDlen != oid_size) continue;
+     for (i = 0; i < (int)oid_size && match; i++) if (oid_list[j].OID[i] != oid[i]) match = 0;
+     if (match) return j;
+   }
+   return -1;
+}
+
+static int _pbes1_decrypt(const unsigned char *enc_data, unsigned long enc_size,
+                          const unsigned char *pass,     unsigned long pass_size,
+                          const unsigned char *salt,     unsigned long salt_size,
+                                unsigned long iterations,
+                          const unsigned long *oid,      unsigned long oid_size,
+                                unsigned char *dec_data, unsigned long *dec_size)
+{
+   int id = _oid_to_id(oid, oid_size);
+   int err, hid = -1, cid = -1;
+   unsigned int keylen, blklen;
+   unsigned char key_iv[32] = { 0 }, pad;
+   unsigned long len = sizeof(key_iv), pwlen = pass_size;
+   symmetric_CBC cbc;
+   unsigned char *pw = NULL;
+
+   /* https://tools.ietf.org/html/rfc8018#section-6.1.2 */
+   if (id == PBE_MD2_DES  || id == PBE_MD2_RC2) hid = find_hash("md2");
+   if (id == PBE_MD5_DES  || id == PBE_MD5_RC2) hid = find_hash("md5");
+   if (id == PBE_SHA1_DES || id == PBE_SHA1_RC2 || id == PBE_SHA1_3DES) hid = find_hash("sha1");
+
+   if (id == PBE_MD2_RC2 || id == PBE_MD5_RC2 || id == PBE_SHA1_RC2) {
+      cid = find_cipher("rc2");
+      keylen = 8;
+      blklen = 8;
+   }
+   if (id == PBE_MD2_DES || id == PBE_MD5_DES || id == PBE_SHA1_DES) {
+      cid = find_cipher("des");
+      keylen = 8;
+      blklen = 8;
+   }
+   if (id == PBE_SHA1_3DES) {
+      cid = find_cipher("3des");
+      keylen = 24;
+      blklen = 8;
+   }
+
+   if (id == PBE_SHA1_3DES) {
+      /* convert password to unicode/utf16-be */
+      pwlen = pass_size * 2;
+      pw = XMALLOC(pwlen + 2);
+      if (pw == NULL) goto LBL_ERROR;
+      if ((err = _simple_utf8_to_utf16(pass, pass_size, pw, &pwlen) != CRYPT_OK)) goto LBL_ERROR;
+      pw[pwlen++] = 0;
+      pw[pwlen++] = 0;
+      /* derive KEY */
+      if ((err = _kdf_pkcs12(hid, pw, pwlen, salt, salt_size, iterations, 1, key_iv, keylen)) != CRYPT_OK) goto LBL_ERROR;
+      /* derive IV */
+      if ((err = _kdf_pkcs12(hid, pw, pwlen, salt, salt_size, iterations, 2, key_iv+24, blklen)) != CRYPT_OK) goto LBL_ERROR;
+   }
+   else {
+      if ((err = pkcs_5_alg1(pass, pass_size, salt, iterations, hid, key_iv, &len)) != CRYPT_OK) goto LBL_ERROR;
+      /* the output has 16 bytes: [KEY-8-bytes][IV-8-bytes] */
+   }
+
+   if (hid != -1 && cid != -1) {
+      if (salt_size != 8 || enc_size < blklen) goto LBL_ERROR;
+      if ((err = cbc_start(cid, key_iv + keylen, key_iv, keylen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR;
+      if ((err = cbc_decrypt(enc_data, dec_data, enc_size, &cbc)) != CRYPT_OK) goto LBL_ERROR;
+      if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR;
+      pad = dec_data[enc_size-1];
+      if (pad < 1 || pad > blklen) goto LBL_ERROR;
+      *dec_size = enc_size - pad;
+      err = CRYPT_OK;
+      goto LBL_DONE;
+   }
+
+LBL_ERROR:
+   err = CRYPT_INVALID_ARG;
+LBL_DONE:
+   zeromem(key_iv, sizeof(key_iv));
+   if (pw) { zeromem(pw, pwlen); XFREE(pw); }
+   return err;
+}
+
+static int _pbes2_pbkdf2_decrypt(const unsigned char *enc_data, unsigned long enc_size,
+                                 const unsigned char *pass,     unsigned long pass_size,
+                                 const unsigned char *salt,     unsigned long salt_size,
+                                 const unsigned char *iv,       unsigned long iv_size,
+                                       unsigned long iterations,
+                                                 int hmacid,
+                                                 int encid,
+                                                 int extra_arg,
+                                       unsigned char *dec_data, unsigned long *dec_size)
+{
+   int err, hid = -1, cid = -1;
+   unsigned char k[32], pad;
+   unsigned long klen = sizeof(k);
+   symmetric_CBC cbc;
+
+   /* https://tools.ietf.org/html/rfc8018#section-6.2.2 */
+
+   if (hmacid == HMAC_WITH_SHA1)   hid = find_hash("sha1");
+   if (hmacid == HMAC_WITH_SHA224) hid = find_hash("sha224");
+   if (hmacid == HMAC_WITH_SHA256) hid = find_hash("sha256");
+   if (hmacid == HMAC_WITH_SHA384) hid = find_hash("sha384");
+   if (hmacid == HMAC_WITH_SHA512) hid = find_hash("sha512");
+   if (hid == -1) return CRYPT_INVALID_ARG;
+
+   if (encid == DES_EDE3_CBC) {
+      /* https://tools.ietf.org/html/rfc8018#appendix-B.2.2 */
+      cid = find_cipher("3des");
+      klen = 24;
+      if (klen > sizeof(k) || iv_size != 8 || iv == NULL || cid == -1) goto LBL_ERROR;
+      if ((err = pkcs_5_alg2(pass, pass_size, salt, salt_size, iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR;
+      if ((err = cbc_start(cid, iv, k, klen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR;
+      if ((err = cbc_decrypt(enc_data, dec_data, enc_size, &cbc)) != CRYPT_OK) goto LBL_ERROR;
+      if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR;
+      pad = dec_data[enc_size-1];
+      if (pad < 1 || pad > 8) goto LBL_ERROR;
+      *dec_size = enc_size - pad;
+      return CRYPT_OK;
+   }
+
+   if (encid == DES_CBC) {
+      /* https://tools.ietf.org/html/rfc8018#appendix-B.2.1 */
+      cid = find_cipher("des");
+      klen = 8; /* 64 bits */
+      if (klen > sizeof(k) || iv_size != 8 || iv == NULL || cid == -1) goto LBL_ERROR;
+      if ((err = pkcs_5_alg2(pass, pass_size, salt, salt_size, iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR;
+      if ((err = cbc_start(cid, iv, k, klen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR;
+      if ((err = cbc_decrypt(enc_data, dec_data, enc_size, &cbc)) != CRYPT_OK) goto LBL_ERROR;
+      if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR;
+      pad = dec_data[enc_size-1];
+      if (pad < 1 || pad > 8) goto LBL_ERROR;
+      *dec_size = enc_size - pad;
+      return CRYPT_OK;
+   }
+
+   if (encid == RC2_CBC) {
+     /* https://tools.ietf.org/html/rfc8018#appendix-B.2.3 */
+      cid = find_cipher("rc2");
+      klen = 4; /* default: 32 bits */
+      if (extra_arg == 160)  klen = 5;
+      if (extra_arg == 120)  klen = 8;
+      if (extra_arg == 58)   klen = 16;
+      if (extra_arg >= 256)  klen = extra_arg / 8;
+      if (klen > sizeof(k) || iv_size != 8 || iv == NULL || cid == -1) goto LBL_ERROR;
+      if ((err = pkcs_5_alg2(pass, pass_size, salt, salt_size, iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR;
+      if ((err = cbc_start(cid, iv, k, klen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR;
+      if ((err = cbc_decrypt(enc_data, dec_data, enc_size, &cbc)) != CRYPT_OK) goto LBL_ERROR;
+      if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR;
+      pad = dec_data[enc_size-1];
+      if (pad < 1 || pad > 8) goto LBL_ERROR;
+      *dec_size = enc_size - pad;
+      return CRYPT_OK;
+   }
+
+LBL_ERROR:
+   zeromem(k, sizeof(k));
+   return CRYPT_INVALID_ARG;
+}
+
+static int _der_decode_pkcs8_flexi(const unsigned char *in,  unsigned long inlen,
+                                   const void *pwd, unsigned long pwdlen,
+                                   ltc_asn1_list **decoded_list)
+{
+   unsigned long len = inlen;
+   unsigned long dec_size;
+   unsigned char *dec_data = NULL;
+   ltc_asn1_list *l = NULL;
+   int err;
+
+   *decoded_list = NULL;
+   if ((err = der_decode_sequence_flexi(in, &len, &l)) == CRYPT_OK) {
+      /* the following "if" detects whether it is encrypted or not */
+      if (l->type == LTC_ASN1_SEQUENCE &&
+          l->child && l->child->type == LTC_ASN1_SEQUENCE &&
+          l->child->child && l->child->child->type == LTC_ASN1_OBJECT_IDENTIFIER &&
+          l->child->child->next && l->child->child->next->type == LTC_ASN1_SEQUENCE &&
+          l->child->next && l->child->next->type == LTC_ASN1_OCTET_STRING) {
+         ltc_asn1_list *lalgoid = l->child->child;
+         ltc_asn1_list *lalgparam = l->child->child->next;
+         unsigned char *enc_data = l->child->next->data;
+         unsigned long enc_size = l->child->next->size;
+         dec_size = enc_size;
+         if ((dec_data = XMALLOC(dec_size)) == NULL) {
+            err = CRYPT_MEM;
+            goto LBL_DONE;
+         }
+         if (lalgparam->child && lalgparam->child->type == LTC_ASN1_OCTET_STRING &&
+             lalgparam->child->next && lalgparam->child->next->type == LTC_ASN1_INTEGER) {
+            /* PBES1: encrypted pkcs8 - pbeWithMD5AndDES-CBC:
+             *  0:d=0  hl=4 l= 329 cons: SEQUENCE
+             *  4:d=1  hl=2 l=  27 cons:   SEQUENCE             (== *lalg)
+             *  6:d=2  hl=2 l=   9 prim:     OBJECT             :pbeWithMD5AndDES-CBC (== 1.2.840.113549.1.5.3)
+             * 17:d=2  hl=2 l=  14 cons:     SEQUENCE           (== *lalgparam)
+             * 19:d=3  hl=2 l=   8 prim:       OCTET STRING     [HEX DUMP]:8EDF749A06CCDE51 (== salt)
+             * 29:d=3  hl=2 l=   2 prim:       INTEGER          :0800  (== iterations)
+             * 33:d=1  hl=4 l= 296 prim:   OCTET STRING         :bytes (== encrypted data)
+             */
+            unsigned long iter = mp_get_int(lalgparam->child->next->data);
+            unsigned long salt_size = lalgparam->child->size;
+            unsigned char *salt = lalgparam->child->data;
+            err = _pbes1_decrypt(enc_data, enc_size, pwd, pwdlen, salt, salt_size, iter, lalgoid->data, lalgoid->size, dec_data, &dec_size);
+            if (err != CRYPT_OK) goto LBL_DONE;
+         }
+         else if (PBES2 == _oid_to_id(lalgoid->data, lalgoid->size) &&
+                  lalgparam->child && lalgparam->child->type == LTC_ASN1_SEQUENCE &&
+                  lalgparam->child->child && lalgparam->child->child->type == LTC_ASN1_OBJECT_IDENTIFIER &&
+                  lalgparam->child->child->next && lalgparam->child->child->next->type == LTC_ASN1_SEQUENCE &&
+                  lalgparam->child->next && lalgparam->child->next->type == LTC_ASN1_SEQUENCE &&
+                  lalgparam->child->next->child && lalgparam->child->next->child->type == LTC_ASN1_OBJECT_IDENTIFIER) {
+            /* 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             (== *lalg)
+             *  6:d=2  hl=2 l=   9 prim:     OBJECT             :PBES2 (== 1.2.840.113549.1.5.13)
+             * 17:d=2  hl=2 l=  65 cons:     SEQUENCE           (== *lalgparam)
+             * 19:d=3  hl=2 l=  41 cons:       SEQUENCE
+             * 21:d=4  hl=2 l=   9 prim:         OBJECT         :PBKDF2
+             * 32:d=4  hl=2 l=  28 cons:         SEQUENCE
+             * 34:d=5  hl=2 l=   8 prim:           OCTET STRING [HEX DUMP]:28BA4ABF6AA76A3D (== salt)
+             * 44:d=5  hl=2 l=   2 prim:           INTEGER      :0800 (== iterations)
+             * 48:d=5  hl=2 l=  12 cons:           SEQUENCE     (this sequence is optional, may be missing)
+             * 50:d=6  hl=2 l=   8 prim:             OBJECT     :hmacWithSHA256
+             * 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
+             * 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)
+             */
+            ltc_asn1_list *lkdf = lalgparam->child->child;
+            ltc_asn1_list *lenc = lalgparam->child->next->child;
+            int kdfid = _oid_to_id(lkdf->data, lkdf->size);
+            int encid = _oid_to_id(lenc->data, lenc->size);
+            if (PBKDF2 == kdfid &&
+                lkdf->next && lkdf->next->type == LTC_ASN1_SEQUENCE &&
+                lkdf->next->child && lkdf->next->child->type == LTC_ASN1_OCTET_STRING &&
+                lkdf->next->child->next && lkdf->next->child->next->type == LTC_ASN1_INTEGER) {
+               unsigned long iter = mp_get_int(lkdf->next->child->next->data);
+               unsigned long salt_size = lkdf->next->child->size;
+               unsigned char *salt = lkdf->next->child->data;
+               unsigned char *iv = NULL;
+               unsigned long iv_size = 0;
+               unsigned long arg = 0;
+               ltc_asn1_list *loptseq = lkdf->next->child->next->next;
+               int hmacid = HMAC_WITH_SHA1; /* this is default */
+               if (loptseq && loptseq->type == LTC_ASN1_SEQUENCE &&
+                   loptseq->child && loptseq->child->type == LTC_ASN1_OBJECT_IDENTIFIER) {
+                  /* this sequence is optional */
+                  hmacid = _oid_to_id(loptseq->child->data, loptseq->child->size);
+               }
+               if (lenc->next && lenc->next->type == LTC_ASN1_OCTET_STRING) {
+                  /* DES-CBC + DES_EDE3_CBC */
+                  iv = lenc->next->data;
+                  iv_size = lenc->next->size;
+               }
+               else if (lenc->next && lenc->next->type == LTC_ASN1_SEQUENCE &&
+                        lenc->next->child && lenc->next->child->type == LTC_ASN1_INTEGER &&
+                        lenc->next->child->next && lenc->next->child->next->type == LTC_ASN1_OCTET_STRING) {
+                  /* RC2-CBC is a bit special */
+                  iv = lenc->next->child->next->data;
+                  iv_size = lenc->next->child->next->size;
+                  arg = mp_get_int(lenc->next->child->data);
+               }
+               err = _pbes2_pbkdf2_decrypt(enc_data, enc_size, pwd, pwdlen, salt, salt_size, iv, iv_size, iter, hmacid, encid, arg, dec_data, &dec_size);
+               if (err != CRYPT_OK) goto LBL_DONE;
+            }
+            else {
+               /* non-PBKDF2 algorithms are not supported */
+               err = CRYPT_INVALID_PACKET;
+               goto LBL_DONE;
+            }
+         }
+         else {
+            /* unsupported encryption */
+            err = CRYPT_INVALID_PACKET;
+            goto LBL_DONE;
+         }
+         der_free_sequence_flexi(l);
+         l = NULL;
+         err = der_decode_sequence_flexi(dec_data, &dec_size, &l);
+         if (err != CRYPT_OK) goto LBL_DONE;
+         *decoded_list = l;
+      }
+      else {
+         /* not encrypted */
+         err = CRYPT_OK;
+         *decoded_list = l;
+      }
+   }
+
+LBL_DONE:
+   if (dec_data) XFREE(dec_data);
+   return err;
+}
+
+/* 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;
+   oid_st        ecoid;
+   int           err;
+   char          OID[256];
+   const ltc_ecc_curve *curve;
+   ltc_asn1_list *p = NULL, *l = NULL;
+
+   LTC_ARGCHK(in          != NULL);
+   LTC_ARGCHK(key         != NULL);
+   LTC_ARGCHK(ltc_mp.name != NULL);
+
+   /* get EC alg oid */
+   err = pk_get_oid(PKA_EC, &ecoid);
+   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 = _der_decode_pkcs8_flexi(in, inlen, pwd, pwdlen, &l)) == CRYPT_OK) {
+      if (l->type == LTC_ASN1_SEQUENCE &&
+          l->child && l->child->type == LTC_ASN1_INTEGER &&
+          l->child->next && l->child->next->type == LTC_ASN1_SEQUENCE &&
+          l->child->next->child && l->child->next->child->type == LTC_ASN1_OBJECT_IDENTIFIER &&
+          l->child->next->next && l->child->next->next->type == LTC_ASN1_OCTET_STRING) {
+         ltc_asn1_list *lseq = l->child->next;
+         ltc_asn1_list *lpri = l->child->next->next;
+         ltc_asn1_list *lecoid = l->child->next->child;
+
+         if ((lecoid->size != ecoid.OIDlen) ||
+            XMEMCMP(ecoid.OID, lecoid->data, ecoid.OIDlen * sizeof(ecoid.OID[0]))) {
+            err = CRYPT_PK_INVALID_TYPE;
+            goto LBL_DONE;
+         }
+
+         if (lseq->child->next && lseq->child->next->type == 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       (== *lseq)
+             *  7:d=2  hl=2 l=   7 prim:     OBJECT       :id-ecPublicKey
+             * 16:d=2  hl=2 l=   5 prim:     OBJECT       :secp256k1 (== 1.3.132.0.10)
+             * 23:d=1  hl=2 l=  77 prim:   OCTET STRING   :bytes (== privatekey)
+             */
+            ltc_asn1_list *loid = lseq->child->next;
+            len = sizeof(OID);
+            if ((err = pk_oid_num_to_str(loid->data, loid->size, OID, &len)) != CRYPT_OK) { goto LBL_DONE; }
+            if ((err = ecc_get_curve(OID, &curve)) != CRYPT_OK)                           { goto LBL_DONE; }
+            if ((err = ecc_set_dp(curve, key)) != CRYPT_OK)                               { goto LBL_DONE; }
+         }
+         else if (lseq->child->next && lseq->child->next->type == LTC_ASN1_SEQUENCE) {
+            /* 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             (== *lseq)
+             *   9:d=2  hl=2 l=   7 prim:     OBJECT             :id-ecPublicKey
+             *  18:d=2  hl=3 l= 130 cons:     SEQUENCE           (== *lcurve)
+             *  21:d=3  hl=2 l=   1 prim:       INTEGER          :01
+             *  24:d=3  hl=2 l=  44 cons:       SEQUENCE         (== *lfield)
+             *  26:d=4  hl=2 l=   7 prim:         OBJECT         :prime-field
+             *  35:d=4  hl=2 l=  33 prim:         INTEGER        :(== curve.prime)
+             *  70:d=3  hl=2 l=   6 cons:       SEQUENCE         (== *lpoint)
+             *  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 (== curve.G-point)
+             * 113:d=3  hl=2 l=  33 prim:       INTEGER          :(== curve.order)
+             * 148:d=3  hl=2 l=   1 prim:       INTEGER          :(== curve.cofactor)
+             * 151:d=1  hl=2 l=  77 prim:   OCTET STRING         :bytes (== privatekey)
+             */
+            ltc_asn1_list *lcurve = lseq->child->next;
+
+            if (lcurve->child && lcurve->child->type == LTC_ASN1_INTEGER &&
+                lcurve->child->next && lcurve->child->next->type == LTC_ASN1_SEQUENCE &&
+                lcurve->child->next->next && lcurve->child->next->next->type == LTC_ASN1_SEQUENCE &&
+                lcurve->child->next->next->next && lcurve->child->next->next->next->type == LTC_ASN1_OCTET_STRING &&
+                lcurve->child->next->next->next->next && lcurve->child->next->next->next->next->type == LTC_ASN1_INTEGER &&
+                lcurve->child->next->next->next->next->next && lcurve->child->next->next->next->next->next->type == LTC_ASN1_INTEGER) {
+
+               ltc_asn1_list *lfield = lcurve->child->next;
+               ltc_asn1_list *lpoint = lcurve->child->next->next;
+               ltc_asn1_list *lg     = lcurve->child->next->next->next;
+               ltc_asn1_list *lorder = lcurve->child->next->next->next->next;
+               cofactor = mp_get_int(lcurve->child->next->next->next->next->next->data);
+
+               if (lfield->child && lfield->child->type == LTC_ASN1_OBJECT_IDENTIFIER &&
+                   lfield->child->next && lfield->child->next->type == LTC_ASN1_INTEGER &&
+                   lpoint->child && lpoint->child->type == LTC_ASN1_OCTET_STRING &&
+                   lpoint->child->next && lpoint->child->next->type == LTC_ASN1_OCTET_STRING) {
+
+                  ltc_asn1_list *lprime = lfield->child->next;
+                  if ((err = mp_read_unsigned_bin(a, lpoint->child->data, lpoint->child->size)) != CRYPT_OK) {
+                     goto LBL_DONE;
+                  }
+                  if ((err = mp_read_unsigned_bin(b, lpoint->child->next->data, lpoint->child->next->size)) != CRYPT_OK) {
+                     goto LBL_DONE;
+                  }
+                  if ((err = ltc_ecc_import_point(lg->data, lg->size, lprime->data, a, b, gx, gy)) != CRYPT_OK) {
+                     goto LBL_DONE;
+                  }
+                  if ((err = ecc_set_dp_from_mpis(a, b, lprime->data, lorder->data, gx, gy, cofactor, key)) != CRYPT_OK) {
+                     goto LBL_DONE;
+                  }
+               }
+            }
+         }
+         else {
+            err = CRYPT_INVALID_PACKET;
+            goto LBL_DONE;
+         }
+
+         /* load private key value 'k' */
+         len = lpri->size;
+         if ((err = der_decode_sequence_flexi(lpri->data, &len, &p)) == CRYPT_OK) {
+            if (p->type == LTC_ASN1_SEQUENCE &&
+                p->child && p->child->type == LTC_ASN1_INTEGER &&
+                p->child->next && p->child->next->type == 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$ */

+ 506 - 0
tests/ecc_test.c

@@ -630,6 +630,26 @@ static int _ecc_import_export(void) {
         openssl req -new -x509 -keyform der -key long_pric.der  -sha512 -subj '/CN=Test Cert EC' -out x509_cert_longc.der  -outform der -days 365000
         openssl req -new -x509 -keyform der -key short_pri.der  -sha512 -subj '/CN=Test Cert EC' -out x509_cert_short.der  -outform der -days 365000
         openssl req -new -x509 -keyform der -key short_pric.der -sha512 -subj '/CN=Test Cert EC' -out x509_cert_shortc.der -outform der -days 365000
+        # pkcs8 without password
+        openssl pkcs8 -topk8 -inform DER -outform DER -nocrypt -in long_pri.der   -out long_pri_pkcs8.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -nocrypt -in long_pric.der  -out long_pric_pkcs8.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -nocrypt -in short_pri.der  -out short_pri_pkcs8.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -nocrypt -in short_pric.der -out short_pric_pkcs8.der
+        # password protected - PBES1
+        openssl pkcs8 -topk8 -inform DER -outform DER -passout pass:secret -in long_pri.der -v1 PBE-MD2-DES     -out long_pri_pkcs8_pbe_md2_des.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -passout pass:secret -in long_pri.der -v1 PBE-MD2-RC2-64  -out long_pri_pkcs8_pbe_md2_rc2_64.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -passout pass:secret -in long_pri.der -v1 PBE-MD5-DES     -out long_pri_pkcs8_pbe_md5_des.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -passout pass:secret -in long_pri.der -v1 PBE-SHA1-RC2-64 -out long_pri_pkcs8_pbe_sha1_rc2_64.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -passout pass:secret -in long_pri.der -v1 PBE-MD5-RC2-64  -out long_pri_pkcs8_pbe_md5_rc2_64.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -passout pass:secret -in long_pri.der -v1 PBE-SHA1-DES    -out long_pri_pkcs8_pbe_sha1_des.der
+        # password protected - PBES2
+        openssl pkcs8 -topk8 -inform DER -outform DER -passout pass:secret -in long_pri.der -v2 rc2  -out long_pri_pkcs8_pbkdf2_rc2_cbc.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -passout pass:secret -in long_pri.der -v2 des  -out long_pri_pkcs8_pbkdf2_des_cbc.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -passout pass:secret -in long_pri.der -v2 des3 -out long_pri_pkcs8_pbkdf2_des_ede3_cbc.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -passout pass:secret -in long_pri.der -v2 des3 -v2prf hmacWithSHA224 -out long_pri_pkcs8_pbkdf2_sha224_des_ede3_cbc.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -passout pass:secret -in long_pri.der -v2 des3 -v2prf hmacWithSHA256 -out long_pri_pkcs8_pbkdf2_sha256_des_ede3_cbc.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -passout pass:secret -in long_pri.der -v2 des3 -v2prf hmacWithSHA384 -out long_pri_pkcs8_pbkdf2_sha384_des_ede3_cbc.der
+        openssl pkcs8 -topk8 -inform DER -outform DER -passout pass:secret -in long_pri.der -v2 des3 -v2prf hmacWithSHA512 -out long_pri_pkcs8_pbkdf2_sha512_des_ede3_cbc.der
     */
    static const unsigned char long_pri[] = { /* private + long public, explicit curve params */
       0x30, 0x82, 0x01, 0x13, 0x02, 0x01, 0x01, 0x04, 0x20, 0x0c, 0xf1, 0xad, 0x2f, 0x03, 0xf7, 0x91,
@@ -651,6 +671,372 @@ static int _ecc_import_export(void) {
       0x6c, 0x6e, 0x32, 0x5b, 0xf7, 0x63, 0x62, 0x94, 0x24, 0x24, 0xdb, 0xec, 0x3f, 0x8b, 0xe5, 0x6e,
       0x4b, 0x64, 0x37, 0x31, 0x24, 0x79, 0x4d
    };
+   static const unsigned char long_pri_pkcs8[] = { /* private + long public, explicit curve params, PKCS8 */
+      0x30, 0x82, 0x01, 0x23, 0x02, 0x01, 0x00, 0x30, 0x81, 0xae, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce,
+      0x3d, 0x02, 0x01, 0x30, 0x81, 0xa2, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 0x48,
+      0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+      0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x30, 0x06, 0x04, 0x01, 0x00, 0x04, 0x01, 0x07, 0x04,
+      0x41, 0x04, 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac, 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87,
+      0x0b, 0x07, 0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9, 0x59, 0xf2, 0x81, 0x5b, 0x16, 0xf8,
+      0x17, 0x98, 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc, 0x0e, 0x11,
+      0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10,
+      0xd4, 0xb8, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+      0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e,
+      0x8c, 0xd0, 0x36, 0x41, 0x41, 0x02, 0x01, 0x01, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04,
+      0x20, 0x0c, 0xf1, 0xad, 0x2f, 0x03, 0xf7, 0x91, 0x1b, 0xba, 0x03, 0xcf, 0x23, 0x37, 0xc8, 0xf2,
+      0xf7, 0x36, 0xce, 0x65, 0xf1, 0x84, 0x2d, 0x7d, 0x9f, 0x5f, 0x9e, 0x21, 0xd9, 0x5e, 0x49, 0xbd,
+      0x23, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x2a, 0xf9, 0x0b, 0xda, 0xbe, 0x71, 0x66, 0x9e, 0xd1,
+      0xcf, 0x12, 0xd0, 0x24, 0xaf, 0xba, 0xb6, 0x7f, 0xfb, 0x96, 0x27, 0x3e, 0x2f, 0xbd, 0x1e, 0xd5,
+      0xf9, 0x8d, 0x6c, 0x73, 0x9d, 0xc5, 0x16, 0x91, 0xbd, 0xb2, 0xb9, 0x1b, 0x40, 0x10, 0x5a, 0xb7,
+      0x6c, 0x6e, 0x32, 0x5b, 0xf7, 0x63, 0x62, 0x94, 0x24, 0x24, 0xdb, 0xec, 0x3f, 0x8b, 0xe5, 0x6e,
+      0x4b, 0x64, 0x37, 0x31, 0x24, 0x79, 0x4d
+   };
+#if defined(LTC_MD2) && defined(LTC_DES)
+   static const unsigned char long_pri_pkcs8_pbe_md2_des[] = {
+      0x30, 0x82, 0x01, 0x49, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+      0x01, 0x30, 0x0e, 0x04, 0x08, 0xd8, 0x1c, 0x80, 0xac, 0xd9, 0xfa, 0x9d, 0xbc, 0x02, 0x02, 0x08,
+      0x00, 0x04, 0x82, 0x01, 0x28, 0xe1, 0xd5, 0xa8, 0x9a, 0xa8, 0x23, 0x85, 0x53, 0x18, 0xb3, 0x96,
+      0x67, 0x8d, 0x45, 0x72, 0xf8, 0x69, 0xc4, 0xb1, 0x01, 0x3e, 0x04, 0xf7, 0xf7, 0x5d, 0x07, 0xad,
+      0xec, 0x8e, 0xd6, 0x23, 0x00, 0xe7, 0x59, 0xb0, 0x98, 0xbb, 0xdb, 0x85, 0xdb, 0x59, 0x4d, 0xb5,
+      0x53, 0xb3, 0x32, 0x50, 0x66, 0x75, 0xc4, 0x69, 0x05, 0x07, 0xee, 0xd4, 0xd8, 0x33, 0xcd, 0x4c,
+      0x94, 0xad, 0x82, 0xc7, 0x89, 0x53, 0x65, 0x9f, 0x55, 0x44, 0x95, 0x20, 0xe8, 0x4a, 0xc2, 0xef,
+      0x41, 0xf2, 0x9d, 0xf8, 0x3d, 0x16, 0x8a, 0x6a, 0x4e, 0x85, 0x90, 0xa7, 0xf9, 0xf8, 0xac, 0x16,
+      0x76, 0xf2, 0x29, 0x4b, 0x93, 0xec, 0xd8, 0x17, 0x3f, 0x89, 0x84, 0x79, 0x75, 0x90, 0x5f, 0xc3,
+      0xf2, 0xb8, 0x1a, 0x0a, 0x25, 0xf4, 0xe2, 0x59, 0xe0, 0xea, 0xa6, 0x57, 0xc4, 0x9c, 0xce, 0xfd,
+      0xa8, 0xbc, 0xf6, 0x0d, 0x3a, 0x47, 0x14, 0x9d, 0x6a, 0x92, 0x77, 0xe4, 0xcb, 0x88, 0x6e, 0xfa,
+      0x19, 0xa4, 0x3d, 0x58, 0xdb, 0x5f, 0xc7, 0xad, 0x91, 0x64, 0xb0, 0x1f, 0xe2, 0x66, 0xc5, 0x5a,
+      0x28, 0x21, 0xb0, 0xc1, 0xc8, 0x73, 0x55, 0xd8, 0x43, 0x66, 0x6a, 0x5c, 0xcd, 0xb0, 0x89, 0x60,
+      0x59, 0x31, 0xe0, 0x2f, 0x20, 0x3b, 0x83, 0xdf, 0x27, 0xcf, 0x33, 0xcc, 0xb9, 0xb6, 0xe0, 0xec,
+      0x8b, 0x94, 0x4b, 0xc4, 0x1c, 0x25, 0xba, 0x97, 0x6c, 0x83, 0x22, 0x8c, 0xca, 0x9d, 0xc6, 0xaa,
+      0x74, 0x3f, 0x46, 0xdc, 0xba, 0x7a, 0x36, 0x04, 0xa7, 0xc8, 0x65, 0xb4, 0xf7, 0x14, 0x53, 0x8c,
+      0xff, 0x4d, 0x19, 0xc1, 0xdb, 0xa4, 0xcc, 0x52, 0xc2, 0xd9, 0x38, 0x16, 0x8f, 0xd8, 0x6e, 0x55,
+      0x41, 0xa8, 0xe0, 0x15, 0xd6, 0x2d, 0xa4, 0x37, 0x9f, 0xcc, 0x42, 0x3c, 0xcb, 0xcc, 0x92, 0x04,
+      0xc8, 0xcf, 0xbc, 0x60, 0xfb, 0x45, 0xff, 0x62, 0x74, 0xa1, 0xe9, 0xba, 0x1e, 0x5d, 0x44, 0x6f,
+      0x0e, 0xac, 0xdf, 0xde, 0xb1, 0xbb, 0x47, 0x5e, 0x0c, 0x88, 0x0a, 0x85, 0x0b, 0xa8, 0x9e, 0xcb,
+      0x32, 0x99, 0x8d, 0xb1, 0xdd, 0x12, 0x08, 0xeb, 0x7e, 0x45, 0x70, 0x12, 0xe3
+   };
+#endif
+#if defined(LTC_MD2) && defined(LTC_RC2)
+   static const unsigned char long_pri_pkcs8_pbe_md2_rc2_64[] = {
+      0x30, 0x82, 0x01, 0x49, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+      0x04, 0x30, 0x0e, 0x04, 0x08, 0xa2, 0x28, 0xb7, 0x2a, 0x08, 0x1c, 0x4a, 0xc4, 0x02, 0x02, 0x08,
+      0x00, 0x04, 0x82, 0x01, 0x28, 0x78, 0x12, 0x02, 0x58, 0x9b, 0xea, 0x77, 0xba, 0x84, 0x20, 0x96,
+      0x63, 0xf0, 0xf3, 0x38, 0x0b, 0x98, 0x53, 0x63, 0x8d, 0xa4, 0x5a, 0xa0, 0xa9, 0x21, 0x93, 0xd0,
+      0x56, 0xc9, 0xd2, 0x67, 0xb2, 0x5e, 0xb5, 0x9f, 0x15, 0x8c, 0x3c, 0x9a, 0xaf, 0x9c, 0xe5, 0x8b,
+      0xe6, 0x61, 0xac, 0xa4, 0x26, 0x75, 0x96, 0xea, 0x73, 0xaf, 0xd6, 0xb7, 0x4c, 0x66, 0x33, 0x98,
+      0x9e, 0x0b, 0xf8, 0xe6, 0x9c, 0xfd, 0x83, 0x0f, 0x55, 0x86, 0x9f, 0xa9, 0xf0, 0x23, 0xcb, 0x80,
+      0xe5, 0x32, 0x50, 0xea, 0x5b, 0x7d, 0xe2, 0x69, 0xc4, 0x6b, 0x61, 0xb2, 0xb8, 0x81, 0xe9, 0x05,
+      0xcb, 0x76, 0xae, 0xa5, 0x37, 0x0f, 0x3c, 0xe6, 0xde, 0x24, 0x6a, 0x9c, 0xf2, 0x0a, 0x28, 0x6a,
+      0xc9, 0xec, 0xef, 0xd7, 0xda, 0xcc, 0xf4, 0x3b, 0x74, 0x36, 0xc5, 0xaf, 0x53, 0xd8, 0xf4, 0x30,
+      0x0b, 0xd4, 0xb6, 0x36, 0xdc, 0x90, 0x4f, 0x83, 0x44, 0x79, 0xea, 0xc9, 0xb7, 0xb2, 0xd0, 0x03,
+      0xa6, 0x63, 0x7e, 0x1d, 0xa8, 0x4e, 0x93, 0x16, 0x7a, 0x4f, 0xd2, 0x8b, 0xd6, 0x78, 0x7d, 0x48,
+      0x41, 0x7c, 0xba, 0xc3, 0x64, 0x6f, 0x11, 0x22, 0x6d, 0x40, 0xb8, 0xc9, 0x03, 0x7a, 0x2c, 0xdf,
+      0x76, 0x78, 0x4f, 0x5f, 0x50, 0x03, 0x7a, 0xaf, 0x78, 0x91, 0xbb, 0x2a, 0xe6, 0x5e, 0x0f, 0xf5,
+      0x60, 0x9e, 0x8a, 0x2f, 0xdb, 0x9e, 0x57, 0xbe, 0xf6, 0x0f, 0x76, 0x6e, 0x44, 0x91, 0x7b, 0x36,
+      0x88, 0x9c, 0xf9, 0xbe, 0x13, 0x3e, 0x6b, 0x85, 0x62, 0xda, 0x1f, 0xf9, 0x73, 0x98, 0x8a, 0x0d,
+      0xdf, 0x11, 0x74, 0x18, 0xe1, 0x1c, 0xd1, 0x3f, 0x02, 0x43, 0xd4, 0x46, 0xe3, 0x8a, 0x3b, 0x6c,
+      0x7f, 0x81, 0xb4, 0xc3, 0x85, 0x4f, 0x89, 0x67, 0x26, 0x5a, 0x08, 0x35, 0x31, 0xd3, 0x15, 0xbb,
+      0xcc, 0x7d, 0x7b, 0x99, 0x41, 0xdb, 0x43, 0xa0, 0x83, 0x84, 0x74, 0x6c, 0x0a, 0x80, 0x46, 0xdc,
+      0xc8, 0x88, 0x87, 0x01, 0x21, 0x19, 0xd4, 0x1e, 0xf4, 0x09, 0x0e, 0x18, 0x31, 0x91, 0x37, 0x35,
+      0x1d, 0x07, 0xaf, 0x87, 0x92, 0x3d, 0xf8, 0xee, 0x6f, 0x87, 0x7b, 0x52, 0x3d
+   };
+#endif
+#if defined(LTC_MD5) && defined(LTC_DES)
+   static const unsigned char long_pri_pkcs8_pbe_md5_des[] = {
+      0x30, 0x82, 0x01, 0x49, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+      0x03, 0x30, 0x0e, 0x04, 0x08, 0x33, 0xe7, 0xd9, 0xf1, 0x35, 0xd9, 0x74, 0x83, 0x02, 0x02, 0x08,
+      0x00, 0x04, 0x82, 0x01, 0x28, 0x2f, 0x77, 0x7c, 0x48, 0xc9, 0x43, 0x6d, 0xdb, 0xd0, 0x1a, 0xef,
+      0xfb, 0x29, 0x5e, 0x53, 0xa3, 0x52, 0x28, 0x27, 0x76, 0xc2, 0x01, 0x76, 0x5a, 0xea, 0x98, 0xe6,
+      0x72, 0xdf, 0x06, 0xa2, 0xf5, 0xd0, 0x7b, 0x74, 0xe4, 0x6b, 0x98, 0xa6, 0xb5, 0xe1, 0x02, 0xf7,
+      0xab, 0x2c, 0xf1, 0xeb, 0xf4, 0xec, 0xa6, 0xba, 0xd3, 0xd5, 0xb2, 0x26, 0x83, 0xeb, 0xff, 0xc9,
+      0xf8, 0x7b, 0xbf, 0xab, 0xdc, 0xe5, 0xe4, 0x91, 0xd5, 0x48, 0xba, 0x49, 0xcb, 0xc5, 0xf1, 0x71,
+      0x48, 0x1e, 0x96, 0x7c, 0x10, 0xe4, 0xa9, 0x35, 0xa7, 0xe6, 0x82, 0x97, 0x6f, 0xe4, 0x64, 0xd4,
+      0x53, 0xa9, 0xf1, 0x1b, 0x6c, 0x31, 0xa1, 0xc7, 0x12, 0x46, 0x45, 0x6f, 0x45, 0xb2, 0x09, 0x3a,
+      0xfe, 0x35, 0x4e, 0xbf, 0x7d, 0xf8, 0xcf, 0x94, 0x78, 0x0c, 0x78, 0xfb, 0xce, 0xc1, 0x30, 0xcd,
+      0x6d, 0x6b, 0x08, 0x5e, 0xf6, 0xf5, 0x97, 0xff, 0x5e, 0x63, 0x44, 0x36, 0xa5, 0x71, 0x04, 0xe5,
+      0x2d, 0xd9, 0xe3, 0x41, 0x91, 0x09, 0x1e, 0xa3, 0x30, 0xff, 0x12, 0x2a, 0x7a, 0xe1, 0x8f, 0x9c,
+      0x38, 0x13, 0x3d, 0xc3, 0xbb, 0x68, 0xfa, 0xc0, 0xc6, 0x35, 0x77, 0xed, 0xe8, 0x73, 0xca, 0xc3,
+      0x87, 0x62, 0xa9, 0x0e, 0xef, 0xcf, 0x73, 0x3c, 0xb3, 0xa0, 0x1b, 0xb5, 0x5d, 0x72, 0x89, 0x82,
+      0xd4, 0xf6, 0x37, 0x0b, 0x57, 0x8f, 0x48, 0xd4, 0xf1, 0x10, 0xa1, 0xe5, 0x25, 0x90, 0xeb, 0xde,
+      0x8d, 0x2a, 0x9d, 0xfb, 0x7c, 0x0d, 0xdc, 0x38, 0x45, 0x9e, 0xa0, 0x05, 0x98, 0x4e, 0x72, 0x9f,
+      0x3d, 0xde, 0xc7, 0x00, 0xf9, 0xaf, 0xdc, 0x67, 0x47, 0x73, 0xf7, 0xcf, 0x63, 0x80, 0xe3, 0x05,
+      0xb3, 0xda, 0x9f, 0x4b, 0x27, 0xd3, 0x14, 0xc9, 0x62, 0xd5, 0x09, 0xde, 0x4d, 0xe7, 0x21, 0x67,
+      0xfa, 0x10, 0x34, 0x18, 0xbf, 0xde, 0xf7, 0x95, 0x25, 0x6d, 0xba, 0xe4, 0x10, 0xf0, 0x9d, 0x05,
+      0x7b, 0xe4, 0xb5, 0xc0, 0x21, 0xb3, 0x7d, 0xcd, 0x1d, 0x80, 0xd0, 0x10, 0xd4, 0xdb, 0x9f, 0x06,
+      0xd5, 0x86, 0xea, 0x62, 0x96, 0xb7, 0x31, 0x73, 0xde, 0x25, 0xd0, 0xbb, 0xb2
+   };
+#endif
+#if defined(LTC_MD5) && defined(LTC_RC2)
+   static const unsigned char long_pri_pkcs8_pbe_md5_rc2_64[] = {
+      0x30, 0x82, 0x01, 0x49, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+      0x06, 0x30, 0x0e, 0x04, 0x08, 0x95, 0x82, 0x6d, 0x08, 0xe4, 0x7e, 0xae, 0x5f, 0x02, 0x02, 0x08,
+      0x00, 0x04, 0x82, 0x01, 0x28, 0x93, 0x2c, 0xd8, 0x27, 0xed, 0x13, 0xe1, 0x31, 0xef, 0x7c, 0x44,
+      0x9c, 0xce, 0x85, 0x17, 0x38, 0x5a, 0xe3, 0xd8, 0xe9, 0xfd, 0x1e, 0x81, 0xae, 0x9c, 0xd7, 0x8b,
+      0x11, 0x4e, 0x92, 0x08, 0x3a, 0x97, 0x2c, 0x4f, 0x9a, 0xb7, 0x10, 0xda, 0x6a, 0x06, 0x9e, 0xe2,
+      0xb6, 0x41, 0xf8, 0xb3, 0xd4, 0x42, 0xcc, 0x67, 0xe8, 0x25, 0x76, 0x9a, 0xc2, 0x66, 0x1a, 0x94,
+      0x19, 0x0c, 0xe1, 0x43, 0x27, 0x27, 0x1e, 0xad, 0xfb, 0xce, 0xb7, 0x96, 0xfb, 0x5d, 0x6d, 0xf3,
+      0xe1, 0x73, 0xc5, 0x1c, 0xa0, 0xbe, 0x94, 0x2c, 0xe7, 0x1c, 0x04, 0xa9, 0xfe, 0xdf, 0x15, 0x79,
+      0x0c, 0x5e, 0xf8, 0xe2, 0xb9, 0x4a, 0xa0, 0xc5, 0x89, 0x2c, 0xf8, 0x1d, 0x5f, 0xcc, 0xf0, 0xb6,
+      0xe8, 0x31, 0xeb, 0xe5, 0xb4, 0x9d, 0x2a, 0xa8, 0x8d, 0xff, 0x69, 0xf7, 0x83, 0x65, 0xbb, 0xa2,
+      0xdd, 0xcd, 0x97, 0x41, 0x6e, 0xfa, 0xb6, 0xe1, 0x76, 0x7e, 0xa3, 0x24, 0x9b, 0x23, 0x58, 0x0e,
+      0xeb, 0x08, 0x00, 0x96, 0x53, 0xae, 0x6c, 0xb9, 0xaa, 0x5c, 0x9a, 0xf8, 0xee, 0xcd, 0xfd, 0xe5,
+      0xc5, 0x40, 0x62, 0x58, 0x6d, 0xf0, 0x10, 0xd5, 0x85, 0xeb, 0xed, 0x8a, 0x75, 0xe9, 0x8c, 0x2b,
+      0xe7, 0x39, 0xaf, 0xb1, 0x15, 0xdb, 0x4f, 0xe3, 0xa5, 0x24, 0x1d, 0xd2, 0xae, 0x82, 0x88, 0x1a,
+      0x37, 0x4c, 0x6b, 0x30, 0x9d, 0x6f, 0x93, 0x9c, 0x87, 0x99, 0xd1, 0x1c, 0x93, 0x0c, 0xbb, 0xf9,
+      0x70, 0x36, 0x28, 0x56, 0x68, 0x27, 0x2f, 0x1e, 0xf1, 0x86, 0x0a, 0x23, 0x04, 0xe6, 0x72, 0x1f,
+      0x1b, 0x71, 0x45, 0x0b, 0xe7, 0x74, 0x45, 0x8e, 0x7f, 0x94, 0xbc, 0xcd, 0x6c, 0xf8, 0xf3, 0xed,
+      0x44, 0x02, 0x4d, 0x0a, 0xdd, 0xe9, 0xe4, 0x46, 0x31, 0x94, 0x28, 0x9b, 0x5f, 0x05, 0x37, 0xf4,
+      0x05, 0x9c, 0xa3, 0x9c, 0xdf, 0xb7, 0xfb, 0xab, 0xe0, 0x07, 0x26, 0x40, 0x79, 0x12, 0x9a, 0x78,
+      0xf6, 0xb6, 0x30, 0x3d, 0x4e, 0x16, 0x2e, 0x39, 0x96, 0x98, 0x2a, 0x8c, 0xa7, 0xdb, 0xa0, 0x4a,
+      0x3f, 0x42, 0x30, 0xd3, 0x5d, 0xd0, 0x26, 0xd0, 0xc5, 0xd5, 0xa4, 0x10, 0x10
+   };
+#endif
+#if defined(LTC_SHA1) && defined(LTC_DES)
+   static const unsigned char long_pri_pkcs8_pbe_sha1_des[] = {
+      0x30, 0x82, 0x01, 0x49, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+      0x0a, 0x30, 0x0e, 0x04, 0x08, 0x7c, 0x01, 0xae, 0xc9, 0x05, 0x43, 0x40, 0x70, 0x02, 0x02, 0x08,
+      0x00, 0x04, 0x82, 0x01, 0x28, 0xff, 0x96, 0x47, 0x56, 0x02, 0xd5, 0xd3, 0x2a, 0xf0, 0x44, 0x47,
+      0x7e, 0x74, 0x28, 0x62, 0x3f, 0x2b, 0xd4, 0xa9, 0xcc, 0x2c, 0xb7, 0x03, 0xc7, 0xa6, 0x39, 0xde,
+      0xc1, 0x46, 0xf1, 0xcd, 0x53, 0xb8, 0x76, 0xcd, 0xb8, 0xfd, 0xe8, 0x96, 0x1d, 0x52, 0xc5, 0xc2,
+      0x33, 0x2c, 0x2e, 0x4a, 0xe1, 0x83, 0x2e, 0x8a, 0x3a, 0x73, 0xfe, 0x50, 0x70, 0xcf, 0x2a, 0x29,
+      0xd5, 0x8a, 0x77, 0x96, 0xa3, 0x29, 0x7e, 0xfa, 0x74, 0xde, 0x78, 0x31, 0xd6, 0x78, 0x0a, 0x4f,
+      0x67, 0x8e, 0x26, 0xc9, 0x64, 0xf3, 0xde, 0xda, 0x5d, 0x15, 0xc2, 0x6b, 0x22, 0x25, 0x9e, 0x98,
+      0x41, 0x71, 0x4c, 0x09, 0x56, 0x90, 0x44, 0x7d, 0x16, 0xab, 0x7e, 0xd3, 0x75, 0x54, 0xbd, 0x88,
+      0x85, 0x4a, 0x01, 0xf4, 0x17, 0x19, 0xe2, 0x43, 0x5f, 0x31, 0xf9, 0x0b, 0x78, 0xd3, 0xb6, 0xc8,
+      0xa0, 0x29, 0x65, 0x86, 0xbc, 0x4b, 0xcb, 0xe2, 0xe8, 0xe7, 0x06, 0xe2, 0x27, 0xa3, 0x6a, 0xdc,
+      0x9f, 0x42, 0x40, 0xc4, 0x38, 0x49, 0x3b, 0x15, 0x28, 0x82, 0x9f, 0xa0, 0x2d, 0x42, 0x30, 0xa9,
+      0x28, 0x84, 0x41, 0x2b, 0xa3, 0xfb, 0xf1, 0x74, 0xa1, 0xfa, 0xff, 0x9d, 0xb6, 0x7e, 0x9b, 0x9f,
+      0xfa, 0xbd, 0x00, 0x17, 0x17, 0xa6, 0xb5, 0x2a, 0x1f, 0x6b, 0x55, 0x6c, 0xd4, 0x4b, 0xbe, 0xbb,
+      0xa5, 0xa7, 0x9f, 0x0c, 0x90, 0x04, 0x91, 0x09, 0x4d, 0x82, 0xe1, 0x67, 0x21, 0x96, 0x3a, 0x3b,
+      0xcf, 0x7f, 0xe9, 0xb9, 0xcc, 0x56, 0xd8, 0xc7, 0xe4, 0x98, 0x30, 0x11, 0x8f, 0xfd, 0xe5, 0xbc,
+      0x5e, 0xc4, 0x60, 0xe9, 0xd4, 0xc6, 0xf2, 0x60, 0xf3, 0xcd, 0x36, 0xa4, 0xe4, 0x6c, 0xfe, 0xbf,
+      0xab, 0xd5, 0x2f, 0x12, 0xf4, 0xa2, 0xf0, 0xeb, 0x10, 0xd9, 0x74, 0xef, 0x7c, 0x37, 0x8d, 0xdd,
+      0xc1, 0xaa, 0x84, 0xf6, 0xf1, 0xb6, 0x5b, 0x43, 0x51, 0x06, 0x78, 0xae, 0x8e, 0x9d, 0xc5, 0xc9,
+      0x26, 0xdc, 0x05, 0xa3, 0x00, 0xfa, 0x4a, 0x27, 0x5f, 0x19, 0xf3, 0x88, 0x2e, 0x01, 0xb8, 0xe7,
+      0x23, 0x37, 0x77, 0xa1, 0xbb, 0xb0, 0x66, 0xe2, 0xba, 0x10, 0x50, 0x06, 0x65
+   };
+#endif
+#if defined(LTC_SHA1) && defined(LTC_RC2)
+   static const unsigned char long_pri_pkcs8_pbe_sha1_rc2_64[] = {
+      0x30, 0x82, 0x01, 0x49, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+      0x0b, 0x30, 0x0e, 0x04, 0x08, 0x64, 0x3c, 0xdb, 0x86, 0xd9, 0xa0, 0xae, 0x3e, 0x02, 0x02, 0x08,
+      0x00, 0x04, 0x82, 0x01, 0x28, 0x78, 0x85, 0x55, 0x7f, 0x37, 0xb8, 0xf7, 0xff, 0x94, 0x94, 0xf3,
+      0xf2, 0x21, 0x05, 0x6d, 0x75, 0xca, 0x03, 0x1c, 0xa3, 0x9f, 0x47, 0x41, 0x14, 0x57, 0xdd, 0x63,
+      0x71, 0x6c, 0xc2, 0x51, 0x14, 0x4a, 0x0d, 0x63, 0x12, 0xa8, 0x27, 0xf6, 0x3c, 0xb7, 0x47, 0x6d,
+      0xa0, 0x72, 0xfe, 0x60, 0x9f, 0x1c, 0xc8, 0xe4, 0xe5, 0xfe, 0x68, 0x9d, 0x85, 0x0f, 0x8e, 0x52,
+      0x2e, 0x30, 0xd5, 0x81, 0xd8, 0xc9, 0x05, 0x14, 0x1b, 0x1b, 0xf3, 0xbc, 0x95, 0x6d, 0x5d, 0x94,
+      0x71, 0xff, 0xa8, 0xfe, 0xa7, 0x34, 0xff, 0x30, 0xbe, 0x8e, 0xe4, 0x65, 0x6b, 0xd0, 0xa2, 0x43,
+      0x42, 0x14, 0x63, 0x36, 0x6f, 0x5d, 0x79, 0x56, 0x1b, 0x23, 0xd6, 0xdf, 0x39, 0x75, 0x48, 0x07,
+      0xa2, 0x5f, 0x8d, 0x11, 0x7c, 0x95, 0x48, 0x18, 0x2d, 0xdd, 0x92, 0x14, 0x4f, 0xfd, 0x45, 0x7e,
+      0x60, 0x68, 0xde, 0x47, 0x04, 0x0d, 0x0a, 0xa6, 0x3a, 0x30, 0xcb, 0x29, 0xc7, 0x9e, 0x27, 0xc3,
+      0x2d, 0x49, 0xbd, 0x1e, 0xc5, 0xc9, 0xd8, 0xd2, 0x22, 0x72, 0xe2, 0xd0, 0x8e, 0x03, 0xe8, 0x84,
+      0xfd, 0x7e, 0xb8, 0x8a, 0xd7, 0x70, 0x6d, 0x0b, 0xec, 0x67, 0xd0, 0xb3, 0x08, 0x9a, 0x31, 0x32,
+      0x43, 0x1f, 0xa3, 0xd1, 0x6b, 0x3a, 0x63, 0xbc, 0xca, 0x25, 0x1e, 0x55, 0xd7, 0x21, 0x68, 0x77,
+      0xfa, 0x41, 0x70, 0xdc, 0x3a, 0xfb, 0x05, 0x19, 0xd8, 0x8a, 0xe3, 0xe7, 0xfc, 0xf1, 0xc1, 0x0d,
+      0xd4, 0x9e, 0x64, 0xd0, 0x91, 0xa5, 0x4d, 0x7b, 0x8b, 0xd9, 0xee, 0xa7, 0x6b, 0x2b, 0x0f, 0xd9,
+      0xcf, 0xb3, 0xb4, 0x5b, 0x4e, 0xcc, 0xac, 0x53, 0xe5, 0xd3, 0xdd, 0x73, 0x40, 0xa5, 0x35, 0x71,
+      0xeb, 0xca, 0xa7, 0xc0, 0xae, 0x70, 0xdf, 0x14, 0x83, 0xbe, 0xd8, 0x37, 0xfa, 0x8b, 0x14, 0xdb,
+      0x0c, 0x4e, 0x98, 0xc7, 0xe6, 0x40, 0x38, 0x94, 0x69, 0xd4, 0xd4, 0xa9, 0xb5, 0x3f, 0xec, 0xac,
+      0x14, 0x59, 0x46, 0xb5, 0x98, 0xb0, 0x99, 0x89, 0xea, 0xf5, 0x43, 0xb4, 0x47, 0xa9, 0xb1, 0xf2,
+      0x03, 0x2a, 0xaf, 0xd5, 0x5d, 0x81, 0xae, 0x3b, 0xb4, 0x52, 0x11, 0x85, 0xcb
+   };
+#endif
+#if defined(LTC_DES)
+   static const unsigned char long_pri_pkcs8_pbkdf2_des_cbc[] = {
+      0x30, 0x82, 0x01, 0x6b, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+      0x0d, 0x30, 0x30, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c,
+      0x30, 0x0e, 0x04, 0x08, 0xda, 0x6b, 0x0a, 0x58, 0x7e, 0xd2, 0x9d, 0x38, 0x02, 0x02, 0x08, 0x00,
+      0x30, 0x11, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x07, 0x04, 0x08, 0xcc, 0x5c, 0x19, 0x7c, 0xa6,
+      0x0d, 0x01, 0x4b, 0x04, 0x82, 0x01, 0x28, 0x02, 0x9d, 0xec, 0xa4, 0xe1, 0x42, 0xc4, 0xdb, 0x18,
+      0x32, 0x26, 0x96, 0x8b, 0x87, 0x1a, 0xb7, 0x66, 0x8e, 0xfd, 0x23, 0x1e, 0x1e, 0x20, 0x18, 0xcd,
+      0x81, 0x1b, 0x67, 0x86, 0x78, 0xae, 0xb3, 0x70, 0x81, 0xf9, 0x6a, 0x26, 0x4e, 0x31, 0x64, 0xf8,
+      0x7e, 0xbf, 0xf3, 0xd3, 0xea, 0x7c, 0xda, 0x5d, 0x4d, 0xb7, 0xe2, 0xda, 0x9a, 0x80, 0x94, 0xd1,
+      0x65, 0x5f, 0x57, 0x17, 0xbc, 0xac, 0xd3, 0xb4, 0x94, 0xdc, 0xd0, 0x34, 0xe9, 0xed, 0x57, 0x97,
+      0x53, 0xe9, 0x24, 0x21, 0xac, 0x2b, 0xd1, 0xd9, 0x35, 0x7f, 0xf0, 0x79, 0x14, 0xce, 0x96, 0xe2,
+      0x55, 0xfb, 0xb9, 0x6e, 0xeb, 0xbf, 0xc8, 0xf2, 0x66, 0xc1, 0x42, 0xee, 0x94, 0x22, 0xac, 0x6a,
+      0xe2, 0xf6, 0xba, 0xfc, 0xeb, 0xc1, 0xd0, 0xec, 0x3c, 0x16, 0xa4, 0x36, 0x7a, 0xbf, 0xe9, 0x9d,
+      0x39, 0xd6, 0x32, 0x54, 0x3e, 0x86, 0xcf, 0xe4, 0x32, 0x1c, 0xc5, 0x54, 0x3f, 0x8d, 0x6e, 0xb9,
+      0x6c, 0x3d, 0xd7, 0x68, 0xd7, 0x67, 0xdd, 0x04, 0x0e, 0x8c, 0xfd, 0x62, 0x1a, 0x21, 0xa8, 0xcc,
+      0x67, 0xbd, 0x4f, 0x9b, 0x3c, 0x99, 0xd5, 0xa5, 0x98, 0x12, 0x33, 0x04, 0xcf, 0x1b, 0x58, 0x3f,
+      0xb2, 0x70, 0xfe, 0x92, 0xff, 0x7a, 0x73, 0xf9, 0x37, 0xd5, 0x20, 0x0e, 0x49, 0xed, 0xb3, 0x77,
+      0x73, 0x0f, 0x3e, 0xf8, 0x15, 0xc1, 0xfc, 0x28, 0x47, 0x10, 0xe8, 0x30, 0xee, 0xa9, 0x96, 0xcf,
+      0x39, 0xb6, 0x83, 0xe2, 0x84, 0x1d, 0x0e, 0x65, 0xb7, 0x02, 0x08, 0xf7, 0x8d, 0xe7, 0xf2, 0xcc,
+      0x52, 0xc2, 0xe6, 0x1d, 0xf6, 0x96, 0x17, 0x3e, 0x3f, 0xd8, 0x70, 0x8d, 0x2c, 0x62, 0x00, 0xf3,
+      0x32, 0xbd, 0x1c, 0x6b, 0x4a, 0x0c, 0xc6, 0x46, 0x61, 0x92, 0x1c, 0x01, 0x11, 0xbc, 0x55, 0xdd,
+      0x82, 0xd1, 0xbf, 0x2e, 0x1e, 0x97, 0xbe, 0xa7, 0x6e, 0x5a, 0xcd, 0xc6, 0x8f, 0x38, 0x24, 0x8f,
+      0xb8, 0x36, 0x3d, 0x06, 0x82, 0x14, 0x5b, 0x1a, 0x84, 0x1e, 0x47, 0x53, 0x3a, 0x12, 0x21, 0x23,
+      0xbe, 0xe4, 0xf4, 0x57, 0xc7, 0x31, 0x45, 0x24, 0x46, 0x94, 0x53, 0x0b, 0x1d, 0xcd, 0x57
+   };
+#endif
+#if defined(LTC_DES)
+   static const unsigned char long_pri_pkcs8_pbkdf2_des_ede3_cbc[] = {
+      0x30, 0x82, 0x01, 0x6e, 0x30, 0x40, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+      0x0d, 0x30, 0x33, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c,
+      0x30, 0x0e, 0x04, 0x08, 0x6a, 0x99, 0x55, 0x06, 0x40, 0xd5, 0xe6, 0xc9, 0x02, 0x02, 0x08, 0x00,
+      0x30, 0x14, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x04, 0x08, 0x7f, 0xf2,
+      0xa7, 0xa3, 0x2c, 0xbb, 0x8e, 0x78, 0x04, 0x82, 0x01, 0x28, 0x55, 0x4d, 0xcb, 0xab, 0xb8, 0x6e,
+      0xcf, 0x00, 0xd2, 0xe8, 0x1e, 0x0e, 0xe1, 0x8f, 0x51, 0x8e, 0x32, 0x68, 0xaf, 0x44, 0xa6, 0xf2,
+      0x9e, 0x11, 0xd7, 0x0f, 0xa7, 0xd5, 0x74, 0x77, 0xbc, 0x6b, 0x53, 0x40, 0x70, 0xb6, 0x02, 0xdb,
+      0xa6, 0x2e, 0xc7, 0x20, 0x15, 0x78, 0x91, 0xcc, 0x5b, 0xa7, 0x15, 0x58, 0x65, 0xeb, 0xc7, 0x6f,
+      0xb8, 0x14, 0xc9, 0x5f, 0x89, 0x58, 0xe2, 0xab, 0x69, 0x17, 0xe2, 0xe7, 0xe0, 0xa4, 0x59, 0xb7,
+      0x6a, 0xc2, 0xe5, 0xba, 0x03, 0x0e, 0xcc, 0x0a, 0xb1, 0xf0, 0x69, 0xb2, 0x90, 0xac, 0x30, 0x79,
+      0xd4, 0xa3, 0x90, 0xa2, 0x60, 0x37, 0x7d, 0xf8, 0xd9, 0x49, 0xa3, 0x0b, 0x6d, 0xd9, 0x98, 0x9e,
+      0xb0, 0x6a, 0xad, 0x97, 0x08, 0xf1, 0xfd, 0xec, 0xf8, 0xa7, 0x3c, 0xf6, 0x48, 0x81, 0x5b, 0x6d,
+      0x19, 0xcc, 0xed, 0x49, 0x94, 0x05, 0x6e, 0xa4, 0x9b, 0x58, 0xdd, 0xaf, 0xd7, 0x3d, 0x12, 0xe6,
+      0xf4, 0x12, 0x46, 0xd9, 0x82, 0xde, 0xb7, 0xc4, 0xeb, 0x1c, 0x3a, 0xef, 0x93, 0x82, 0x3d, 0xf8,
+      0x55, 0x88, 0xe5, 0x54, 0xd6, 0x74, 0x1c, 0x20, 0xbd, 0x40, 0x65, 0x99, 0x19, 0x5f, 0x25, 0x62,
+      0x35, 0x6d, 0x32, 0x64, 0xd7, 0xa1, 0x45, 0xa8, 0xc4, 0x8d, 0xe0, 0x6d, 0x14, 0x85, 0x84, 0x75,
+      0x62, 0x0f, 0xb0, 0xe9, 0xb1, 0xca, 0x31, 0x97, 0x22, 0x41, 0xb3, 0xf5, 0xdf, 0x5c, 0xbf, 0x3f,
+      0x4f, 0x01, 0xf8, 0xe7, 0xbc, 0xdc, 0xb2, 0x9a, 0x7d, 0x0c, 0x96, 0x38, 0x48, 0x7a, 0x1b, 0x89,
+      0x2b, 0xab, 0xa6, 0xbd, 0xee, 0x7a, 0xf8, 0x85, 0x82, 0x80, 0x8c, 0x3b, 0x05, 0x3c, 0x40, 0x69,
+      0x97, 0x0a, 0x4c, 0x45, 0xae, 0x38, 0x22, 0xc5, 0x95, 0xf2, 0x4f, 0x0c, 0xd5, 0x54, 0x23, 0x92,
+      0x9b, 0x06, 0x81, 0xca, 0xa5, 0x1e, 0x91, 0x7e, 0x2b, 0x85, 0xb4, 0xd4, 0xeb, 0xb6, 0xee, 0x22,
+      0x10, 0x72, 0xaf, 0x9e, 0x6d, 0xcc, 0x16, 0x24, 0x01, 0x44, 0x48, 0xaa, 0xc9, 0xf8, 0x38, 0x72,
+      0x7a, 0x35, 0x94, 0x20, 0x58, 0xa2, 0x1c, 0x81, 0xaf, 0x47, 0x3b, 0xb8, 0x23, 0xbb, 0x71, 0x09,
+      0xbf, 0x93
+   };
+#endif
+#if defined(LTC_RC2)
+   static const unsigned char long_pri_pkcs8_pbkdf2_rc2_cbc[] = {
+      0x30, 0x82, 0x01, 0x76, 0x30, 0x48, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+      0x0d, 0x30, 0x3b, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c,
+      0x30, 0x11, 0x04, 0x08, 0xbf, 0xef, 0x1a, 0x42, 0x5d, 0xc3, 0x6b, 0x0f, 0x02, 0x02, 0x08, 0x00,
+      0x02, 0x01, 0x10, 0x30, 0x19, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x30,
+      0x0d, 0x02, 0x01, 0x3a, 0x04, 0x08, 0xfe, 0xf2, 0x09, 0x0c, 0xa4, 0xd0, 0xe6, 0x83, 0x04, 0x82,
+      0x01, 0x28, 0x61, 0x18, 0x73, 0xb7, 0x9d, 0x58, 0xc8, 0x4a, 0xf4, 0x24, 0xec, 0xb4, 0xe6, 0x24,
+      0xa7, 0xf0, 0x1e, 0xea, 0xc3, 0x57, 0x44, 0xb7, 0x5a, 0x77, 0xe5, 0x3c, 0x1c, 0x6a, 0x6b, 0x70,
+      0x6e, 0x64, 0x35, 0xa5, 0x5d, 0x32, 0xe3, 0xce, 0xe8, 0x79, 0xa4, 0x7f, 0x2b, 0xfc, 0xcb, 0x07,
+      0x62, 0xcd, 0xc9, 0x15, 0x30, 0xdf, 0x69, 0xae, 0xe8, 0xb4, 0x83, 0xec, 0x2a, 0xaf, 0xb3, 0x29,
+      0x92, 0x77, 0xf3, 0x31, 0x4d, 0x5f, 0xcb, 0xea, 0xa2, 0x4d, 0xfb, 0xa1, 0x68, 0xbe, 0x00, 0x01,
+      0x6d, 0x3f, 0xc6, 0xc1, 0x13, 0xee, 0xb0, 0x5a, 0x52, 0xce, 0xdc, 0x12, 0xf8, 0x42, 0x22, 0x2f,
+      0x57, 0x2e, 0x54, 0xac, 0x48, 0x31, 0x4d, 0x3c, 0xa1, 0x97, 0x5e, 0x17, 0x74, 0x88, 0x9b, 0x31,
+      0x91, 0x69, 0x00, 0x00, 0x15, 0x2c, 0xc2, 0xac, 0x70, 0x84, 0x9c, 0x7e, 0x5d, 0xc9, 0xee, 0x06,
+      0xcc, 0x38, 0x9d, 0x7d, 0xea, 0x71, 0xc3, 0x4f, 0x99, 0x08, 0xde, 0xb0, 0x1b, 0x3b, 0x2a, 0xbd,
+      0x7e, 0x01, 0x3b, 0x5e, 0xe5, 0xc2, 0x54, 0xf2, 0x30, 0xe5, 0xa0, 0xf3, 0x69, 0x87, 0x77, 0xed,
+      0xa1, 0x37, 0x76, 0x6a, 0xec, 0xe2, 0x9c, 0x8d, 0x4c, 0xe9, 0xf4, 0xd0, 0xca, 0xb5, 0x8f, 0xd0,
+      0x63, 0x17, 0x41, 0xcb, 0x29, 0x58, 0x4f, 0x2a, 0xd1, 0xe1, 0x03, 0x73, 0x09, 0xcc, 0x93, 0xc6,
+      0xde, 0x1e, 0x34, 0x0f, 0xb3, 0x67, 0xfd, 0x5e, 0x49, 0x16, 0x84, 0x84, 0x6a, 0x8f, 0x55, 0x22,
+      0x0b, 0xe4, 0xd8, 0xee, 0x2e, 0x9f, 0x25, 0x19, 0x89, 0x19, 0xe6, 0x8d, 0x64, 0x31, 0x38, 0x68,
+      0xfa, 0x40, 0x84, 0xca, 0x39, 0xef, 0x1a, 0x4a, 0xe9, 0x04, 0xee, 0xcc, 0x4a, 0xea, 0x19, 0x96,
+      0xa4, 0xcd, 0x62, 0x76, 0xb3, 0xc4, 0x2c, 0x23, 0x75, 0x24, 0xcd, 0x49, 0xe2, 0x17, 0x81, 0x45,
+      0x24, 0x55, 0xeb, 0xe1, 0xb4, 0xeb, 0xda, 0xc5, 0x56, 0xac, 0xfa, 0x30, 0xbd, 0x05, 0xbb, 0x03,
+      0x65, 0x50, 0xdc, 0xbf, 0xdf, 0xff, 0x2a, 0x80, 0x85, 0x6d, 0x6a, 0x5c, 0x93, 0xb8, 0x81, 0xc4,
+      0xca, 0x91, 0x08, 0x7b, 0x8a, 0x9d, 0xe9, 0x2d, 0xfc, 0x3b
+   };
+#endif
+#if defined(LTC_SHA224) && defined(LTC_DES)
+   static const unsigned char long_pri_pkcs8_pbkdf2_sha224_des_ede3_cbc[] = {
+      0x30, 0x82, 0x01, 0x7c, 0x30, 0x4e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+      0x0d, 0x30, 0x41, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c,
+      0x30, 0x1c, 0x04, 0x08, 0xb2, 0x82, 0x71, 0xc5, 0xd6, 0x3c, 0x2b, 0x92, 0x02, 0x02, 0x08, 0x00,
+      0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x08, 0x05, 0x00, 0x30, 0x14,
+      0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x04, 0x08, 0x4a, 0x46, 0x2a, 0xa9,
+      0xd5, 0x9f, 0x79, 0xea, 0x04, 0x82, 0x01, 0x28, 0xc4, 0x27, 0x05, 0xa8, 0x01, 0xa7, 0xc9, 0x0d,
+      0x0e, 0x74, 0x06, 0x4a, 0xb8, 0x07, 0x9f, 0x7b, 0x0f, 0x82, 0xfd, 0x2c, 0xb5, 0x4f, 0x63, 0xed,
+      0xed, 0x86, 0x96, 0x79, 0x08, 0x2d, 0x5f, 0x6d, 0x8c, 0x83, 0xc9, 0xcc, 0xd4, 0x9b, 0x0a, 0x81,
+      0x60, 0x22, 0x09, 0xb9, 0x12, 0xca, 0xf1, 0xad, 0x61, 0x22, 0xf0, 0x6b, 0xdb, 0x52, 0x99, 0xae,
+      0x70, 0x2b, 0x61, 0x63, 0xdc, 0x2f, 0xc1, 0xd3, 0xb5, 0x28, 0xbb, 0xa1, 0xd2, 0xb7, 0xaf, 0xbb,
+      0x86, 0xa1, 0x1b, 0x46, 0x0a, 0xc9, 0xab, 0x44, 0xd2, 0x9c, 0x16, 0x18, 0x8b, 0x4a, 0x92, 0x56,
+      0x5b, 0x50, 0x39, 0x1b, 0x88, 0x50, 0x92, 0x35, 0xb8, 0x85, 0xc3, 0xaa, 0x56, 0x76, 0xde, 0xbf,
+      0x68, 0x91, 0x2e, 0xc8, 0x28, 0x29, 0xd8, 0x71, 0x60, 0xe3, 0xf0, 0x5a, 0x66, 0x85, 0xdd, 0x6b,
+      0x5c, 0xaf, 0xf1, 0x28, 0xf8, 0xdc, 0xa7, 0x8d, 0xc4, 0x9b, 0xcb, 0xb2, 0x99, 0x34, 0x4d, 0x76,
+      0xa0, 0x8b, 0xf2, 0x18, 0x8e, 0x42, 0xe0, 0x79, 0xc3, 0xeb, 0x0f, 0x00, 0xe7, 0xbe, 0x83, 0xdf,
+      0xba, 0xa5, 0xf1, 0x81, 0x05, 0x1c, 0xc9, 0xda, 0xea, 0xe1, 0xc4, 0x38, 0x24, 0x1e, 0xcf, 0xea,
+      0x22, 0x05, 0x75, 0x43, 0xfe, 0xfe, 0x14, 0xf7, 0x6d, 0x41, 0x67, 0xcf, 0xfd, 0x57, 0xa7, 0xfc,
+      0x22, 0x03, 0x14, 0xc1, 0xf6, 0x4d, 0x40, 0x4e, 0xf1, 0xec, 0x72, 0xec, 0x3c, 0xb1, 0x87, 0x44,
+      0xe9, 0x72, 0xc5, 0x8b, 0x48, 0xd9, 0x98, 0x08, 0x55, 0xc5, 0x40, 0x26, 0xf5, 0x8d, 0x73, 0x5e,
+      0x35, 0x98, 0x71, 0x09, 0x98, 0xfa, 0xb7, 0x1c, 0x35, 0xcd, 0xd4, 0xf1, 0x65, 0xb4, 0x59, 0xdb,
+      0x9e, 0x79, 0xe7, 0x21, 0x99, 0xd7, 0x9e, 0x8c, 0x13, 0x77, 0x0c, 0x5e, 0xae, 0x43, 0x82, 0xf1,
+      0x83, 0x79, 0x7d, 0x37, 0x51, 0xde, 0x65, 0x26, 0x1f, 0x8f, 0x81, 0x1c, 0x55, 0x40, 0xec, 0xaf,
+      0x3f, 0x0a, 0x68, 0xd2, 0xc7, 0x59, 0x47, 0xda, 0x78, 0x0c, 0x0e, 0x59, 0x6a, 0x93, 0xcd, 0x05,
+      0x09, 0x51, 0x47, 0xb1, 0x45, 0x3f, 0x67, 0xf8, 0x76, 0x50, 0x76, 0xa3, 0x2d, 0x31, 0x17, 0x73
+   };
+#endif
+#if defined(LTC_SHA256) && defined(LTC_DES)
+   static const unsigned char long_pri_pkcs8_pbkdf2_sha256_des_ede3_cbc[] = {
+      0x30, 0x82, 0x01, 0x7c, 0x30, 0x4e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+      0x0d, 0x30, 0x41, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c,
+      0x30, 0x1c, 0x04, 0x08, 0x93, 0x6e, 0x0a, 0x02, 0x8e, 0x72, 0xac, 0x98, 0x02, 0x02, 0x08, 0x00,
+      0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x09, 0x05, 0x00, 0x30, 0x14,
+      0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x04, 0x08, 0x89, 0xa4, 0xc9, 0xd9,
+      0x82, 0xfa, 0x02, 0x76, 0x04, 0x82, 0x01, 0x28, 0xec, 0xd9, 0xee, 0xbf, 0xfa, 0xe6, 0x51, 0xdb,
+      0x02, 0xcb, 0xf3, 0x2c, 0x55, 0xdb, 0x83, 0x90, 0x5d, 0x9e, 0xf6, 0xbe, 0x10, 0xae, 0x35, 0x8c,
+      0x22, 0x39, 0xfc, 0xf9, 0xd1, 0x23, 0x27, 0x68, 0xd3, 0x15, 0x46, 0xed, 0x5d, 0x15, 0xfb, 0xdf,
+      0x6f, 0xe1, 0x01, 0x1c, 0xed, 0x4c, 0xfc, 0x78, 0x94, 0x47, 0x71, 0x92, 0xbc, 0xa1, 0xa6, 0x06,
+      0x74, 0x22, 0xcc, 0xbb, 0x49, 0x98, 0x43, 0xf1, 0xc2, 0xde, 0x4e, 0xeb, 0x56, 0x0e, 0x03, 0xc1,
+      0xf1, 0xc1, 0x80, 0x4b, 0x70, 0xd0, 0x8f, 0xf3, 0xd8, 0x18, 0x08, 0x41, 0x7a, 0xf9, 0x8b, 0x74,
+      0xe5, 0x28, 0x61, 0x77, 0x2f, 0x84, 0xb3, 0xb3, 0x68, 0xce, 0x19, 0xf0, 0xc6, 0xa9, 0xc1, 0x29,
+      0x96, 0xca, 0x3b, 0xdb, 0x13, 0x99, 0x86, 0xbe, 0x21, 0x0d, 0x00, 0xd7, 0x30, 0x15, 0x74, 0xfb,
+      0x43, 0xf7, 0x14, 0x97, 0x6d, 0xed, 0xeb, 0xe3, 0x4d, 0x67, 0x80, 0x35, 0x03, 0x69, 0x0d, 0xbe,
+      0xf1, 0x99, 0x6b, 0x53, 0xb7, 0xa3, 0xdf, 0xf4, 0xc3, 0xda, 0x20, 0x9b, 0xbf, 0xf9, 0x3f, 0x19,
+      0xae, 0xd5, 0x37, 0x91, 0x36, 0x42, 0xf3, 0x7d, 0xad, 0x40, 0x3c, 0x2a, 0x7f, 0x2d, 0xf1, 0x79,
+      0xee, 0x4c, 0x08, 0x3a, 0xd6, 0x35, 0x9b, 0xc9, 0xff, 0xd8, 0x41, 0x41, 0xd1, 0xc6, 0xa1, 0xba,
+      0x4d, 0xc6, 0xb7, 0x85, 0x05, 0xa1, 0x8e, 0xeb, 0xd1, 0xd2, 0x3a, 0x13, 0xd7, 0xbd, 0xb0, 0x02,
+      0xfe, 0x54, 0xfe, 0xf4, 0xfd, 0x31, 0x0c, 0x42, 0x78, 0xb9, 0x17, 0x90, 0x36, 0x17, 0xb8, 0x1a,
+      0x08, 0xe8, 0x7e, 0x5f, 0xbb, 0x30, 0xc2, 0xec, 0xd5, 0x08, 0xbc, 0xae, 0x2f, 0xe0, 0xca, 0xf2,
+      0x44, 0x2c, 0xa4, 0xb5, 0xec, 0xb9, 0xc2, 0xa3, 0x4a, 0x1a, 0x49, 0xfb, 0x3e, 0x5c, 0xb5, 0xd8,
+      0xb6, 0xf0, 0xbc, 0xa2, 0xda, 0xaa, 0x7a, 0x05, 0x4d, 0x06, 0xc0, 0x4b, 0x8f, 0x59, 0xce, 0x56,
+      0x02, 0x26, 0xb2, 0xa0, 0x5f, 0x74, 0xbb, 0x0b, 0x01, 0x1c, 0xb2, 0x0b, 0x8a, 0x80, 0xa4, 0x5d,
+      0x6e, 0x52, 0x24, 0xd0, 0xbe, 0xf5, 0x8e, 0x9e, 0x9e, 0x02, 0x40, 0x08, 0x99, 0xe0, 0x2c, 0xf9
+   };
+#endif
+#if defined(LTC_SHA384) && defined(LTC_DES)
+   static const unsigned char long_pri_pkcs8_pbkdf2_sha384_des_ede3_cbc[] = {
+      0x30, 0x82, 0x01, 0x7c, 0x30, 0x4e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+      0x0d, 0x30, 0x41, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c,
+      0x30, 0x1c, 0x04, 0x08, 0xfd, 0x6c, 0xdf, 0x0b, 0x23, 0xed, 0x71, 0xf7, 0x02, 0x02, 0x08, 0x00,
+      0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x0a, 0x05, 0x00, 0x30, 0x14,
+      0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x04, 0x08, 0x99, 0xd0, 0x84, 0x7d,
+      0x6d, 0x4e, 0x82, 0xe1, 0x04, 0x82, 0x01, 0x28, 0xac, 0x9a, 0x2c, 0x71, 0xdf, 0x1a, 0x19, 0x38,
+      0xee, 0xc4, 0x9d, 0x7a, 0x27, 0xe0, 0xb9, 0x69, 0x32, 0xed, 0xe7, 0xa1, 0x77, 0x16, 0x60, 0x18,
+      0x7a, 0xf1, 0x47, 0xc1, 0x98, 0x48, 0xa4, 0xff, 0xab, 0x83, 0x1a, 0x7d, 0xe3, 0xdb, 0xcc, 0xf0,
+      0x40, 0x94, 0x3a, 0x6a, 0x3f, 0xf7, 0x88, 0x19, 0x59, 0xf4, 0xd8, 0x1b, 0x87, 0x14, 0x5b, 0x9c,
+      0x1f, 0xc5, 0xaf, 0x80, 0xe8, 0x06, 0xdb, 0xfa, 0x2c, 0xac, 0x61, 0x1c, 0xec, 0xec, 0x99, 0x5e,
+      0x06, 0x6e, 0x68, 0x4c, 0xb0, 0xc8, 0x6f, 0x74, 0x2c, 0x1e, 0x58, 0x2f, 0x49, 0x82, 0xa4, 0x2b,
+      0xb4, 0x4a, 0x2d, 0x77, 0x13, 0x87, 0xed, 0xbd, 0x71, 0x5a, 0x29, 0x29, 0x0c, 0x88, 0x4a, 0xf3,
+      0x76, 0x37, 0x7e, 0x04, 0x3c, 0x45, 0x76, 0x98, 0x22, 0x20, 0x97, 0xef, 0xae, 0x4a, 0xa9, 0x08,
+      0x54, 0xef, 0x43, 0xe0, 0x86, 0x54, 0x72, 0x44, 0xd1, 0x25, 0x9c, 0xb6, 0x7d, 0x88, 0xbd, 0x8f,
+      0xbe, 0xcb, 0xa8, 0x63, 0xfe, 0x66, 0x54, 0xa2, 0xce, 0x77, 0x19, 0x7e, 0xdd, 0xf7, 0x4d, 0xdc,
+      0xb1, 0xf7, 0xbf, 0x3c, 0xb5, 0xd2, 0x30, 0x9d, 0x3c, 0x35, 0x09, 0x37, 0xae, 0xae, 0x0f, 0x0b,
+      0x9d, 0xf5, 0x10, 0xae, 0x56, 0x83, 0x4f, 0xd8, 0xcd, 0xfe, 0xb7, 0xa9, 0x54, 0xf9, 0xb3, 0x89,
+      0xf6, 0x9a, 0x11, 0x60, 0x04, 0x4d, 0x80, 0xaf, 0x74, 0x73, 0x2d, 0xc4, 0x24, 0x23, 0xaa, 0x50,
+      0x4c, 0xf1, 0xd6, 0x2d, 0xc6, 0x74, 0xeb, 0x62, 0x02, 0xda, 0x81, 0x68, 0xc8, 0x68, 0xf0, 0x82,
+      0x71, 0xb2, 0xa5, 0x8e, 0x45, 0x93, 0x29, 0x94, 0x8f, 0xec, 0x11, 0x65, 0xcc, 0xd6, 0x4c, 0x2e,
+      0x0d, 0x4e, 0x45, 0xb4, 0x4e, 0x97, 0x38, 0xd0, 0xc2, 0x61, 0x43, 0x78, 0xa4, 0x08, 0x0a, 0x58,
+      0x3f, 0x66, 0xdb, 0x34, 0x42, 0x17, 0x42, 0x92, 0x04, 0x9a, 0x2d, 0x73, 0xaf, 0x58, 0x38, 0xc8,
+      0x3f, 0x5b, 0x83, 0x95, 0x3d, 0xae, 0xae, 0x60, 0x2b, 0x6d, 0xd9, 0xb4, 0xe3, 0x97, 0x6b, 0x49,
+      0xef, 0xd9, 0x68, 0xbb, 0x8d, 0x3a, 0x7e, 0xcb, 0x57, 0x33, 0xf5, 0x1a, 0x8d, 0xb4, 0x6d, 0xfb
+   };
+#endif
+#if defined(LTC_SHA512) && defined(LTC_DES)
+   static const unsigned char long_pri_pkcs8_pbkdf2_sha512_des_ede3_cbc[] = {
+      0x30, 0x82, 0x01, 0x7c, 0x30, 0x4e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+      0x0d, 0x30, 0x41, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c,
+      0x30, 0x1c, 0x04, 0x08, 0xad, 0xb1, 0xe1, 0x21, 0xdc, 0xe5, 0x09, 0xee, 0x02, 0x02, 0x08, 0x00,
+      0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x0b, 0x05, 0x00, 0x30, 0x14,
+      0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x04, 0x08, 0x1a, 0x8b, 0x81, 0x3b,
+      0x97, 0x7d, 0xfa, 0x51, 0x04, 0x82, 0x01, 0x28, 0x6d, 0x6f, 0x93, 0x77, 0xcb, 0x52, 0x2d, 0x3b,
+      0x82, 0x12, 0x80, 0xce, 0x9e, 0x69, 0x03, 0xe4, 0x64, 0xa1, 0x4b, 0x8e, 0x60, 0x51, 0x4d, 0x08,
+      0xe1, 0x25, 0x5d, 0xe6, 0xed, 0x20, 0x23, 0x4c, 0x4e, 0xa3, 0xe8, 0xab, 0x7a, 0xf8, 0x54, 0x65,
+      0x22, 0x92, 0x0c, 0x45, 0xab, 0x1c, 0xe2, 0x68, 0x4e, 0xf3, 0xa9, 0x61, 0xd6, 0x44, 0x9d, 0x55,
+      0x19, 0xc6, 0xd9, 0x2a, 0x0d, 0x45, 0x7d, 0xca, 0xa4, 0x41, 0xb5, 0x6d, 0xd5, 0x09, 0xf2, 0xb6,
+      0x81, 0x95, 0x64, 0xdb, 0x2b, 0xed, 0x83, 0x6b, 0x44, 0xa6, 0xce, 0x36, 0x8d, 0x23, 0x89, 0xb6,
+      0xf3, 0xb0, 0xe0, 0xcf, 0x57, 0x72, 0xc7, 0x61, 0x3f, 0x29, 0xb9, 0xea, 0xe8, 0x7a, 0xca, 0x43,
+      0x90, 0x79, 0x81, 0x8a, 0xe2, 0x3c, 0xd1, 0xa6, 0xd9, 0x09, 0xd8, 0x7d, 0xd0, 0x90, 0x69, 0x7e,
+      0xdd, 0x40, 0xde, 0xba, 0x11, 0xc6, 0x6f, 0x75, 0xfc, 0xc3, 0x99, 0x43, 0xd2, 0xa4, 0x16, 0x2e,
+      0x95, 0x99, 0x12, 0x77, 0xe8, 0x86, 0x9a, 0xf9, 0x97, 0xf4, 0x43, 0x99, 0x1d, 0x7b, 0xe0, 0x69,
+      0xb0, 0xe9, 0x45, 0xd0, 0x0b, 0xaa, 0xd0, 0xa9, 0x90, 0x85, 0x39, 0xd9, 0xe0, 0xe4, 0xe5, 0xf3,
+      0xcf, 0xb6, 0x60, 0x63, 0x51, 0x0b, 0xd8, 0x3d, 0xa2, 0x0f, 0xf6, 0x53, 0x09, 0x2e, 0x11, 0xc4,
+      0xe6, 0xe3, 0xfa, 0xfb, 0x9f, 0x4d, 0xf4, 0xef, 0xb2, 0xf6, 0x9b, 0xc6, 0xb3, 0x75, 0x66, 0xfd,
+      0x1b, 0x44, 0xba, 0x3c, 0xa8, 0x51, 0xbe, 0x97, 0xf1, 0x54, 0xb5, 0xcc, 0x6f, 0x5f, 0x1d, 0x9b,
+      0xee, 0xed, 0x7a, 0x82, 0xfa, 0x40, 0x39, 0xa7, 0xf5, 0x8e, 0x5e, 0x42, 0xfa, 0x37, 0xcc, 0xe8,
+      0x99, 0x38, 0xc1, 0xab, 0x83, 0xb8, 0x3c, 0x25, 0x17, 0x5f, 0xb7, 0x45, 0x0f, 0xcd, 0xec, 0x2a,
+      0x47, 0x07, 0x02, 0xba, 0x92, 0xc1, 0x79, 0xf1, 0x95, 0xc7, 0x83, 0x46, 0xd7, 0x9e, 0x04, 0x96,
+      0x3c, 0x5d, 0x7e, 0x70, 0xe6, 0x2b, 0x72, 0x70, 0x42, 0x66, 0x17, 0x0e, 0xc3, 0xcf, 0x32, 0x28,
+      0x0c, 0xf9, 0x46, 0x38, 0xb7, 0x64, 0xd6, 0x51, 0xf9, 0xbd, 0x57, 0xf2, 0x7a, 0xcc, 0x02, 0xe3
+   };
+#endif
    static const unsigned char long_pric[] = { /* private + compressed public, explicit curve params */
       0x30, 0x81, 0xd3, 0x02, 0x01, 0x01, 0x04, 0x20, 0x0c, 0xf1, 0xad, 0x2f, 0x03, 0xf7, 0x91, 0x1b,
       0xba, 0x03, 0xcf, 0x23, 0x37, 0xc8, 0xf2, 0xf7, 0x36, 0xce, 0x65, 0xf1, 0x84, 0x2d, 0x7d, 0x9f,
@@ -667,6 +1053,23 @@ static int _ecc_import_export(void) {
       0x12, 0xd0, 0x24, 0xaf, 0xba, 0xb6, 0x7f, 0xfb, 0x96, 0x27, 0x3e, 0x2f, 0xbd, 0x1e, 0xd5, 0xf9,
       0x8d, 0x6c, 0x73, 0x9d, 0xc5, 0x16
    };
+   static const unsigned char long_pric_pkcs8[] = { /* private + compressed public, explicit curve params, PKCS8 */
+      0x30, 0x81, 0xe3, 0x02, 0x01, 0x00, 0x30, 0x81, 0x8e, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+      0x02, 0x01, 0x30, 0x81, 0x82, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce,
+      0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+      0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f, 0x30, 0x06, 0x04, 0x01, 0x00, 0x04, 0x01, 0x07, 0x04, 0x21,
+      0x02, 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac, 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87, 0x0b,
+      0x07, 0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9, 0x59, 0xf2, 0x81, 0x5b, 0x16, 0xf8, 0x17,
+      0x98, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+      0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c,
+      0xd0, 0x36, 0x41, 0x41, 0x02, 0x01, 0x01, 0x04, 0x4d, 0x30, 0x4b, 0x02, 0x01, 0x01, 0x04, 0x20,
+      0x0c, 0xf1, 0xad, 0x2f, 0x03, 0xf7, 0x91, 0x1b, 0xba, 0x03, 0xcf, 0x23, 0x37, 0xc8, 0xf2, 0xf7,
+      0x36, 0xce, 0x65, 0xf1, 0x84, 0x2d, 0x7d, 0x9f, 0x5f, 0x9e, 0x21, 0xd9, 0x5e, 0x49, 0xbd, 0x23,
+      0xa1, 0x24, 0x03, 0x22, 0x00, 0x03, 0x2a, 0xf9, 0x0b, 0xda, 0xbe, 0x71, 0x66, 0x9e, 0xd1, 0xcf,
+      0x12, 0xd0, 0x24, 0xaf, 0xba, 0xb6, 0x7f, 0xfb, 0x96, 0x27, 0x3e, 0x2f, 0xbd, 0x1e, 0xd5, 0xf9,
+      0x8d, 0x6c, 0x73, 0x9d, 0xc5, 0x16
+   };
    static const unsigned char long_pub[] = { /* long public, explicit curve params */
       0x30, 0x81, 0xf5, 0x30, 0x81, 0xae, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x30,
       0x81, 0xa2, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01,
@@ -709,6 +1112,17 @@ static int _ecc_import_export(void) {
       0x6e, 0x32, 0x5b, 0xf7, 0x63, 0x62, 0x94, 0x24, 0x24, 0xdb, 0xec, 0x3f, 0x8b, 0xe5, 0x6e, 0x4b,
       0x64, 0x37, 0x31, 0x24, 0x79, 0x4d
    };
+   static const unsigned char short_pri_pkcs8[] = { /* private + long public, curve by OID, PKCS8 */
+      0x30, 0x81, 0x84, 0x02, 0x01, 0x00, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
+      0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x0a, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04,
+      0x20, 0x0c, 0xf1, 0xad, 0x2f, 0x03, 0xf7, 0x91, 0x1b, 0xba, 0x03, 0xcf, 0x23, 0x37, 0xc8, 0xf2,
+      0xf7, 0x36, 0xce, 0x65, 0xf1, 0x84, 0x2d, 0x7d, 0x9f, 0x5f, 0x9e, 0x21, 0xd9, 0x5e, 0x49, 0xbd,
+      0x23, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x2a, 0xf9, 0x0b, 0xda, 0xbe, 0x71, 0x66, 0x9e, 0xd1,
+      0xcf, 0x12, 0xd0, 0x24, 0xaf, 0xba, 0xb6, 0x7f, 0xfb, 0x96, 0x27, 0x3e, 0x2f, 0xbd, 0x1e, 0xd5,
+      0xf9, 0x8d, 0x6c, 0x73, 0x9d, 0xc5, 0x16, 0x91, 0xbd, 0xb2, 0xb9, 0x1b, 0x40, 0x10, 0x5a, 0xb7,
+      0x6c, 0x6e, 0x32, 0x5b, 0xf7, 0x63, 0x62, 0x94, 0x24, 0x24, 0xdb, 0xec, 0x3f, 0x8b, 0xe5, 0x6e,
+      0x4b, 0x64, 0x37, 0x31, 0x24, 0x79, 0x4d
+   };
    static const unsigned char short_pric[] = { /* private + compressed public, curve by OID */
       0x30, 0x54, 0x02, 0x01, 0x01, 0x04, 0x20, 0x0c, 0xf1, 0xad, 0x2f, 0x03, 0xf7, 0x91, 0x1b, 0xba,
       0x03, 0xcf, 0x23, 0x37, 0xc8, 0xf2, 0xf7, 0x36, 0xce, 0x65, 0xf1, 0x84, 0x2d, 0x7d, 0x9f, 0x5f,
@@ -717,6 +1131,15 @@ static int _ecc_import_export(void) {
       0x12, 0xd0, 0x24, 0xaf, 0xba, 0xb6, 0x7f, 0xfb, 0x96, 0x27, 0x3e, 0x2f, 0xbd, 0x1e, 0xd5, 0xf9,
       0x8d, 0x6c, 0x73, 0x9d, 0xc5, 0x16
    };
+   static const unsigned char short_pric_pkcs8[] = { /* private + compressed public, curve by OID, PKCS8 */
+      0x30, 0x64, 0x02, 0x01, 0x00, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01,
+      0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x0a, 0x04, 0x4d, 0x30, 0x4b, 0x02, 0x01, 0x01, 0x04, 0x20,
+      0x0c, 0xf1, 0xad, 0x2f, 0x03, 0xf7, 0x91, 0x1b, 0xba, 0x03, 0xcf, 0x23, 0x37, 0xc8, 0xf2, 0xf7,
+      0x36, 0xce, 0x65, 0xf1, 0x84, 0x2d, 0x7d, 0x9f, 0x5f, 0x9e, 0x21, 0xd9, 0x5e, 0x49, 0xbd, 0x23,
+      0xa1, 0x24, 0x03, 0x22, 0x00, 0x03, 0x2a, 0xf9, 0x0b, 0xda, 0xbe, 0x71, 0x66, 0x9e, 0xd1, 0xcf,
+      0x12, 0xd0, 0x24, 0xaf, 0xba, 0xb6, 0x7f, 0xfb, 0x96, 0x27, 0x3e, 0x2f, 0xbd, 0x1e, 0xd5, 0xf9,
+      0x8d, 0x6c, 0x73, 0x9d, 0xc5, 0x16
+   };
    static const unsigned char short_pub[] = { /* long public, curve by OID */
       0x30, 0x56, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b,
       0x81, 0x04, 0x00, 0x0a, 0x03, 0x42, 0x00, 0x04, 0x2a, 0xf9, 0x0b, 0xda, 0xbe, 0x71, 0x66, 0x9e,
@@ -912,6 +1335,89 @@ static int _ecc_import_export(void) {
    DO(_ecc_key_cmp(PK_PUBLIC, &pub, &key));
    ecc_free(&key);
 
+   /* import - private PKCS8 format - no password */
+   DO(ecc_import_pkcs8(long_pri_pkcs8, sizeof(long_pri_pkcs8),   NULL, 0, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+   DO(ecc_import_pkcs8(long_pric_pkcs8, sizeof(long_pric_pkcs8),  NULL, 0, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+   DO(ecc_import_pkcs8(short_pri_pkcs8, sizeof(short_pri_pkcs8),  NULL, 0, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+   DO(ecc_import_pkcs8(short_pric_pkcs8, sizeof(short_pric_pkcs8), NULL, 0, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+
+   /* import - private PKCS8 format - password protected (PBES1 algorithms) */
+#ifdef LTC_MD2
+   DO(ecc_import_pkcs8(long_pri_pkcs8_pbe_md2_des, sizeof(long_pri_pkcs8_pbe_md2_des), "secret", 6, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+#endif
+#ifdef LTC_MD5
+   DO(ecc_import_pkcs8(long_pri_pkcs8_pbe_md5_des, sizeof(long_pri_pkcs8_pbe_md5_des), "secret", 6, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+#endif
+#ifdef LTC_SHA1
+   DO(ecc_import_pkcs8(long_pri_pkcs8_pbe_sha1_des, sizeof(long_pri_pkcs8_pbe_sha1_des), "secret", 6, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+#endif
+#if defined(LTC_RC2) && defined(LTC_MD2)
+   DO(ecc_import_pkcs8(long_pri_pkcs8_pbe_md2_rc2_64, sizeof(long_pri_pkcs8_pbe_md2_rc2_64), "secret", 6, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+#endif
+#if defined(LTC_RC2) && defined(LTC_MD5)
+   DO(ecc_import_pkcs8(long_pri_pkcs8_pbe_md5_rc2_64, sizeof(long_pri_pkcs8_pbe_md5_rc2_64), "secret", 6, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+#endif
+#if defined(LTC_RC2) && defined(LTC_SHA1)
+   DO(ecc_import_pkcs8(long_pri_pkcs8_pbe_sha1_rc2_64, sizeof(long_pri_pkcs8_pbe_sha1_rc2_64), "secret", 6, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+#endif
+
+   /* import - private PKCS8 format - password protected (PBES2 algorithms) */
+#if defined(LTC_RC2)
+   DO(ecc_import_pkcs8(long_pri_pkcs8_pbkdf2_rc2_cbc, sizeof(long_pri_pkcs8_pbkdf2_rc2_cbc), "secret", 6, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+#endif
+#if defined(LTC_DES)
+   DO(ecc_import_pkcs8(long_pri_pkcs8_pbkdf2_des_cbc, sizeof(long_pri_pkcs8_pbkdf2_des_cbc), "secret", 6, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+#endif
+#if defined(LTC_DES)
+   DO(ecc_import_pkcs8(long_pri_pkcs8_pbkdf2_des_ede3_cbc, sizeof(long_pri_pkcs8_pbkdf2_des_ede3_cbc), "secret", 6, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+#endif
+#if defined(LTC_SHA224) && defined(LTC_DES)
+   DO(ecc_import_pkcs8(long_pri_pkcs8_pbkdf2_sha224_des_ede3_cbc, sizeof(long_pri_pkcs8_pbkdf2_sha224_des_ede3_cbc), "secret", 6, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+#endif
+#if defined(LTC_SHA256) && defined(LTC_DES)
+   DO(ecc_import_pkcs8(long_pri_pkcs8_pbkdf2_sha256_des_ede3_cbc, sizeof(long_pri_pkcs8_pbkdf2_sha256_des_ede3_cbc), "secret", 6, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+#endif
+#if defined(LTC_SHA384) && defined(LTC_DES)
+   DO(ecc_import_pkcs8(long_pri_pkcs8_pbkdf2_sha384_des_ede3_cbc, sizeof(long_pri_pkcs8_pbkdf2_sha384_des_ede3_cbc), "secret", 6, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+#endif
+#if defined(LTC_SHA512) && defined(LTC_DES)
+   DO(ecc_import_pkcs8(long_pri_pkcs8_pbkdf2_sha512_des_ede3_cbc, sizeof(long_pri_pkcs8_pbkdf2_sha512_des_ede3_cbc), "secret", 6, &key));
+   DO(_ecc_key_cmp(PK_PRIVATE, &pri, &key));
+   ecc_free(&key);
+#endif
+
    /* import - X.509 EC certificates */
    DO(ecc_import_x509(x509_cert_long,   sizeof(x509_cert_long),   &key));
    DO(_ecc_key_cmp(PK_PUBLIC, &pub, &key));