Skip to content

Commit

Permalink
Require event log for TPM attestation support
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 676107661
Change-Id: Ie995188cf47615161214ec4447a0fee614249d13
  • Loading branch information
jessieqliu authored and copybara-github committed Sep 18, 2024
1 parent c8d84a3 commit cb9c456
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 14 deletions.
35 changes: 23 additions & 12 deletions client/securesession/securesession.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"errors"
"fmt"
"net/url"
"os"
"sync/atomic"
"syscall"

Expand Down Expand Up @@ -69,6 +70,8 @@ const (
// value guarantees incoming records will fit in the buffer.
const recordBufferSize = 16384

var eventLogFile = "/sys/kernel/security/tpm0/binary_bios_measurements"

// ekmToken is a struct that implements credentials.PerRPCCredentials to
// store a bearer token for authenticating requests to the EKM.
type ekmToken struct {
Expand Down Expand Up @@ -320,7 +323,7 @@ func (c *SecureSessionClient) handshake(ctx context.Context) error {
}

// negotiateAttestation confirms attestation evidence options with the server.
func (c *SecureSessionClient) negotiateAttestation(ctx context.Context) error {
func (c *SecureSessionClient) negotiateAttestation(ctx context.Context) (ret error) {
req := &pb.NegotiateAttestationRequest{
SessionContext: c.ctx,
}
Expand All @@ -334,21 +337,27 @@ func (c *SecureSessionClient) negotiateAttestation(ctx context.Context) error {
if err := tryReescalatePrivileges(); err != nil {
return fmt.Errorf("failed to re-escalate to root privileges to open TPM device: %w", err)
}
defer func() {
// If failed to deescalate and there are no other errors, override the return.
if err := tryDeescalatePrivileges(); err != nil && ret == nil {
ret = fmt.Errorf("failed to de-escalate to user privileges: %v", err)
}
}()

if _, err := tpm2.OpenTPM("/dev/tpmrm0"); err != nil {
glog.Infof("TPM not available. Using null attestation")
glog.InfoContextf(ctx, "TPM not available. Using null attestation")
} else if _, err = os.Stat(eventLogFile); errors.Is(err, os.ErrNotExist) {
// If the TPM is available but event log is not, log and continue with null attestation.
glog.ErrorContextf(ctx, "TPM is available but Event Log is not. Using null attestation.")
} else {
// If both TPM and Event Log are available, add to supported evidence types.
evidenceTypes.Types = append(evidenceTypes.Types, aepb.AttestationEvidenceType_TPM2_QUOTE)
evidenceTypes.Types = append(evidenceTypes.Types, aepb.AttestationEvidenceType_TCG_EVENT_LOG)

// Communicate to the server the nonce types that we support.
evidenceTypes.NonceTypes = append(evidenceTypes.NonceTypes, aepb.NonceType_NONCE_EKM32)
}

if err := tryDeescalatePrivileges(); err != nil {
return fmt.Errorf("failed to de-escalate to user privileges: %w", err)
}

// Write marshalled attestation evidence to TLS channel.
marshaledEvidenceTypes, err := proto.Marshal(evidenceTypes)
if err != nil {
Expand Down Expand Up @@ -390,11 +399,18 @@ func (c *SecureSessionClient) negotiateAttestation(ctx context.Context) error {
return nil
}

func (c *SecureSessionClient) addTpmEvidence(evidence *aepb.AttestationEvidence) error {
func (c *SecureSessionClient) addTpmEvidence(evidence *aepb.AttestationEvidence) (ret error) {
// Attempt to re-escalate execution privileges.
if err := tryReescalatePrivileges(); err != nil {
return fmt.Errorf("failed to re-escalate to root privileges to generate attestation: %w", err)
}
defer func() {
// If failed to deescalate and there are no other errors, override the return.
if err := tryDeescalatePrivileges(); err != nil && ret == nil {
ret = fmt.Errorf("failed to de-escalate to user privileges: %v", err)
}
}()

rwc, err := tpm2.OpenTPM("/dev/tpmrm0")
if err != nil {
glog.Errorf("Error opening TPM device: %v", err)
Expand Down Expand Up @@ -448,17 +464,12 @@ nonceLoop:
}

att, err := ek.Attest(tpmclient.AttestOpts{Nonce: nonce})

if err != nil {
return fmt.Errorf("error generating attestation: %v", err)
}

glog.Infof("Obtained attestation from the vTPM")

if err := tryDeescalatePrivileges(); err != nil {
return fmt.Errorf("failed to de-escalate to user privileges: %w", err)
}

// Add GCE instance info to the attestation proto.
projectID, err := metadata.ProjectID()
// If unable to retrieve the Project ID, set to empty string.
Expand Down
4 changes: 2 additions & 2 deletions transportshim/transportshim.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
// buffer multiple byte slices. In initial testing, the TLS implementation
// can read somewhere between 2KB to 8KB per call, and the largest vTPM
// attestation is on the order of 32KB, so we set the size of the channel
// to 100 to accomodate for this.
// to 100 to accommodate for this.
const sendBufLen = 100

// Allow 1 MB of bytes to be buffered through the receiveBuf channel.
Expand All @@ -50,7 +50,7 @@ func NewTransportShim() ShimInterface {
return t
}

// QueueReceiveBuf inputs data receved from the counterparty, to be read.
// QueueReceiveBuf inputs data received from the counterparty, to be read.
func (shim *TransportShim) QueueReceiveBuf(buf []byte) {
for _, b := range buf {
shim.receiveBuf <- b
Expand Down

0 comments on commit cb9c456

Please sign in to comment.