-
Notifications
You must be signed in to change notification settings - Fork 392
/
tpm_linux.go
102 lines (87 loc) · 2.3 KB
/
tpm_linux.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright 2020 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package tss
import (
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/google/go-tpm/tpm"
"github.com/google/go-tpm/tpm2"
)
const (
tpmRoot = "/sys/class/tpm"
)
func probeSystemTPMs() ([]probedTPM, error) {
var tpms []probedTPM
tpmDevs, err := ioutil.ReadDir(tpmRoot)
if os.IsNotExist(err) {
return nil, nil
} else if err != nil {
return nil, err
}
// TPM look up is hardcoded. Taken from googles go-attestation.
// go-tpm does not support GetCapability with the required subcommand.
// Implementation will be updated asap this is fixed in Go-tpm
for _, tpmDev := range tpmDevs {
if strings.HasPrefix(tpmDev.Name(), "tpm") {
tpm := probedTPM{
Path: filepath.Join(tpmRoot, tpmDev.Name()),
}
if _, err := os.Stat(filepath.Join(tpm.Path, "caps")); err != nil {
if !os.IsNotExist(err) {
return nil, err
}
tpm.Version = TPMVersion20
} else {
tpm.Version = TPMVersion12
}
tpms = append(tpms, tpm)
}
}
return tpms, nil
}
func newTPM(pTPM probedTPM) (*TPM, error) {
interf := TPMInterfaceDirect
var rwc io.ReadWriteCloser
var err error
switch pTPM.Version {
case TPMVersion12:
devPath := filepath.Join("/dev", filepath.Base(pTPM.Path))
interf = TPMInterfaceKernelManaged
rwc, err = tpm.OpenTPM(devPath)
if err != nil {
return nil, err
}
case TPMVersion20:
// If the TPM has a kernel-provided resource manager, we should
// use that instead of communicating directly.
devPath := filepath.Join("/dev", filepath.Base(pTPM.Path))
f, err := ioutil.ReadDir(filepath.Join(pTPM.Path, "device", "tpmrm"))
if err != nil {
if !os.IsNotExist(err) {
return nil, err
}
} else if len(f) > 0 {
devPath = filepath.Join("/dev", f[0].Name())
interf = TPMInterfaceKernelManaged
}
rwc, err = tpm2.OpenTPM(devPath)
if err != nil {
return nil, err
}
}
return &TPM{
Version: pTPM.Version,
Interf: interf,
SysPath: pTPM.Path,
RWC: rwc,
}, nil
}
// MeasurementLog reads the TCPA eventlog in binary format
// from the Linux kernel
func (t *TPM) MeasurementLog() ([]byte, error) {
return ioutil.ReadFile("/sys/kernel/security/tpm0/binary_bios_measurements")
}