Hi,
I'm currently working on audit session in order to achieve the following goals:
- remotely attest that a TPM really executed a sequence of commands w/ success
- (bonus) get the Response of each audited command
After reading a bunch of resources:
I've unsterstood the following: we have an untrusted component1 (outside the TPM) which maintain an audit log w/ TPM command & response parameters and TPM2_GetSessionAuditDigest allows to get an attestation about the digest of the audit session.
Theoretically, from the untrusted audit log a remote party is able to recompute a digest and check if it matches the one produced by TPM2_GetSessionAuditDigest to know if it can be trusted.
|
// NewAudit initializes a new CommandAudit with the specified hash algorithm. |
|
func NewAudit(hash TPMIAlgHash) (*CommandAudit, error) { |
|
h, err := hash.Hash() |
|
if err != nil { |
|
return nil, err |
|
} |
|
return &CommandAudit{ |
|
hash: hash, |
|
digest: make([]byte, h.Size()), |
|
}, nil |
|
} |
|
|
|
// AuditCommand extends the audit digest with the given command and response. |
|
// Go Generics do not allow type parameters on methods, otherwise this would be |
|
// a method on CommandAudit. |
|
// See https://github.com/golang/go/issues/49085 for more information. |
|
func AuditCommand[C Command[R, *R], R any](a *CommandAudit, cmd C, rsp *R) error { |
|
cc := cmd.Command() |
|
cpHash, err := auditCPHash[R](cc, a.hash, cmd) |
|
if err != nil { |
|
return err |
|
} |
|
rpHash, err := auditRPHash(cc, a.hash, rsp) |
|
if err != nil { |
|
return err |
|
} |
|
ha, err := a.hash.Hash() |
|
if err != nil { |
|
return err |
|
} |
|
h := ha.New() |
|
h.Write(a.digest) |
|
h.Write(cpHash) |
|
h.Write(rpHash) |
|
a.digest = h.Sum(nil) |
|
return nil |
|
} |
CommandAudit & AuditCommand functions seems to provide this logic but not in a way that is suitable for my use case.
Ideally would like to obtain this kind of output:
hash(commandA)<DELIMITER>marshal(responseA)
hash(commandB)<DELIMITER>marshal(responseB)
hash(commandC)<DELIMITER>marshal(responseC)
...
- It would allow to keep command privacy2
- It would allow the remote party to unmarshal the response to access some values (e.g. GetCapability, etc.)
- It would allow to reproduce the hash w/ the same logic implemented in
AuditCommand (i.e. auditRPHash)
It doesn't seems that Command or/and Response to be marshallable which prevent me to achieve my goals.
Does my request make sense or I miss something obvious?
Thank you in advance for your support!
Hi,
I'm currently working on audit session in order to achieve the following goals:
After reading a bunch of resources:
I've unsterstood the following: we have an untrusted component1 (outside the TPM) which maintain an audit log w/ TPM command & response parameters and
TPM2_GetSessionAuditDigestallows to get an attestation about the digest of the audit session.Theoretically, from the untrusted audit log a remote party is able to recompute a digest and check if it matches the one produced by
TPM2_GetSessionAuditDigestto know if it can be trusted.go-tpm/tpm2/audit.go
Lines 17 to 53 in bf12020
CommandAudit&AuditCommandfunctions seems to provide this logic but not in a way that is suitable for my use case.Ideally would like to obtain this kind of output:
AuditCommand(i.e. auditRPHash)It doesn't seems that Command or/and Response to be marshallable which prevent me to achieve my goals.
Does my request make sense or I miss something obvious?
Thank you in advance for your support!
Footnotes
an application ↩
I would like to avoid to have access to auth value but maybe that even the marshal version is encrypted ↩