Background
In secure media processing scenarios, we have hardware-protected memory regions (enforced by hardware firewall) that need to be accessed by Trusted Applications (TAs). The typical use case is:
- Hardware demux writes audio/video data directly to a secure memory buffer
- REE (Normal World) CPU cannot access this memory due to hardware firewall protection
- REE only knows the physical address and passes it to the TA
- TA needs to access this memory for decoding/processing
Current Limitations
Currently, OP-TEE's mobj mechanism has strict restrictions on memory types:
1. mobj_phys_alloc() only supports 4 predefined memory types:
enum buf_is_attr {
CORE_MEM_TEE_RAM,
CORE_MEM_TA_RAM,
CORE_MEM_NSEC_SHM,
CORE_MEM_SDP_MEM,
};
For arbitrary hardware-protected physical memory regions (e.g., secure audio/video buffers allocated by hardware), none of these types apply.
2. mobj_reg_shm_alloc() only accepts non-secure memory:
/* Only Non-secure memory can be mapped there */
if (!core_pbuf_is(CORE_MEM_NON_SEC, mobj_reg_shm->pages[i],
SMALL_PAGE_SIZE))
goto err;
This prevents mapping secure physical memory regions.
3. Cannot use shared memory approach:
- REE cannot access the memory (hardware firewall)
- Even if mapped as non-cacheable, REE's CPU cache might leak sensitive data
- Violates the security model
Current Workaround
We currently work around this by implementing a PTA-based proxy:
// PTA maps physical memory in kernel space
static TEE_Result xdev_map_phys_region(uint32_t instance_id, ...) {
kva = (vaddr_t)core_mmu_add_mapping(MEM_AREA_RAM_SEC, pa, len);
// Store kva, TA accesses via PTA read/write calls
}
// TA calls PTA for each read/write operation
utee_xdev_read_phys_region(handle, offset, buf, len);
utee_xdev_write_phys_region(handle, offset, buf, len);
Drawbacks:
- Every memory access requires a trap to secure world (performance overhead)
- Cannot directly access memory from TA
- More complex code structure
Proposed Solution
Add support for mapping arbitrary physical memory regions directly to TA address space, with proper security controls.
Option 1: Extend mobj_phys_alloc() with a new memory type
enum buf_is_attr {
CORE_MEM_TEE_RAM,
CORE_MEM_TA_RAM,
CORE_MEM_NSEC_SHM,
CORE_MEM_SDP_MEM,
CORE_MEM_SECURE_DEVICE, // New: for hardware-protected regions
};
Option 2: Add a new API for arbitrary physical memory mapping
/**
* mobj_phys_alloc_unchecked() - Create mobj for arbitrary physical memory
* @pa: Physical address
* @size: Size in bytes
* @mem_type: Memory type attributes (cache, etc.)
*
* This function creates an mobj for arbitrary physical memory without
* security checks. Caller (PTA) is responsible for ensuring the physical
* address is valid and accessible in secure world.
*/
struct mobj *mobj_phys_alloc_unchecked(paddr_t pa, size_t size,
uint32_t mem_type);
Option 3: Add PTA helper for mapping to TA address space
/**
* pta_map_phys_to_ta() - Map physical memory to calling TA's address space
* @pa: Physical address
* @size: Size in bytes
* @prot: Protection flags (TEE_MATTR_UR, TEE_MATTR_UW)
* @flags: Mapping flags (cached/non-cached)
* @va: [out] Virtual address in TA's address space
*
* Returns TEE_SUCCESS or error code
*/
TEE_Result pta_map_phys_to_ta(paddr_t pa, size_t size, uint32_t prot,
uint32_t flags, vaddr_t *va);
Use Case Example
// In TA:
TEE_Result decode_audio(uint64_t secure_audio_pa, uint32_t size) {
void *audio_buffer;
// Map physical memory directly to TA address space
TEE_Result res = map_secure_phys_region(secure_audio_pa, size,
TEE_MATTR_UR,
&audio_buffer);
if (res != TEE_SUCCESS)
return res;
// Direct access - no PTA calls needed
uint8_t *data = (uint8_t *)audio_buffer;
parse_audio_frame(data, size);
decode_audio_frame(data, size);
unmap_secure_phys_region(audio_buffer);
return TEE_SUCCESS;
}
Security Considerations
- Access Control: Only PTAs should be able to create such mappings, not TAs directly
- Validation: PTA should validate that the physical address is within allowed ranges
- Isolation: Each TA session should only access its own mapped regions
- Cleanup: Automatic cleanup when TA session closes
Benefits
- Performance: Zero-copy, direct memory access from TA
- Simplicity: Cleaner code, no PTA proxy needed for every access
- Flexibility: Supports various hardware-protected memory scenarios (DRM, secure camera, etc.)
- Standard: Aligns with how other TEE implementations handle secure memory
Questions
- Is there a security reason why arbitrary physical memory mapping is not supported?
- Would any of the proposed solutions be acceptable?
- Are there alternative approaches we should consider?
Environment
- OP-TEE Version: 4.1.0
- Platform: ARM64
- Use Case: Secure audio/video processing with hardware firewall protection
Thank you for considering this feature request!
Background
In secure media processing scenarios, we have hardware-protected memory regions (enforced by hardware firewall) that need to be accessed by Trusted Applications (TAs). The typical use case is:
Current Limitations
Currently, OP-TEE's
mobjmechanism has strict restrictions on memory types:1.
mobj_phys_alloc()only supports 4 predefined memory types:For arbitrary hardware-protected physical memory regions (e.g., secure audio/video buffers allocated by hardware), none of these types apply.
2.
mobj_reg_shm_alloc()only accepts non-secure memory:This prevents mapping secure physical memory regions.
3. Cannot use shared memory approach:
Current Workaround
We currently work around this by implementing a PTA-based proxy:
Drawbacks:
Proposed Solution
Add support for mapping arbitrary physical memory regions directly to TA address space, with proper security controls.
Option 1: Extend
mobj_phys_alloc()with a new memory typeOption 2: Add a new API for arbitrary physical memory mapping
Option 3: Add PTA helper for mapping to TA address space
Use Case Example
Security Considerations
Benefits
Questions
Environment
Thank you for considering this feature request!