OP-TEE / optee_os

Trusted side of the TEE
Other
1.6k stars 1.07k forks source link

Reading secure object from OPTEE-OS core #6441

Closed Amit-Radur closed 1 year ago

Amit-Radur commented 1 year ago

Would like to read an object file that is stored into secure storage, i.e. at /data/tee from OPTEE-OS core, and then pass it to an crypto engine block registered as drvcrypt_register_xxx, Does it need to have PTA that would call API like TEE_MemMove ?

jenswi-linaro commented 1 year ago

If you need a PTA or not depends on how this is triggered.

etienne-lms commented 1 year ago

I agree with @jenswi-linaro. A PTA is not a driver, it's just an interface between a client and core service. From docs PTA section:

A Pseudo Trusted Application is not a Trusted Application. A Pseudo TA is not a specific entity. A Pseudo TA is an interface. It is an interface exposed by the OP-TEE Core to its outer world: to secure client Trusted Applications and to non-secure client entities.

Amit-Radur commented 1 year ago

@jenswi-linaro @etienne-lms Okay, but how do one verify encryption/decryption of an file that resides in secure storage (at /data/tee, and file has data like "abc" that needed to be verified with encryption/decryption) using vendor specific crypto Engine. Whenever I try opening an new session (TEE_IOC_OPEN_SESSION running say "optee_example_hello_world" CA) , it jumps[1]: into the my crypto engine registered with drvcrypt_register_xxx but how to pass the file data to this registered crypto engine driver.

Can APIs like "TEE_OpenPersistentObject" be called while OPTEE-OS is still booting (from tee_fs_init_key_manager()) ?

[1]: ioctl(3, TEE_IOC_VERSION, {impl_id=TEE_IMPL_ID_OPTEE, gen_caps=TEE_GEN_CAP_GP|TEE_GEN_CAP_MEMREF_NULL, impl_caps=TEE_OPTEE_CA0 ioctl(3, TEE_IOC_OPEN_SESSION, {buf_len=184, buf_ptr={uuid=8aaaf200-2450-11e4-abe2-0002a5d5c51b, clnt_login=TEE_IOCTL_LOGIN_Pb D/TC:?? 00 ldelf_load_ldelf:96 ldelf load address 0x40006000 D/LD: ldelf:142 Loading TS 8aaaf200-2450-11e4-abe2-0002a5d5c51b F/TC:?? 00 trace_syscall:149 syscall #3 (syscall_get_property) F/TC:?? 00 trace_syscall:149 syscall #5 (syscall_open_ta_session) D/TC:?? 00 ldelf_syscall_open_bin:142 Lookup user TA ELF 8aaaf200-2450-11e4-abe2-0002a5d5c51b (Secure Storage TA) D/TC:?? 00 ree_fs_open_primitive:417 ### ree_fs_open_primitive F/TC:?? 00 plat_prng_add_jitter_entropy:72 0xC3 D/TC:?? 00 tee_fs_htree_open:654 verify### root

etienne-lms commented 1 year ago

IIUC, what you're look for is more or less the tee_pobj layer: _teepobj.c. Or have a look at where OP-TEE core implements the secure storage API function exposeds to TAs (the GP TEE Internal Core API functions): _tee_svcstorage.c.

Can APIs like "TEE_OpenPersistentObject" be called while OPTEE-OS is still booting (from tee_fs_init_key_manager()) ?

TEE_OpenPersistentObject() is a user Trusted Application function. When OP-TEE core boots, no TA can be executed (like userland applications on top of the Linux kernel).

Amit-Radur commented 1 year ago

@etienne-lms Thanks for the pointers.

Or have a look at where OP-TEE core implements the secure storage API function exposed to TAs (the GP TEE Internal Core API functions): tee_svc_storage.c.

Do we have any such example TA's using APIs from tee_svc_storage.c ?

Also, is there a way to avoid calling into vendor specific drvcrypt_register_xxx (authenc.c) whenever there is user space CA application (like I mentioned above for optee_example_hello_world or for optee_example_secure_storage) ?

etienne-lms commented 1 year ago

TAs cannot call functions from tee_svc_storage.c. TAs execute in CPU user mode while core executes in CPU privileged mode. TAs uses system calls to reach core which in turn call functions from tee_svc_storage.c. For example, a TA can call TEE_OpenPersistentObject() which call _utee_storage_obj_open() which issues a syscall to switch execution in core, privileged mode, in function syscall_storage_obj_open() (_tee_svcstorage.c).

TAs never access raw secure storage data, they can only access their own persistent objects, following the TEE Object formalism defined by the GP TEE API specifications.

etienne-lms commented 1 year ago

Also, is there a way to avoid calling into vendor specific drvcrypt_register_xxx (authenc.c) whenever there is user space CA application (like I mentioned above for optee_example_hello_world or for optee_example_secure_storage) ?

Crypto drivers registered in core drvcrypto framework are used for all related crypto operations requested by the core, how ever is the caller.

If you want your HW crypto module to be used only for specific crypto operation from specific callers, you should not integrate it in OP-TEE drvcrypt framework. You will need a dedicated PTA with a dedicated interface that clients (non-secure applications and/or secure TAs) will explicitly invoke for those specific operation.

Amit-Radur commented 1 year ago

TAs never access raw secure storage data, they can only access their own persistent objects, following the TEE Object formalism defined by the GP TEE API specifications.

Okay, got this point but OPTEE core should allow to create secure storage object on own its using APIIs like tee_pobj_create_final, and access these objects to perform encryption/decryption operations on it, right ?

If so, it would be really helpful to know which exact API one should use to create secure storage object?

etienne-lms commented 1 year ago

OP-TEE core could do that, for sure. Up to now, there was not need for such an API. Note that OP-TEE core must ensure it will not create object that could conflict with object created by TAs. Note also that OP-TEE may not be able to reach the secure storage at boot time. For example, when the secure storage is located in a Linux file system (CFG_TEE_FS=y), OP-TEE needs the non-secure OS (or some equivalent) to access the storage.

Maybe can you describe more precisely what is your need so we can discuss the best way to handle it?

Amit-Radur commented 1 year ago

Maybe can you describe more precisely what is your need so we can discuss the best way to handle it?

At the moment, I have HW accelerated crypto block registered as drvcrypt using drvcrypt_register_xxx() functions. It does support AES operations, and registers to AE (Authenticated Encryption), and verified it by encrypting/decrypting some data that is defined locally , for instance I have (vendor_aes_engine_huk.c)

uint8_t payload_data[] __aligned(4) = {11, 22, 33, 44, 55, 66, 77, 88};

aes_gcm_encrypt_image() {
    /*
     * This payload_data along with aad (combined_data) is passed to 
     */
    ret = crypto_authenc_enc_final(ctx, virt_to_phys(combined_data), sizeof(payload_data),
                    virt_to_phys(enc_data), &enc_data_len, enc_tag, &enc_tag_len);
}    

/* This is more of test code to prove encryption/decryption works, and we use tee_otp_get_hw_unique_key
 *  so that it can be called at boot time.
 */
 TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey)
 {
        memset(&hwkey->data[0], 0, sizeof(hwkey->data));
        aes_gcm_encrypt_image(); // This should read a file from REE file system, and perform encrypt/decrypt on it.

        return TEE_SUCCESS;
}

Now I would like to verify it using a file that is stored in secure storage or REE file system instead of having this data locally. Can there be TA that would pass file data to crypto_authenc_enc_final() , and that would eventually call into vendor specific HW crypto block or from vendor_aes_engine_huk.c one read REE file system file.

Also, looked at core/tee/tee_ta_enc_manager.c where like tee_ta_decrypt_init, can have tee_ta_encrypt_init/decrypt to verify it, but how to trigger these functions ?

etienne-lms commented 1 year ago

Do you mean you want to get the HUK from the secure storage? If so there is a chicken and egg problem. The keys used to cipher and authenticate data in the secure storage are derived from the HUK.

Amit-Radur commented 1 year ago

Do you mean you want to get the HUK from the secure storage?

No, I wanted to have payload (for encryption/decryption) from secure storage (or file stored in Linux file system) in term of a file. The key to authenticate data is taken by HW Crypto AES engine itself.

Amit-Radur commented 1 year ago

Another query I have, when a secure storage object is created (using a TA say optee_example_secure_storage) , the objecte is in encrypted form, May I know what is code flow that encrypts this object, is it happen here ?

https://github.com/ForgeRock/optee-os/blob/master/core/tee/fs_htree.c#L639

etienne-lms commented 1 year ago

Yes core/tee/fs_htree.c is where secure storage data are ciphered/signed/verified using AES GCM. Helpful details in Secure storage "hash-tree" section documentation about keys involved in secure storage (SSK, TSK and FEK) and related crypto operations.

Amit-Radur commented 1 year ago

@etienne-lms, I think for cipher process (encryption for FEK) it uses AES ECB mode but for decryption (the entire Image) it uses AES GCM.

The image here is the object file that gets created in encrypted form, right ?

Also, while running a simple TA (optee_example_secure_storage), control does not enter into following if condition even for once, and wondering how encryption is performed.

if (create) { const struct tee_fs_htree_image dummy_head = { .counter = 0 }; . . .

https://github.com/ForgeRock/optee-os/blob/master/core/tee/fs_htree.c#L632C2-L634C1

Looking to offload this encryption/decryption to HW based crypto engine block.

etienne-lms commented 1 year ago

@etienne-lms, I think for cipher process (encryption for FEK) it uses AES ECB mode but for decryption (the entire Image) it uses AES GCM.

The image here is the object file that gets created in encrypted form, right ?

(edited in bold): I meant, yes you are right

You can check the key ladder from Secure storage "hash-tree" section documentation. FEK is encrypted/decrypted with AES ECB while the data payload (read from storage/written to storage) is processed (encrypted/signed and decrypted/authenticated) with AES GCM.

Note that encrypted FEK is also stored in the secure storage, with some other payload side information (metadata). The metadata are also processed with AES GCM.

Also, while running a simple TA (optee_example_secure_storage), control does not enter into following if condition even for once, and wondering how encryption is performed.

Likely because the hash tree was already created before you run _optee_example_securestorage. Try with an fully reset secure storage and run _optee_example_securestorage before any other OP-TEE TA invocation.

Amit-Radur commented 1 year ago

@etienne-lms , Thanks for the answers. May I know, which particular structure points to actual payload data, is it https://github.com/ForgeRock/optee-os/blob/master/core/include/tee/fs_htree.h#L55 ?

Also, in case of Versal, and STM32 platform, the encryption/decryption is completely offloaded to Hardware block instead of doing it through software algorithms ?

Amit-Radur commented 1 year ago

@jenswi-linaro @etienne-lms , can you please look into the latest queries ?

etienne-lms commented 1 year ago

Hi @Amit-Radur, sorry for the delayed answer.

Few new below your pointer is shows the IDs used to distinguish hash tree head blobs (TEE_FS_HTREE_TYPE_HEAD), meta data blobs (TEE_FS_HTREE_TYPE_NODE) and payload blobs (TEE_FS_HTREE_TYPE_BLOCK): https://github.com/ForgeRock/optee-os/blob/master/core/include/tee/fs_htree.h#L65.

Also, in case of Versal, and STM32 platform, the encryption/decryption is completely offloaded to Hardware block instead of doing it through software algorithms ?

For Versal, I cannot tell. I guess the answer is yes when CFG_VERSAL_CRYPTO_DRIVER=y but you should rather ask @ldts.

For STM32 based on STM32MP13 (PLATFORM=stm32mp1-135F_DK), the answer is yes: STM32 SAES driver (_core/drivers/crypto/stm32/stm32saes.c) is used for AES ECB and GCM.

For STM32 based on STM32MP15 (e.g. PLATFORM=stm32mp1-157C_DK2), the answer is no when using the default released setup. The platform chip embeds an STM32 CRYP instance that supports AES ECB and GCM (_core/drivers/crypto/stm32/stm32cryp.c) but the default setup assigns it to Linux (for some legacy reasons). You can however assign STM32 CRYP to OP-TEE. To do so, on STM32MP15x-DK2 boards for example, you need to have Linux and U-Boot using stm32mp157c-dk2-scmi.dts DTS file (see https://github.com/OP-TEE/build/pull/701), disable cryp@54001000 node in Linux arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts file and enable that cryp@54001000 node in OP-TEE OS core/arch/arm/dts/stm32mp157c-dk2.dts file. The same changes can apply to STM32MP15x-EV1/ED1 boards (resp. stm32mp157c-ev1*.dts and stm32mp157c-ed1*.dts) boards. Such changes can't apply to STM32MP15x-DK1 board (stm32mp157a-dk1*.dts) as this chip variant does not embed any STM32 CRYP instance.

Amit-Radur commented 1 year ago

@etienne-lms, Thanks. It helped.

What I see, in order to create an encrypted object (using OPTEE secure storage, and encryption/decryption is completely offloaded to Hardware block). Platform must support/implement drvcrypt_register_cipher and drvcrypt_register_authenc, its because HASH tree that manages secure storage using AES ECB (comes from cipher driver), and AES GCM (come from authenc driver).

Is this right understanding ?

Is there other way to use OPTEE's encrypted file system without going through HASH tree, for instance a platform that has Hardware crypto block that does support AES GCM (for encryption/decryption, there is no AES ECB), and an Image file that is stored in encrypted file system (or may be reading from non secure Linux filesystem) ?

Also, from STM32MP13, stm32_cipher_final() is empty() https://github.com/OP-TEE/optee_os/blob/master/core/drivers/crypto/stm32/cipher.c#L148

But then how encryption take place for fek ? https://github.com/OP-TEE/optee_os/blob/master/core/tee/tee_fs_key_manager.c#L122

etienne-lms commented 1 year ago

What I see, in order to create an encrypted object (using OPTEE secure storage, and encryption/decryption is completely offloaded to Hardware block). Platform must support/implement drvcrypt_register_cipher and drvcrypt_register_authenc, its because HASH tree that manages secure storage using AES ECB (comes from cipher driver), and AES GCM (come from authenc driver).

Is this right understanding ?

Yes.

Is there other way to use OPTEE's encrypted file system without going through HASH tree, for instance a platform that has Hardware crypto block that does support AES GCM (for encryption/decryption, there is no AES ECB), and an Image file that is stored in encrypted file system (or may be reading from non secure Linux filesystem) ?

The hash tree is there to protect the data stored in OP-TEE secure storage. It is highly recommended to use it. You could implement another mechanism but do that with care and with advise from experts.

Also, from STM32MP13, stm32_cipher_final() is empty() https://github.com/OP-TEE/optee_os/blob/master/core/drivers/crypto/stm32/cipher.c#L148

That is because everything is done from the update operation, unless I missed something. I think we should even remove the function since it's useless, crypto API don't mandate .final handlers to be populated in the crypto drivers operations structures:

Amit-Radur commented 1 year ago

Thanks @etienne-lms , almost got all my answers to get going on this.

The final thing, would like to know what are the other mechanism can be used to secure storage without going hash tree layer given that platform does only support AES GCM( ?

etienne-lms commented 1 year ago

I know no available solution for OP-TEE REE_FS secure storage not using the hash tree. As for AES GCM, I think there are ways to use an AES GCM sequence to mimic an AES ECB operation, just drop the authen tag part.

Amit-Radur commented 1 year ago

Okay, thanks for clarifying this. Marking it close.