Skip to content

Commit a81a552

Browse files
kwtj43yzz127arvind5jerryrhyugrminch
authored
Merge physical-tpm-preview to main (for v1.12) (#174)
* CASSINI-8033: Support Azure TDX report generation in Amber client CLI (intel#43) * Updated Azure adapter per TDX1.4 preview. * resolve tpm read issue - paravisor only update report when read full region Signed-off-by: Jerry Yu <jerry.yu@intel.com> * Removed GET nonce call to TrustAuthority. * update README * define nv index 0x1400002 if not yet Signed-off-by: Jerry Yu <jerry.yu@intel.com> * verify user data hash in the evidence Ensure the collected evidence matches the user data(hash) provided to the vTPM * use nonce to validate the evidence freshness * print out base64 encoded evidence (#97) Signed-off-by: Jerry Yu <jerry.yu@intel.com> * Modified Connector to use new attestation end-point for Azure tdvm. (#100) * Add sleep time of 3 sec to reflect user data in runtime data. * Updated Azure adapter per TDX1.4 preview. * Modified Connector to use new attestation end-point for Azure tdvm. (#100) * Azure TDX+vTPM composite attestation (#125) * Draft changes for TDX/TPM composite attestation. * Help correction. * Misc code clean up. * Misc cleanup * Add pcr selection, additional refactoring of TPM/adapter. * Owner auth, request-ids, token signing alg. * Updates while debugging against poc/tpm_with_coordinator-main-rebase cc75186c. * Minor changes * Add user-data/verifier-nonce handling * Miscellaneous fixes from debugging. * Add sleep to workaround Azure bug. * Adjust the name of user_data/nonce. * Wire up misc command line options into request body. * Refactor TPM/vTPM and composite attestation. * Revive "evidence" command (by popular demand). * Correct command line usage (--aztdx vs. --tdx). * Fix incorrect error handling in TPM adapter. * Enable checkmarx check in CI * Bump CLI version. * CI updates. * Unit test correction. * Unit test corrections. * Cassini 21810 -- README files for AZ-TDX/vTPM preview (#139) * Initial commit for TPM readmes. * Changes from first review feedback; ready for final review. * Fix typo --------- Co-authored-by: Thompson, Kent <kent.thompson@intel.com> * CASSINI-21986: Remove 3 second sleep from azure adapter. * Misc fixes, unit tests and comment updates. * Correction. * Address pull request comments. * Miscellaneous fixes made during "physical-tpm" validation. (#144) * CASSINI-21986: Remove 3 second sleep from azure adapter. * Misc fixes, unit tests and comment updates. * Correction. * Address pull request comments. * Address pull request comments. * Remove info message when writing to NV ram. * Remove info/time from logrus messages when used in trustauthority-cli. * Clean up comment. * Consistently print '0x' and hex for TPM handles. * AK provisioning. * Changes to send TPMT_Public instead of AK public key to the provisioning service. * WIP: Debug ak-provisioning, add tpm-simulator and initial unit tests. * Unit test correction. * Unit test correction. * Add Ak certificate to evidence command. * Update ak provisioning endpoint * Address CASSINI-22273 and other miscellaneous changes. * Misc code clean up. * Misc updates for validation (error typo, max handle values, support "all" for pcr selections, better config.json parsing). * Fix unit tests. * Rebase with tpm-preview. * Consistently add '0x' and hex to TPM handle messages. * WIP * Unit tests for go-tpm package. * Misc cleanup. * Fix connector unit-tests. * Increase unit-test coverage for go-connector package. * Version bump. * Unit test correction. * Unit test correction. * Address PR comments. --------- Signed-off-by: Jerry Yu <jerry.yu@intel.com> Co-authored-by: Yanhui Zhao <wildyz.yky@gmail.com> Co-authored-by: Rawat, Arvind <arvind.rawat@intel.com> Co-authored-by: Jerry Yu <jerry.yu@intel.com> Co-authored-by: Yanhui Zhao <yanhui.zhao@intel.com> Co-authored-by: Glenn Minch <97639000+grminch@users.noreply.github.com>
1 parent 430e5b1 commit a81a552

33 files changed

+1753
-118
lines changed

go-aztdx/aztdx_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ func (m *MockTpm) CreateEK(ekHandle int) error {
3838
return args.Error(0)
3939
}
4040

41+
func (m *MockTpm) CreateAK(akHandle int, ekHandle int) error {
42+
args := m.Called(akHandle, ekHandle)
43+
return args.Error(0)
44+
}
45+
46+
func (m *MockTpm) ActivateCredential(ekHandle int, akHandle int, credentialBlob []byte, secret []byte) ([]byte, error) {
47+
args := m.Called(ekHandle, akHandle, credentialBlob, secret)
48+
return args.Get(0).([]byte), args.Error(1)
49+
}
50+
4151
func (m *MockTpm) NVRead(nvHandle int) ([]byte, error) {
4252
args := m.Called(nvHandle)
4353
return args.Get(0).([]byte), args.Error(1)

go-connector/ak_certificate.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright (c) 2022-2024 Intel Corporation
3+
* All rights reserved.
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
package connector
8+
9+
import (
10+
"bytes"
11+
"crypto/x509"
12+
"encoding/json"
13+
"fmt"
14+
"io"
15+
"net/http"
16+
17+
"github.com/google/uuid"
18+
"github.com/pkg/errors"
19+
"github.com/sirupsen/logrus"
20+
)
21+
22+
type akCertificateRequest struct {
23+
EkCertificateDer []byte `json:"ek_certificate_der"`
24+
AKTpmtPublic []byte `json:"ak_tpmt_public"`
25+
}
26+
27+
type akCertificateRequestResponse struct {
28+
CredentialBlob []byte `json:"credential_blob"`
29+
Secret []byte `json:"secret"`
30+
EncryptedAkCertDer []byte `json:"encrypted_ak_cert_der"`
31+
}
32+
33+
const akProvisioningApiPath = "/ak-provisioning/v1/ak-certs"
34+
35+
func (connector *trustAuthorityConnector) GetAKCertificate(ekCert *x509.Certificate, akTpmtPublic []byte) ([]byte, []byte, []byte, error) {
36+
if ekCert == nil {
37+
return nil, nil, nil, errors.New("EK certificate cannot be nil")
38+
}
39+
40+
if len(akTpmtPublic) == 0 {
41+
return nil, nil, nil, errors.New("The AK's TPMT_PUBLIC cannot be nil or empty")
42+
}
43+
44+
akCertRequest := akCertificateRequest{
45+
AKTpmtPublic: akTpmtPublic,
46+
EkCertificateDer: ekCert.Raw,
47+
}
48+
49+
requestBody, err := json.Marshal(akCertRequest)
50+
if err != nil {
51+
return nil, nil, nil, err
52+
}
53+
54+
logrus.Debugf("REQ: %s", string(requestBody))
55+
56+
url := fmt.Sprintf("%s%s", connector.cfg.ApiUrl, akProvisioningApiPath)
57+
newRequest := func() (*http.Request, error) {
58+
return http.NewRequest(http.MethodPost, url, bytes.NewReader(requestBody))
59+
}
60+
61+
var headers = map[string]string{
62+
headerXApiKey: connector.cfg.ApiKey,
63+
headerAccept: mimeApplicationJson,
64+
headerContentType: mimeApplicationJson,
65+
HeaderRequestId: uuid.New().String(),
66+
}
67+
68+
var response akCertificateRequestResponse
69+
processResponse := func(resp *http.Response) error {
70+
body, err := io.ReadAll(resp.Body)
71+
if err != nil {
72+
return errors.Errorf("Failed to read body from %s: %s", url, err)
73+
}
74+
75+
dec := json.NewDecoder(bytes.NewReader(body))
76+
dec.DisallowUnknownFields()
77+
err = dec.Decode(&response)
78+
if err != nil {
79+
return errors.Errorf("Failed to decode json from %s: %s", err, string(body))
80+
}
81+
return nil
82+
}
83+
84+
if err := doRequest(*connector.rclient, connector.cfg.TlsCfg, newRequest, nil, headers, processResponse); err != nil {
85+
return nil, nil, nil, err
86+
}
87+
88+
return response.CredentialBlob, response.Secret, response.EncryptedAkCertDer, nil
89+
}

go-connector/ak_certificate_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2022-2024 Intel Corporation
3+
* All rights reserved.
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
package connector
8+
9+
import (
10+
"crypto/tls"
11+
"crypto/x509"
12+
"encoding/json"
13+
"net/http"
14+
"net/http/httptest"
15+
"testing"
16+
)
17+
18+
func TestGetAKCertificate(t *testing.T) {
19+
testServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
20+
if r.URL.Path == akProvisioningApiPath {
21+
w.WriteHeader(http.StatusOK)
22+
response := akCertificateRequestResponse{}
23+
24+
j, err := json.Marshal(&response)
25+
if err != nil {
26+
t.Fatal(err)
27+
}
28+
29+
w.Write([]byte(j))
30+
} else {
31+
w.WriteHeader(http.StatusNotFound)
32+
}
33+
}))
34+
35+
ctr, err := New(&Config{
36+
ApiUrl: testServer.URL,
37+
TlsCfg: &tls.Config{InsecureSkipVerify: true},
38+
})
39+
if err != nil {
40+
t.Fatal(err)
41+
}
42+
43+
_, _, _, err = ctr.GetAKCertificate(&x509.Certificate{}, make([]byte, 100))
44+
if err != nil {
45+
t.Fatal(err)
46+
}
47+
}

go-connector/connector.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package connector
88
import (
99
"context"
1010
"crypto/tls"
11+
"crypto/x509"
1112
"net/http"
1213
"net/url"
1314
"strings"
@@ -33,6 +34,11 @@ type Connector interface {
3334
// only "azure" is supported. 'reqId' is an optional string that is included in the
3435
// x-request-id header that can be used for troubleshooting.
3536
AttestEvidence(evidence interface{}, cloudProvider string, reqId string) (AttestResponse, error)
37+
38+
// GetAkCertificate sends the TPM's EK certificate and the AK's TPMT_PUBLIC structure
39+
// to Intel Trust Authority and returns an encrypted AK certificate, a secret, and credential blob
40+
// that can be decrypted by the TPM (ActivateCredential command).
41+
GetAKCertificate(ekCert *x509.Certificate, akTpmtPublic []byte) ([]byte, []byte, []byte, error)
3642
}
3743

3844
// GetNonceArgs holds the request parameters needed for getting nonce from Intel Trust Authority

go-connector/connector_factory.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) 2022-2024 Intel Corporation
3+
* All rights reserved.
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
package connector
8+
9+
// ConnectorFactory is an interface for instantiating Connector
10+
// objects.
11+
type ConnectorFactory interface {
12+
NewConnector(config *Config) (Connector, error)
13+
}
14+
15+
// NewConnectorFactory returns a default instance of ConnectorFactory
16+
// that will communicate with a remote instance of Intel Trust Authority.
17+
func NewConnectorFactory() ConnectorFactory {
18+
return &connectorFactory{}
19+
}
20+
21+
type connectorFactory struct{}
22+
23+
func (c *connectorFactory) NewConnector(config *Config) (Connector, error) {
24+
return New(config)
25+
}

go-connector/mocks_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
package connector
77

88
import (
9+
"crypto/x509"
10+
911
"github.com/golang-jwt/jwt/v4"
1012
"github.com/stretchr/testify/mock"
1113
)
@@ -46,3 +48,8 @@ func (m *MockConnector) AttestEvidence(evidence interface{}, cloudProvider strin
4648
args := m.Called(evidence, cloudProvider, reqId)
4749
return args.Get(0).(AttestResponse), args.Error(1)
4850
}
51+
52+
func (m *MockConnector) GetAKCertificate(ekCert *x509.Certificate, akTpmtPublic []byte) ([]byte, []byte, []byte, error) {
53+
args := m.Called(ekCert, akTpmtPublic)
54+
return args.Get(0).([]byte), args.Get(1).([]byte), args.Get(2).([]byte), args.Error(3)
55+
}

go-tpm/activate.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) 2022-2024 Intel Corporation
3+
* All rights reserved.
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
package tpm
8+
9+
import (
10+
"github.com/canonical/go-tpm2"
11+
"github.com/pkg/errors"
12+
)
13+
14+
func (tpm *trustedPlatformModule) ActivateCredential(ekHandle int, akHandle int, credentialBlob []byte, secret []byte) ([]byte, error) {
15+
16+
// verify the ak handle and create an "akContext" needed for ActivateCredential
17+
ak := tpm2.Handle(akHandle)
18+
if ak.Type() != tpm2.HandleTypePersistent {
19+
return nil, ErrInvalidHandle
20+
}
21+
22+
if !tpm.ctx.DoesHandleExist(ak) {
23+
return nil, ErrHandleDoesNotExist
24+
}
25+
26+
akContext, err := tpm.ctx.NewResourceContext(ak)
27+
if err != nil {
28+
return nil, errors.Wrapf(err, "Failed to create resource context for handle 0x%x", akHandle)
29+
}
30+
akContext.SetAuthValue(tpm.ownerAuth)
31+
32+
// verify the ek handle and create an "ekContext" needed for ActivateCredential
33+
ek := tpm2.Handle(ekHandle)
34+
if ek.Type() != tpm2.HandleTypePersistent {
35+
return nil, ErrInvalidHandle
36+
}
37+
38+
if !tpm.ctx.DoesHandleExist(ek) {
39+
return nil, ErrHandleDoesNotExist
40+
}
41+
42+
ekContext, err := tpm.ctx.NewResourceContext(ek)
43+
if err != nil {
44+
return nil, errors.Wrapf(err, "Failed to create resource context for handle 0x%x", ekHandle)
45+
}
46+
47+
// start a session with endorsement hierarchy policy permissions
48+
ekAuthSession, err := tpm.ctx.StartAuthSession(nil, nil, tpm2.SessionTypePolicy, nil, tpm2.HashAlgorithmSHA256)
49+
if err != nil {
50+
return nil, err
51+
}
52+
53+
_, _, err = tpm.ctx.PolicySecret(tpm.ctx.EndorsementHandleContext(), ekAuthSession, nil, nil, 0, nil, nil)
54+
if err != nil {
55+
return nil, err
56+
}
57+
58+
decrypted, err := tpm.ctx.ActivateCredential(akContext, ekContext, credentialBlob, secret, nil, ekAuthSession)
59+
if err != nil {
60+
return nil, err
61+
}
62+
63+
return decrypted, nil
64+
}

go-tpm/activate_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright (c) 2022-2024 Intel Corporation
3+
* All rights reserved.
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
package tpm
8+
9+
// TODO: negative unit tests for ActivateCredential (positive test are in tpm_e2e_test.go)

0 commit comments

Comments
 (0)