forked from Foxboron/sbctl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tpm.go
81 lines (73 loc) · 1.84 KB
/
tpm.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
package sbctl
import (
"errors"
"os"
"github.com/foxboron/go-uefi/efi/signature"
"github.com/foxboron/go-uefi/efi/util"
"github.com/foxboron/sbctl/fs"
"github.com/google/go-attestation/attest"
)
var (
ErrOprom = errors.New("uefi has oprom")
ErrNoEventlog = errors.New("no eventlog found")
// For the sake of clarity we reserve this GUID for our SignatureList.
// It says: OpROMIsAnnoying!
eventlogGUID = *util.StringToGUID("4f52704f-494d-41736e-6e6f79696e6721")
)
func GetEventlogEvents(eventlog string) ([]attest.Event, error) {
if _, err := fs.Fs.Stat(eventlog); err != nil {
if errors.Is(err, os.ErrNotExist) {
return nil, ErrNoEventlog
}
return nil, err
}
b, err := fs.ReadFile(eventlog)
if err != nil {
return nil, err
}
log, err := attest.ParseEventLog(b)
if err != nil {
return nil, err
}
// TODO: Hardcoded. Should probably make this dynamic
return log.Events(attest.HashSHA256), nil
}
func CheckEventlogOprom(eventlog string) error {
events, err := GetEventlogEvents(eventlog)
if err != nil {
return err
}
for _, event := range events {
switch event.Type.String() {
case "EV_EFI_BOOT_SERVICES_DRIVER":
return ErrOprom
}
}
return nil
}
func GetEventlogChecksums(eventlog string) (*signature.SignatureDatabase, error) {
events, err := GetEventlogEvents(eventlog)
if err != nil {
return nil, err
}
sigdb := signature.NewSignatureDatabase()
for _, event := range events {
switch event.Type.String() {
case "EV_EFI_BOOT_SERVICES_DRIVER":
if err = sigdb.Append(signature.CERT_SHA256_GUID, eventlogGUID, event.Digest); err != nil {
return nil, err
}
}
}
return sigdb, nil
}
func DetectTPMEventlog(sb *signature.SignatureDatabase) bool {
for _, l := range *sb {
for _, sig := range l.Signatures {
if util.CmpEFIGUID(sig.Owner, eventlogGUID) {
return true
}
}
}
return false
}