attest: Make PCRs included in quote configurable (#311)

Change the low-level Quote() functions so that the PCRs to be
included in the quote is selectable. Does not change the
high-level attestPlatform functions, which still retrieve
all PCRs.
This commit is contained in:
smo4201 2023-06-27 01:04:59 +02:00 committed by GitHub
parent b92d1c69bf
commit 8af5f4e7de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 24 additions and 19 deletions

View File

@ -103,7 +103,7 @@ type ak interface {
close(tpmBase) error
marshal() ([]byte, error)
activateCredential(tpm tpmBase, in EncryptedCredential, ek *EK) ([]byte, error)
quote(t tpmBase, nonce []byte, alg HashAlg) (*Quote, error)
quote(t tpmBase, nonce []byte, alg HashAlg, selectedPCRs []int) (*Quote, error)
attestationParameters() AttestationParameters
certify(tb tpmBase, handle interface{}) (*CertificationParameters, error)
}
@ -143,7 +143,16 @@ func (k *AK) ActivateCredential(tpm *TPM, in EncryptedCredential) (secret []byte
// This is a low-level API. Consumers seeking to attest the state of the
// platform should use tpm.AttestPlatform() instead.
func (k *AK) Quote(tpm *TPM, nonce []byte, alg HashAlg) (*Quote, error) {
return k.ak.quote(tpm.tpm, nonce, alg)
pcrs := make([]int, 24)
for pcr := range pcrs {
pcrs[pcr] = pcr
}
return k.ak.quote(tpm.tpm, nonce, alg, pcrs)
}
// QuotePCRs is like Quote() but allows the caller to select a subset of the PCRs.
func (k *AK) QuotePCRs(tpm *TPM, nonce []byte, alg HashAlg, pcrs []int) (*Quote, error) {
return k.ak.quote(tpm.tpm, nonce, alg, pcrs)
}
// AttestationParameters returns information about the AK, typically used to

View File

@ -65,7 +65,7 @@ func (k *trousersKey12) activateCredential(tb tpmBase, in EncryptedCredential, e
return cred, nil
}
func (k *trousersKey12) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, error) {
func (k *trousersKey12) quote(tb tpmBase, nonce []byte, alg HashAlg, selectedPCRs []int) (*Quote, error) {
t, ok := tb.(*trousersTPM)
if !ok {
return nil, fmt.Errorf("expected *linuxTPM, got %T", tb)
@ -73,6 +73,9 @@ func (k *trousersKey12) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, er
if alg != HashSHA1 {
return nil, fmt.Errorf("only SHA1 algorithms supported on TPM 1.2, not %v", alg)
}
if selectedPCRs != nil {
return nil, fmt.Errorf("selecting PCRs not supported on TPM 1.2 (parameter must be nil)")
}
quote, rawSig, err := attestation.GetQuote(t.ctx, k.blob, nonce)
if err != nil {

View File

@ -61,7 +61,7 @@ func (k *windowsKey12) activateCredential(t tpmBase, in EncryptedCredential, ek
return decryptCredential(secretKey, in.Secret)
}
func (k *windowsKey12) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, error) {
func (k *windowsKey12) quote(tb tpmBase, nonce []byte, alg HashAlg, selectedPCRs []int) (*Quote, error) {
if alg != HashSHA1 {
return nil, fmt.Errorf("only SHA1 algorithms supported on TPM 1.2, not %v", alg)
}
@ -80,11 +80,6 @@ func (k *windowsKey12) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, err
return nil, fmt.Errorf("TPMCommandInterface() failed: %v", err)
}
selectedPCRs := make([]int, 24)
for pcr := range selectedPCRs {
selectedPCRs[pcr] = pcr
}
sig, pcrc, err := tpm1.Quote(tpm, tpmKeyHnd, nonce, selectedPCRs[:], wellKnownAuth[:])
if err != nil {
return nil, fmt.Errorf("Quote() failed: %v", err)
@ -160,7 +155,7 @@ func (k *windowsKey20) activateCredential(t tpmBase, in EncryptedCredential, ek
return tpm.pcp.ActivateCredential(k.hnd, append(in.Credential, in.Secret...))
}
func (k *windowsKey20) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, error) {
func (k *windowsKey20) quote(tb tpmBase, nonce []byte, alg HashAlg, selectedPCRs []int) (*Quote, error) {
t, ok := tb.(*windowsTPM)
if !ok {
return nil, fmt.Errorf("expected *windowsTPM, got %T", tb)
@ -174,7 +169,7 @@ func (k *windowsKey20) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, err
if err != nil {
return nil, fmt.Errorf("TPMCommandInterface() failed: %v", err)
}
return quote20(tpm, tpmKeyHnd, alg.goTPMAlg(), nonce)
return quote20(tpm, tpmKeyHnd, alg.goTPMAlg(), nonce, selectedPCRs)
}
func (k *windowsKey20) close(tpm tpmBase) error {

View File

@ -236,12 +236,9 @@ func readEKCertFromNVRAM20(tpm io.ReadWriter, nvramCertIndex tpmutil.Handle) (*x
return ParseEKCertificate(ekCert)
}
func quote20(tpm io.ReadWriter, akHandle tpmutil.Handle, hashAlg tpm2.Algorithm, nonce []byte) (*Quote, error) {
sel := tpm2.PCRSelection{Hash: hashAlg}
numPCRs := 24
for pcr := 0; pcr < numPCRs; pcr++ {
sel.PCRs = append(sel.PCRs, pcr)
}
func quote20(tpm io.ReadWriter, akHandle tpmutil.Handle, hashAlg tpm2.Algorithm, nonce []byte, selectedPCRs []int) (*Quote, error) {
sel := tpm2.PCRSelection{Hash: hashAlg,
PCRs: selectedPCRs}
quote, sig, err := tpm2.Quote(tpm, akHandle, "", "", nonce, sel, tpm2.AlgNull)
if err != nil {
@ -403,6 +400,7 @@ func (t *TPM) attestPCRs(ak *AK, nonce []byte, alg HashAlg) (*Quote, []PCR, erro
if err != nil {
return nil, nil, fmt.Errorf("failed to read %v PCRs: %v", alg, err)
}
quote, err := ak.Quote(t, nonce, alg)
if err != nil {
return nil, nil, fmt.Errorf("failed to quote using %v: %v", alg, err)

View File

@ -518,12 +518,12 @@ func (k *wrappedKey20) certify(tb tpmBase, handle interface{}) (*CertificationPa
return certify(t.rwc, hnd, k.hnd, scheme)
}
func (k *wrappedKey20) quote(tb tpmBase, nonce []byte, alg HashAlg) (*Quote, error) {
func (k *wrappedKey20) quote(tb tpmBase, nonce []byte, alg HashAlg, selectedPCRs []int) (*Quote, error) {
t, ok := tb.(*wrappedTPM20)
if !ok {
return nil, fmt.Errorf("expected *wrappedTPM20, got %T", tb)
}
return quote20(t.rwc, k.hnd, tpm2.Algorithm(alg), nonce)
return quote20(t.rwc, k.hnd, tpm2.Algorithm(alg), nonce, selectedPCRs)
}
func (k *wrappedKey20) attestationParameters() AttestationParameters {