From 619ae55e63345de17092262ddb41ee216e56eec6 Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Mon, 27 Nov 2023 17:33:25 +0100 Subject: [PATCH 1/2] Add a reference example for SP800-108 CTR KDF Adds a reference implementation for a counter mode KDF using the construction recommended by NIST SP 800-108. For this the PSA API's with the mbedtls implementation is used. --- .../SP800-108_counter_KDF/CMakeLists.txt | 47 +++ .../crypto/SP800-108_counter_KDF/README.md | 128 ++++++ examples/crypto/SP800-108_counter_KDF/main.c | 397 ++++++++++++++++++ 3 files changed, 572 insertions(+) create mode 100644 examples/crypto/SP800-108_counter_KDF/CMakeLists.txt create mode 100644 examples/crypto/SP800-108_counter_KDF/README.md create mode 100644 examples/crypto/SP800-108_counter_KDF/main.c diff --git a/examples/crypto/SP800-108_counter_KDF/CMakeLists.txt b/examples/crypto/SP800-108_counter_KDF/CMakeLists.txt new file mode 100644 index 00000000..32165162 --- /dev/null +++ b/examples/crypto/SP800-108_counter_KDF/CMakeLists.txt @@ -0,0 +1,47 @@ +# +# SPDX-FileCopyrightText: Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.27.0) + +project("SP800-108-counter-KDF") +add_executable(kbkdf) +target_sources(kbkdf PRIVATE main.c) +set(CMAKE_C_FLAGS "-std=c99") + +include(ExternalProject) + + +if(NOT DEFINED ${MBEDTLS_ROOT_PATH}) +# Clone the library through using CMAKE +ExternalProject_Add(mbedcrypto + GIT_REPOSITORY "https://github.com/Mbed-TLS/mbedtls" + GIT_TAG "v3.5.1" + GIT_SHALLOW ON + BUILD_ALWAYS OFF + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/source_mbedtls" + INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/install_mbedtls" + CMAKE_CACHE_ARGS + -DCMAKE_INSTALL_PREFIX:PATH= + -DENABLE_TESTING:BOOL=OFF + -DENABLE_PROGRAMS:BOOL=OFF + ) + +else() +# Add the library using the a local folder +ExternalProject_Add(mbedcrypto + SOURCE_DIR "${MBEDTLS_ROOT_PATH}" + INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/install_mbedtls" + CMAKE_CACHE_ARGS + -DCMAKE_INSTALL_PREFIX:PATH= + -DENABLE_TESTING:BOOL=OFF + -DENABLE_PROGRAMS:BOOL=OFF + ) + +endif() + +add_dependencies(kbkdf mbedcrypto) + +target_include_directories(kbkdf PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/install_mbedtls/include) +target_link_libraries(kbkdf ${CMAKE_CURRENT_BINARY_DIR}/install_mbedtls/lib/libmbedcrypto.a) diff --git a/examples/crypto/SP800-108_counter_KDF/README.md b/examples/crypto/SP800-108_counter_KDF/README.md new file mode 100644 index 00000000..30d0486f --- /dev/null +++ b/examples/crypto/SP800-108_counter_KDF/README.md @@ -0,0 +1,128 @@ + + +NIST SP 800-108 counter-mode KDF +================================ + +This example shows a reference implementation for a key based key derivation function for counter mode that conforms to the [NIST SP 800-108r1 recommendation](https://csrc.nist.gov/pubs/sp/800/108/r1/final). + +It includes a HMAC and a CMAC variant. +The CMAC variant implements the suggested addition to prevent a key control attack that is listed in Appendix B of [SP 800-108](https://csrc.nist.gov/pubs/sp/800/108/r1/final). + + + +Building the example +******************** +To build the example CMake 3.10.2 or later is required. +Also [Mbed TLS](https://github.com/Mbed-TLS/mbedtls) is required. +You can either provide a Mbed TLS installation that exists or the build script will clone it into the build folder. +Check the [requirements for building Mbed TLS](https://github.com/Mbed-TLS/mbedtls#compiling) to make sure all required dependencies are installed. + + +To build the example then use CMake + + [optional] export MBEDTLS_ROOT_PATH="/path/to/your/mbedtls" + mkdir build && cd build + cmake -G "Unix Makefiles" .. + cmake --build . + + +Then run the sample + + ./kbkdf + Deriving a key using SP800-108 HMAC(SHA256) counter mode...Done + Key: + ----------------------------------- len: 32 ----------------------------------- + 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0d 0f + 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0d 0f + ------------------------------------- end ------------------------------------- + Label: + ----------------------------------- len: 32 ----------------------------------- + 50 53 41 5f 41 4c 47 5f 53 50 38 30 30 5f 31 30 + 38 5f 43 4f 55 4e 54 45 52 20 53 61 6d 70 6c 65 + ------------------------------------- end ------------------------------------- + Context: + ----------------------------------- len: 49 ----------------------------------- + 53 61 6d 70 6c 65 20 6b 65 79 20 63 72 65 61 74 + 69 6f 6e 20 76 69 61 20 53 50 20 38 30 30 2d 31 + 30 38 72 31 20 43 6f 75 6e 74 65 72 20 6d 6f 64 + 65 + ------------------------------------- end ------------------------------------- + Capacity: 0x2a + + HMAC derived key: + ----------------------------------- len: 42 ----------------------------------- + 81 58 cd 6a e7 50 69 0c 20 54 be 10 66 d2 d8 f3 + 4a b0 14 d0 7f 81 4c bc 7d 3e 3d ca 78 a9 3f 5d + 66 29 b1 14 b4 2a 04 64 a4 89 + ------------------------------------- end ------------------------------------- + + + Deriving a key using SP800-108 HMAC(SHA256) counter mode...Done + Key: + ----------------------------------- len: 32 ----------------------------------- + 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0d 0f + 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0d 0f + ------------------------------------- end ------------------------------------- + Label: + ----------------------------------- len: 32 ----------------------------------- + 50 53 41 5f 41 4c 47 5f 53 50 38 30 30 5f 31 30 + 38 5f 43 4f 55 4e 54 45 52 20 53 61 6d 70 6c 65 + ------------------------------------- end ------------------------------------- + Capacity: 0x2a + + HMAC without context derived key: + ----------------------------------- len: 42 ----------------------------------- + 2f e0 5b d4 22 00 4f a1 9a 48 cd 8c 9b d2 ca 8d + 39 87 ea 6c 5a bc d5 54 3a ed eb 04 e2 b7 00 0c + b6 eb 18 c3 3a 3d 89 67 a7 d6 + ------------------------------------- end ------------------------------------- + + + Deriving a key using SP800-108 CMAC counter mode...Done + Key: + ----------------------------------- len: 16 ----------------------------------- + 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0d 0f + ------------------------------------- end ------------------------------------- + Label: + ----------------------------------- len: 32 ----------------------------------- + 50 53 41 5f 41 4c 47 5f 53 50 38 30 30 5f 31 30 + 38 5f 43 4f 55 4e 54 45 52 20 53 61 6d 70 6c 65 + ------------------------------------- end ------------------------------------- + Context: + ----------------------------------- len: 49 ----------------------------------- + 53 61 6d 70 6c 65 20 6b 65 79 20 63 72 65 61 74 + 69 6f 6e 20 76 69 61 20 53 50 20 38 30 30 2d 31 + 30 38 72 31 20 43 6f 75 6e 74 65 72 20 6d 6f 64 + 65 + ------------------------------------- end ------------------------------------- + Capacity: 0x2a + + CMAC derived key: + ----------------------------------- len: 42 ----------------------------------- + 3c 50 b5 5a 13 b9 49 ad 25 b4 b4 0f c3 7f 55 38 + 36 b5 9f a0 d0 74 b7 3c 83 17 6d 4c 10 5f c2 17 + 83 8e c4 a1 b0 7b 8a be a8 f1 + ------------------------------------- end ------------------------------------- + + + Deriving a key using SP800-108 CMAC counter mode...Done + Key: + ----------------------------------- len: 16 ----------------------------------- + 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0d 0f + ------------------------------------- end ------------------------------------- + Label: + ----------------------------------- len: 32 ----------------------------------- + 50 53 41 5f 41 4c 47 5f 53 50 38 30 30 5f 31 30 + 38 5f 43 4f 55 4e 54 45 52 20 53 61 6d 70 6c 65 + ------------------------------------- end ------------------------------------- + Capacity: 0x2a + + CMAC without context derived key: + ----------------------------------- len: 42 ----------------------------------- + e1 ec fc 00 1e 2e 9a db d0 16 b3 b4 f3 23 ce 00 + c1 05 82 ec 81 e1 fc 19 40 47 4c a6 84 f9 e5 07 + b5 8a bd 03 bc e5 23 82 05 11 + ------------------------------------- end ------------------------------------- diff --git a/examples/crypto/SP800-108_counter_KDF/main.c b/examples/crypto/SP800-108_counter_KDF/main.c new file mode 100644 index 00000000..e9cf20d0 --- /dev/null +++ b/examples/crypto/SP800-108_counter_KDF/main.c @@ -0,0 +1,397 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include + +#define CMAC_KEY_LENGTH (16) +#define OTUPUT_LENGTH (42) +#define AES_BLOCK_SIZE PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES) +#define L_LENGTH (sizeof(uint32_t)) + +/* 2^29 -1 */ +#define PSA_ALG_SP800_108_COUNTER_CMAC_INIT_CAPACITY (0x1fffffff) + +static uint8_t m_input_cmac_key[CMAC_KEY_LENGTH] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0d, 0x0f}; + +static uint8_t m_input_hmac_key[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0d, 0x0f, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0d, 0x0f}; + +/* Label that identifies the purpose for the derived keying material */ +static uint8_t m_label[] = {"PSA_ALG_SP800_108_COUNTER Sample"}; +/* Don't include the NULL terminator in the length */ +const size_t label_length = sizeof(m_label) - 1; + +/* Context containing the information related to the derived keying material */ +static uint8_t m_context[] = {"Sample key creation via SP 800-108r1 Counter mode"}; +/* Don't include the NULL terminator in the length */ +const size_t context_length = sizeof(m_context) - 1; + +/* Buffer to hold the key generated from CMAC_CTR_KDF */ +static uint8_t m_output[OTUPUT_LENGTH] = {0}; + +static size_t min(size_t a, size_t b){ + return a < b ? a : b; +} + +static void print_hex(const uint8_t *out, const size_t out_length) +{ + printf("----------------------------------- len: %lu -----------------------------------\n", + out_length); + printf("%02x ", out[0]); + for (size_t i = 1; i < out_length; i++) { + if (i % 16 == 0) { + printf("\n"); + } + printf("%02x ", out[i]); + } + printf("\n------------------------------------- end " + "-------------------------------------\n"); +} + +static void print_parameters(const uint8_t *key_buffer, const size_t key_buffer_length, + uint8_t *label, const size_t label_length, const uint8_t *context, + const size_t context_length, const size_t capacity) +{ + printf("Key:\n"); + print_hex(key_buffer, key_buffer_length); + printf("Label:\n"); + print_hex(label, label_length); + if (context_length > 0) { + printf("Context:\n"); + print_hex(context, context_length); + } + printf("Capacity: %#lx\n\n", (unsigned long) capacity); +} + +static psa_status_t import_hmac_key(const uint8_t *key_buffer, const size_t key_buffer_length, + const psa_algorithm_t alg, psa_key_id_t *key_id) +{ + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + /* Configure the input key attributes */ + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_MESSAGE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_HMAC(alg)); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_HMAC); + + /* Import the master key into the keystore */ + return psa_import_key(&key_attributes, key_buffer, key_buffer_length, key_id); +} + +/* Adds ( label || 0x00 || context|| [L]_4 ) to given mac operation */ +static psa_status_t mac_update_fixed_input(psa_mac_operation_t *op, const uint8_t *label, + const size_t label_length, const uint8_t *context, + const size_t context_length, const uint8_t * L) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + /* 0x00 byte used to separate the label from the context */ + uint8_t zero_byte = 0x00; + + status = psa_mac_update(op, label, label_length); + if (status != PSA_SUCCESS) { + printf("\npsa_mac_update label failed! (Error: %d)\n", status); + return status; + } + + status = psa_mac_update(op, &zero_byte, sizeof(zero_byte)); + if (status != PSA_SUCCESS) { + printf("\npsa_mac_update zero_byte failed! (Error: %d)\n", status); + return status; + } + + status = psa_mac_update(op, context, context_length); + if (status != PSA_SUCCESS) { + printf("\npsa_mac_update context failed! (Error: %d)\n", status); + return status; + } + + status = psa_mac_update(op, L, L_LENGTH); + if (status != PSA_SUCCESS) { + printf("\npsa_mac_update L failed! (Error: %d)\n", status); + return status; + } + + return PSA_SUCCESS; +} + +static psa_status_t sp800_108_counter_hmac_kdf(psa_algorithm_t hash_alg, const uint8_t *key_buffer, + const size_t key_buffer_length, const uint8_t *label, + const size_t label_length, const uint8_t *context, + const size_t context_length, const size_t capacity, + uint8_t *output, const size_t output_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + psa_key_id_t key_id; + size_t output_size; + size_t bytes_produced = 0; + /* Set the capacity in bits and big-endian*/ + uint8_t L[L_LENGTH] = {PSA_BYTES_TO_BITS(capacity) >> 24, PSA_BYTES_TO_BITS(capacity) >> 16, PSA_BYTES_TO_BITS(capacity) >> 8, PSA_BYTES_TO_BITS(capacity)}; + + printf("Deriving a key using SP800-108 HMAC(SHA256) counter mode..."); + + /* Can only output 2^29 -1 bytes*/ + if (capacity > PSA_ALG_SP800_108_COUNTER_CMAC_INIT_CAPACITY && + output_length > PSA_ALG_SP800_108_COUNTER_CMAC_INIT_CAPACITY) { + printf("\ncapacity or output_length is greater than 2^29-1\n"); + return PSA_ERROR_INVALID_ARGUMENT; + } + + status = import_hmac_key(key_buffer, key_buffer_length, hash_alg, &key_id); + if (status != PSA_SUCCESS) { + printf("\nimport_hmac_key failed! (Error: %d)\n", status); + return status; + } + + /* K_i = HMAC(K_in, [i]_4 || label || 0x00 || context || [L]_4 ) */ + for (uint32_t i = 1; bytes_produced < output_length; i++) { + uint8_t K_i[PSA_HASH_MAX_SIZE] = {0}; + + /* Initialize the HMAC operation and input K_in */ + status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_HMAC(hash_alg)); + if (status != PSA_SUCCESS) { + printf("\n\npsa_mac_sign_setup failed! (Error: %d)\n", status); + goto error; + } + + /* counter is needed as 4 byte big-endian */ + uint8_t counter_be[sizeof(i)] = {i >> 24, i >> 16, i >> 8, i}; + + /* [i]_4 */ + status = psa_mac_update(&operation, counter_be, sizeof(i)); + if (status != PSA_SUCCESS) { + printf("\npsa_mac_update [i]_4 failed! (Error: %d)\n", status); + goto error; + } + + /* label || 0x00 || context || [L]_4 */ + status = mac_update_fixed_input(&operation, label, label_length, context, + context_length, L); + if (status != PSA_SUCCESS) { + printf("\nmac_update_fixed_input failed! (Error: %d)\n", status); + goto error; + } + + status = psa_mac_sign_finish(&operation, K_i, sizeof(K_i), &output_size); + if (status != PSA_SUCCESS) { + printf("\npsa_mac_sign_finish failed! (Error: %d)\n", status); + goto error; + } + + memcpy(output + bytes_produced, K_i, + min(output_size, output_length - bytes_produced)); + bytes_produced += min(output_size, output_length - bytes_produced); + } + psa_destroy_key(key_id); + printf("Done\n"); + + return PSA_SUCCESS; + +error: + psa_destroy_key(key_id); + psa_mac_abort(&operation); + return status; +} + +static psa_status_t import_cmac_key(const uint8_t *key_buffer, const uint8_t key_buffer_length, + psa_key_id_t *key_id) +{ + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + /* Configure the input key attributes */ + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_MESSAGE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_CMAC); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&key_attributes, PSA_BYTES_TO_BITS(CMAC_KEY_LENGTH)); + + /* Import the master key into the keystore */ + return psa_import_key(&key_attributes, key_buffer, key_buffer_length, key_id); +} + +static psa_status_t sp800_108_counter_cmac_kdf(const uint8_t *key_buffer, + const size_t key_buffer_length, uint8_t *label, + const size_t label_length, const uint8_t *context, + const size_t context_length, const size_t capacity, + uint8_t *output, const size_t output_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + psa_key_id_t key_id; + uint8_t K_0[AES_BLOCK_SIZE] = {0}; + size_t output_size; + size_t bytes_produced = 0; + /* Set the capacity in bits and big-endian*/ + uint8_t L[L_LENGTH] = {PSA_BYTES_TO_BITS(capacity) >> 24, PSA_BYTES_TO_BITS(capacity) >> 16, PSA_BYTES_TO_BITS(capacity) >> 8, PSA_BYTES_TO_BITS(capacity)}; + + if (key_buffer_length != CMAC_KEY_LENGTH) { + printf("\nwrong key size got %lu expected %d\n", key_buffer_length, CMAC_KEY_LENGTH); + return PSA_ERROR_INVALID_ARGUMENT; + } + + /* Can only output 2^29 -1 bytes*/ + if (capacity > PSA_ALG_SP800_108_COUNTER_CMAC_INIT_CAPACITY && + output_length > PSA_ALG_SP800_108_COUNTER_CMAC_INIT_CAPACITY) { + printf("\ncapacity or output_length is greater than 2^29-1\n"); + return PSA_ERROR_INVALID_ARGUMENT; + } + + printf("Deriving a key using SP800-108 CMAC counter mode..."); + + status = import_cmac_key(key_buffer, key_buffer_length, &key_id); + if (status != PSA_SUCCESS) { + printf("\nimport_cmac_key failed! (Error: %d)\n", status); + return status; + } + + /* Generate K_0 = CMAC(K_in, label || 0x00 || context|| [L]_4) */ + status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_CMAC); + if (status != PSA_SUCCESS) { + printf("\npsa_mac_sign_setup failed! (Error: %d)\n", status); + goto error; + } + + status = + mac_update_fixed_input(&operation, label, label_length, context, context_length, L); + if (status != PSA_SUCCESS) { + printf("\nmac_update_fixed_input failed! (Error: %d)\n", status); + goto error; + } + + status = psa_mac_sign_finish(&operation, K_0, sizeof(K_0), &output_size); + if (status != PSA_SUCCESS) { + printf("\npsa_mac_sign_finish failed! (Error: %d)\n", status); + goto error; + } + + /* K_i = CMAC(K_in, [i]_4 || label || 0x00 || context || [L]_4 || K_0) */ + for (uint32_t i = 1; bytes_produced < output_length; i++) { + uint8_t K_i[AES_BLOCK_SIZE] = {0}; + /* Setup a new operation */ + status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_CMAC); + if (status != PSA_SUCCESS) { + printf("\npsa_mac_sign_setup - 2 failed! (Error: %d)\n", status); + goto error; + } + + /* counter is needed as 4 byte big-endian */ + uint8_t counter_be[sizeof(i)] = {i >> 24, i >> 16, i >> 8, i}; + + /* [i]_4 */ + status = psa_mac_update(&operation, counter_be, sizeof(i)); + if (status != PSA_SUCCESS) { + printf("\npsa_mac_update [i]_4 failed! (Error: %d)\n", status); + goto error; + } + + /* label || 0x00 || context || [L]_4 */ + status = mac_update_fixed_input(&operation, label, label_length, context, + context_length, L); + if (status != PSA_SUCCESS) { + printf("\nmac_update_fixed_input failed! (Error: %d)\n", status); + goto error; + } + + /* K_0 */ + status = psa_mac_update(&operation, K_0, sizeof(K_0)); + if (status != PSA_SUCCESS) { + printf("\npsa_mac_update K_0 failed! (Error: %d)\n", status); + goto error; + } + + status = psa_mac_sign_finish(&operation, K_i, sizeof(K_i), &output_size); + if (status != PSA_SUCCESS) { + printf("\npsa_mac_sign_finish failed! (Error: %d)\n", status); + goto error; + } + + memcpy(output + bytes_produced, K_i, + min(output_size, output_length - bytes_produced)); + bytes_produced += min(output_size, output_length - bytes_produced); + } + psa_destroy_key(key_id); + printf("Done\n"); + + return PSA_SUCCESS; +error: + psa_destroy_key(key_id); + psa_mac_abort(&operation); + return status; +} + +int main(void) +{ + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + printf("psa_crypto_init failed! (Error: %d)\n", status); + return EXIT_FAILURE; + } + + /* Do a SP800-108 counter HMAC kdf with SHA256 */ + status = sp800_108_counter_hmac_kdf( + PSA_ALG_SHA_256, m_input_hmac_key, sizeof(m_input_hmac_key), m_label, label_length, + m_context, context_length, OTUPUT_LENGTH, m_output, sizeof(m_output)); + if (status != PSA_SUCCESS){ + return EXIT_FAILURE; + } + + print_parameters(m_input_hmac_key, sizeof(m_input_hmac_key), m_label, label_length, + m_context, context_length, OTUPUT_LENGTH); + printf("HMAC derived key:\n"); + print_hex(m_output, sizeof(m_output)); + printf("\n\n"); + + + status = sp800_108_counter_hmac_kdf(PSA_ALG_SHA_256, m_input_hmac_key, + sizeof(m_input_hmac_key), m_label, label_length, + m_context, 0, OTUPUT_LENGTH, m_output, sizeof(m_output)); + if (status != PSA_SUCCESS){ + return EXIT_FAILURE; + } + + print_parameters(m_input_hmac_key, sizeof(m_input_hmac_key), m_label, label_length, + m_context, 0, OTUPUT_LENGTH); + printf("HMAC without context derived key:\n"); + print_hex(m_output, sizeof(m_output)); + printf("\n\n"); + + + /* Do a SP800-108 counter CMAC kdf */ + status = sp800_108_counter_cmac_kdf(m_input_cmac_key, sizeof(m_input_cmac_key), m_label, + label_length, m_context, context_length, OTUPUT_LENGTH, + m_output, sizeof(m_output)); + + if (status != PSA_SUCCESS){ + return EXIT_FAILURE; + } + + print_parameters(m_input_cmac_key, sizeof(m_input_cmac_key), m_label, label_length, + m_context, context_length, OTUPUT_LENGTH); + printf("CMAC derived key:\n"); + print_hex(m_output, sizeof(m_output)); + printf("\n\n"); + + + status = sp800_108_counter_cmac_kdf(m_input_cmac_key, sizeof(m_input_cmac_key), m_label, + label_length, m_context, 0, OTUPUT_LENGTH, m_output, + sizeof(m_output)); + + if (status != PSA_SUCCESS){ + return EXIT_FAILURE; + } + + print_parameters(m_input_cmac_key, sizeof(m_input_cmac_key), m_label, label_length, + m_context, 0, OTUPUT_LENGTH); + printf("CMAC without context derived key:\n"); + print_hex(m_output, sizeof(m_output)); + printf("\n\n"); +} From 5b8af1e83a5b294b80c6d98bdbcd09abd81d9df1 Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Wed, 17 Jan 2024 16:00:17 +0100 Subject: [PATCH 2/2] fixup! Add a reference example for SP800-108 CTR KDF --- .../SP800-108_counter_KDF/CMakeLists.txt | 2 +- .../crypto/SP800-108_counter_KDF/README.md | 58 +++++++++---------- examples/crypto/SP800-108_counter_KDF/main.c | 34 +++++------ 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/examples/crypto/SP800-108_counter_KDF/CMakeLists.txt b/examples/crypto/SP800-108_counter_KDF/CMakeLists.txt index 32165162..99875c99 100644 --- a/examples/crypto/SP800-108_counter_KDF/CMakeLists.txt +++ b/examples/crypto/SP800-108_counter_KDF/CMakeLists.txt @@ -1,5 +1,5 @@ # -# SPDX-FileCopyrightText: Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-FileCopyrightText: Copyright (c) 2023-2024 Nordic Semiconductor ASA # # SPDX-License-Identifier: Apache-2.0 diff --git a/examples/crypto/SP800-108_counter_KDF/README.md b/examples/crypto/SP800-108_counter_KDF/README.md index 30d0486f..a6c4a7bb 100644 --- a/examples/crypto/SP800-108_counter_KDF/README.md +++ b/examples/crypto/SP800-108_counter_KDF/README.md @@ -1,5 +1,5 @@ @@ -34,95 +34,95 @@ Then run the sample ./kbkdf Deriving a key using SP800-108 HMAC(SHA256) counter mode...Done Key: - ----------------------------------- len: 32 ----------------------------------- + ------------------- len: 32 ------------------- 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0d 0f 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0d 0f - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- Label: - ----------------------------------- len: 32 ----------------------------------- + ------------------- len: 32 ------------------- 50 53 41 5f 41 4c 47 5f 53 50 38 30 30 5f 31 30 38 5f 43 4f 55 4e 54 45 52 20 53 61 6d 70 6c 65 - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- Context: - ----------------------------------- len: 49 ----------------------------------- + ------------------- len: 49 ------------------- 53 61 6d 70 6c 65 20 6b 65 79 20 63 72 65 61 74 69 6f 6e 20 76 69 61 20 53 50 20 38 30 30 2d 31 30 38 72 31 20 43 6f 75 6e 74 65 72 20 6d 6f 64 65 - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- Capacity: 0x2a HMAC derived key: - ----------------------------------- len: 42 ----------------------------------- + ------------------- len: 42 ------------------- 81 58 cd 6a e7 50 69 0c 20 54 be 10 66 d2 d8 f3 4a b0 14 d0 7f 81 4c bc 7d 3e 3d ca 78 a9 3f 5d 66 29 b1 14 b4 2a 04 64 a4 89 - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- Deriving a key using SP800-108 HMAC(SHA256) counter mode...Done Key: - ----------------------------------- len: 32 ----------------------------------- + ------------------- len: 32 ------------------- 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0d 0f 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0d 0f - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- Label: - ----------------------------------- len: 32 ----------------------------------- + ------------------- len: 32 ------------------- 50 53 41 5f 41 4c 47 5f 53 50 38 30 30 5f 31 30 38 5f 43 4f 55 4e 54 45 52 20 53 61 6d 70 6c 65 - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- Capacity: 0x2a HMAC without context derived key: - ----------------------------------- len: 42 ----------------------------------- + ------------------- len: 42 ------------------- 2f e0 5b d4 22 00 4f a1 9a 48 cd 8c 9b d2 ca 8d 39 87 ea 6c 5a bc d5 54 3a ed eb 04 e2 b7 00 0c b6 eb 18 c3 3a 3d 89 67 a7 d6 - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- Deriving a key using SP800-108 CMAC counter mode...Done Key: - ----------------------------------- len: 16 ----------------------------------- + ------------------- len: 16 ------------------- 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0d 0f - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- Label: - ----------------------------------- len: 32 ----------------------------------- + ------------------- len: 32 ------------------- 50 53 41 5f 41 4c 47 5f 53 50 38 30 30 5f 31 30 38 5f 43 4f 55 4e 54 45 52 20 53 61 6d 70 6c 65 - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- Context: - ----------------------------------- len: 49 ----------------------------------- + ------------------- len: 49 ------------------- 53 61 6d 70 6c 65 20 6b 65 79 20 63 72 65 61 74 69 6f 6e 20 76 69 61 20 53 50 20 38 30 30 2d 31 30 38 72 31 20 43 6f 75 6e 74 65 72 20 6d 6f 64 65 - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- Capacity: 0x2a CMAC derived key: - ----------------------------------- len: 42 ----------------------------------- + ------------------- len: 42 ------------------- 3c 50 b5 5a 13 b9 49 ad 25 b4 b4 0f c3 7f 55 38 36 b5 9f a0 d0 74 b7 3c 83 17 6d 4c 10 5f c2 17 83 8e c4 a1 b0 7b 8a be a8 f1 - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- Deriving a key using SP800-108 CMAC counter mode...Done Key: - ----------------------------------- len: 16 ----------------------------------- + ------------------- len: 16 ------------------- 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0d 0f - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- Label: - ----------------------------------- len: 32 ----------------------------------- + ------------------- len: 32 ------------------- 50 53 41 5f 41 4c 47 5f 53 50 38 30 30 5f 31 30 38 5f 43 4f 55 4e 54 45 52 20 53 61 6d 70 6c 65 - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- Capacity: 0x2a CMAC without context derived key: - ----------------------------------- len: 42 ----------------------------------- + ------------------- len: 42 ------------------- e1 ec fc 00 1e 2e 9a db d0 16 b3 b4 f3 23 ce 00 c1 05 82 ec 81 e1 fc 19 40 47 4c a6 84 f9 e5 07 b5 8a bd 03 bc e5 23 82 05 11 - ------------------------------------- end ------------------------------------- + --------------------- end --------------------- \ No newline at end of file diff --git a/examples/crypto/SP800-108_counter_KDF/main.c b/examples/crypto/SP800-108_counter_KDF/main.c index e9cf20d0..19cdf60d 100644 --- a/examples/crypto/SP800-108_counter_KDF/main.c +++ b/examples/crypto/SP800-108_counter_KDF/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-FileCopyrightText: Copyright (c) 2023-24 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,9 +12,9 @@ #include #define CMAC_KEY_LENGTH (16) -#define OTUPUT_LENGTH (42) +#define OUTPUT_LENGTH (42) #define AES_BLOCK_SIZE PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES) -#define L_LENGTH (sizeof(uint32_t)) +#define L_LENGTH (4) /* 2^29 -1 */ #define PSA_ALG_SP800_108_COUNTER_CMAC_INIT_CAPACITY (0x1fffffff) @@ -29,16 +29,16 @@ static uint8_t m_input_hmac_key[] = { /* Label that identifies the purpose for the derived keying material */ static uint8_t m_label[] = {"PSA_ALG_SP800_108_COUNTER Sample"}; -/* Don't include the NULL terminator in the length */ +/* Don't include the null terminator in the length */ const size_t label_length = sizeof(m_label) - 1; /* Context containing the information related to the derived keying material */ static uint8_t m_context[] = {"Sample key creation via SP 800-108r1 Counter mode"}; -/* Don't include the NULL terminator in the length */ +/* Don't include the null terminator in the length */ const size_t context_length = sizeof(m_context) - 1; /* Buffer to hold the key generated from CMAC_CTR_KDF */ -static uint8_t m_output[OTUPUT_LENGTH] = {0}; +static uint8_t m_output[OUTPUT_LENGTH] = {0}; static size_t min(size_t a, size_t b){ return a < b ? a : b; @@ -46,7 +46,7 @@ static size_t min(size_t a, size_t b){ static void print_hex(const uint8_t *out, const size_t out_length) { - printf("----------------------------------- len: %lu -----------------------------------\n", + printf("------------------- len: %lu -------------------\n", out_length); printf("%02x ", out[0]); for (size_t i = 1; i < out_length; i++) { @@ -55,8 +55,8 @@ static void print_hex(const uint8_t *out, const size_t out_length) } printf("%02x ", out[i]); } - printf("\n------------------------------------- end " - "-------------------------------------\n"); + printf("\n--------------------- end " + "---------------------\n"); } static void print_parameters(const uint8_t *key_buffer, const size_t key_buffer_length, @@ -339,13 +339,13 @@ int main(void) /* Do a SP800-108 counter HMAC kdf with SHA256 */ status = sp800_108_counter_hmac_kdf( PSA_ALG_SHA_256, m_input_hmac_key, sizeof(m_input_hmac_key), m_label, label_length, - m_context, context_length, OTUPUT_LENGTH, m_output, sizeof(m_output)); + m_context, context_length, OUTPUT_LENGTH, m_output, sizeof(m_output)); if (status != PSA_SUCCESS){ return EXIT_FAILURE; } print_parameters(m_input_hmac_key, sizeof(m_input_hmac_key), m_label, label_length, - m_context, context_length, OTUPUT_LENGTH); + m_context, context_length, OUTPUT_LENGTH); printf("HMAC derived key:\n"); print_hex(m_output, sizeof(m_output)); printf("\n\n"); @@ -353,13 +353,13 @@ int main(void) status = sp800_108_counter_hmac_kdf(PSA_ALG_SHA_256, m_input_hmac_key, sizeof(m_input_hmac_key), m_label, label_length, - m_context, 0, OTUPUT_LENGTH, m_output, sizeof(m_output)); + m_context, 0, OUTPUT_LENGTH, m_output, sizeof(m_output)); if (status != PSA_SUCCESS){ return EXIT_FAILURE; } print_parameters(m_input_hmac_key, sizeof(m_input_hmac_key), m_label, label_length, - m_context, 0, OTUPUT_LENGTH); + m_context, 0, OUTPUT_LENGTH); printf("HMAC without context derived key:\n"); print_hex(m_output, sizeof(m_output)); printf("\n\n"); @@ -367,7 +367,7 @@ int main(void) /* Do a SP800-108 counter CMAC kdf */ status = sp800_108_counter_cmac_kdf(m_input_cmac_key, sizeof(m_input_cmac_key), m_label, - label_length, m_context, context_length, OTUPUT_LENGTH, + label_length, m_context, context_length, OUTPUT_LENGTH, m_output, sizeof(m_output)); if (status != PSA_SUCCESS){ @@ -375,14 +375,14 @@ int main(void) } print_parameters(m_input_cmac_key, sizeof(m_input_cmac_key), m_label, label_length, - m_context, context_length, OTUPUT_LENGTH); + m_context, context_length, OUTPUT_LENGTH); printf("CMAC derived key:\n"); print_hex(m_output, sizeof(m_output)); printf("\n\n"); status = sp800_108_counter_cmac_kdf(m_input_cmac_key, sizeof(m_input_cmac_key), m_label, - label_length, m_context, 0, OTUPUT_LENGTH, m_output, + label_length, m_context, 0, OUTPUT_LENGTH, m_output, sizeof(m_output)); if (status != PSA_SUCCESS){ @@ -390,7 +390,7 @@ int main(void) } print_parameters(m_input_cmac_key, sizeof(m_input_cmac_key), m_label, label_length, - m_context, 0, OTUPUT_LENGTH); + m_context, 0, OUTPUT_LENGTH); printf("CMAC without context derived key:\n"); print_hex(m_output, sizeof(m_output)); printf("\n\n");