microsoft / ms-tpm-20-ref

Reference implementation of the TCG Trusted Platform Module 2.0 specification.
Other
345 stars 134 forks source link

NV_MEMORY_SIZE #67

Closed railabouni closed 2 years ago

railabouni commented 2 years ago

hi all,

https://github.com/microsoft/ms-tpm-20-ref/blob/d7a7c200fae3ab947efef8902d219072de94cc3e/Samples/ARM32-FirmwareTPM/optee_ta/fTPM/reference/include/TpmProfile.h#L207

reading the TpmProfile.h, I found that: NV_MEMORY_SIZE is defined to 16 Kilobytes, is there a particular reason for choosing this size (and not 12/20 KB for example)? as I've read here: https://trustedcomputinggroup.org/wp-content/uploads/PC-Client-Specific-Platform-TPM-Profile-for-TPM-2p0-v1p05p_r14_pub.pdf they do mention the 3834 Bytes without taking into consideration storage of any other persistent object, data or code that requires or consumes non-volatile memory. an older spec mentioned: 6962 bytes. (https://trustedcomputinggroup.org/wp-content/uploads/TCG_PC_Client_Platform_TPM_Profile_PTP_2.0_r1.03_v22.pdf)

Thank you!

bradlitterell commented 2 years ago

TL;DR; 16kB was a convenient size for the reference code to use for example.

Long Answer: The Reference code handling of NV data is very implementation specific. A separate implementation could choose to do things differently. Thus NV_MEMORY_SIZE is also implementation specific. Specifically, the reference code stores all NV data within this single large NV area, though that isn't required. For example, a specific implementation could store different index types in separate storage, subject to the minimums for other capabilities. E.g. TPM_PT_NV_COUNTERS_MAX has a minimum of 6 counters in the PC Platform spec, but a non-PC TPM could do something yet different. And even a PC implementation could create a new NV_COUNTER_MEMORY_SIZE definition of physical space solely for counters. It's not required that a TPM use the reference code in its implementation, so an implementation could store those counters in a separate NV region if it chose to.

Since the reference code stores everything within the same 16kB region reflected in NV_MEMORY_SIZE, there is a lot of additional "overhead" beyond the data called out in Section 4.5.1 Table 4. See 4.5.1 "Note: The sizes indicated in the table are the maximum size of the data area only and do not address the overhead. TPM vendors need to account for the overhead." In particular, Table 4 doesn't account for the various global data objects in the reference code, or does it account for TPM_PT_HR_PERSISTENT_MIN. These require a fair-sized block of NV space. Note also that the actual number of bytes required to support TPM_PT_HR_PERSISTENT_MIN == 7 (Section 4.1 Table 1) depends on the list of enabled algorithms. E.g. enabling RSA4k vs RSA2k will increase the number of required bytes for the same number of persistent objects. This is why the PC Platform spec doesn't specify bytes directly, but rather defines requirements in terms of capabilities.

Thus, an implementation can tweak NV_MEMORY_SIZE to fit its needs or do something differently. 16KB is a reasonable size for a minimal implementation using the reference code's NV storage strategy (everything in a big bucket), consistent with the PC platform spec while leaving a reasonable amount of space available for application use.

The official requirements for any given implementation are based on the specific requirements in the platform specs, which based on enabled options will result in an implementation-specific byte count.

railabouni commented 2 years ago

Thank you for the detailed response @BradL-Msft! greatly appreciated :)