From d3cbbe80851477cf2f85256d402faf038bac6c26 Mon Sep 17 00:00:00 2001 From: wangyu- Date: Sun, 24 Jun 2018 07:58:19 -0500 Subject: [PATCH] implement hkdf --- encrypt.cpp | 35 ++- lib/{aes.c => aes.cpp} | 0 lib/aes_faster_c/{aes.c => aes.cpp} | 0 lib/aes_faster_c/{wrapper.c => wrapper.cpp} | 0 lib/{md5.c => md5.cpp} | 0 lib/{pbkdf2-sha1.c => pbkdf2-sha1.cpp} | 0 lib/{pbkdf2-sha256.c => pbkdf2-sha256.cpp} | 253 +++++++++++++++++++- lib/pbkdf2-sha256.h | 19 +- makefile | 4 +- 9 files changed, 293 insertions(+), 18 deletions(-) rename lib/{aes.c => aes.cpp} (100%) rename lib/aes_faster_c/{aes.c => aes.cpp} (100%) rename lib/aes_faster_c/{wrapper.c => wrapper.cpp} (100%) rename lib/{md5.c => md5.cpp} (100%) rename lib/{pbkdf2-sha1.c => pbkdf2-sha1.cpp} (100%) rename lib/{pbkdf2-sha256.c => pbkdf2-sha256.cpp} (80%) diff --git a/encrypt.cpp b/encrypt.cpp index 7f77b05..1cb6adc 100755 --- a/encrypt.cpp +++ b/encrypt.cpp @@ -37,6 +37,8 @@ int is_hmac_used=0; //TODO key negotiation and forward secrecy + + int my_init_keys(const char * user_passwd,int is_client) { char tmp[1000]=""; @@ -57,28 +59,35 @@ int my_init_keys(const char * user_passwd,int is_client) md5((uint8_t*)(salt_text),strlen(salt_text),salt); //TODO different salt per session unsigned char pbkdf2_output1[400]=""; - PKCS5_PBKDF2_HMAC_SHA256((uint8_t*)user_passwd,len,salt,16,10000, 32,pbkdf2_output1); //TODO HKDF, argon2 ? + PKCS5_PBKDF2_HMAC_SHA256((uint8_t*)user_passwd,len,salt,16,10000, 32,pbkdf2_output1); //TODO argon2 ? - unsigned char pbkdf2_output2[400]=""; - PKCS5_PBKDF2_HMAC_SHA256(pbkdf2_output1,32,0,0,1, hmac_key_len*2+cipher_key_len*2,pbkdf2_output2); //stretch it + //unsigned char pbkdf2_output2[400]=""; + //PKCS5_PBKDF2_HMAC_SHA256(pbkdf2_output1,32,0,0,1, hmac_key_len*2+cipher_key_len*2,pbkdf2_output2); //stretch it + + const char *info_hmac_encrypt="server-->client hmac"; + const char *info_hmac_decrypt="client-->server hmac"; + const char *info_cipher_encrypt="server-->client cipher"; + const char *info_cipher_decrypt="client-->server cipher"; if(is_client) { - memcpy(cipher_key_encrypt,pbkdf2_output2,cipher_key_len); - memcpy(cipher_key_decrypt,pbkdf2_output2+cipher_key_len,cipher_key_len); - - memcpy(hmac_key_encrypt,pbkdf2_output2+cipher_key_len*2,hmac_key_len); - memcpy(hmac_key_decrypt,pbkdf2_output2+cipher_key_len*2+hmac_key_len,hmac_key_len); + const char *tmp; + tmp=info_hmac_encrypt; info_hmac_encrypt=info_hmac_decrypt;info_hmac_decrypt=tmp; + tmp=info_cipher_encrypt; info_cipher_encrypt=info_cipher_decrypt;info_cipher_decrypt=tmp; } else { - memcpy(cipher_key_decrypt,pbkdf2_output2,cipher_key_len); - memcpy(cipher_key_encrypt,pbkdf2_output2+cipher_key_len,cipher_key_len); - - memcpy(hmac_key_decrypt,pbkdf2_output2+cipher_key_len*2,hmac_key_len); - memcpy(hmac_key_encrypt,pbkdf2_output2+cipher_key_len*2+hmac_key_len,hmac_key_len); + //nop } + assert( hkdf_sha256_expand( pbkdf2_output1,32, (unsigned char *)info_cipher_encrypt,strlen(info_cipher_encrypt), cipher_key_encrypt, cipher_key_len ) ==0); + assert( hkdf_sha256_expand( pbkdf2_output1,32, (unsigned char *)info_cipher_decrypt,strlen(info_cipher_decrypt), cipher_key_decrypt, cipher_key_len ) ==0); + assert( hkdf_sha256_expand( pbkdf2_output1,32, (unsigned char *)info_hmac_encrypt,strlen(info_hmac_encrypt), hmac_key_encrypt, hmac_key_len ) ==0); + assert( hkdf_sha256_expand( pbkdf2_output1,32, (unsigned char *)info_hmac_decrypt,strlen(info_hmac_decrypt), hmac_key_decrypt, hmac_key_len ) ==0); + + + + } print_binary_chars(normal_key,16); diff --git a/lib/aes.c b/lib/aes.cpp similarity index 100% rename from lib/aes.c rename to lib/aes.cpp diff --git a/lib/aes_faster_c/aes.c b/lib/aes_faster_c/aes.cpp similarity index 100% rename from lib/aes_faster_c/aes.c rename to lib/aes_faster_c/aes.cpp diff --git a/lib/aes_faster_c/wrapper.c b/lib/aes_faster_c/wrapper.cpp similarity index 100% rename from lib/aes_faster_c/wrapper.c rename to lib/aes_faster_c/wrapper.cpp diff --git a/lib/md5.c b/lib/md5.cpp similarity index 100% rename from lib/md5.c rename to lib/md5.cpp diff --git a/lib/pbkdf2-sha1.c b/lib/pbkdf2-sha1.cpp similarity index 100% rename from lib/pbkdf2-sha1.c rename to lib/pbkdf2-sha1.cpp diff --git a/lib/pbkdf2-sha256.c b/lib/pbkdf2-sha256.cpp similarity index 80% rename from lib/pbkdf2-sha256.c rename to lib/pbkdf2-sha256.cpp index 85cb3dc..528f550 100644 --- a/lib/pbkdf2-sha256.c +++ b/lib/pbkdf2-sha256.cpp @@ -1,5 +1,5 @@ /* - this file is from https://github.com/kholia/PKCS5_PBKDF2 + this file is from https://github.com/kholia/PKCS5_PBKDF2, with additional code of hkdf_sha256 * FIPS-180-2 compliant SHA-256 implementation * @@ -34,12 +34,14 @@ #include #include + #if defined(TEST) ||defined(DEBUG) #undef TEST #undef DEBUG #warning "undefined TEST/DEBUG" #endif + typedef struct { unsigned long total[2]; /*!< number of bytes processed */ unsigned long state[8]; /*!< intermediate digest state */ @@ -50,6 +52,7 @@ typedef struct { int is224; /*!< 0 => SHA-256, else SHA-224 */ } sha2_context; + /* * 32-bit integer manipulation macros (big endian) */ @@ -869,3 +872,251 @@ int main() } #endif + + + +const int sha256_len=32; + +#define MBEDTLS_MD_MAX_SIZE 64 +#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80 + +static void * (* const volatile memset_func)( void *, int, size_t ) = memset; + +void mbedtls_platform_zeroize( void *buf, size_t len ) +{ + memset_func( buf, 0, len ); +} + +int hkdf_sha256_extract( + const unsigned char *salt, size_t salt_len, + const unsigned char *ikm, size_t ikm_len, + unsigned char *prk ) +{ + unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' }; + + if( salt == NULL ) + { + size_t hash_len; + + hash_len = sha256_len; + + if( hash_len == 0 ) + { + return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; + } + + salt = null_salt; + salt_len = hash_len; + } + + sha2_hmac (salt, salt_len, ikm, ikm_len, prk ,0); + return 0; +} + +int hkdf_sha256_expand( const unsigned char *prk, + size_t prk_len, const unsigned char *info, + size_t info_len, unsigned char *okm, size_t okm_len ) +{ + size_t hash_len; + size_t where = 0; + size_t n; + size_t t_len = 0; + size_t i; + int ret = 0; + sha2_context ctx; + unsigned char t[MBEDTLS_MD_MAX_SIZE]; + + if( okm == NULL ) + { + return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); + } + + hash_len = sha256_len; + + if( prk_len < hash_len || hash_len == 0 ) + { + return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); + } + + if( info == NULL ) + { + info = (const unsigned char *) ""; + info_len = 0; + } + + n = okm_len / hash_len; + + if( (okm_len % hash_len) != 0 ) + { + n++; + } + + if( n > 255 ) + { + return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); + } + + /* + mbedtls_md_init( &ctx ); + + if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 ) + { + goto exit; + }*/ + + /* RFC 5869 Section 2.3. */ + for( i = 1; i <= n; i++ ) + { + size_t num_to_copy; + unsigned char c = i & 0xff; + + sha2_hmac_starts( &ctx, prk, prk_len,0 ); + + sha2_hmac_update( &ctx, t, t_len ); + + sha2_hmac_update( &ctx, info, info_len ); + + /* The constant concatenated to the end of each t(n) is a single octet. + * */ + sha2_hmac_update( &ctx, &c, 1 ); + + sha2_hmac_finish( &ctx, t ); + num_to_copy = i != n ? hash_len : okm_len - where; + memcpy( okm + where, t, num_to_copy ); + where += hash_len; + t_len = hash_len; + } + +//exit: + //mbedtls_md_free( &ctx ); + mbedtls_platform_zeroize( &ctx, sizeof( ctx ) ); + + mbedtls_platform_zeroize( t, sizeof( t ) ); + + return( ret ); +} + +int hkdf_sha256( const unsigned char *salt, + size_t salt_len, const unsigned char *ikm, size_t ikm_len, + const unsigned char *info, size_t info_len, + unsigned char *okm, size_t okm_len ) +{ + int ret; + unsigned char prk[MBEDTLS_MD_MAX_SIZE]; + + ret = hkdf_sha256_extract( salt, salt_len, ikm, ikm_len, prk ); + + if( ret == 0 ) + { + ret = hkdf_sha256_expand( prk, sha256_len, + info, info_len, okm, okm_len ); + } + + mbedtls_platform_zeroize( prk, sizeof( prk ) ); + + return( ret ); +} + +#ifdef HKDF_SHA256_TEST + +#include +int hex_to_number(char a) +{ + if(a>='0' &&a<='9') + return a-'0'; + if(a>='a'&& a<='f') return a- 'a' +10; + + assert(0==1); + return -1; +} +int base16_decode(const char *a,unsigned char *buf) +{ + int len=strlen(a); + assert(len%2==0); + + for(int i=0,j=0;i",(int)(ikm[j])); + printf("\n---------------------------\n"); + for(int j=0;j",(int)(output[j])); + printf("\n---------------------------\n"); + for(int j=0;j",(int)(okm[j])); + printf("\n===========================\n"); + } + + +} + +#endif + + diff --git a/lib/pbkdf2-sha256.h b/lib/pbkdf2-sha256.h index e647de7..c599aea 100644 --- a/lib/pbkdf2-sha256.h +++ b/lib/pbkdf2-sha256.h @@ -9,5 +9,20 @@ void PKCS5_PBKDF2_HMAC_SHA256(unsigned char *password, size_t plen, const unsigned long iteration_count, const unsigned long key_length, unsigned char *output); -void sha2( const unsigned char *input, size_t ilen, - unsigned char output[32], int is224 ); +//void sha2( const unsigned char *input, size_t ilen,unsigned char output[32], int is224 ); + +int hkdf_sha256_extract( + const unsigned char *salt, size_t salt_len, + const unsigned char *ikm, size_t ikm_len, + unsigned char *prk ); + +int hkdf_sha256_expand( const unsigned char *prk, + size_t prk_len, const unsigned char *info, + size_t info_len, unsigned char *okm, size_t okm_len ); + +int hkdf_sha256( const unsigned char *salt, + size_t salt_len, const unsigned char *ikm, size_t ikm_len, + const unsigned char *info, size_t info_len, + unsigned char *okm, size_t okm_len ); + + diff --git a/makefile b/makefile index 53b13a8..c73278c 100755 --- a/makefile +++ b/makefile @@ -10,8 +10,8 @@ cc_arm= /toolchains/arm-2014.05/bin/arm-none-linux-gnueabi-g++ #cc_bcm2708=/home/wangyu/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++ FLAGS= -std=c++11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers ${OPT} -COMMON=main.cpp lib/md5.c lib/pbkdf2-sha1.c lib/pbkdf2-sha256.c encrypt.cpp log.cpp network.cpp common.cpp connection.cpp misc.cpp fd_manager.cpp -lpthread -SOURCES= $(COMMON) lib/aes_faster_c/aes.c lib/aes_faster_c/wrapper.c +COMMON=main.cpp lib/md5.cpp lib/pbkdf2-sha1.cpp lib/pbkdf2-sha256.cpp encrypt.cpp log.cpp network.cpp common.cpp connection.cpp misc.cpp fd_manager.cpp -lpthread +SOURCES= $(COMMON) lib/aes_faster_c/aes.cpp lib/aes_faster_c/wrapper.cpp SOURCES_TINY_AES= $(COMMON) lib/aes.c SOURCES_AES_ACC=$(COMMON) $(wildcard lib/aes_acc/aes*.c)