RyanC 13 gadi atpakaļ
vecāks
revīzija
c98857a47e

+ 5 - 0
libtomcrypt.dsp

@@ -825,6 +825,11 @@ SOURCE=.\src\misc\error_to_string.c
 SOURCE=.\src\misc\zeromem.c
 # End Source File
 # End Group
+# Begin Source File
+
+SOURCE=.\src\misc\hkdf\hkdf.c
+# End Source File
+# End Group
 # Begin Group "modes"
 
 # PROP Default_Filter ""

+ 22 - 0
libtomcrypt_VS2005.vcproj

@@ -2954,6 +2954,28 @@
 					/>
 				</FileConfiguration>
 			</File>
+			<File
+				RelativePath="src\misc\hkdf\hkdf.c"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
 			<Filter
 				Name="base64"
 				>

+ 22 - 0
libtomcrypt_VS2008.vcproj

@@ -2946,6 +2946,28 @@
 					/>
 				</FileConfiguration>
 			</File>
+			<File
+				RelativePath="src\misc\hkdf\hkdf.c"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions=""
+					/>
+				</FileConfiguration>
+			</File>
 			<Filter
 				Name="base64"
 				>

+ 2 - 1
makefile

@@ -156,7 +156,8 @@ src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \
 src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \
 src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \
 src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o \
-src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \
+src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/misc/hkdf/hkdf.o \
+src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \
 src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \
 src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \
 src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \

+ 2 - 1
makefile.icc

@@ -141,7 +141,8 @@ src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \
 src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \
 src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \
 src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o \
-src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \
+src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/misc/hkdf/hkdf.o \
+src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \
 src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \
 src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \
 src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \

+ 2 - 1
makefile.msvc

@@ -51,7 +51,8 @@ src/misc/crypt/crypt_prng_is_valid.obj src/misc/crypt/crypt_register_cipher.obj
 src/misc/crypt/crypt_register_hash.obj src/misc/crypt/crypt_register_prng.obj \
 src/misc/crypt/crypt_unregister_cipher.obj src/misc/crypt/crypt_unregister_hash.obj \
 src/misc/crypt/crypt_unregister_prng.obj src/misc/error_to_string.obj src/misc/pkcs5/pkcs_5_1.obj \
-src/misc/pkcs5/pkcs_5_2.obj src/misc/zeromem.obj src/modes/cbc/cbc_decrypt.obj src/modes/cbc/cbc_done.obj \
+src/misc/pkcs5/pkcs_5_2.obj src/misc/zeromem.obj src/misc/hkdf/hkdf.obj \
+src/modes/cbc/cbc_decrypt.obj src/modes/cbc/cbc_done.obj \
 src/modes/cbc/cbc_encrypt.obj src/modes/cbc/cbc_getiv.obj src/modes/cbc/cbc_setiv.obj \
 src/modes/cbc/cbc_start.obj src/modes/cfb/cfb_decrypt.obj src/modes/cfb/cfb_done.obj \
 src/modes/cfb/cfb_encrypt.obj src/modes/cfb/cfb_getiv.obj src/modes/cfb/cfb_setiv.obj \

+ 2 - 1
makefile.shared

@@ -146,7 +146,8 @@ src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \
 src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \
 src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \
 src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o \
-src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \
+src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/misc/hkdf/hkdf.o \
+src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \
 src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \
 src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \
 src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \

+ 2 - 1
makefile.unix

@@ -87,7 +87,8 @@ src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \
 src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \
 src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \
 src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o \
-src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \
+src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/misc/hkdf/hkdf.o \
+src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \
 src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \
 src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \
 src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \

+ 1 - 0
src/headers/tomcrypt.h

@@ -74,6 +74,7 @@ enum {
 #include <tomcrypt_misc.h>
 #include <tomcrypt_argchk.h>
 #include <tomcrypt_pkcs.h>
+#include <tomcrypt_hkdf.h>
 
 #ifdef __cplusplus
    }

+ 7 - 0
src/headers/tomcrypt_custom.h

@@ -360,6 +360,13 @@
 
 #endif /* LTC_NO_PKCS */
 
+/* LTC_HKDF Key Derivation/Expansion stuff */
+#ifndef LTC_NO_HKDF
+
+#define LTC_HKDF
+
+#endif /* LTC_NO_HKDF */
+
 /* cleanup */
 
 #ifdef LTC_MECC

+ 26 - 0
src/headers/tomcrypt_hkdf.h

@@ -0,0 +1,26 @@
+/* LTC_HKDF Header Info */
+
+/* ===> LTC_HKDF -- RFC5869 HMAC-based Key Derivation Function <=== */
+#ifdef LTC_HKDF
+
+int hkdf_extract(int hash_idx,
+                 const unsigned char *salt, unsigned long saltlen,
+                 const unsigned char *in,   unsigned long inlen,
+                       unsigned char *out,  unsigned long *outlen);
+
+int hkdf_expand(int hash_idx,
+                const unsigned char *info, unsigned long infolen,
+                const unsigned char *in,   unsigned long inlen,
+                      unsigned char *out,  unsigned long outlen);
+
+int hkdf(int hash_idx,
+         const unsigned char *salt, unsigned long saltlen,
+         const unsigned char *info, unsigned long infolen,
+         const unsigned char *in,   unsigned long inlen,
+               unsigned char *out,  unsigned long outlen);
+
+#endif  /* LTC_HKDF */
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */

+ 113 - 0
src/misc/hkdf/hkdf.c

@@ -0,0 +1,113 @@
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <tomcrypt.h>
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b))?(a):(b)
+#endif
+
+/* This is mostly just a wrapper around hmac_memory */
+int hkdf_extract(int hash_idx, const unsigned char *salt, unsigned long  saltlen,
+                               const unsigned char *in,   unsigned long  inlen,
+                                     unsigned char *out,  unsigned long *outlen)
+{
+   /* libtomcrypt chokes on a zero length HMAC key, so we need to check for
+      that.  HMAC specifies that keys shorter than the hash's blocksize are
+      0 padded to the block size.  HKDF specifies that a NULL salt is to be
+      substituted with a salt comprised of hashLen 0 bytes.  HMAC's padding
+      means that in either case the HMAC is actually using a blocksize long
+      zero filled key.  Unless blocksize < hashLen (which wouldn't make any
+      sense), we can use a single 0 byte as the HMAC key and still generate
+      valid results for HKDF. */
+   if (salt == NULL || saltlen == 0) {
+      return hmac_memory(hash_idx, "",   1,       in, inlen, out, outlen); 
+   } else {
+      return hmac_memory(hash_idx, salt, saltlen, in, inlen, out, outlen);
+   }
+}
+
+int hkdf_expand(int hash_idx, const unsigned char *info, unsigned long infolen,
+                              const unsigned char *in,   unsigned long inlen,
+                                    unsigned char *out,  unsigned long outlen)
+{
+   const unsigned long hashsize = hash_descriptor[hash_idx].hashsize;
+   int err;
+   unsigned char N;
+   unsigned long Noutlen, outoff;
+
+   unsigned char *T,  *dat;
+   unsigned long Tlen, datlen;
+
+   /* RFC5869 parameter restrictions */
+   if (inlen < hashsize || outlen > hashsize * 255)
+      return CRYPT_INVALID_ARG;
+   if (info == NULL && infolen != 0)
+      return CRYPT_INVALID_ARG;
+   assert(out != NULL);
+
+   Tlen = hashsize + infolen + 1;
+   T = XMALLOC(Tlen); /* Replace with static buffer? */
+   if (T == NULL) {
+      return CRYPT_MEM;
+   }
+   XMEMCPY(T + hashsize, info, infolen);
+
+   /* HMAC data T(1) doesn't include a previous hash value */
+   dat    = T    + hashsize;
+   datlen = Tlen - hashsize;
+
+   N = 0;
+   outoff = 0; /* offset in out to write to */
+   while (1) { /* an exit condition breaks mid-loop */
+      Noutlen = MIN(hashsize, outlen - outoff);
+      T[Tlen - 1] = ++N;
+      if ((err = hmac_memory(hash_idx, in, inlen, dat, datlen,
+                             out + outoff, &Noutlen)) != CRYPT_OK) {
+         zeromem(T, Tlen);
+         XFREE(T);
+         return err;
+      }
+      outoff += Noutlen;
+
+      if (outoff >= outlen) /* loop exit condition */
+         break;
+
+      /* All subsequent HMAC data T(N) DOES include the previous hash value */
+      XMEMCPY(T, out + hashsize * (N-1), hashsize);
+      if (N == 1) {
+         dat = T;
+         datlen = Tlen;
+      }
+   }
+   zeromem(T, Tlen);
+   XFREE(T);
+   return CRYPT_OK;
+}
+
+/* all in one step */
+int hkdf(int hash_idx, const unsigned char *salt, unsigned long saltlen,
+                       const unsigned char *info, unsigned long infolen,
+                       const unsigned char *in,   unsigned long inlen,
+                             unsigned char *out,  unsigned long outlen)
+{
+   unsigned long hashsize = hash_descriptor[hash_idx].hashsize;
+   int err;
+   unsigned char *extracted = XMALLOC(hashsize); /* replace with static buffer? */
+   if (extracted == NULL) {
+      return CRYPT_MEM;
+   }
+   if ((err = hkdf_extract(hash_idx, salt, saltlen, in, inlen, extracted, &hashsize)) != 0) {
+      zeromem(extracted, hashsize);
+      XFREE(extracted);
+      return err;
+   }
+   err = hkdf_expand(hash_idx, extracted, hashsize, info, infolen, out, outlen);
+   zeromem(extracted, hashsize);
+   XFREE(extracted);
+   return err;
+}
+
+
+/* vim: set ts=2 sw=2 et ai si: */