Browse Source

add pkcs12_kdf()

Karel Miko 7 years ago
parent
commit
b3f483a204

+ 1 - 0
src/headers/tomcrypt_custom.h

@@ -463,6 +463,7 @@
 
 
 #define LTC_PKCS_1
 #define LTC_PKCS_1
 #define LTC_PKCS_5
 #define LTC_PKCS_5
+#define LTC_PKCS_12
 
 
 /* Include ASN.1 DER (required by DSA/RSA) */
 /* Include ASN.1 DER (required by DSA/RSA) */
 #define LTC_DER
 #define LTC_DER

+ 1 - 0
src/headers/tomcrypt_pkcs.h

@@ -103,6 +103,7 @@ int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
 int pkcs_5_test (void);
 int pkcs_5_test (void);
 #endif  /* LTC_PKCS_5 */
 #endif  /* LTC_PKCS_5 */
 
 
+
 /* ref:         $Format:%D$ */
 /* ref:         $Format:%D$ */
 /* git commit:  $Format:%H$ */
 /* git commit:  $Format:%H$ */
 /* commit time: $Format:%ai$ */
 /* commit time: $Format:%ai$ */

+ 12 - 0
src/headers/tomcrypt_private.h

@@ -305,6 +305,18 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i
 
 
 #endif /* LTC_DER */
 #endif /* LTC_DER */
 
 
+/* tomcrypt_pkcs.h */
+
+#ifdef LTC_PKCS_12
+
+int pkcs12_kdf(               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);
+
+#endif  /* LTC_PKCS_12 */
+
 /* tomcrypt_prng.h */
 /* tomcrypt_prng.h */
 
 
 #define _LTC_PRNG_EXPORT(which) \
 #define _LTC_PRNG_EXPORT(which) \

+ 3 - 0
src/misc/crypt/crypt.c

@@ -436,6 +436,9 @@ const char *crypt_build_settings =
 #if defined(LTC_PKCS_5)
 #if defined(LTC_PKCS_5)
     " PKCS#5 "
     " PKCS#5 "
 #endif
 #endif
+#if defined(LTC_PKCS_12)
+    " PKCS#12 "
+#endif
 #if defined(LTC_PADDING)
 #if defined(LTC_PADDING)
     " PADDING "
     " PADDING "
 #endif
 #endif

+ 81 - 0
src/misc/pkcs12/pkcs12_kdf.c

@@ -0,0 +1,81 @@
+/* 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_PKCS_12
+
+int pkcs12_kdf(               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;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */