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-AM64X: Using HSM to build OPT keywriter application

Part Number: PROCESSOR-SDK-AM64X

Tool/software:

Hi Team

We are implementing secure boot on a AM64X based custom board. We want to use a HSM to keep our custom keys (SMPK, BMPK, SMEK, BMEK) secret.

We think we can accomplish this with respect to signing the bootloaders and the kernel. However, we found a fundamental flaw in the build process of the keywriter application.

In order to explain the flaw, we refer to the diagram here https://software-dl.ti.com/tisci/esd/10_00_08/6_topic_user_guides/key_writer.html?highlight=fek#procedure. This diagram suggests, that the SMEK and BMEK keys are AES encrypted with a temporary AES-256 key.

The SMEK and BMEK keys are used to AES encrypt the bootloaders and/or the kernel , see https://software-dl.ti.com/tisci/esd/10_00_08/6_topic_user_guides/secure_boot_signing.html#signing-an-encrypted-binary-for-secure-boot and must be therefore held secret.

To accomplish this, we want to keep the SMEK and BMEK keys inside the HSM. However, if we do so, we are no more able to AES encrypt the keys. This is because encrypting the keys requires the keys to be extracted in plain from the HSM which is not (must no be) possible. Note that we want to use the PKCS#11 API to talk with the HSM. This API does not provide any means to AES encode data where the data is itself a key located in the HSM.

Any idea how to resolve this issue ?

  • Hello,

    The SMEK or BMEK must leave the HSM in one form or another for the keywriter to burn them into the efuses. I have only heard about PKCS#11 HSMs but a quick search on the internet suggests that there is a provision of extractable symmetric keys:

    https://python-pkcs11.readthedocs.io/en/latest/applied.html#aes-des

    Regards,

    Prashant

  • Hello,

    Making secret keys extractable is not a real solution. We don't need a HSM if secret keys are extractable.

    Obviously the TI commissioning process requires a secret key to leave the HSM. From our point of view this is a security issue. And a very good example how complexity leads to less security. Is there any good reason why you don't simply encode the customer keys with TI FEC-pub ?

  • Is there any good reason why you don't simply encode the customer keys with TI FEC-pub ?

    Could you please elaborate more on this?

    My current understanding is:

    In a symmetric encryption/decryption scheme, both the entities (HSM & ROM/TIFS for encryption & decryption respectively) must have access to the same symmetric key. So, the symmetric key must leave the HSM in one form or another & burnt into the efuses.

    Are you suggesting that the key can not leave the HSM in plain (ofcourse) or encrypted form but could leave in some other form?

    Thanks,

    Prashant 

  • I agree in that symmetric keys must be known to ROM/TIFS and therefore leave our HSM. However, I think this fact is exactly the reason why TI encrypts the SMEK/BMEK keys before writing them into the X509 extensions, right ?

    Point is that this very encryption procedure forces us to read the SMEK/BMEK keys in plain from the HSM. Please have a look at the gen_keywr_cert.sh script provided by the OPT keywriter. In particular the gen_sym_key_x509_extension() function call.

    gen_sym_key_x509_extension(){
        # gen_iv <OUTFILE>
        gen_iv "$4"
        # gen_rs <OUTFILE>
        gen_rs "$5"
        IV=$(xxd -p -c 32 "$4")
        cat "$2" "$5" > "$6"
        openssl dgst -sha512 -binary "$2" > "$3"
        echo "$1,$(xxd -p $3)" >> "${output_info[hash_csv]}"
        openssl aes-256-cbc -e -K "${aes256key_info[val]}" -iv "${IV}" -nopad -in "$6" -out "$7"
    }

    The $2 argument in the red marked line refers to either the SMEK or the BMEK secret key which obviously must be read in plain from the HSM.

  • Hello,

    However, I think this fact is exactly the reason why TI encrypts the SMEK/BMEK keys before writing them into the X509 extensions, right ?

    That is one reason to justify the encryption of the SMEK/BMEK keys.

    But, the another reason is that one cannot know these keys from the certificate alone without knowing the random AES key. Since, this random AES key is itself encrypted with the TIFEK public key, the TIFS keywriter is the only entity that can decrypt the SMEK/BMEK encryption keys from the certificate & thus preserving the secrecy of these keys.

    The $2 argument in the red marked line refers to either the SMEK or the BMEK secret key which obviously must be read in plain from the HSM.

    The current keywriter is designed on the assumption that the keys are present in the local filesystem. So, It then takes the responsibility of reading those keys & encrypting them for putting in the X.509 certificate.

    For any custom design, that function is subject to change. You could modify it to get the keys in encrypted form from the HSM & save it to passed output file ("$7" argument). Everything else in the keywriter remains unaffected.

    Regards,

    Prashant

  • For any custom design, that function is subject to change. You could modify it to get the keys in encrypted form from the HSM & save it to passed output file ("$7" argument). Everything else in the keywriter remains unaffected.

    I agree that this function is subject to change. But how would you modify this function then ? I would be very grateful for any hint. However, I'm afraid this is not possible. So far, I did not find any PKCS#11 command sequence that covers what is required by that function while keeping the secret keys inside the HSM.

  • Hello,

    Can you please explain a little bit about your current architecture for the keywriter certificate generation procedure?

    Is there a local host that is performing the keywriter certificate generation procedure & it interacts with the PKCS#11 interface to get any necessary output from the HSM like the public key hashes, etc?

    Is it possible to just port the keywriter certificate generation script inside the HSM, ask it run to the script, and provide the output (certificate)?

    Thanks,

    Prashant

  • Ok, I try to explain. We target an architecture as depicted below:

    We will have an admin host (violet) connected to a dedicated port of the HSM (blue) where all key management tasks will be performed. This includes key generation. Note that dedication is defined by elevated access rights not necessarily by the physical connection. CI/CD (green) and development hosts (green) are connected to the HSM via network. The keywriter build infrastructure (and therefore certificate generation) will be deployed to the admin host (violet).

    The procedure we target to build the keywriter application is as follows:

    1) On the HSM: Generate RSA key pairs (SMPK, BMPK)
    => Private keys cannot leave the HSM
    2) On the HSM:  Generate AES keys (SMEK, BMEK)
    => AES keys cannot leave the HSM
    3) On the HSM: Generate the temporary AES-256 key.
     => Here we could accept to (temporarily) store the AES-256 key in the file system of the admin host instead. However, we think this does not really contribute to an improvement.
    4) On the admin host: Build keywriter application

    During keywriter application build, the admin host interacts with the HSM through PKCS#11 as you mentioned above.

    Is it possible to just port the keywriter certificate generation script inside the HSM, ask it run to the script, and provide the output (certificate)?

    We do not know if this is possible. We need a HSM vendor that provides this capability. We could possibly loose standard compliance guarantees in doing so. Therefore we hesitate to touch the HSM.

    Currently the only viable solution we can think of looks as follows:

    1) On the HSM: Generate RSA key pairs (SMPK, BMPK)
    2) On the admin host: Generate AES keys (SMEK, BMEK)
    3) On the admin host: Generate the temporary AES-256 key
    4) On the admin host: Build keywriter application
    5) On the admin host: Transfer the AES keys to the HSM
    6) On the HSM: Make the imported keys sensitive (thus cannot leave the HSM any more)
    7) On the admin host: Delete all AES keys

    Some more info:
    Step (4) in our target procedure (see above) is impossible due to the following instructions in the gen_sym_key_x509_extension() function called by the gen_keywr_cert.sh script:

    gen_rs "$5"
    cat "$2" "$5" > "$6"
    openssl aes-256-cbc -e -K "${aes256key_info[val]}" -iv "${IV}" -nopad -in "$6" -out "$7"

    $5 is a 32 byte random number
    $2 is the 32 byte SMEK/BMEK key
    $IV is a 16 byte random number

    From our point of view, the openssl call which encrypts the SMEK/BMEK keys could possibly be replaced by something like the following:
    pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so -l -p <pin> --wrap \
        --id <wrapping-key> --application-id <key-to-be-wrapped> -m AES-CBC --iv ${IV} > $7

    This function wraps <key-to-be-wrapped> (e.g. SMEK) by <wrapping-key> (e.g. AES-256) both located on the HSM and outputs the AES-CBC encrypted result. I checked this with SoftHSM.

    However, the 32 byte random number $5 appended to $2 (cat "$2" "$5" > "$6") spits us into the soup. This results in yet another 64 byte value which is the value effectively encrypted.

    What is this 32 byte appendix good for ? The SMEK/BMEK keys are already well aligned and padding is not required, correct ?

    Regards

    Walter