oak
oak copied to clipboard
Create DICE Attester template
This PR adds a template for the Attester
class that will be used in all layers that support Protobuf.
Ref https://github.com/project-oak/oak/issues/4074
cc @conradgrobler @souravdasgupta for now the Protobuf Attester
can live in the oak_remote_attestation
crate (but potentially could be moved to a separate one).
And we also can have a similar Attester
for oak_dice
(the one that doesn't support Protobuf).
Though we need to understand how to pass measurements in a generic way (considering that we'll have custom measurements)
I personally don't like the name "attester" for this. This is specific to DICE (not generic attestation), and it does a much narrower thing that attesting in that it reads DICE data up to some layer and generates new DICE data that includes the next layer. Something like DiceLayerBuilder would be more appropriate.
In terms of specifying the measurements, I think the approach in https://github.com/project-oak/oak/blob/main/oak_dice/src/cert.rs#L138 to take the additional claims should be sufficient. This will leave the measurement as a separate implementation required by the layer and this can become a single implementation that works for all cases: start with a DICE data struct -> add some additional claims -> end up with a new DICE data struct.
The one additional requirements would be to specify where to add the new certificate: as a layer or a application keys.
I personally don't like the name "attester" for this. This is specific to DICE (not generic attestation), and it does a much narrower thing that attesting in that it reads DICE data up to some layer and generates new DICE data that includes the next layer. Something like DiceLayerBuilder would be more appropriate.
The name Attester
was taken from RATS (https://datatracker.ietf.org/doc/html/rfc9334#name-attester)
In Remote ATtestation procedureS (RATS), one peer (the "Attester") produces believable information about itself ("Evidence") to enable a remote peer (the "Relying Party") to decide whether or not to consider that Attester a trustworthy peer.
My issue that this does not provide such evidence, but is only one single step in the process of providing the evidence. The overall attestation evidence relies on multiple other components, such as the ASP generating an attestaiton report and the various layers measuring the code.
Stage0 Attester
can contain the code that generates the Attestation Report.
The idea is that we have attesters in each layer, and the last layer's attester becomes the one that generates the final evidence.
Measurements can also be implemented via a trait MeasurementProvider
, and they could run as part of the attester.
I'm just trying to abstract the attestation logic behind one interface.
Measurements can also be implemented via a
trait MeasurementProvider
, and they could run as part of the attester.
That feels more like a dependency injection pattern, which feels more appropriate for Java than Rust. I would prefer splitting the measurement completely from the DICE data generation, since this would be reusable in future if we switch to other forms of attestation such as RTMRs.
I'm just trying to abstract the attestation logic behind one interface.
I believe the interface for DICE is too specific to have a single abstraction for all attestation. I would split it into two parts: reusable parts that would also apply to other attestation mechanisms, and a DICE specific interface that this PR represents.
We still need an object from which we could request the Evidence
(not the DICE data), for example when the Hostlib or an application wants to get an evidence.
The idea is that we have attesters in each layer, and the last layer's attester becomes the one that generates the final evidence.
At the very least it should be clear that this is DICE-specific, so the name should include dice. This interface would not be suitable for RTMR-based attestations.
We can keep the concept of attester as an object from which you could request an Evidence
and make it a trait:
trait Attester {
fn get_evidence(&self) -> Evidence;
}
impl Attester for DiceAttester {}
impl Attester for RtmrAttester {}
And DiceAttester
will have an additional method:
impl DiceAttester {
fn generate_dice_data(&self) -> DiceData {}
}
We can keep the concept of attester as an object from which you could request an
Evidence
and make it a trait:
They won't even have the same evidence format, since there are no concept of layers in RTMRs.
They won't even have the same evidence format, since there are no concept of layers in RTMRs.
Ok, will not add a trait, and will keep a name DiceAttester
, so that it's specific to DICE. And in the future we'll have a separate RtmrAttester
.
@ipetr0v is this still relevant or useful for discussion? or can it be closed?
@ipetr0v is this still relevant or useful for discussion? or can it be closed?
I'll close this PR since it's outdated. But I still think it may be benefitial to have a unifier Attester
(or pick a different name) abstraction for different layers (and on different stacks).