mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-10-11 01:58:29 -04:00
Add measurement reader (#1381)
Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
5bad5f768b
commit
8c87bba755
12 changed files with 216 additions and 9 deletions
45
measurement-reader/cmd/main.go
Normal file
45
measurement-reader/cmd/main.go
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||
"github.com/edgelesssys/constellation/v2/internal/oid"
|
||||
"github.com/edgelesssys/constellation/v2/measurement-reader/internal/sorted"
|
||||
"github.com/edgelesssys/constellation/v2/measurement-reader/internal/tpm"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logger.New(logger.JSONLog, zapcore.InfoLevel)
|
||||
variant := os.Getenv(constants.AttestationVariant)
|
||||
attestationVariant, err := oid.FromString(variant)
|
||||
if err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to parse attestation variant")
|
||||
}
|
||||
|
||||
var m []sorted.Measurement
|
||||
switch attestationVariant {
|
||||
case oid.AWSNitroTPM{}, oid.AzureSEVSNP{}, oid.AzureTrustedLaunch{}, oid.GCPSEVES{}, oid.QEMUVTPM{}:
|
||||
m, err = tpm.Measurements()
|
||||
if err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to read TPM measurements")
|
||||
}
|
||||
default:
|
||||
log.With(zap.String("attestationVariant", variant)).Fatalf("Unsupported attestation variant")
|
||||
}
|
||||
|
||||
fmt.Println("Measurements:")
|
||||
for _, measurement := range m {
|
||||
fmt.Printf("\t%s : 0x%0X\n", measurement.Index, measurement.Value)
|
||||
}
|
||||
}
|
14
measurement-reader/internal/sorted/sorted.go
Normal file
14
measurement-reader/internal/sorted/sorted.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
// Type definition for sorted measurements.
|
||||
package sorted
|
||||
|
||||
// Measurement wraps a measurement custom index and value.
|
||||
type Measurement struct {
|
||||
Index string
|
||||
Value []byte
|
||||
}
|
50
measurement-reader/internal/tpm/tpm.go
Normal file
50
measurement-reader/internal/tpm/tpm.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
// Package tpm reads measurements from a TPM.
|
||||
package tpm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
|
||||
"github.com/edgelesssys/constellation/v2/measurement-reader/internal/sorted"
|
||||
tpmClient "github.com/google/go-tpm-tools/client"
|
||||
"github.com/google/go-tpm/tpm2"
|
||||
)
|
||||
|
||||
// Measurements returns a sorted list of TPM PCR measurements.
|
||||
func Measurements() ([]sorted.Measurement, error) {
|
||||
m, err := vtpm.GetSelectedMeasurements(vtpm.OpenVTPM, tpmClient.FullPcrSel(tpm2.AlgSHA256))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return sortMeasurements(m), nil
|
||||
}
|
||||
|
||||
func sortMeasurements(m measurements.M) []sorted.Measurement {
|
||||
keys := make([]uint32, 0, len(m))
|
||||
for idx := range m {
|
||||
keys = append(keys, idx)
|
||||
}
|
||||
sort.Slice(keys, func(i, j int) bool {
|
||||
return keys[i] < keys[j]
|
||||
})
|
||||
|
||||
var measurements []sorted.Measurement
|
||||
for _, idx := range keys {
|
||||
expected := m[idx].Expected
|
||||
measurements = append(measurements, sorted.Measurement{
|
||||
Index: fmt.Sprintf("PCR[%02d]", idx),
|
||||
Value: expected[:],
|
||||
})
|
||||
}
|
||||
|
||||
return measurements
|
||||
}
|
78
measurement-reader/internal/tpm/tpm_test.go
Normal file
78
measurement-reader/internal/tpm/tpm_test.go
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package tpm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||
"github.com/edgelesssys/constellation/v2/measurement-reader/internal/sorted"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSortMeasurements(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
input measurements.M
|
||||
want []sorted.Measurement
|
||||
}{
|
||||
"pre sorted": {
|
||||
input: measurements.M{
|
||||
0: measurements.WithAllBytes(0x11, false),
|
||||
1: measurements.WithAllBytes(0x22, false),
|
||||
2: measurements.WithAllBytes(0x33, false),
|
||||
},
|
||||
want: []sorted.Measurement{
|
||||
{
|
||||
Index: "PCR[00]",
|
||||
Value: bytes.Repeat([]byte{0x11}, 32),
|
||||
},
|
||||
{
|
||||
Index: "PCR[01]",
|
||||
Value: bytes.Repeat([]byte{0x22}, 32),
|
||||
},
|
||||
{
|
||||
Index: "PCR[02]",
|
||||
Value: bytes.Repeat([]byte{0x33}, 32),
|
||||
},
|
||||
},
|
||||
},
|
||||
"unsorted": {
|
||||
input: measurements.M{
|
||||
1: measurements.WithAllBytes(0x22, false),
|
||||
0: measurements.WithAllBytes(0x11, false),
|
||||
2: measurements.WithAllBytes(0x33, false),
|
||||
},
|
||||
want: []sorted.Measurement{
|
||||
{
|
||||
Index: "PCR[00]",
|
||||
Value: bytes.Repeat([]byte{0x11}, 32),
|
||||
},
|
||||
{
|
||||
Index: "PCR[01]",
|
||||
Value: bytes.Repeat([]byte{0x22}, 32),
|
||||
},
|
||||
{
|
||||
Index: "PCR[02]",
|
||||
Value: bytes.Repeat([]byte{0x33}, 32),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
got := sortMeasurements(tc.input)
|
||||
for i := range got {
|
||||
assert.Equal(got[i].Index, tc.want[i].Index)
|
||||
assert.Equal(got[i].Value, tc.want[i].Value)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue