add hkdf impl
This commit is contained in:
parent
d84af284a3
commit
c98857a47e
@ -825,6 +825,11 @@ SOURCE=.\src\misc\error_to_string.c
|
|||||||
SOURCE=.\src\misc\zeromem.c
|
SOURCE=.\src\misc\zeromem.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\misc\hkdf\hkdf.c
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
# Begin Group "modes"
|
# Begin Group "modes"
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
# PROP Default_Filter ""
|
||||||
|
@ -2954,6 +2954,28 @@
|
|||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</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
|
<Filter
|
||||||
Name="base64"
|
Name="base64"
|
||||||
>
|
>
|
||||||
|
@ -2946,6 +2946,28 @@
|
|||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</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
|
<Filter
|
||||||
Name="base64"
|
Name="base64"
|
||||||
>
|
>
|
||||||
|
3
makefile
3
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_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_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/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_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/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 \
|
src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \
|
||||||
|
@ -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_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_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/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_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/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 \
|
src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \
|
||||||
|
@ -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_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_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/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_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/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 \
|
src/modes/cfb/cfb_encrypt.obj src/modes/cfb/cfb_getiv.obj src/modes/cfb/cfb_setiv.obj \
|
||||||
|
@ -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_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_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/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_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/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 \
|
src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \
|
||||||
|
@ -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_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_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/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_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/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 \
|
src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \
|
||||||
|
@ -74,6 +74,7 @@ enum {
|
|||||||
#include <tomcrypt_misc.h>
|
#include <tomcrypt_misc.h>
|
||||||
#include <tomcrypt_argchk.h>
|
#include <tomcrypt_argchk.h>
|
||||||
#include <tomcrypt_pkcs.h>
|
#include <tomcrypt_pkcs.h>
|
||||||
|
#include <tomcrypt_hkdf.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -360,6 +360,13 @@
|
|||||||
|
|
||||||
#endif /* LTC_NO_PKCS */
|
#endif /* LTC_NO_PKCS */
|
||||||
|
|
||||||
|
/* LTC_HKDF Key Derivation/Expansion stuff */
|
||||||
|
#ifndef LTC_NO_HKDF
|
||||||
|
|
||||||
|
#define LTC_HKDF
|
||||||
|
|
||||||
|
#endif /* LTC_NO_HKDF */
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
|
|
||||||
#ifdef LTC_MECC
|
#ifdef LTC_MECC
|
||||||
|
26
src/headers/tomcrypt_hkdf.h
Normal file
26
src/headers/tomcrypt_hkdf.h
Normal file
@ -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
src/misc/hkdf/hkdf.c
Normal file
113
src/misc/hkdf/hkdf.c
Normal file
@ -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: */
|
Loading…
x
Reference in New Issue
Block a user