Hi, I'm currently working on porting TFA to our upcoming SOC. We plan to support Measured boot using external I2C TPM module. I'm wondering about the implementation of that in BL1. Do you think that I need to write the measurements directly to the I2C module in BL1 ? I'm asking because I would like to have the least source of problems in BL1 which I can't upgrade. I thought of storing the measurements in secure RAM and perhaps copy later. Would love to hear your thoughts.
PS. Actually I would love to have the option to choose to implement TPM also in SW (fTPM using optee - as was done in the POC). I think that if I store the measurement of BL2 in secure RAM I can later change the specific TPM while upgrading only BL2/BL31...
Thanks, Ramon
Hello Ramon,
In my view, there are pros and cons for each of these solutions. Choosing the best design depends on the exact platform requirements.
Given that BL1 cannot be updated on your platform, you probably want to keep it as simple as possible to reduce the risk of introducing unpatchable bugs. If BL1 is responsible for measuring BL2 and writing this measurement into the I2C TPM, obviously it needs the measurement logic as well as some (potentially simplified) TPM driver. This might be undesirable, depending on how complex the TPM driver would be. -> This is solution 1 (BL1 measures BL2 and records the measurement in the TPM).
An alternate design, as you say, is to measure BL2 from BL1, but initially store the measurement in secure RAM. Later, some other, updatable software component (e.g. BL2) can pick it up and store it in the TPM on behalf of BL1.
This removes the need to have a TPM driver in BL1. However, this is theoretically a bit less secure than solution 1 because it is conceptually easier to tamper with secure RAM than with the TPM, which is a separate chip dedicated to protect this kind of data. That being said, the window of time for which the measurement is kept in secure RAM before being securely stored in TPM might be small enough that the risk of someone tampering with it is acceptable. -> This is solution 2 (BL1 just measures BL2, BL2 records its own measurement).
Another option is for BL2 to self-measure itself (and store its own measurement to the TPM). This means BL1 does not even need the measurement capability. However, for this design to be secure, trust needs to be established in BL2, i.e. we need to be sure that it's not been tampered with and that we can trust it will correctly take the measurements and record them.
Typically this means you need trusted boot support in BL1 in order to verify the authenticity of BL2 image (unless there is some other way to establish this trust, perhaps delegating the authentication to some other entity). If you were not planning to enable trusted boot in BL1 then this is pulling extra complexity in BL1 anyway.
Also, the self-measurement needs to happen early enough in BL2, before any change is made to BL2 global data. Else, what you measure will not be BL2 initial state, but rather some early state of BL2. If this state is non-deterministic (think about the initialization of a canary with random value for stack smashing protection) then this makes it impossible to get a measurement which you can use for attestation purposes. -> This is solution 3 (BL2 self-measures itself).
To me, solution 3 sounds like the most complex one (but I thought it would be good to mention it in case it suits your use case). Which of solution 1 or 2 is best really depends on your requirements. In any case, it should be possible to implement any of these solutions with the current TF-A code base. It has been designed with the intent to leave as much freedom as possible to platform implementations. Effectively the only expectation is that the platform layer should provide 3 hooks - init, measure and exit - in BL1 and in BL2. If, say, you wanted to go with solution 3 then all 3 hooks for BL1 would do nothing.
I hope that helps.
Regards, Sandrine
On 5/30/22 12:15, Ramon Fried wrote:
Hi, I'm currently working on porting TFA to our upcoming SOC. We plan to support Measured boot using external I2C TPM module. I'm wondering about the implementation of that in BL1. Do you think that I need to write the measurements directly to the I2C module in BL1 ? I'm asking because I would like to have the least source of problems in BL1 which I can't upgrade. I thought of storing the measurements in secure RAM and perhaps copy later. Would love to hear your thoughts.
PS. Actually I would love to have the option to choose to implement TPM also in SW (fTPM using optee - as was done in the POC). I think that if I store the measurement of BL2 in secure RAM I can later change the specific TPM while upgrading only BL2/BL31...
Thanks, Ramon
On 5/30/22 9:09 AM, Sandrine Bailleux via TF-A wrote:
Hello Ramon,
In my view, there are pros and cons for each of these solutions. Choosing the best design depends on the exact platform requirements.
Given that BL1 cannot be updated on your platform, you probably want to keep it as simple as possible to reduce the risk of introducing unpatchable bugs. If BL1 is responsible for measuring BL2 and writing this measurement into the I2C TPM, obviously it needs the measurement logic as well as some (potentially simplified) TPM driver. This might be undesirable, depending on how complex the TPM driver would be. -> This is solution 1 (BL1 measures BL2 and records the measurement in the TPM).
One additional note on this-- The TPM has a special, simple, hardware interface specifically designed for making this initial measurement. The interface avoids the need for a complicated driver or even having software compute the measurement.
The simplified BL1 driver could do: -write any data to TPM_HASH_START register -write the bytes of the image to be measured to TPM_HASH_DATA register -write any data to TPM_HASH_END register
That results in extending a measurement of the image into PCR0.
One thing to consider would be the performance of this interface. I don't know details of how long it takes, but it is slower than having the AP cores compute the haqsh.
Thanks, Stuart
Hi Stuart, The problem with implementing a driver for a specific TPM in BL1 is that you're stuck with that specific 3rd party TPM for life (or until the next tapeout). I would like to minimize the 3rd party drivers (outside the SOC) in BL1. Thanks, Ramon.
On Tue, May 31, 2022 at 6:30 PM Stuart Yoder stuart.yoder@arm.com wrote:
On 5/30/22 9:09 AM, Sandrine Bailleux via TF-A wrote:
Hello Ramon,
In my view, there are pros and cons for each of these solutions. Choosing the best design depends on the exact platform requirements.
Given that BL1 cannot be updated on your platform, you probably want to keep it as simple as possible to reduce the risk of introducing unpatchable bugs. If BL1 is responsible for measuring BL2 and writing this measurement into the I2C TPM, obviously it needs the measurement logic as well as some (potentially simplified) TPM driver. This might be undesirable, depending on how complex the TPM driver would be. -> This is solution 1 (BL1 measures BL2 and records the measurement in the TPM).
One additional note on this-- The TPM has a special, simple, hardware interface specifically designed for making this initial measurement. The interface avoids the need for a complicated driver or even having software compute the measurement.
The simplified BL1 driver could do: -write any data to TPM_HASH_START register -write the bytes of the image to be measured to TPM_HASH_DATA register -write any data to TPM_HASH_END register
That results in extending a measurement of the image into PCR0.
One thing to consider would be the performance of this interface. I don't know details of how long it takes, but it is slower than having the AP cores compute the haqsh.
Thanks, Stuart
On 6/4/22 8:53 AM, Ramon Fried wrote:
Hi Stuart, The problem with implementing a driver for a specific TPM in BL1 is that you're stuck with that specific 3rd party TPM for life (or until the next tapeout). I would like to minimize the 3rd party drivers (outside the SOC) in BL1.
With the interface I described you shouldn't need any vendor specific TPM driver in BL1. The locations of the TPM_HASH_START/DATA/END registers are standard. BL1 simply needs to be able access the TPM via the SPI or I2C bus.
Stuart
Sorry I might be missing some discussion. What is the reason to measure tf-a itself? Measuring the fip image has to measure tf-a also. Do you have some memory limits to flash fip?
BR, Maxim.
On Tue, 7 Jun 2022 at 11:22, Stuart Yoder via TF-A tf-a@lists.trustedfirmware.org wrote:
On 6/4/22 8:53 AM, Ramon Fried wrote:
Hi Stuart, The problem with implementing a driver for a specific TPM in BL1 is that you're stuck with that specific 3rd party TPM for life (or until the next tapeout). I would like to minimize the 3rd party drivers (outside the SOC) in BL1.
With the interface I described you shouldn't need any vendor specific TPM driver in BL1. The locations of the TPM_HASH_START/DATA/END registers are standard. BL1 simply needs to be able access the TPM via the SPI or I2C bus.
Stuart
TF-A mailing list -- tf-a@lists.trustedfirmware.org To unsubscribe send an email to tf-a-leave@lists.trustedfirmware.org
On Tue, Jun 7, 2022 at 11:55 AM Maxim Uvarov maxim.uvarov@linaro.org wrote:
Sorry I might be missing some discussion. What is the reason to measure tf-a itself? Measuring the fip image has to measure tf-a also. Do you have some memory limits to flash fip?
When you mention tf-a, do you mean only bl1 ? how would you know in the end the bl2, bl31, and bl33 were not tampered ? Thanks, Ramon
BR, Maxim.
On Tue, 7 Jun 2022 at 11:22, Stuart Yoder via TF-A tf-a@lists.trustedfirmware.org wrote:
On 6/4/22 8:53 AM, Ramon Fried wrote:
Hi Stuart, The problem with implementing a driver for a specific TPM in BL1 is that you're stuck with that specific 3rd party TPM for life (or until the next tapeout). I would like to minimize the 3rd party drivers (outside the SOC) in BL1.
With the interface I described you shouldn't need any vendor specific TPM driver in BL1. The locations of the TPM_HASH_START/DATA/END registers are standard. BL1 simply needs to be able access the TPM via the SPI or I2C bus.
Stuart
TF-A mailing list -- tf-a@lists.trustedfirmware.org To unsubscribe send an email to tf-a-leave@lists.trustedfirmware.org
On Tue, 7 Jun 2022 at 18:13, Ramon Fried rfried.dev@gmail.com wrote:
On Tue, Jun 7, 2022 at 11:55 AM Maxim Uvarov maxim.uvarov@linaro.org wrote:
Sorry I might be missing some discussion. What is the reason to measure tf-a itself? Measuring the fip image has to measure tf-a also. Do you have some memory limits to flash fip?
When you mention tf-a, do you mean only bl1 ?
yes.
how would you know in the end the bl2, bl31, and bl33 were not tampered ?
you flash fip (ml2,bl31, bl33), erase eFuse and if the signature of the fip does not match then it will not be loaded. Measurements can start after optee (ftpm) starts..
Thanks, Ramon
BR, Maxim.
On Tue, 7 Jun 2022 at 11:22, Stuart Yoder via TF-A tf-a@lists.trustedfirmware.org wrote:
On 6/4/22 8:53 AM, Ramon Fried wrote:
Hi Stuart, The problem with implementing a driver for a specific TPM in BL1 is that you're stuck with that specific 3rd party TPM for life (or until the next tapeout). I would like to minimize the 3rd party drivers (outside the SOC) in BL1.
With the interface I described you shouldn't need any vendor specific TPM driver in BL1. The locations of the TPM_HASH_START/DATA/END registers are standard. BL1 simply needs to be able access the TPM via the SPI or I2C bus.
Stuart
TF-A mailing list -- tf-a@lists.trustedfirmware.org To unsubscribe send an email to tf-a-leave@lists.trustedfirmware.org
On Tue, Jun 7, 2022 at 6:27 PM Maxim Uvarov maxim.uvarov@linaro.org wrote:
On Tue, 7 Jun 2022 at 18:13, Ramon Fried rfried.dev@gmail.com wrote:
On Tue, Jun 7, 2022 at 11:55 AM Maxim Uvarov maxim.uvarov@linaro.org wrote:
Sorry I might be missing some discussion. What is the reason to measure tf-a itself? Measuring the fip image has to measure tf-a also. Do you have some memory limits to flash fip?
When you mention tf-a, do you mean only bl1 ?
yes.
how would you know in the end the bl2, bl31, and bl33 were not tampered ?
you flash fip (ml2,bl31, bl33), erase eFuse and if the signature of the fip does not match then it will not be loaded. Measurements can start after optee (ftpm) starts..
What you suggest is for enabling measured boot you'll need secure boot. These are two separate things.
Thanks, Ramon
BR, Maxim.
On Tue, 7 Jun 2022 at 11:22, Stuart Yoder via TF-A tf-a@lists.trustedfirmware.org wrote:
On 6/4/22 8:53 AM, Ramon Fried wrote:
Hi Stuart, The problem with implementing a driver for a specific TPM in BL1 is that you're stuck with that specific 3rd party TPM for life (or until the next tapeout). I would like to minimize the 3rd party drivers (outside the SOC) in BL1.
With the interface I described you shouldn't need any vendor specific TPM driver in BL1. The locations of the TPM_HASH_START/DATA/END registers are standard. BL1 simply needs to be able access the TPM via the SPI or I2C bus.
Stuart
TF-A mailing list -- tf-a@lists.trustedfirmware.org To unsubscribe send an email to tf-a-leave@lists.trustedfirmware.org
Hi Sandrine, Thanks for your great answer. After reading your answer I just realized that Measured boot is not an extension to Secure boot, it's parallel. So solution 1 looks like a great choice. Thanks again. Ramon
On Mon, May 30, 2022 at 5:10 PM Sandrine Bailleux sandrine.bailleux@arm.com wrote:
Hello Ramon,
In my view, there are pros and cons for each of these solutions. Choosing the best design depends on the exact platform requirements.
Given that BL1 cannot be updated on your platform, you probably want to keep it as simple as possible to reduce the risk of introducing unpatchable bugs. If BL1 is responsible for measuring BL2 and writing this measurement into the I2C TPM, obviously it needs the measurement logic as well as some (potentially simplified) TPM driver. This might be undesirable, depending on how complex the TPM driver would be. -> This is solution 1 (BL1 measures BL2 and records the measurement in the TPM).
An alternate design, as you say, is to measure BL2 from BL1, but initially store the measurement in secure RAM. Later, some other, updatable software component (e.g. BL2) can pick it up and store it in the TPM on behalf of BL1.
This removes the need to have a TPM driver in BL1. However, this is theoretically a bit less secure than solution 1 because it is conceptually easier to tamper with secure RAM than with the TPM, which is a separate chip dedicated to protect this kind of data. That being said, the window of time for which the measurement is kept in secure RAM before being securely stored in TPM might be small enough that the risk of someone tampering with it is acceptable. -> This is solution 2 (BL1 just measures BL2, BL2 records its own measurement).
Another option is for BL2 to self-measure itself (and store its own measurement to the TPM). This means BL1 does not even need the measurement capability. However, for this design to be secure, trust needs to be established in BL2, i.e. we need to be sure that it's not been tampered with and that we can trust it will correctly take the measurements and record them.
Typically this means you need trusted boot support in BL1 in order to verify the authenticity of BL2 image (unless there is some other way to establish this trust, perhaps delegating the authentication to some other entity). If you were not planning to enable trusted boot in BL1 then this is pulling extra complexity in BL1 anyway.
Also, the self-measurement needs to happen early enough in BL2, before any change is made to BL2 global data. Else, what you measure will not be BL2 initial state, but rather some early state of BL2. If this state is non-deterministic (think about the initialization of a canary with random value for stack smashing protection) then this makes it impossible to get a measurement which you can use for attestation purposes. -> This is solution 3 (BL2 self-measures itself).
To me, solution 3 sounds like the most complex one (but I thought it would be good to mention it in case it suits your use case). Which of solution 1 or 2 is best really depends on your requirements. In any case, it should be possible to implement any of these solutions with the current TF-A code base. It has been designed with the intent to leave as much freedom as possible to platform implementations. Effectively the only expectation is that the platform layer should provide 3 hooks - init, measure and exit - in BL1 and in BL2. If, say, you wanted to go with solution 3 then all 3 hooks for BL1 would do nothing.
I hope that helps.
Regards, Sandrine
On 5/30/22 12:15, Ramon Fried wrote:
Hi, I'm currently working on porting TFA to our upcoming SOC. We plan to support Measured boot using external I2C TPM module. I'm wondering about the implementation of that in BL1. Do you think that I need to write the measurements directly to the I2C module in BL1 ? I'm asking because I would like to have the least source of problems in BL1 which I can't upgrade. I thought of storing the measurements in secure RAM and perhaps copy later. Would love to hear your thoughts.
PS. Actually I would love to have the option to choose to implement TPM also in SW (fTPM using optee - as was done in the POC). I think that if I store the measurement of BL2 in secure RAM I can later change the specific TPM while upgrading only BL2/BL31...
Thanks, Ramon
tf-a@lists.trustedfirmware.org