This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-AM62A: Reading HS-SE encryption keys in U-boot and/or Linux

Part Number: PROCESSOR-SDK-AM62A

Tool/software:

Hi,

I'm working on ciphering and deciphering Linux images in U-boot. I have successfully converted my SoC state to HS-SE with the otp keywriter tool. Now I want to use the key I programmed into HSM to decrypt some encrypted Linux images during my boot process. 

Is there a way to extract the keys from the HSM securely in U-boot? 

I have referenced /board-support/u-boot-2021.01+gitAUTOINC+2ee8efd654-g2ee8efd654/drivers/firmware/ti_sci.c but I don't see the method to do so.

SDK version: ti-processor-sdk-linux-am62axx-evm-08.06.00.45

Thank you,

Joseph

  • Hello,

    Is there a way to extract the keys from the HSM securely in U-boot? 

    That is not possible.

    The best you can do is use the following TISCI message to authenticate and decrypt a signed and encrypted blob.

    https://software-dl.ti.com/tisci/esd/latest/2_tisci_msgs/security/PROC_BOOT.html#proc-boot-authenticate-image-and-configure-processor

    Regards,

    Prashant

  • Hi Prashant,

    Thanks for your response and sharing this TISCI message. I read up on TISCI_MSG_PROC_SET_CONFIG and I don't see how it relates to decryption. I see the A53 config flags in ti_sci.h but again these don't mention decryption.

    I'm currently signing and encrypting images using the appimage_x509_cert_gen.py script from the mcu sdk. In U-boot I can authenticate the images and even decrypt them but I'm hardcoding the aes key in U-boot for testing purposes. I want to move away from this as I've confirmed authentication and decryption are working. 

    I know you said it's not possible to extract the keys. Instead, is there another method to decrypt my images that uses the keys stored in the HSM somehow?

    Are there any examples for how this is done?

    Regards,

    Joseph

  • Hello,

    The message I referred to is: TISCI_MSG_PROC_AUTH_BOOT

    Given a signed and encrypted blob, this message returns the raw decrypted blob if the blob is signed and encrypted with the correct keys. These keys would be the active programmed key (SMPK/SMEK or BMPK/BMEK) in the efuses.

    Regards,

    Prashant

  • Thanks for clarifying. I'm slightly familiar with this message as I've had to add debug in the function below.

    void ti_secure_image_post_process(void **p_image, size_t *p_size)
    {
    	struct ti_sci_handle *ti_sci = get_ti_sci_handle();
    	struct ti_sci_proc_ops *proc_ops = &ti_sci->ops.proc_ops;
    	size_t cert_length;
    	u64 image_addr;
    	u32 image_size;
    	int ret;
    
    	image_size = *p_size;
    
    	if (!image_size)
    		return;
    
    	if (get_device_type() == K3_DEVICE_TYPE_GP) {
    		if (ti_secure_cert_detected(*p_image)) {
    			printf("Warning: Detected image signing certificate on GP device. "
    			       "Skipping certificate to prevent boot failure. "
    			       "This will fail if the image was also encrypted\n");
    
    			cert_length = ti_secure_cert_length(*p_image);
    			if (cert_length > *p_size) {
    				printf("Invalid signing certificate size\n");
    				return;
    			}
    
    			*p_image += cert_length;
    			*p_size -= cert_length;
    		}
    
    		return;
    	}
    
    	if (get_device_type() != K3_DEVICE_TYPE_HS_SE &&
    	    !ti_secure_cert_detected(*p_image)) {
    		printf("Warning: Did not detect image signing certificate. "
    		       "Skipping authentication to prevent boot failure. "
    		       "This will fail on Security Enforcing(HS-SE) devices\n");
    		return;
    	}
    
    	/* Clean out image so it can be seen by system firmware */
    	image_addr = dma_map_single(*p_image, *p_size, DMA_BIDIRECTIONAL);
    
    	debug("Authenticating image at address 0x%016llx\n", image_addr);
    	debug("Authenticating image of size %d bytes\n", image_size);
    
    	/* Authenticate image */
    	ret = proc_ops->proc_auth_boot_image(ti_sci, &image_addr, &image_size);
    	if (ret) {
    		printf("Authentication failed!\n");
    		hang();
    	}
    
    	/* Invalidate any stale lines over data written by system firmware */
    	if (image_size)
    		dma_unmap_single(image_addr, image_size, DMA_BIDIRECTIONAL);
    
    	/*
    	 * The image_size returned may be 0 when the authentication process has
    	 * moved the image. When this happens no further processing on the
    	 * image is needed or often even possible as it may have also been
    	 * placed behind a firewall when moved.
    	 */
    	*p_size = image_size;
    
    	/*
    	 * Output notification of successful authentication to re-assure the
    	 * user that the secure code is being processed as expected. However
    	 * suppress any such log output in case of building for SPL and booting
    	 * via YMODEM. This is done to avoid disturbing the YMODEM serial
    	 * protocol transactions.
    	 */
    	if (!(IS_ENABLED(CONFIG_SPL_BUILD) &&
    	      IS_ENABLED(CONFIG_SPL_YMODEM_SUPPORT) &&
    	      spl_boot_device() == BOOT_DEVICE_UART))
    		printf("Authentication passed\n");
    }

    I found that I was only able to pass authentication when the p_image I passed in had the signature at the top followed by the decrypted data. The p_size I passed in was the size of the decrypted image with the certificate. 

    1. Also for some reason the image_size returned from proc_auth_boot_image is always 0. There's a comment that explains why but how are we expected to handle this? Should we be adding our own code to save the expected image size?

    2. Outside of U-boot what is the correct order for signing and encrypting images? Should we sign the image first and then encrypt or vice-versa?

    I noticed inside U-boot, it first tries to decrypt the blob and then authenticates using ti_secure_image_post_process()

    Thanks,

    Joseph

  • Hello,

    1. Also for some reason the image_size returned from proc_auth_boot_image is always 0. There's a comment that explains why but how are we expected to handle this? Should we be adding our own code to save the expected image size?

    It should not be 0. If the authentication is successful, the image_size field will be equal to the decrypted blob size.

    2. Outside of U-boot what is the correct order for signing and encrypting images? Should we sign the image first and then encrypt or vice-versa?

    Please see the following guide:

    https://software-dl.ti.com/tisci/esd/latest/6_topic_user_guides/secure_boot_signing.html#signing-an-encrypted-binary-for-secure-boot

    The following script in the MCU+ SDK implements those steps:

    https://github.com/TexasInstruments/mcupsdk-core-k3/blob/k3_next/tools/boot/signing/appimage_x509_cert_gen.py

    Regards,

    Prashant

  • Hi Prashant,

    Thanks again for your detailed response. Based on your replies it sounds like TISCI_MSG_PROC_AUTH_BOOT takes care of both authentication and decryption as long as the blobs are encrypted and signed in the right order.

    I think I may know where my problem is. I will try turning off CONFIG_FIT_CIPHER in U-boot so it doesn't try to decrypt my images manually first. What then is the purpose of CONFIG_FIT_CIPHER if not for secure boot?

    Best,

    Joseph

  • Hi Prashant,

    I was able to boot my encrypted Linux images using TISCI_MSG_PROC_AUTH_BOOT. Not sure if this has been fixed in the recent versions but there's a bug in the appimage_x509_cert_gen.py script where "initalVector" is spelled incorrectly causing issues when calling the script by default.

    I also used authtype 2 in the script to get everything working. Is this the expected input parameter? From below, what does "Move to the certificate start after authentication" mean?

    help='Authentication type. [0/1/2]. 0 - Move to destination address specified after authentication, 1 - In place authentication, 2 - Move to the certificate start after authentication. Default is 1')

    Thanks,

    Joseph

  • Hello,

    Not sure if this has been fixed in the recent versions but there's a bug in the appimage_x509_cert_gen.py script where "initalVector" is spelled incorrectly causing issues when calling the script by default.

    Not sure what issue you saw. It is just an identifier so it should not cause any issues.

    From below, what does "Move to the certificate start after authentication" mean?

    Given a signed image (X.509 certificate + blob) at address X, the TIFS moves the blob to address where the certificate starts after the authentication. This means, the address X would contain the raw blob after successful authentication.

    Regards,

    Prashant