Skip to main content
PJose.4
Senior
March 8, 2024
Question

STM32U585 - TFM Application HKDF Implementation Using PSA Crypto

  • March 8, 2024
  • 3 replies
  • 1378 views

Hello @st_it

I am taking the reference implementation of the HKDF Algorithm using PSA API in the TFM Application Project and using the following algorithm :

PSA_ALG_HKDF(PSA_ALG_SHA_256);

I m able to export the output key to the console and am getting an output for the test vectors taken from RFC5869 as shown below:

PJose4_0-1709902659779.png

But when using the same Hash, IKM, Salt, Info as given in the test vector set Im getting a different value as shown in the below format:(value displayed Derived Key Material is expected to be same as OKM in above Figure)

PJose4_1-1709902754844.png

The codes i have used the same format that was already present to be specific:
TFM_Appli_NonSecure->Middlewares/trustedfirmware/test/crypto_tests_common.c : 

void psa_key_derivation_test(psa_algorithm_t deriv_alg,
struct test_result_t *ret);


Requesting your support to solve this issue and validate the HKDF Function Implementation

Thanks and Regards

Philip Jose
This topic has been closed for replies.

3 replies

Technical Moderator
April 1, 2024

Hi @PJose.4 

I can see that the first digits of your outputs are the same as the OKM last digits

CMYL_0-1712010499826.png

What is the status returned by the psa_key_derivation_test() API, did you see any of the output failing messages 

"Failed to input salt " or " .... key" or ".... Info"

Can you give more details, how you configured the RFC5869 test vector before calling psa_key_derivation_test() ?

Best regards

 

PJose.4
PJose.4Author
Senior
April 2, 2024

Hi @CMYL 
Greetings
Thanks for your reply

While testing the function im not getting any fail message at any of the steps.
i have given the RFC Test vectors as array types as shown below:

uint8_t key_deriv_secret[22] = {0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b 	 								 
 ,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b};
uint8_t key_deriv_seed_salt[13] = 
 {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c};
uint8_t key_deriv_label_info[10] = {0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9};

 

The functionalities implemented has not been changed. The hash algorithm used is 

 psa_algorithm_t deriv_alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);

Attaching the code of the function for your reference

 deriv_ops = psa_key_derivation_operation_init();

	 psa_set_key_usage_flags(&input_key_attr, PSA_KEY_USAGE_DERIVE);
	 psa_set_key_algorithm(&input_key_attr, deriv_alg);
	 psa_set_key_type(&input_key_attr, PSA_KEY_TYPE_DERIVE);

	 /* Force to use HMAC-SHA256 as HMAC operation so far */
	 status = psa_import_key(&input_key_attr, key_deriv_secret,
	 22, &input_handle);
	 if (status != PSA_SUCCESS) {
	 TEST_FAIL("Failed to import secret");
	 return;
	 }

	 status = psa_key_derivation_setup(&deriv_ops, deriv_alg);
	 if (status != PSA_SUCCESS) {
	 TEST_FAIL("Failed to setup derivation operation");
	 goto destroy_key;
	 }

	 if (PSA_ALG_IS_HKDF(deriv_alg)) {
	 status = psa_key_derivation_input_bytes(&deriv_ops,
	 PSA_KEY_DERIVATION_INPUT_SALT,
	 key_deriv_seed_salt,
	 13);
	 if (status != PSA_SUCCESS) {
	 TEST_FAIL("Failed to input salt");
	 goto deriv_abort;
	 }

	 status = psa_key_derivation_input_key(&deriv_ops,
	 PSA_KEY_DERIVATION_INPUT_SECRET,
	 input_handle);
	 if (status != PSA_SUCCESS) {
	 TEST_FAIL("Failed to input key");
	 goto deriv_abort;
	 }

	 status = psa_key_derivation_input_bytes(&deriv_ops,
	 PSA_KEY_DERIVATION_INPUT_INFO,
	 key_deriv_label_info,
	 10);
	 if (status != PSA_SUCCESS) {
	 TEST_FAIL("Failed to input info");
	 goto deriv_abort;
	 }
	 } else {
	 TEST_FAIL("Unsupported derivation algorithm");
	 goto deriv_abort;
	 }

	 if (NR_TEST_AES_MODE < 1) {
	 TEST_LOG("No AES algorithm to verify. Output raw data instead");
 psa_set_key_type(&output_key_attr, PSA_KEY_TYPE_AES);//PSA_KEY_TYPE_RAW_DATA
	 psa_set_key_usage_flags(&output_key_attr,PSA_KEY_USAGE_DERIVE );//PSA_KEY_USAGE_EXPORT
	 psa_set_key_bits(&output_key_attr, 336);
	 } else {
	 psa_set_key_usage_flags(&output_key_attr, PSA_KEY_USAGE_ENCRYPT);
	 psa_set_key_algorithm(&output_key_attr, test_aes_mode_array[0]);
	 psa_set_key_type(&output_key_attr, PSA_KEY_TYPE_AES);
	 }
	 psa_set_key_bits(&output_key_attr,
	 PSA_BYTES_TO_BITS(KEY_DERIVE_OUTPUT_LEN));

	 status = psa_key_derivation_output_key(&output_key_attr, &deriv_ops,
	 &output_handle);
	 if (status != PSA_SUCCESS) {
	 TEST_FAIL("Failed to output key");
	 goto deriv_abort;
	 }

 size_t output_length = 32; // Replace with the actual desired length
	 uint8_t out_Key_material[32] = {0};

 psa_status_t status1 = psa_key_derivation_output_bytes(&deriv_ops, out_Key_material, output_length);
	 if (status1 != PSA_SUCCESS) {
	 // Handle the error
	 printf("Key derivation output failed with status %lu\n", (unsigned long)status);
	 } else {
	 // Now, 'output_key_material' contains the derived key in byte array form
	 // You can save it to your storage or use it as needed
	 printf("Derived key material: ");
	 for (size_t i = 0; i < output_length; ++i) {
//	 printf("%02X", output_key_material[i]);

	 	 printf("%02X", out_Key_material[i]);}
	 printf("\n");
	 }
//	 }

	 ret->val = TEST_PASSED;
	 printf("\n\r key derivation output key completed");

	 deriv_abort:
	 psa_key_derivation_abort(&deriv_ops);
	 destroy_key:
	 psa_destroy_key(input_handle);
	 if (output_handle) {
	 psa_destroy_key(output_handle);
	 }

 Please let me know your thoughts in this 
Thanks and Regards

Philip

PJose.4
PJose.4Author
Senior
April 30, 2024

Hi @CMYL 
Could you please suggest some solution
THanks