cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U585 - TFM Application HKDF Implementation Using PSA Crypto

PJose.4
Senior

Hello @st

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
3 REPLIES 3
CMYL
ST Employee

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
Senior

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
Senior

Hi @CMYL 
Could you please suggest some solution
THanks