mirror of
https://github.com/google/go-attestation.git
synced 2025-06-11 19:51:46 +00:00
attest: Support certification by ECC AKs.
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Test / test-linux (1.22.x) (push) Has been cancelled
Test / test-linux-tpm12 (1.22.x) (push) Has been cancelled
Test / test-macos (1.22.x) (push) Has been cancelled
Test / test-windows (1.22.x) (push) Has been cancelled
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Test / test-linux (1.22.x) (push) Has been cancelled
Test / test-linux-tpm12 (1.22.x) (push) Has been cancelled
Test / test-macos (1.22.x) (push) Has been cancelled
Test / test-windows (1.22.x) (push) Has been cancelled
This commit is contained in:
committed by
Brandon Weeks
parent
1b202b12e8
commit
c7aee80c5d
@ -17,6 +17,7 @@ package attest
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto"
|
"crypto"
|
||||||
|
"crypto/ecdsa"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"errors"
|
"errors"
|
||||||
@ -164,11 +165,6 @@ func (p *CertificationParameters) Verify(opts VerifyOpts) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check the signature over the attestation data verifies correctly.
|
// Check the signature over the attestation data verifies correctly.
|
||||||
// TODO: Support ECC certifying keys
|
|
||||||
pk, ok := opts.Public.(*rsa.PublicKey)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("only RSA verification keys are supported")
|
|
||||||
}
|
|
||||||
if !opts.Hash.Available() {
|
if !opts.Hash.Available() {
|
||||||
return fmt.Errorf("hash function is unavailable")
|
return fmt.Errorf("hash function is unavailable")
|
||||||
}
|
}
|
||||||
@ -184,9 +180,18 @@ func (p *CertificationParameters) Verify(opts VerifyOpts) error {
|
|||||||
return fmt.Errorf("DecodeSignature() failed: %v", err)
|
return fmt.Errorf("DecodeSignature() failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch pk := opts.Public.(type) {
|
||||||
|
case *rsa.PublicKey:
|
||||||
if err := rsa.VerifyPKCS1v15(pk, opts.Hash, hsh.Sum(nil), sig.RSA.Signature); err != nil {
|
if err := rsa.VerifyPKCS1v15(pk, opts.Hash, hsh.Sum(nil), sig.RSA.Signature); err != nil {
|
||||||
return fmt.Errorf("could not verify attestation: %v", err)
|
return fmt.Errorf("could not verify attestation: %v", err)
|
||||||
}
|
}
|
||||||
|
case *ecdsa.PublicKey:
|
||||||
|
if ok := ecdsa.Verify(pk, hsh.Sum(nil), sig.ECC.R, sig.ECC.S); !ok {
|
||||||
|
return fmt.Errorf("could not verify ECC attestation")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported public key type: %T", pub)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -31,13 +31,19 @@ import (
|
|||||||
"github.com/google/go-tpm/legacy/tpm2"
|
"github.com/google/go-tpm/legacy/tpm2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSimTPM20CertificationParameters(t *testing.T) {
|
func TestSimTPM20CertificationParametersRSA(t *testing.T) {
|
||||||
sim, tpm := setupSimulatedTPM(t)
|
sim, tpm := setupSimulatedTPM(t)
|
||||||
defer sim.Close()
|
defer sim.Close()
|
||||||
testCertificationParameters(t, tpm)
|
testCertificationParameters(t, tpm, RSA)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTPM20CertificationParameters(t *testing.T) {
|
func TestSimTPM20CertificationParametersECC(t *testing.T) {
|
||||||
|
sim, tpm := setupSimulatedTPM(t)
|
||||||
|
defer sim.Close()
|
||||||
|
testCertificationParameters(t, tpm, ECDSA)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTPM20CertificationParametersRSA(t *testing.T) {
|
||||||
if !*testLocal {
|
if !*testLocal {
|
||||||
t.SkipNow()
|
t.SkipNow()
|
||||||
}
|
}
|
||||||
@ -46,11 +52,23 @@ func TestTPM20CertificationParameters(t *testing.T) {
|
|||||||
t.Fatalf("OpenTPM() failed: %v", err)
|
t.Fatalf("OpenTPM() failed: %v", err)
|
||||||
}
|
}
|
||||||
defer tpm.Close()
|
defer tpm.Close()
|
||||||
testCertificationParameters(t, tpm)
|
testCertificationParameters(t, tpm, RSA)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCertificationParameters(t *testing.T, tpm *TPM) {
|
func TestTPM20CertificationParametersECC(t *testing.T) {
|
||||||
ak, err := tpm.NewAK(nil)
|
if !*testLocal {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
tpm, err := OpenTPM(nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("OpenTPM() failed: %v", err)
|
||||||
|
}
|
||||||
|
defer tpm.Close()
|
||||||
|
testCertificationParameters(t, tpm, ECDSA)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCertificationParameters(t *testing.T, tpm *TPM, akAlg Algorithm) {
|
||||||
|
ak, err := tpm.NewAK(&AKConfig{Algorithm: akAlg})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -59,12 +77,12 @@ func testCertificationParameters(t *testing.T, tpm *TPM) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if pub.Type != tpm2.AlgRSA {
|
|
||||||
t.Fatal("non-RSA verifying key")
|
|
||||||
}
|
|
||||||
|
|
||||||
pk := &rsa.PublicKey{E: int(pub.RSAParameters.Exponent()), N: pub.RSAParameters.Modulus()}
|
pk, err := pub.Key()
|
||||||
hash, err := pub.RSAParameters.Sign.Hash.Hash()
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
hash, err := pub.NameAlg.Hash()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -170,13 +188,19 @@ func testCertificationParameters(t *testing.T, tpm *TPM) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSimTPM20KeyCertification(t *testing.T) {
|
func TestSimTPM20KeyCertificationRSA(t *testing.T) {
|
||||||
sim, tpm := setupSimulatedTPM(t)
|
sim, tpm := setupSimulatedTPM(t)
|
||||||
defer sim.Close()
|
defer sim.Close()
|
||||||
testKeyCertification(t, tpm)
|
testKeyCertification(t, tpm, RSA)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTPM20KeyCertification(t *testing.T) {
|
func TestSimTPM20KeyCertificationECC(t *testing.T) {
|
||||||
|
sim, tpm := setupSimulatedTPM(t)
|
||||||
|
defer sim.Close()
|
||||||
|
testKeyCertification(t, tpm, ECDSA)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTPM20KeyCertificationRSA(t *testing.T) {
|
||||||
if !*testLocal {
|
if !*testLocal {
|
||||||
t.SkipNow()
|
t.SkipNow()
|
||||||
}
|
}
|
||||||
@ -185,11 +209,23 @@ func TestTPM20KeyCertification(t *testing.T) {
|
|||||||
t.Fatalf("OpenTPM() failed: %v", err)
|
t.Fatalf("OpenTPM() failed: %v", err)
|
||||||
}
|
}
|
||||||
defer tpm.Close()
|
defer tpm.Close()
|
||||||
testKeyCertification(t, tpm)
|
testKeyCertification(t, tpm, RSA)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testKeyCertification(t *testing.T, tpm *TPM) {
|
func TestTPM20KeyCertificationECC(t *testing.T) {
|
||||||
ak, err := tpm.NewAK(nil)
|
if !*testLocal {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
tpm, err := OpenTPM(nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("OpenTPM() failed: %v", err)
|
||||||
|
}
|
||||||
|
defer tpm.Close()
|
||||||
|
testKeyCertification(t, tpm, ECDSA)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testKeyCertification(t *testing.T, tpm *TPM, akAlg Algorithm) {
|
||||||
|
ak, err := tpm.NewAK(&AKConfig{Algorithm: akAlg})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("NewAK() failed: %v", err)
|
t.Fatalf("NewAK() failed: %v", err)
|
||||||
}
|
}
|
||||||
@ -198,8 +234,11 @@ func testKeyCertification(t *testing.T, tpm *TPM) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("DecodePublic() failed: %v", err)
|
t.Fatalf("DecodePublic() failed: %v", err)
|
||||||
}
|
}
|
||||||
pk := &rsa.PublicKey{E: int(pub.RSAParameters.Exponent()), N: pub.RSAParameters.Modulus()}
|
pk, err := pub.Key()
|
||||||
hash, err := pub.RSAParameters.Sign.Hash.Hash()
|
if err != nil {
|
||||||
|
t.Fatalf("pub.Key() failed: %v", err)
|
||||||
|
}
|
||||||
|
hash, err := pub.NameAlg.Hash()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("cannot access AK's hash function: %v", err)
|
t.Fatalf("cannot access AK's hash function: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -566,6 +566,27 @@ func (k *wrappedKey20) activateCredential(tb tpmBase, in EncryptedCredential, ek
|
|||||||
}, k.hnd, ekHnd, credential, secret)
|
}, k.hnd, ekHnd, credential, secret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sigSchemeFromPublicKey(pub []byte) (tpm2.SigScheme, error) {
|
||||||
|
tpmPub, err := tpm2.DecodePublic(pub)
|
||||||
|
if err != nil {
|
||||||
|
return tpm2.SigScheme{}, fmt.Errorf("decode public key: %v", err)
|
||||||
|
}
|
||||||
|
switch tpmPub.Type {
|
||||||
|
case tpm2.AlgRSA:
|
||||||
|
return tpm2.SigScheme{
|
||||||
|
Alg: tpm2.AlgRSASSA,
|
||||||
|
Hash: tpm2.AlgSHA256,
|
||||||
|
}, nil
|
||||||
|
case tpm2.AlgECC:
|
||||||
|
return tpm2.SigScheme{
|
||||||
|
Alg: tpm2.AlgECDSA,
|
||||||
|
Hash: tpm2.AlgSHA256,
|
||||||
|
}, nil
|
||||||
|
default:
|
||||||
|
return tpm2.SigScheme{}, fmt.Errorf("public key of alg 0x%x not supported", tpmPub.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (k *wrappedKey20) certify(tb tpmBase, handle interface{}) (*CertificationParameters, error) {
|
func (k *wrappedKey20) certify(tb tpmBase, handle interface{}) (*CertificationParameters, error) {
|
||||||
t, ok := tb.(*wrappedTPM20)
|
t, ok := tb.(*wrappedTPM20)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -575,9 +596,9 @@ func (k *wrappedKey20) certify(tb tpmBase, handle interface{}) (*CertificationPa
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("expected tpmutil.Handle, got %T", handle)
|
return nil, fmt.Errorf("expected tpmutil.Handle, got %T", handle)
|
||||||
}
|
}
|
||||||
scheme := tpm2.SigScheme{
|
scheme, err := sigSchemeFromPublicKey(k.public)
|
||||||
Alg: tpm2.AlgRSASSA,
|
if err != nil {
|
||||||
Hash: tpm2.AlgSHA256,
|
return nil, fmt.Errorf("get signature scheme: %v", err)
|
||||||
}
|
}
|
||||||
return certify(t.rwc, hnd, k.hnd, scheme)
|
return certify(t.rwc, hnd, k.hnd, scheme)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user