/
txt.go
206 lines (189 loc) · 5.08 KB
/
txt.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
package registers
import (
"fmt"
"github.com/9elements/converged-security-suite/v2/pkg/errors"
pkgbytes "github.com/linuxboot/fiano/pkg/bytes"
)
const (
// TxtTPMDecode for external use
TxtTPMDecode = 0xFED40000
// TxtTPMDecodeSize is the size of the TCG defined TIS MMIO space
TxtTPMDecodeSize = 0x5000
// TxtPublicSpace for external test
TxtPublicSpace = 0xFED30000
// TxtPublicSpaceSize exports the size of TXTPublicSpace in memory map
TxtPublicSpaceSize = 0x10000
// TxtPrivateSpace for external test
TxtPrivateSpace = 0xFED20000
// TxtPrivateSpaceSize for external test
TxtPrivateSpaceSize = 0x10000
)
//TXTConfigSpace holds the TXT config space
type TXTConfigSpace []byte
//PhysicalMemoryReader accesses device physical memory
type PhysicalMemoryReader interface {
ReadPhysBuf(addr int64, buf []byte) error
}
// FetchTXTConfigSpaceRaw returns a raw copy of the TXT config space
//
// Warning, this function may trigger undocumented registers which affects
// other registers or anything else.
func FetchTXTConfigSpaceRaw(mem PhysicalMemoryReader) (TXTConfigSpace, error) {
data := make([]byte, TxtPublicSpaceSize)
if err := mem.ReadPhysBuf(TxtPublicSpace, data); err != nil {
return nil, err
}
return data, nil
}
// FetchTXTConfigSpace is a deprecated alias for FetchTXTConfigSpaceRaw.
// DEPRECATED: The function was renamed to FetchTXTConfigSpaceRaw.
func FetchTXTConfigSpace(mem PhysicalMemoryReader) (TXTConfigSpace, error) {
return FetchTXTConfigSpaceRaw(mem)
}
var (
physMemDenyList = pkgbytes.Ranges{
{
// This is an undocumented register which triggers ACM_POLICY_STATUS
// corruption.
Offset: 0xFED30370,
Length: 8,
},
}
)
// FetchTXTConfigSpaceSafe returns a filtered raw copy of the TXT config space,
// it excludes registers, which is not supposed to be read (in contrast
// to FetchTXTConfigSpaceRaw).
func FetchTXTConfigSpaceSafe(mem PhysicalMemoryReader) (TXTConfigSpace, error) {
data := make([]byte, TxtPublicSpaceSize)
byteRanges := pkgbytes.Range{
Offset: TxtPublicSpace,
Length: TxtPublicSpaceSize,
}.Exclude(physMemDenyList...)
for _, byteRange := range byteRanges {
startIdx := byteRange.Offset - TxtPublicSpace
endIdx := byteRange.Offset - TxtPublicSpace + byteRange.Length
if err := mem.ReadPhysBuf(int64(byteRange.Offset), data[startIdx:endIdx]); err != nil {
return nil, err
}
}
return data, nil
}
type supportedTXTRegister struct {
id RegisterID
fetch func(data TXTConfigSpace) (Register, error)
}
var supportedTXTRegistersIDs = []supportedTXTRegister{
{
id: AcmPolicyStatusRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadACMPolicyStatusRegister(data)
},
},
{
id: ACMStatusRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadACMStatusRegister(data)
},
},
{
id: TXTDMAProtectedRangeRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTXTDMAProtectedRangeRegister(data)
},
},
{
id: TXTErrorCodeRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTxtErrorCode(data)
},
},
{
id: TXTPublicKeyRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTXTPublicKeyRegister(data)
},
},
{
id: TXTStatusRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTXTStatus(data)
},
},
{
id: TXTErrorStatusRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTXTErrorStatusRegister(data)
},
},
{
id: TXTBootStatusRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTXTBootStatusRegister(data)
},
},
{
id: TXTVerFSBIfRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTXTVerFSBIF(data)
},
},
{
id: TXTVerEMIfRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTXTVerEMIF(data)
},
},
{
id: TXTDeviceIDRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTXTDeviceIDRegister(data)
},
},
{
id: TXTSINITBaseRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTXTSInitBase(data)
},
},
{
id: TXTSINITSizeRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTXTSInitSize(data)
},
},
{
id: TXTMLEJoinRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTXTMLEJoin(data)
},
},
{
id: TXTHeapBaseRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTXTHeapBase(data)
},
},
{
id: TXTHeapSizeRegisterID,
fetch: func(data TXTConfigSpace) (Register, error) {
return ReadTXTHeapSize(data)
},
},
}
// ReadTXTRegisters fetches all supported TXT registers
func ReadTXTRegisters(data TXTConfigSpace) (Registers, error) {
var result Registers
var mErr errors.MultiError
for _, registerInfo := range supportedTXTRegistersIDs {
reg, err := registerInfo.fetch(data)
if err != nil {
_ = mErr.Add(fmt.Errorf("failed to fetch MSR register %s, err: %v", registerInfo.id, err))
continue
}
result = append(result, reg)
}
if mErr.Count() > 0 {
return result, mErr
}
return result, nil
}