attest: ActivateCredentialWithEK() method that can be used with non-default EKs. (#340)

This commit is contained in:
zhsh 2023-06-29 13:38:36 +10:00 committed by GitHub
parent a56e8c4896
commit 60adf13bc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 7 deletions

View File

@ -131,13 +131,24 @@ func (k *AK) Marshal() ([]byte, error) {
}
// ActivateCredential decrypts the secret using the key to prove that the AK
// was generated on the same TPM as the EK.
// was generated on the same TPM as the EK. This method can be used with TPMs
// that have the default EK, i.e. RSA EK with handle 0x81010001.
//
// This operation is synonymous with TPM2_ActivateCredential.
func (k *AK) ActivateCredential(tpm *TPM, in EncryptedCredential) (secret []byte, err error) {
return k.ak.activateCredential(tpm.tpm, in, k.ek)
}
// ActivateCredential decrypts the secret using the key to prove that the AK
// was generated on the same TPM as the EK. This method can be used with TPMs
// that have an ECC EK. The 'ek' argument must be one of EKs returned from
// TPM.EKs() or TPM.EKCertificates().
//
// This operation is synonymous with TPM2_ActivateCredential.
func (k *AK) ActivateCredentialWithEK(tpm *TPM, in EncryptedCredential, ek EK) (secret []byte, err error) {
return k.ak.activateCredential(tpm.tpm, in, &ek)
}
// Quote returns a quote over the platform state, signed by the AK.
//
// This is a low-level API. Consumers seeking to attest the state of the

View File

@ -115,11 +115,7 @@ func testActivateCredential(t *testing.T, useEK bool) {
}
ek := chooseEK(t, EKs)
var akConfig *AKConfig
if useEK {
akConfig = &AKConfig{EK: &ek}
}
ak, err := tpm.NewAK(akConfig)
ak, err := tpm.NewAK(nil)
if err != nil {
t.Fatalf("NewAK() failed: %v", err)
}
@ -135,7 +131,12 @@ func testActivateCredential(t *testing.T, useEK bool) {
t.Fatalf("Generate() failed: %v", err)
}
decryptedSecret, err := ak.ActivateCredential(tpm, *challenge)
var decryptedSecret []byte
if useEK {
decryptedSecret, err = ak.ActivateCredentialWithEK(tpm, *challenge, ek)
} else {
decryptedSecret, err = ak.ActivateCredential(tpm, *challenge)
}
if err != nil {
t.Errorf("ak.ActivateCredential() failed: %v", err)
}

View File

@ -91,12 +91,62 @@ func ExampleAK_credentialActivation() {
}
}
func ExampleAK_credentialActivationWithEK() {
tpm, err := attest.OpenTPM(nil)
if err != nil {
log.Fatalf("Failed to open TPM: %v", err)
}
defer tpm.Close()
// Create a new AK.
ak, err := tpm.NewAK(nil)
if err != nil {
log.Fatalf("Failed to create AK: %v", err)
}
defer ak.Close(tpm)
// Read the EK certificates.
ekCerts, err := tpm.EKCertificates()
if err != nil {
log.Fatalf("Failed to enumerate EKs: %v", err)
}
// Read parameters necessary to generate a challenge.
ap := ak.AttestationParameters()
// Try activating with each EK certificate.
for _, ek := range ekCerts {
// Generate a credential activation challenge (usually done on the server).
activation := attest.ActivationParameters{
TPMVersion: tpm.Version(),
EK: ek.Public,
AK: ap,
}
secret, challenge, err := activation.Generate()
if err != nil {
log.Fatalf("Failed to generate activation challenge: %v", err)
}
// Challenge the AK & EK properties to recieve the decrypted secret.
decrypted, err := ak.ActivateCredentialWithEK(tpm, *challenge, ek)
if err != nil {
log.Fatalf("Failed to activate credential: %v", err)
}
// Check that the AK completed the challenge (usually done on the server).
if subtle.ConstantTimeCompare(secret, decrypted) == 0 {
log.Fatal("Activation response did not match secret")
}
}
}
func TestExampleAK(t *testing.T) {
if !*testExamples {
t.SkipNow()
}
ExampleAK()
ExampleAK_credentialActivation()
ExampleAK_credentialActivationWithEK()
}
func TestExampleTPM(t *testing.T) {