diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index be8033296..4689f3a4d 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -4,7 +4,7 @@ * \brief Consistency checks for configuration options */ /* - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -191,6 +191,10 @@ #error "MBEDTLS_HAVEGE_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C) +#error "MBEDTLS_HKDF_C defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C) #error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites" #endif diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 7c9acb230..a59e9c5ca 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -8,7 +8,7 @@ * memory footprint. */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -2091,6 +2091,21 @@ */ //#define MBEDTLS_HAVEGE_C +/** + * \def MBEDTLS_HKDF_C + * + * Enable the HKDF algorithm (RFC 5869). + * + * Module: library/hkdf.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the Hashed Message Authentication Code + * (HMAC)-based key derivation function (HKDF). + */ +#define MBEDTLS_HKDF_C + /** * \def MBEDTLS_HMAC_DRBG_C * diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h index 8b4d3a875..c7f6a72b0 100644 --- a/include/mbedtls/error.h +++ b/include/mbedtls/error.h @@ -4,7 +4,7 @@ * \brief Error to string translation */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -88,6 +88,7 @@ * RSA 4 11 * ECP 4 9 (Started from top) * MD 5 5 + * HKDF 5 1 (Started from top) * CIPHER 6 8 * SSL 6 17 (Started from top) * SSL 7 31 diff --git a/include/mbedtls/hkdf.h b/include/mbedtls/hkdf.h new file mode 100644 index 000000000..6833e7272 --- /dev/null +++ b/include/mbedtls/hkdf.h @@ -0,0 +1,125 @@ +/** + * \file hkdf.h + * + * \brief This file contains the HKDF interface. + * + * The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is + * specified by RFC 5869. + */ +/* + * Copyright (C) 2016-2018, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_HKDF_H +#define MBEDTLS_HKDF_H + +#include "md.h" + +/** + * \name HKDF Error codes + * \{ + */ +#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80 /**< Bad input parameters to function. */ +/* \} name */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief This is the HMAC-based Extract-and-Expand Key Derivation Function + * (HKDF). + * + * \param md A hash function; md.size denotes the length of the hash + * function output in bytes. + * \param salt An optional salt value (a non-secret random value); + * if the salt is not provided, a string of all zeros of + * md.size length is used as the salt. + * \param salt_len The length in bytes of the optional \p salt. + * \param ikm The input keying material. + * \param ikm_len The length in bytes of \p ikm. + * \param info An optional context and application specific information + * string. This can be a zero-length string. + * \param info_len The length of \p info in bytes. + * \param okm The output keying material of \p okm_len bytes. + * \param okm_len The length of the output keying material in bytes. This + * must be less than or equal to 255 * md.size bytes. + * + * \return 0 on success. + * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. + * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying + * MD layer. + */ +int mbedtls_hkdf( const mbedtls_md_info_t *md, 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 ); + +/** + * \brief Take the input keying material \p ikm and extract from it a + * fixed-length pseudorandom key \p prk. + * + * \param md A hash function; md.size denotes the length of the + * hash function output in bytes. + * \param salt An optional salt value (a non-secret random value); + * if the salt is not provided, a string of all zeros + * of md.size length is used as the salt. + * \param salt_len The length in bytes of the optional \p salt. + * \param ikm The input keying material. + * \param ikm_len The length in bytes of \p ikm. + * \param[out] prk A pseudorandom key of at least md.size bytes. + * + * \return 0 on success. + * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. + * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying + * MD layer. + */ +int mbedtls_hkdf_extract( const mbedtls_md_info_t *md, + const unsigned char *salt, size_t salt_len, + const unsigned char *ikm, size_t ikm_len, + unsigned char *prk ); + +/** + * \brief Expand the supplied \p prk into several additional pseudorandom + * keys, which is the output of the HKDF. + * + * \param md A hash function; md.size denotes the length of the hash + * function output in bytes. + * \param prk A pseudorandom key of at least md.size bytes. \p prk is usually, + * the output from the HKDF extract step. + * \param prk_len The length in bytes of \p prk. + * \param info An optional context and application specific information + * string. This can be a zero-length string. + * \param info_len The length of \p info in bytes. + * \param okm The output keying material of \p okm_len bytes. + * \param okm_len The length of the output keying material in bytes. This + * must be less than or equal to 255 * md.size bytes. + * + * \return 0 on success. + * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. + * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying + * MD layer. + */ +int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk, + size_t prk_len, const unsigned char *info, + size_t info_len, unsigned char *okm, size_t okm_len ); + +#ifdef __cplusplus +} +#endif + +#endif /* hkdf.h */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 6177ca2b4..b730d082b 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -29,6 +29,7 @@ set(src_crypto error.c gcm.c havege.c + hkdf.c hmac_drbg.c md.c md2.c diff --git a/library/Makefile b/library/Makefile index b155c720e..5721d7e39 100644 --- a/library/Makefile +++ b/library/Makefile @@ -56,6 +56,7 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \ ecjpake.o ecp.o \ ecp_curves.o entropy.o entropy_poll.o \ error.o gcm.o havege.o \ + hkdf.o \ hmac_drbg.o md.o md2.o \ md4.o md5.o md_wrap.o \ memory_buffer_alloc.o oid.o \ diff --git a/library/error.c b/library/error.c index 222d85b62..58c5a6f35 100644 --- a/library/error.c +++ b/library/error.c @@ -101,6 +101,10 @@ #include "mbedtls/gcm.h" #endif +#if defined(MBEDTLS_HKDF_C) +#include "mbedtls/hkdf.h" +#endif + #if defined(MBEDTLS_HMAC_DRBG_C) #include "mbedtls/hmac_drbg.h" #endif @@ -698,6 +702,11 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" ); #endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_HKDF_C) + if( use_ret == -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "HKDF - Bad input parameters to function" ); +#endif /* MBEDTLS_HKDF_C */ + #if defined(MBEDTLS_HMAC_DRBG_C) if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) ) mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" ); diff --git a/library/hkdf.c b/library/hkdf.c new file mode 100644 index 000000000..d2e55e869 --- /dev/null +++ b/library/hkdf.c @@ -0,0 +1,180 @@ +/* + * HKDF implementation -- RFC 5869 + * + * Copyright (C) 2016-2018, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_HKDF_C) + +#include +#include "mbedtls/hkdf.h" +#include "mbedtls/platform_util.h" + +int mbedtls_hkdf( const mbedtls_md_info_t *md, 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 = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk ); + + if( ret == 0 ) + { + ret = mbedtls_hkdf_expand( md, prk, mbedtls_md_get_size( md ), + info, info_len, okm, okm_len ); + } + + mbedtls_platform_zeroize( prk, sizeof( prk ) ); + + return( ret ); +} + +int mbedtls_hkdf_extract( const mbedtls_md_info_t *md, + 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 = mbedtls_md_get_size( md ); + + if( hash_len == 0 ) + { + return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; + } + + salt = null_salt; + salt_len = hash_len; + } + + return( mbedtls_md_hmac( md, salt, salt_len, ikm, ikm_len, prk ) ); +} + +int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, 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; + mbedtls_md_context_t ctx; + unsigned char t[MBEDTLS_MD_MAX_SIZE]; + + if( okm == NULL ) + { + return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); + } + + hash_len = mbedtls_md_get_size( md ); + + 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; + + ret = mbedtls_md_hmac_starts( &ctx, prk, prk_len ); + if( ret != 0 ) + { + goto exit; + } + + ret = mbedtls_md_hmac_update( &ctx, t, t_len ); + if( ret != 0 ) + { + goto exit; + } + + ret = mbedtls_md_hmac_update( &ctx, info, info_len ); + if( ret != 0 ) + { + goto exit; + } + + /* The constant concatenated to the end of each t(n) is a single octet. + * */ + ret = mbedtls_md_hmac_update( &ctx, &c, 1 ); + if( ret != 0 ) + { + goto exit; + } + + ret = mbedtls_md_hmac_finish( &ctx, t ); + if( ret != 0 ) + { + goto exit; + } + + 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( t, sizeof( t ) ); + + return( ret ); +} + +#endif /* MBEDTLS_HKDF_C */ diff --git a/library/version_features.c b/library/version_features.c index a452caf5e..1b0f180ce 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -579,6 +579,9 @@ static const char *features[] = { #if defined(MBEDTLS_HAVEGE_C) "MBEDTLS_HAVEGE_C", #endif /* MBEDTLS_HAVEGE_C */ +#if defined(MBEDTLS_HKDF_C) + "MBEDTLS_HKDF_C", +#endif /* MBEDTLS_HKDF_C */ #if defined(MBEDTLS_HMAC_DRBG_C) "MBEDTLS_HMAC_DRBG_C", #endif /* MBEDTLS_HMAC_DRBG_C */ diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl index ac0fbff05..7290b87d2 100755 --- a/scripts/generate_errors.pl +++ b/scripts/generate_errors.pl @@ -31,7 +31,7 @@ my $error_format_file = $data_dir.'/error.fmt'; my @low_level_modules = qw( AES ARC4 ASN1 BASE64 BIGNUM BLOWFISH CAMELLIA CCM CMAC CTR_DRBG DES - ENTROPY GCM HMAC_DRBG MD2 MD4 MD5 + ENTROPY GCM HKDF HMAC_DRBG MD2 MD4 MD5 NET OID PADLOCK PBKDF2 RIPEMD160 SHA1 SHA256 SHA512 THREADING XTEA ); my @high_level_modules = qw( CIPHER DHM ECP MD diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 16e19a927..bcd97a05b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -81,6 +81,7 @@ add_test_suite(gcm gcm.aes128_de) add_test_suite(gcm gcm.aes192_de) add_test_suite(gcm gcm.aes256_de) add_test_suite(gcm gcm.camellia) +add_test_suite(hkdf) add_test_suite(hmac_drbg hmac_drbg.misc) add_test_suite(hmac_drbg hmac_drbg.no_reseed) add_test_suite(hmac_drbg hmac_drbg.nopr) diff --git a/tests/Makefile b/tests/Makefile index d85617fdc..e12780904 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -70,6 +70,7 @@ APPS = test_suite_aes.ecb$(EXEXT) test_suite_aes.cbc$(EXEXT) \ test_suite_gcm.aes192_en$(EXEXT) \ test_suite_gcm.aes256_en$(EXEXT) \ test_suite_gcm.camellia$(EXEXT) \ + test_suite_hkdf$(EXEXT) \ test_suite_hmac_drbg.misc$(EXEXT) \ test_suite_hmac_drbg.no_reseed$(EXEXT) \ test_suite_hmac_drbg.nopr$(EXEXT) \ @@ -177,6 +178,10 @@ test_suite_gcm.camellia.c : suites/test_suite_gcm.function suites/test_suite_gcm echo " Gen $@" perl scripts/generate_code.pl suites test_suite_gcm test_suite_gcm.camellia +test_suite_hkdf.c : suites/test_suite_hkdf.function suites/test_suite_hkdf.data scripts/generate_code.pl suites/helpers.function suites/main_test.function + echo " Gen $@" + perl scripts/generate_code.pl suites test_suite_hkdf test_suite_hkdf + test_suite_hmac_drbg.misc.c : suites/test_suite_hmac_drbg.function suites/test_suite_hmac_drbg.misc.data scripts/generate_code.pl suites/helpers.function suites/main_test.function echo " Gen $@" perl scripts/generate_code.pl suites test_suite_hmac_drbg test_suite_hmac_drbg.misc @@ -341,6 +346,10 @@ test_suite_gcm.camellia$(EXEXT): test_suite_gcm.camellia.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +test_suite_hkdf$(EXEXT): test_suite_hkdf.c $(DEP) + echo " CC $<" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + test_suite_hmac_drbg.misc$(EXEXT): test_suite_hmac_drbg.misc.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ diff --git a/tests/suites/test_suite_hkdf.data b/tests/suites/test_suite_hkdf.data new file mode 100644 index 000000000..b58ec93c3 --- /dev/null +++ b/tests/suites/test_suite_hkdf.data @@ -0,0 +1,27 @@ +HKDF RFC5869 Test Vector #1 +depends_on:MBEDTLS_SHA256_C +test_hkdf:6:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865" + +HKDF RFC5869 Test Vector #2 +depends_on:MBEDTLS_SHA256_C +test_hkdf:6:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87" + +HKDF RFC5869 Test Vector #3 +depends_on:MBEDTLS_SHA256_C +test_hkdf:6:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"":"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8" + +HKDF RFC5869 Test Vector #4 +depends_on:MBEDTLS_SHA1_C +test_hkdf:4:"0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":"085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896" + +HKDF RFC5869 Test Vector #5 +depends_on:MBEDTLS_SHA1_C +test_hkdf:4:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f":"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf":"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4" + +HKDF RFC5869 Test Vector #6 +depends_on:MBEDTLS_SHA1_C +test_hkdf:4:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"":"":"0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918" + +HKDF RFC5869 Test Vector #7 +depends_on:MBEDTLS_SHA1_C +test_hkdf:4:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"":"":"2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48" diff --git a/tests/suites/test_suite_hkdf.function b/tests/suites/test_suite_hkdf.function new file mode 100644 index 000000000..c6cd87026 --- /dev/null +++ b/tests/suites/test_suite_hkdf.function @@ -0,0 +1,39 @@ +/* BEGIN_HEADER */ +#include "mbedtls/hkdf.h" +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_HKDF_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE */ +void test_hkdf( int md_alg, char *hex_ikm_string, char *hex_salt_string, + char *hex_info_string, char *hex_okm_string ) +{ + int ret; + size_t ikm_len, salt_len, info_len, okm_len; + unsigned char ikm[1024] = { '\0' }; + unsigned char salt[1024] = { '\0' }; + unsigned char info[1024] = { '\0' }; + unsigned char expected_okm[1024] = { '\0' }; + unsigned char okm[1024] = { '\0' }; + unsigned char okm_string[1000] = { '\0' }; + + const mbedtls_md_info_t *md = mbedtls_md_info_from_type( md_alg ); + TEST_ASSERT( md != NULL ); + + ikm_len = unhexify( ikm, hex_ikm_string ); + salt_len = unhexify( salt, hex_salt_string ); + info_len = unhexify( info, hex_info_string ); + okm_len = unhexify( expected_okm, hex_okm_string ); + + ret = mbedtls_hkdf( md, salt, salt_len, ikm, ikm_len, info, info_len, okm, + okm_len); + TEST_ASSERT( ret == 0 ); + + // Run hexify on it so that it looks nicer if the assertion fails + hexify( okm_string, okm, okm_len ); + TEST_ASSERT( !strcmp( (char *)okm_string, hex_okm_string ) ); +} +/* END_CASE */ diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 802cce719..4c5c480c3 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -178,6 +178,7 @@ + @@ -248,6 +249,7 @@ +