[PATCH v7 0/9] add the support of sha256_hmac and sha256_hkdf

This serie adds the support of sha256_hmac and sha256_hkdf. A first version was sent several months ago just before the integration of mbedtls. This new version is based on mbedtls.
The first patch of this serie add the support of hkdf using mbedtls.
v7: - add missing reviewed-by
v6: - use const for test - set buffer to 0 before using to to compute hmac
v5: - use mbedtls to compute hmac - add tests for hkdf - enabled mbedtls in sandbox_defconfig - some cleanup
v4: - fix computation of the hmac - add more test for hmac - move sha256 common functions to sha256_common.c - some cleanup
v3: - also define sha256_hmac for legacy sha256 - add some #if to define function only when needed
Philippe Reynes (9): tools: kwbimage.h: use linux/compiler_attributes.h tools: renesas_spkgimage.h: use linux/compiler_attributes.h mbedtls: enable support of hkdf lib: sha256: move common function to sha256_common.c lib: sha256: add feature sha256_hmac test: lib: add test for sha256_hmac lib: mbedtls: sha256: add support of key derivation test: lib: add test for key derivation configs: sandbox: enable mbedtls
configs/sandbox_defconfig | 2 + include/u-boot/sha256.h | 24 +++ lib/Makefile | 1 + lib/mbedtls/Kconfig | 14 ++ lib/mbedtls/Makefile | 2 + lib/mbedtls/mbedtls_def_config.h | 4 + lib/mbedtls/sha256.c | 59 ++++--- lib/sha256.c | 67 ++++--- lib/sha256_common.c | 50 ++++++ test/lib/Makefile | 2 + test/lib/test_sha256_hkdf.c | 198 +++++++++++++++++++++ test/lib/test_sha256_hmac.c | 294 +++++++++++++++++++++++++++++++ tools/Makefile | 1 + tools/kwbimage.h | 6 +- tools/renesas_spkgimage.h | 6 +- 15 files changed, 670 insertions(+), 60 deletions(-) create mode 100644 lib/sha256_common.c create mode 100644 test/lib/test_sha256_hkdf.c create mode 100644 test/lib/test_sha256_hmac.c

The attribute __packed was defined in the file tools/kwbimage.h but this attribute is already defined in linux/compiler_attributes.h. So we include <linux/compiler_attributes.h.h> and do not define __packed.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- tools/kwbimage.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/tools/kwbimage.h b/tools/kwbimage.h index 505522332bd..e1fa2e4e215 100644 --- a/tools/kwbimage.h +++ b/tools/kwbimage.h @@ -11,11 +11,7 @@ #include <compiler.h> #include <stdint.h>
-#ifdef __GNUC__ -#define __packed __attribute((packed)) -#else -#define __packed -#endif +#include <linux/compiler_attributes.h>
#define KWBIMAGE_MAX_CONFIG ((0x1dc - 0x20)/sizeof(struct reg_config)) #define MAX_TEMPBUF_LEN 32

The attribute __packed was defined in the file tools/renesas_spkgimage.h but this attribute is already defined in linux/compiler_attributes.h. So we include <linux/compiler_attributes.h.h> and do not define __packed.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- tools/renesas_spkgimage.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/tools/renesas_spkgimage.h b/tools/renesas_spkgimage.h index 367e113de9d..83ec567b0d4 100644 --- a/tools/renesas_spkgimage.h +++ b/tools/renesas_spkgimage.h @@ -11,11 +11,7 @@ #ifndef _SPKGIMAGE_H_ #define _SPKGIMAGE_H_
-#ifdef __GNUC__ -#define __packed __attribute((packed)) -#else -#define __packed -#endif +#include <linux/compiler_attributes.h>
#define SPKG_HEADER_MARKER {'R', 'Z', 'N', '1'} #define SPKG_HEADER_SIZE 24

Adds the support of key derivation using the scheme hkdf.
Reviewed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- lib/mbedtls/Kconfig | 14 ++++++++++++++ lib/mbedtls/Makefile | 2 ++ lib/mbedtls/mbedtls_def_config.h | 4 ++++ 3 files changed, 20 insertions(+)
diff --git a/lib/mbedtls/Kconfig b/lib/mbedtls/Kconfig index 78167ffa252..aa82336ef14 100644 --- a/lib/mbedtls/Kconfig +++ b/lib/mbedtls/Kconfig @@ -297,6 +297,13 @@ config MD5_MBEDTLS This option enables support of hashing using MD5 algorithm with MbedTLS crypto library.
+config HKDF_MBEDTLS + bool "Enable HKDF support with MbedTLS crypto library" + depends on MBEDTLS_LIB_CRYPTO + help + This option enables support of key derivation using HKDF algorithm + with MbedTLS crypto library. + if SPL
config SPL_SHA1_MBEDTLS @@ -335,6 +342,13 @@ config SPL_MD5_MBEDTLS This option enables support of hashing using MD5 algorithm with MbedTLS crypto library.
+config SPL_HKDF_MBEDTLS + bool "Enable HKDF support in SPL with MbedTLS crypto library" + depends on MBEDTLS_LIB_CRYPTO + help + This option enables support of key derivation using HKDF algorithm + with MbedTLS crypto library. + endif # SPL
endif # MBEDTLS_LIB_CRYPTO diff --git a/lib/mbedtls/Makefile b/lib/mbedtls/Makefile index ce0a61e4054..e66c2018d97 100644 --- a/lib/mbedtls/Makefile +++ b/lib/mbedtls/Makefile @@ -33,6 +33,8 @@ mbedtls_lib_crypto-$(CONFIG_$(SPL_)SHA256_MBEDTLS) += \ $(MBEDTLS_LIB_DIR)/sha256.o mbedtls_lib_crypto-$(CONFIG_$(SPL_)SHA512_MBEDTLS) += \ $(MBEDTLS_LIB_DIR)/sha512.o +mbedtls_lib_crypto-$(CONFIG_$(SPL_)HKDF_MBEDTLS) += \ + $(MBEDTLS_LIB_DIR)/hkdf.o
# MbedTLS X509 library obj-$(CONFIG_MBEDTLS_LIB_X509) += mbedtls_lib_x509.o diff --git a/lib/mbedtls/mbedtls_def_config.h b/lib/mbedtls/mbedtls_def_config.h index 1d2314e90e4..fd440c392f9 100644 --- a/lib/mbedtls/mbedtls_def_config.h +++ b/lib/mbedtls/mbedtls_def_config.h @@ -56,6 +56,10 @@ #endif #endif
+#if CONFIG_IS_ENABLED(HKDF_MBEDTLS) +#define MBEDTLS_HKDF_C +#endif + #if defined CONFIG_MBEDTLS_LIB_X509
#if CONFIG_IS_ENABLED(X509_CERTIFICATE_PARSER)

The function sha256_csum_wd is defined in lib/sha256.c and in lib/mbedtls/sha256.c. To avoid duplicating this function (and future function), we move this function to the file lib/sha256_common.c
Reviewed-by: Raymond Mao raymond.mao@linaro.org Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- lib/Makefile | 1 + lib/mbedtls/sha256.c | 27 ------------------------ lib/sha256.c | 36 ------------------------------- lib/sha256_common.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ tools/Makefile | 1 + 5 files changed, 52 insertions(+), 63 deletions(-) create mode 100644 lib/sha256_common.c
diff --git a/lib/Makefile b/lib/Makefile index d24ed629732..17201f66798 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -77,6 +77,7 @@ obj-$(CONFIG_BLAKE2) += blake2/blake2b.o
obj-$(CONFIG_$(XPL_)MD5_LEGACY) += md5.o obj-$(CONFIG_$(XPL_)SHA1_LEGACY) += sha1.o +obj-$(CONFIG_$(XPL_)SHA256) += sha256_common.o obj-$(CONFIG_$(XPL_)SHA256_LEGACY) += sha256.o obj-$(CONFIG_$(XPL_)SHA512_LEGACY) += sha512.o
diff --git a/lib/mbedtls/sha256.c b/lib/mbedtls/sha256.c index 24aa58fa674..2128e598834 100644 --- a/lib/mbedtls/sha256.c +++ b/lib/mbedtls/sha256.c @@ -33,30 +33,3 @@ void sha256_finish(sha256_context *ctx, uint8_t digest[SHA256_SUM_LEN]) mbedtls_sha256_finish(ctx, digest); mbedtls_sha256_free(ctx); } - -void sha256_csum_wd(const unsigned char *input, unsigned int ilen, - unsigned char *output, unsigned int chunk_sz) -{ - sha256_context ctx; - - sha256_starts(&ctx); - - if (IS_ENABLED(CONFIG_HW_WATCHDOG) || IS_ENABLED(CONFIG_WATCHDOG)) { - const unsigned char *curr = input; - const unsigned char *end = input + ilen; - int chunk; - - while (curr < end) { - chunk = end - curr; - if (chunk > chunk_sz) - chunk = chunk_sz; - sha256_update(&ctx, curr, chunk); - curr += chunk; - schedule(); - } - } else { - sha256_update(&ctx, input, ilen); - } - - sha256_finish(&ctx, output); -} diff --git a/lib/sha256.c b/lib/sha256.c index fb195d988f1..827bd9a872b 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -264,39 +264,3 @@ void sha256_finish(sha256_context * ctx, uint8_t digest[32]) PUT_UINT32_BE(ctx->state[6], digest, 24); PUT_UINT32_BE(ctx->state[7], digest, 28); } - -/* - * Output = SHA-256( input buffer ). Trigger the watchdog every 'chunk_sz' - * bytes of input processed. - */ -void sha256_csum_wd(const unsigned char *input, unsigned int ilen, - unsigned char *output, unsigned int chunk_sz) -{ - sha256_context ctx; -#if !defined(USE_HOSTCC) && \ - (defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)) - const unsigned char *end; - unsigned char *curr; - int chunk; -#endif - - sha256_starts(&ctx); - -#if !defined(USE_HOSTCC) && \ - (defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)) - curr = (unsigned char *)input; - end = input + ilen; - while (curr < end) { - chunk = end - curr; - if (chunk > chunk_sz) - chunk = chunk_sz; - sha256_update(&ctx, curr, chunk); - curr += chunk; - schedule(); - } -#else - sha256_update(&ctx, input, ilen); -#endif - - sha256_finish(&ctx, output); -} diff --git a/lib/sha256_common.c b/lib/sha256_common.c new file mode 100644 index 00000000000..7041abd26d9 --- /dev/null +++ b/lib/sha256_common.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * FIPS-180-2 compliant SHA-256 implementation + * + * Copyright (C) 2001-2003 Christophe Devine + */ + +#ifndef USE_HOSTCC +#include <u-boot/schedule.h> +#endif /* USE_HOSTCC */ +#include <string.h> +#include <u-boot/sha256.h> + +#include <linux/compiler_attributes.h> + +/* + * Output = SHA-256( input buffer ). Trigger the watchdog every 'chunk_sz' + * bytes of input processed. + */ +void sha256_csum_wd(const unsigned char *input, unsigned int ilen, + unsigned char *output, unsigned int chunk_sz) +{ + sha256_context ctx; +#if !defined(USE_HOSTCC) && \ + (defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)) + const unsigned char *end; + unsigned char *curr; + int chunk; +#endif + + sha256_starts(&ctx); + +#if !defined(USE_HOSTCC) && \ + (defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)) + curr = (unsigned char *)input; + end = input + ilen; + while (curr < end) { + chunk = end - curr; + if (chunk > chunk_sz) + chunk = chunk_sz; + sha256_update(&ctx, curr, chunk); + curr += chunk; + schedule(); + } +#else + sha256_update(&ctx, input, ilen); +#endif + + sha256_finish(&ctx, output); +} diff --git a/tools/Makefile b/tools/Makefile index ee08a9675df..237fa900a24 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -135,6 +135,7 @@ dumpimage-mkimage-objs := aisimage.o \ generated/lib/hash-checksum.o \ generated/lib/sha1.o \ generated/lib/sha256.o \ + generated/lib/sha256_common.o \ generated/lib/sha512.o \ generated/common/hash.o \ ublimage.o \

Adds the support of the hmac based on sha256. This implementation is based on rfc2104.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- include/u-boot/sha256.h | 4 ++++ lib/mbedtls/sha256.c | 15 ++++++++++++ lib/sha256.c | 51 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+)
diff --git a/include/u-boot/sha256.h b/include/u-boot/sha256.h index 44a9b528b48..99cf78e204c 100644 --- a/include/u-boot/sha256.h +++ b/include/u-boot/sha256.h @@ -45,4 +45,8 @@ void sha256_finish(sha256_context * ctx, uint8_t digest[SHA256_SUM_LEN]); void sha256_csum_wd(const unsigned char *input, unsigned int ilen, unsigned char *output, unsigned int chunk_sz);
+int sha256_hmac(const unsigned char *key, int keylen, + const unsigned char *input, unsigned int ilen, + unsigned char *output); + #endif /* _SHA256_H */ diff --git a/lib/mbedtls/sha256.c b/lib/mbedtls/sha256.c index 2128e598834..7d456a82017 100644 --- a/lib/mbedtls/sha256.c +++ b/lib/mbedtls/sha256.c @@ -10,6 +10,8 @@ #endif /* USE_HOSTCC */ #include <u-boot/sha256.h>
+#include <mbedtls/md.h> + const u8 sha256_der_prefix[SHA256_DER_LEN] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, @@ -33,3 +35,16 @@ void sha256_finish(sha256_context *ctx, uint8_t digest[SHA256_SUM_LEN]) mbedtls_sha256_finish(ctx, digest); mbedtls_sha256_free(ctx); } + +int sha256_hmac(const unsigned char *key, int keylen, + const unsigned char *input, unsigned int ilen, + unsigned char *output) +{ + const mbedtls_md_info_t *md; + + md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); + if (!md) + return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE; + + return mbedtls_md_hmac(md, key, keylen, input, ilen, output); +} diff --git a/lib/sha256.c b/lib/sha256.c index 827bd9a872b..c2e77c854b9 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -264,3 +264,54 @@ void sha256_finish(sha256_context * ctx, uint8_t digest[32]) PUT_UINT32_BE(ctx->state[6], digest, 24); PUT_UINT32_BE(ctx->state[7], digest, 28); } + +int sha256_hmac(const unsigned char *key, int keylen, + const unsigned char *input, unsigned int ilen, + unsigned char *output) +{ + int i; + sha256_context ctx; + unsigned char keybuf[64]; + unsigned char k_ipad[64]; + unsigned char k_opad[64]; + unsigned char tmpbuf[32]; + int keybuf_len; + + if (keylen > 64) { + sha256_starts(&ctx); + sha256_update(&ctx, key, keylen); + sha256_finish(&ctx, keybuf); + + keybuf_len = 32; + } else { + memset(keybuf, 0, sizeof(keybuf)); + memcpy(keybuf, key, keylen); + keybuf_len = keylen; + } + + memset(k_ipad, 0x36, 64); + memset(k_opad, 0x5C, 64); + + for (i = 0; i < keybuf_len; i++) { + k_ipad[i] ^= keybuf[i]; + k_opad[i] ^= keybuf[i]; + } + + sha256_starts(&ctx); + sha256_update(&ctx, k_ipad, sizeof(k_ipad)); + sha256_update(&ctx, input, ilen); + sha256_finish(&ctx, tmpbuf); + + sha256_starts(&ctx); + sha256_update(&ctx, k_opad, sizeof(k_opad)); + sha256_update(&ctx, tmpbuf, sizeof(tmpbuf)); + sha256_finish(&ctx, output); + + memset(k_ipad, 0, sizeof(k_ipad)); + memset(k_opad, 0, sizeof(k_opad)); + memset(tmpbuf, 0, sizeof(tmpbuf)); + memset(keybuf, 0, sizeof(keybuf)); + memset(&ctx, 0, sizeof(sha256_context)); + + return 0; +}

Hi Philippe,
On Thu, 19 Dec 2024 at 08:06, Philippe Reynes < philippe.reynes@softathome.com> wrote:
Adds the support of the hmac based on sha256. This implementation is based on rfc2104.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
include/u-boot/sha256.h | 4 ++++ lib/mbedtls/sha256.c | 15 ++++++++++++ lib/sha256.c | 51 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+)
diff --git a/include/u-boot/sha256.h b/include/u-boot/sha256.h index 44a9b528b48..99cf78e204c 100644 --- a/include/u-boot/sha256.h +++ b/include/u-boot/sha256.h @@ -45,4 +45,8 @@ void sha256_finish(sha256_context * ctx, uint8_t digest[SHA256_SUM_LEN]); void sha256_csum_wd(const unsigned char *input, unsigned int ilen, unsigned char *output, unsigned int chunk_sz);
+int sha256_hmac(const unsigned char *key, int keylen,
const unsigned char *input, unsigned int ilen,
unsigned char *output);
#endif /* _SHA256_H */ diff --git a/lib/mbedtls/sha256.c b/lib/mbedtls/sha256.c index 2128e598834..7d456a82017 100644 --- a/lib/mbedtls/sha256.c +++ b/lib/mbedtls/sha256.c @@ -10,6 +10,8 @@ #endif /* USE_HOSTCC */ #include <u-boot/sha256.h>
+#include <mbedtls/md.h>
const u8 sha256_der_prefix[SHA256_DER_LEN] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, @@ -33,3 +35,16 @@ void sha256_finish(sha256_context *ctx, uint8_t digest[SHA256_SUM_LEN]) mbedtls_sha256_finish(ctx, digest); mbedtls_sha256_free(ctx); }
+int sha256_hmac(const unsigned char *key, int keylen,
const unsigned char *input, unsigned int ilen,
unsigned char *output)
+{
const mbedtls_md_info_t *md;
md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
if (!md)
return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
return mbedtls_md_hmac(md, key, keylen, input, ilen, output);
+} diff --git a/lib/sha256.c b/lib/sha256.c index 827bd9a872b..c2e77c854b9 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -264,3 +264,54 @@ void sha256_finish(sha256_context * ctx, uint8_t digest[32]) PUT_UINT32_BE(ctx->state[6], digest, 24); PUT_UINT32_BE(ctx->state[7], digest, 28); }
+int sha256_hmac(const unsigned char *key, int keylen,
const unsigned char *input, unsigned int ilen,
unsigned char *output)
+{
int i;
sha256_context ctx;
unsigned char keybuf[64];
unsigned char k_ipad[64];
unsigned char k_opad[64];
unsigned char tmpbuf[32];
int keybuf_len;
if (keylen > 64) {
sha256_starts(&ctx);
sha256_update(&ctx, key, keylen);
sha256_finish(&ctx, keybuf);
keybuf_len = 32;
} else {
memset(keybuf, 0, sizeof(keybuf));
memcpy(keybuf, key, keylen);
keybuf_len = keylen;
}
memset(k_ipad, 0x36, 64);
memset(k_opad, 0x5C, 64);
for (i = 0; i < keybuf_len; i++) {
k_ipad[i] ^= keybuf[i];
k_opad[i] ^= keybuf[i];
}
sha256_starts(&ctx);
sha256_update(&ctx, k_ipad, sizeof(k_ipad));
sha256_update(&ctx, input, ilen);
sha256_finish(&ctx, tmpbuf);
sha256_starts(&ctx);
sha256_update(&ctx, k_opad, sizeof(k_opad));
sha256_update(&ctx, tmpbuf, sizeof(tmpbuf));
sha256_finish(&ctx, output);
memset(k_ipad, 0, sizeof(k_ipad));
memset(k_opad, 0, sizeof(k_opad));
memset(tmpbuf, 0, sizeof(tmpbuf));
memset(keybuf, 0, sizeof(keybuf));
memset(&ctx, 0, sizeof(sha256_context));
return 0;
+}
2.25.1
Sounds good to me. Reviewed-by: Raymond Mao raymond.mao@linaro.org
Regards, Raymond

Adds a test for the function sha256_hmac
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- test/lib/Makefile | 1 + test/lib/test_sha256_hmac.c | 294 ++++++++++++++++++++++++++++++++++++ 2 files changed, 295 insertions(+) create mode 100644 test/lib/test_sha256_hmac.c
diff --git a/test/lib/Makefile b/test/lib/Makefile index f516d001747..4c0abcba81a 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_ERRNO_STR) += test_errno_str.o obj-$(CONFIG_UT_LIB_ASN1) += asn1.o obj-$(CONFIG_UT_LIB_RSA) += rsa.o obj-$(CONFIG_AES) += test_aes.o +obj-$(CONFIG_SHA256) += test_sha256_hmac.o obj-$(CONFIG_GETOPT) += getopt.o obj-$(CONFIG_CRC8) += test_crc8.o obj-$(CONFIG_UT_LIB_CRYPT) += test_crypt.o diff --git a/test/lib/test_sha256_hmac.c b/test/lib/test_sha256_hmac.c new file mode 100644 index 00000000000..5279dd78e0f --- /dev/null +++ b/test/lib/test_sha256_hmac.c @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2024 Philippe Reynes philippe.reynes@softathome.com + * + * Unit tests for sha256_hmac functions + */ + +#include <command.h> +#include <test/lib.h> +#include <test/test.h> +#include <test/ut.h> +#include <u-boot/sha256.h> + +struct test_sha256_hmac_s { + const unsigned char *key; + int keylen; + const unsigned char *input; + int ilen; + const unsigned char *expected; + int elen; +}; + +/* + * data comes from: + * https://datatracker.ietf.org/doc/html/rfc4231 + */ +static unsigned char key_test1[] = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; + +static unsigned char input_test1[] = { + 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 }; + +static unsigned char expected_test1[] = { + 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, + 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, + 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, + 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 }; + +static unsigned char key_test2[] = { 0x4a, 0x65, 0x66, 0x65 }; + +static unsigned char input_test2[] = { + 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, + 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68, + 0x69, 0x6e, 0x67, 0x3f }; + +static unsigned char expected_test2[] = { + 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, + 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, + 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, + 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 }; + +static unsigned char key_test3[] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa }; + +static unsigned char input_test3[] = { + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd }; + +static unsigned char expected_test3[] = { + 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, + 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7, + 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22, + 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe }; + +static unsigned char key_test4[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, +}; + +static unsigned char input_test4[] = { + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, +}; + +static unsigned char expected_test4[] = { + 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e, + 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a, + 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07, + 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b, +}; + +static unsigned char key_test5[] = { + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, +}; + +static unsigned char input_test5[] = { + 0x54, 0x65, 0x73, 0x74, 0x20, 0x57, 0x69, 0x74, + 0x68, 0x20, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, +}; + +static unsigned char expected_test5[] = { + 0xa3, 0xb6, 0x16, 0x74, 0x73, 0x10, 0x0e, 0xe0, + 0x6e, 0x0c, 0x79, 0x6c, 0x29, 0x55, 0x55, 0x2b, +}; + +static unsigned char key_test6[] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa }; + +static unsigned char input_test6[] = { + 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69, + 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, + 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a, + 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20, + 0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79, + 0x20, 0x46, 0x69, 0x72, 0x73, 0x74 }; + +static unsigned char expected_test6[] = { + 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, + 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, + 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, + 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 }; + +static unsigned char key_test7[] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, +}; + +static unsigned char input_test7[] = { + 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x75, + 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c, + 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68, + 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6b, 0x65, + 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20, + 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, + 0x68, 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65, + 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6e, 0x65, 0x65, + 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, + 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, + 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62, + 0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65, + 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x61, 0x6c, + 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e, +}; + +static unsigned char expected_test7[] = { + 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, + 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, + 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, + 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2, +}; + +static struct test_sha256_hmac_s test_sha256_hmac[] = { + { + .key = key_test1, + .keylen = sizeof(key_test1), + .input = input_test1, + .ilen = sizeof(input_test1), + .expected = expected_test1, + .elen = sizeof(expected_test1), + }, + { + .key = key_test2, + .keylen = sizeof(key_test2), + .input = input_test2, + .ilen = sizeof(input_test2), + .expected = expected_test2, + .elen = sizeof(expected_test2), + }, + { + .key = key_test3, + .keylen = sizeof(key_test3), + .input = input_test3, + .ilen = sizeof(input_test3), + .expected = expected_test3, + .elen = sizeof(expected_test3), + }, + { + .key = key_test4, + .keylen = sizeof(key_test4), + .input = input_test4, + .ilen = sizeof(input_test4), + .expected = expected_test4, + .elen = sizeof(expected_test4), + }, + { + .key = key_test5, + .keylen = sizeof(key_test5), + .input = input_test5, + .ilen = sizeof(input_test5), + .expected = expected_test5, + .elen = sizeof(expected_test5), + }, + { + .key = key_test6, + .keylen = sizeof(key_test6), + .input = input_test6, + .ilen = sizeof(input_test6), + .expected = expected_test6, + .elen = sizeof(expected_test6), + }, + { + .key = key_test7, + .keylen = sizeof(key_test7), + .input = input_test7, + .ilen = sizeof(input_test7), + .expected = expected_test7, + .elen = sizeof(expected_test7), + }, +}; + +static int _lib_test_sha256_hmac_run(struct unit_test_state *uts, + const unsigned char *key, int keylen, + const unsigned char *input, int ilen, + const unsigned char *expected, int elen) +{ + unsigned char output[SHA256_SUM_LEN]; + int ret; + + ut_assert(elen <= sizeof(output)); + ret = sha256_hmac(key, keylen, input, ilen, output); + ut_assert(!ret); + ut_asserteq_mem(expected, output, elen); + + return 0; +} + +static int lib_test_sha256_hmac_run(struct unit_test_state *uts, + struct test_sha256_hmac_s *test) +{ + return _lib_test_sha256_hmac_run(uts, test->key, test->keylen, + test->input, test->ilen, + test->expected, test->elen); +} + +static int lib_test_sha256_hmac(struct unit_test_state *uts) +{ + int i, ret = 0; + + for (i = 0; i < ARRAY_SIZE(test_sha256_hmac); i++) { + ret = lib_test_sha256_hmac_run(uts, &test_sha256_hmac[i]); + if (ret) + return ret; + } + + return 0; +} + +LIB_TEST(lib_test_sha256_hmac, 0);

Hi Philippe,
On Thu, 19 Dec 2024 at 08:05, Philippe Reynes < philippe.reynes@softathome.com> wrote:
Adds a test for the function sha256_hmac
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
test/lib/Makefile | 1 + test/lib/test_sha256_hmac.c | 294 ++++++++++++++++++++++++++++++++++++ 2 files changed, 295 insertions(+) create mode 100644 test/lib/test_sha256_hmac.c
diff --git a/test/lib/Makefile b/test/lib/Makefile index f516d001747..4c0abcba81a 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_ERRNO_STR) += test_errno_str.o obj-$(CONFIG_UT_LIB_ASN1) += asn1.o obj-$(CONFIG_UT_LIB_RSA) += rsa.o obj-$(CONFIG_AES) += test_aes.o +obj-$(CONFIG_SHA256) += test_sha256_hmac.o obj-$(CONFIG_GETOPT) += getopt.o obj-$(CONFIG_CRC8) += test_crc8.o obj-$(CONFIG_UT_LIB_CRYPT) += test_crypt.o diff --git a/test/lib/test_sha256_hmac.c b/test/lib/test_sha256_hmac.c new file mode 100644 index 00000000000..5279dd78e0f --- /dev/null +++ b/test/lib/test_sha256_hmac.c @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (c) 2024 Philippe Reynes philippe.reynes@softathome.com
- Unit tests for sha256_hmac functions
- */
+#include <command.h> +#include <test/lib.h> +#include <test/test.h> +#include <test/ut.h> +#include <u-boot/sha256.h>
+struct test_sha256_hmac_s {
const unsigned char *key;
int keylen;
const unsigned char *input;
int ilen;
const unsigned char *expected;
int elen;
+};
+/*
- data comes from:
- */
+static unsigned char key_test1[] = {
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
+static unsigned char input_test1[] = {
0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 };
+static unsigned char expected_test1[] = {
0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 };
+static unsigned char key_test2[] = { 0x4a, 0x65, 0x66, 0x65 };
+static unsigned char input_test2[] = {
0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
0x69, 0x6e, 0x67, 0x3f };
+static unsigned char expected_test2[] = {
0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 };
+static unsigned char key_test3[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa };
+static unsigned char input_test3[] = {
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd };
+static unsigned char expected_test3[] = {
0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe };
+static unsigned char key_test4[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19,
+};
+static unsigned char input_test4[] = {
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd,
+};
+static unsigned char expected_test4[] = {
0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e,
0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b,
+};
+static unsigned char key_test5[] = {
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c,
+};
+static unsigned char input_test5[] = {
0x54, 0x65, 0x73, 0x74, 0x20, 0x57, 0x69, 0x74,
0x68, 0x20, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61,
0x74, 0x69, 0x6f, 0x6e,
+};
+static unsigned char expected_test5[] = {
0xa3, 0xb6, 0x16, 0x74, 0x73, 0x10, 0x0e, 0xe0,
0x6e, 0x0c, 0x79, 0x6c, 0x29, 0x55, 0x55, 0x2b,
+};
+static unsigned char key_test6[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa };
+static unsigned char input_test6[] = {
0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20,
0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79,
0x20, 0x46, 0x69, 0x72, 0x73, 0x74 };
+static unsigned char expected_test6[] = {
0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 };
+static unsigned char key_test7[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa,
+};
+static unsigned char input_test7[] = {
0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x75,
0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c,
0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68,
0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6b, 0x65,
0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20,
0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74,
0x68, 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63,
0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x64,
0x61, 0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65,
0x20, 0x6b, 0x65, 0x79, 0x20, 0x6e, 0x65, 0x65,
0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65,
0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20,
0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62,
0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65,
0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65,
0x20, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x61, 0x6c,
0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e,
+};
+static unsigned char expected_test7[] = {
0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb,
0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2,
+};
+static struct test_sha256_hmac_s test_sha256_hmac[] = {
{
.key = key_test1,
.keylen = sizeof(key_test1),
.input = input_test1,
.ilen = sizeof(input_test1),
.expected = expected_test1,
.elen = sizeof(expected_test1),
},
{
.key = key_test2,
.keylen = sizeof(key_test2),
.input = input_test2,
.ilen = sizeof(input_test2),
.expected = expected_test2,
.elen = sizeof(expected_test2),
},
{
.key = key_test3,
.keylen = sizeof(key_test3),
.input = input_test3,
.ilen = sizeof(input_test3),
.expected = expected_test3,
.elen = sizeof(expected_test3),
},
{
.key = key_test4,
.keylen = sizeof(key_test4),
.input = input_test4,
.ilen = sizeof(input_test4),
.expected = expected_test4,
.elen = sizeof(expected_test4),
},
{
.key = key_test5,
.keylen = sizeof(key_test5),
.input = input_test5,
.ilen = sizeof(input_test5),
.expected = expected_test5,
.elen = sizeof(expected_test5),
},
{
.key = key_test6,
.keylen = sizeof(key_test6),
.input = input_test6,
.ilen = sizeof(input_test6),
.expected = expected_test6,
.elen = sizeof(expected_test6),
},
{
.key = key_test7,
.keylen = sizeof(key_test7),
.input = input_test7,
.ilen = sizeof(input_test7),
.expected = expected_test7,
.elen = sizeof(expected_test7),
},
+};
+static int _lib_test_sha256_hmac_run(struct unit_test_state *uts,
const unsigned char *key, int keylen,
const unsigned char *input, int ilen,
const unsigned char *expected, int
elen) +{
unsigned char output[SHA256_SUM_LEN];
int ret;
ut_assert(elen <= sizeof(output));
ret = sha256_hmac(key, keylen, input, ilen, output);
ut_assert(!ret);
ut_asserteq_mem(expected, output, elen);
return 0;
+}
+static int lib_test_sha256_hmac_run(struct unit_test_state *uts,
struct test_sha256_hmac_s *test)
+{
return _lib_test_sha256_hmac_run(uts, test->key, test->keylen,
test->input, test->ilen,
test->expected, test->elen);
+}
+static int lib_test_sha256_hmac(struct unit_test_state *uts) +{
int i, ret = 0;
for (i = 0; i < ARRAY_SIZE(test_sha256_hmac); i++) {
ret = lib_test_sha256_hmac_run(uts, &test_sha256_hmac[i]);
if (ret)
return ret;
}
return 0;
+}
+LIB_TEST(lib_test_sha256_hmac, 0);
2.25.1
Sounds good to me. Reviewed-by: Raymond Mao raymond.mao@linaro.org
Regards, Raymond

Adds the support of key derivation using the scheme hkdf. This scheme is defined in rfc5869.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- include/u-boot/sha256.h | 20 ++++++++++++++++++++ lib/mbedtls/sha256.c | 23 +++++++++++++++++++++++ 2 files changed, 43 insertions(+)
diff --git a/include/u-boot/sha256.h b/include/u-boot/sha256.h index 99cf78e204c..d7a3403270b 100644 --- a/include/u-boot/sha256.h +++ b/include/u-boot/sha256.h @@ -1,6 +1,8 @@ #ifndef _SHA256_H #define _SHA256_H
+#include <linux/compiler_attributes.h> +#include <linux/errno.h> #include <linux/kconfig.h> #include <linux/types.h>
@@ -49,4 +51,22 @@ int sha256_hmac(const unsigned char *key, int keylen, const unsigned char *input, unsigned int ilen, unsigned char *output);
+#if CONFIG_IS_ENABLED(HKDF_MBEDTLS) +int sha256_hkdf(const unsigned char *salt, int saltlen, + const unsigned char *ikm, int ikmlen, + const unsigned char *info, int infolen, + unsigned char *output, int outputlen); +#else +static inline int sha256_hkdf(const unsigned char __always_unused *salt, + int __always_unused saltlen, + const unsigned char __always_unused *ikm, + int __always_unused ikmlen, + const unsigned char __always_unused *info, + int __always_unused infolen, + unsigned char __always_unused *output, + int __always_unused outputlen) { + return -EOPNOTSUPP; +} +#endif + #endif /* _SHA256_H */ diff --git a/lib/mbedtls/sha256.c b/lib/mbedtls/sha256.c index 7d456a82017..59edcb517df 100644 --- a/lib/mbedtls/sha256.c +++ b/lib/mbedtls/sha256.c @@ -12,6 +12,10 @@
#include <mbedtls/md.h>
+#if CONFIG_IS_ENABLED(HKDF_MBEDTLS) +#include <mbedtls/hkdf.h> +#endif + const u8 sha256_der_prefix[SHA256_DER_LEN] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, @@ -48,3 +52,22 @@ int sha256_hmac(const unsigned char *key, int keylen,
return mbedtls_md_hmac(md, key, keylen, input, ilen, output); } + +#if CONFIG_IS_ENABLED(HKDF_MBEDTLS) +int sha256_hkdf(const unsigned char *salt, int saltlen, + const unsigned char *ikm, int ikmlen, + const unsigned char *info, int infolen, + unsigned char *output, int outputlen) +{ + const mbedtls_md_info_t *md; + + md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); + if (!md) + return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE; + + return mbedtls_hkdf(md, salt, saltlen, + ikm, ikmlen, + info, infolen, + output, outputlen); +} +#endif

Hi Philippe,
On Thu, 19 Dec 2024 at 08:05, Philippe Reynes < philippe.reynes@softathome.com> wrote:
Adds the support of key derivation using the scheme hkdf. This scheme is defined in rfc5869.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
include/u-boot/sha256.h | 20 ++++++++++++++++++++ lib/mbedtls/sha256.c | 23 +++++++++++++++++++++++ 2 files changed, 43 insertions(+)
diff --git a/include/u-boot/sha256.h b/include/u-boot/sha256.h index 99cf78e204c..d7a3403270b 100644 --- a/include/u-boot/sha256.h +++ b/include/u-boot/sha256.h @@ -1,6 +1,8 @@ #ifndef _SHA256_H #define _SHA256_H
+#include <linux/compiler_attributes.h> +#include <linux/errno.h> #include <linux/kconfig.h> #include <linux/types.h>
@@ -49,4 +51,22 @@ int sha256_hmac(const unsigned char *key, int keylen, const unsigned char *input, unsigned int ilen, unsigned char *output);
+#if CONFIG_IS_ENABLED(HKDF_MBEDTLS) +int sha256_hkdf(const unsigned char *salt, int saltlen,
const unsigned char *ikm, int ikmlen,
const unsigned char *info, int infolen,
unsigned char *output, int outputlen);
+#else +static inline int sha256_hkdf(const unsigned char __always_unused *salt,
int __always_unused saltlen,
const unsigned char __always_unused *ikm,
int __always_unused ikmlen,
const unsigned char __always_unused *info,
int __always_unused infolen,
unsigned char __always_unused *output,
int __always_unused outputlen) {
return -EOPNOTSUPP;
+} +#endif
#endif /* _SHA256_H */ diff --git a/lib/mbedtls/sha256.c b/lib/mbedtls/sha256.c index 7d456a82017..59edcb517df 100644 --- a/lib/mbedtls/sha256.c +++ b/lib/mbedtls/sha256.c @@ -12,6 +12,10 @@
#include <mbedtls/md.h>
+#if CONFIG_IS_ENABLED(HKDF_MBEDTLS) +#include <mbedtls/hkdf.h> +#endif
const u8 sha256_der_prefix[SHA256_DER_LEN] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, @@ -48,3 +52,22 @@ int sha256_hmac(const unsigned char *key, int keylen,
return mbedtls_md_hmac(md, key, keylen, input, ilen, output);
}
+#if CONFIG_IS_ENABLED(HKDF_MBEDTLS) +int sha256_hkdf(const unsigned char *salt, int saltlen,
const unsigned char *ikm, int ikmlen,
const unsigned char *info, int infolen,
unsigned char *output, int outputlen)
+{
const mbedtls_md_info_t *md;
md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
if (!md)
return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
return mbedtls_hkdf(md, salt, saltlen,
ikm, ikmlen,
info, infolen,
output, outputlen);
+}
+#endif
2.25.1
Sounds good to me. Reviewed-by: Raymond Mao raymond.mao@linaro.org
Regards, Raymond

Adds a test for the function sha256_hkdf.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- test/lib/Makefile | 1 + test/lib/test_sha256_hkdf.c | 198 ++++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 test/lib/test_sha256_hkdf.c
diff --git a/test/lib/Makefile b/test/lib/Makefile index 4c0abcba81a..24ce6ed8f00 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_UT_LIB_ASN1) += asn1.o obj-$(CONFIG_UT_LIB_RSA) += rsa.o obj-$(CONFIG_AES) += test_aes.o obj-$(CONFIG_SHA256) += test_sha256_hmac.o +obj-$(CONFIG_HKDF_MBEDTLS) += test_sha256_hkdf.o obj-$(CONFIG_GETOPT) += getopt.o obj-$(CONFIG_CRC8) += test_crc8.o obj-$(CONFIG_UT_LIB_CRYPT) += test_crypt.o diff --git a/test/lib/test_sha256_hkdf.c b/test/lib/test_sha256_hkdf.c new file mode 100644 index 00000000000..5277b44eba5 --- /dev/null +++ b/test/lib/test_sha256_hkdf.c @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2024 Philippe Reynes philippe.reynes@softathome.com + * + * Unit tests for sha256_hkdf functions + */ + +#include <command.h> +#include <test/lib.h> +#include <test/test.h> +#include <test/ut.h> +#include <u-boot/sha256.h> + +struct test_sha256_hkdf_s { + const unsigned char *salt; + int saltlen; + const unsigned char *ikm; + int ikmlen; + const unsigned char *info; + int infolen; + const unsigned char *expected; + int expectedlen; +}; + +/* + * data comes from: + * https://www.rfc-editor.org/rfc/rfc5869 + */ +static unsigned char salt_test1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c }; + +static unsigned char ikm_test1[] = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b +}; + +static unsigned char info_test1[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 +}; + +static unsigned char expected_test1[] = { + 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, + 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, + 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, + 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, + 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, + 0x58, 0x65 +}; + +static unsigned char salt_test2[] = { + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, +}; + +static unsigned char ikm_test2[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, +}; + +static unsigned char info_test2[] = { + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +static unsigned char expected_test2[] = { + 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, + 0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34, + 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8, + 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c, + 0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72, + 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09, + 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8, + 0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71, + 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87, + 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f, + 0x1d, 0x87, +}; + +static unsigned char salt_test3[] = { +}; + +static unsigned char ikm_test3[] = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, +}; + +static unsigned char info_test3[] = { +}; + +static unsigned char expected_test3[] = { + 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, + 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31, + 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e, + 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, + 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a, + 0x96, 0xc8, +}; + +static struct test_sha256_hkdf_s test_sha256_hkdf[] = { + { + .salt = salt_test1, + .saltlen = sizeof(salt_test1), + .ikm = ikm_test1, + .ikmlen = sizeof(ikm_test1), + .info = info_test1, + .infolen = sizeof(info_test1), + .expected = expected_test1, + .expectedlen = sizeof(expected_test1), + }, + { + .salt = salt_test2, + .saltlen = sizeof(salt_test2), + .ikm = ikm_test2, + .ikmlen = sizeof(ikm_test2), + .info = info_test2, + .infolen = sizeof(info_test2), + .expected = expected_test2, + .expectedlen = sizeof(expected_test2), + }, + { + .salt = salt_test3, + .saltlen = sizeof(salt_test3), + .ikm = ikm_test3, + .ikmlen = sizeof(ikm_test3), + .info = info_test3, + .infolen = sizeof(info_test3), + .expected = expected_test3, + .expectedlen = sizeof(expected_test3), + }, +}; + +static int _lib_test_sha256_hkdf_run(struct unit_test_state *uts, + const unsigned char *salt, int saltlen, + const unsigned char *ikm, int ikmlen, + const unsigned char *info, int infolen, + const unsigned char *expected, + int expectedlen) +{ + unsigned char output[256]; + int ret; + + ut_assert(expectedlen <= sizeof(output)); + ret = sha256_hkdf(salt, saltlen, ikm, ikmlen, info, infolen, output, expectedlen); + ut_assert(!ret); + ut_asserteq_mem(expected, output, expectedlen); + + return 0; +} + +static int lib_test_sha256_hkdf_run(struct unit_test_state *uts, + struct test_sha256_hkdf_s *test) +{ + return _lib_test_sha256_hkdf_run(uts, test->salt, test->saltlen, + test->ikm, test->ikmlen, + test->info, test->infolen, + test->expected, test->expectedlen); +} + +static int lib_test_sha256_hkdf(struct unit_test_state *uts) +{ + int i, ret = 0; + + for (i = 0; i < ARRAY_SIZE(test_sha256_hkdf); i++) { + ret = lib_test_sha256_hkdf_run(uts, &test_sha256_hkdf[i]); + if (ret) + return ret; + } + + return 0; +} + +LIB_TEST(lib_test_sha256_hkdf, 0);

Hi Philippe,
On Thu, 19 Dec 2024 at 08:06, Philippe Reynes < philippe.reynes@softathome.com> wrote:
Adds a test for the function sha256_hkdf.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
test/lib/Makefile | 1 + test/lib/test_sha256_hkdf.c | 198 ++++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 test/lib/test_sha256_hkdf.c
diff --git a/test/lib/Makefile b/test/lib/Makefile index 4c0abcba81a..24ce6ed8f00 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_UT_LIB_ASN1) += asn1.o obj-$(CONFIG_UT_LIB_RSA) += rsa.o obj-$(CONFIG_AES) += test_aes.o obj-$(CONFIG_SHA256) += test_sha256_hmac.o +obj-$(CONFIG_HKDF_MBEDTLS) += test_sha256_hkdf.o obj-$(CONFIG_GETOPT) += getopt.o obj-$(CONFIG_CRC8) += test_crc8.o obj-$(CONFIG_UT_LIB_CRYPT) += test_crypt.o diff --git a/test/lib/test_sha256_hkdf.c b/test/lib/test_sha256_hkdf.c new file mode 100644 index 00000000000..5277b44eba5 --- /dev/null +++ b/test/lib/test_sha256_hkdf.c @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (c) 2024 Philippe Reynes philippe.reynes@softathome.com
- Unit tests for sha256_hkdf functions
- */
+#include <command.h> +#include <test/lib.h> +#include <test/test.h> +#include <test/ut.h> +#include <u-boot/sha256.h>
+struct test_sha256_hkdf_s {
const unsigned char *salt;
int saltlen;
const unsigned char *ikm;
int ikmlen;
const unsigned char *info;
int infolen;
const unsigned char *expected;
int expectedlen;
+};
+/*
- data comes from:
- */
+static unsigned char salt_test1[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c };
+static unsigned char ikm_test1[] = {
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
+};
+static unsigned char info_test1[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9
+};
+static unsigned char expected_test1[] = {
0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a,
0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a,
0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf,
0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18,
0x58, 0x65
+};
+static unsigned char salt_test2[] = {
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+};
+static unsigned char ikm_test2[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+};
+static unsigned char info_test2[] = {
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+};
+static unsigned char expected_test2[] = {
0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1,
0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34,
0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c,
0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72,
0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8,
0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71,
0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f,
0x1d, 0x87,
+};
+static unsigned char salt_test3[] = { +};
+static unsigned char ikm_test3[] = {
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+};
+static unsigned char info_test3[] = { +};
+static unsigned char expected_test3[] = {
0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f,
0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a,
0x96, 0xc8,
+};
+static struct test_sha256_hkdf_s test_sha256_hkdf[] = {
{
.salt = salt_test1,
.saltlen = sizeof(salt_test1),
.ikm = ikm_test1,
.ikmlen = sizeof(ikm_test1),
.info = info_test1,
.infolen = sizeof(info_test1),
.expected = expected_test1,
.expectedlen = sizeof(expected_test1),
},
{
.salt = salt_test2,
.saltlen = sizeof(salt_test2),
.ikm = ikm_test2,
.ikmlen = sizeof(ikm_test2),
.info = info_test2,
.infolen = sizeof(info_test2),
.expected = expected_test2,
.expectedlen = sizeof(expected_test2),
},
{
.salt = salt_test3,
.saltlen = sizeof(salt_test3),
.ikm = ikm_test3,
.ikmlen = sizeof(ikm_test3),
.info = info_test3,
.infolen = sizeof(info_test3),
.expected = expected_test3,
.expectedlen = sizeof(expected_test3),
},
+};
+static int _lib_test_sha256_hkdf_run(struct unit_test_state *uts,
const unsigned char *salt, int
saltlen,
const unsigned char *ikm, int ikmlen,
const unsigned char *info, int
infolen,
const unsigned char *expected,
int expectedlen)
+{
unsigned char output[256];
int ret;
ut_assert(expectedlen <= sizeof(output));
ret = sha256_hkdf(salt, saltlen, ikm, ikmlen, info, infolen,
output, expectedlen);
ut_assert(!ret);
ut_asserteq_mem(expected, output, expectedlen);
return 0;
+}
+static int lib_test_sha256_hkdf_run(struct unit_test_state *uts,
struct test_sha256_hkdf_s *test)
+{
return _lib_test_sha256_hkdf_run(uts, test->salt, test->saltlen,
test->ikm, test->ikmlen,
test->info, test->infolen,
test->expected,
test->expectedlen); +}
+static int lib_test_sha256_hkdf(struct unit_test_state *uts) +{
int i, ret = 0;
for (i = 0; i < ARRAY_SIZE(test_sha256_hkdf); i++) {
ret = lib_test_sha256_hkdf_run(uts, &test_sha256_hkdf[i]);
if (ret)
return ret;
}
return 0;
+}
+LIB_TEST(lib_test_sha256_hkdf, 0);
2.25.1
Sounds good to me. Reviewed-by: Raymond Mao raymond.mao@linaro.org
Regards, Raymond

Enable mbedtls to have at least one config with mbedtls enabled.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com --- configs/sandbox_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 718e4a8283c..1258044241a 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -352,6 +352,8 @@ CONFIG_FS_CRAMFS=y CONFIG_ADDR_MAP=y CONFIG_CMD_DHRYSTONE=y CONFIG_MBEDTLS_LIB=y +CONFIG_MBEDTLS_LIB_CRYPTO=y +CONFIG_HKDF_MBEDTLS=y CONFIG_ECDSA=y CONFIG_ECDSA_VERIFY=y CONFIG_TPM=y

On Thu, 19 Dec 2024 14:05:45 +0100, Philippe Reynes wrote:
This serie adds the support of sha256_hmac and sha256_hkdf. A first version was sent several months ago just before the integration of mbedtls. This new version is based on mbedtls.
The first patch of this serie add the support of hkdf using mbedtls.
[...]
Applied to u-boot/master, thanks!
participants (3)
-
Philippe Reynes
-
Raymond Mao
-
Tom Rini