-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathtypes_interface.go
306 lines (274 loc) · 10.8 KB
/
types_interface.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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
// Copyright 2019 Canonical Ltd.
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package tpm2
import (
"crypto"
"crypto/cipher"
_ "crypto/sha1"
_ "crypto/sha256"
_ "crypto/sha512"
"fmt"
"hash"
)
// This file contains types defined in section 9 (Interface Types) in
// part 2 of the library spec. Interface types are used by the TPM
// implementation to check that a value is appropriate for the context
// during unmarshalling. This package has limited support for some
// algorithm interfaces by defining context specific algorithm types
// based on the AlgorithmId type. Note that no interface types with
// TPM_HANDLE as the underlying type are supported, as this package
// doesn't use handles in most APIs.
var _ crypto.SignerOpts = HashAlgorithmId(0)
// HashAlgorithmId corresponds to the TPMI_ALG_HASH type
type HashAlgorithmId AlgorithmId
// GetHash returns the equivalent crypto.Hash value for this algorithm if one
// exists, and 0 if one does not exist.
func (a HashAlgorithmId) GetHash() crypto.Hash {
switch a {
case HashAlgorithmSHA1:
return crypto.SHA1
case HashAlgorithmSHA256:
return crypto.SHA256
case HashAlgorithmSHA384:
return crypto.SHA384
case HashAlgorithmSHA512:
return crypto.SHA512
case HashAlgorithmSHA3_256:
return crypto.SHA3_256
case HashAlgorithmSHA3_384:
return crypto.SHA3_384
case HashAlgorithmSHA3_512:
return crypto.SHA3_512
default:
return 0
}
}
// HashFunc implements [crypto.SignerOpts.HashFunc].
//
// This will return 0 if the algorithm does not have a corresponding
// crypto.Hash.
func (a HashAlgorithmId) HashFunc() crypto.Hash {
return a.GetHash()
}
// IsValid determines if the digest algorithm is valid. This
// should be checked by code that deserializes an algorithm before
// calling Size if it does not want to panic.
//
// Note that this does not guarantee that the [HashAlgorithmId.GetHash]
// will return a valid corresponding [crypto.Hash].
func (a HashAlgorithmId) IsValid() bool {
switch a {
case HashAlgorithmSHA1:
case HashAlgorithmSHA256:
case HashAlgorithmSHA384:
case HashAlgorithmSHA512:
case HashAlgorithmSHA256_192:
case HashAlgorithmSM3_256:
case HashAlgorithmSHA3_256:
case HashAlgorithmSHA3_384:
case HashAlgorithmSHA3_512:
case HashAlgorithmSHAKE256_192:
case HashAlgorithmSHAKE256_256:
case HashAlgorithmSHAKE256_512:
default:
return false
}
return true
}
// Available determines if the TPM digest algorithm has an equivalent go
// [crypto.Hash] that is linked into the current binary.
func (a HashAlgorithmId) Available() bool {
return a.GetHash().Available()
}
// NewHash constructs a new hash.Hash implementation for this algorithm.
// It will panic if [HashAlgorithmId.Available] returns false.
func (a HashAlgorithmId) NewHash() hash.Hash {
return a.GetHash().New()
}
// Size returns the size of the algorithm. It will panic if
// [HashAlgorithmId.IsValid] returns false.
func (a HashAlgorithmId) Size() int {
switch a {
case HashAlgorithmSHA1:
return 20
case HashAlgorithmSHA256:
return 32
case HashAlgorithmSHA384:
return 48
case HashAlgorithmSHA512:
return 64
case HashAlgorithmSHA256_192:
return 24
case HashAlgorithmSM3_256:
return 32
case HashAlgorithmSHA3_256:
return 32
case HashAlgorithmSHA3_384:
return 48
case HashAlgorithmSHA3_512:
return 64
case HashAlgorithmSHAKE256_192:
return 24
case HashAlgorithmSHAKE256_256:
return 32
case HashAlgorithmSHAKE256_512:
return 64
default:
panic("unknown hash algorithm")
}
}
const (
HashAlgorithmNull HashAlgorithmId = HashAlgorithmId(AlgorithmNull) // TPM_ALG_NULL
HashAlgorithmSHA1 HashAlgorithmId = HashAlgorithmId(AlgorithmSHA1) // TPM_ALG_SHA1
HashAlgorithmSHA256 HashAlgorithmId = HashAlgorithmId(AlgorithmSHA256) // TPM_ALG_SHA256
HashAlgorithmSHA384 HashAlgorithmId = HashAlgorithmId(AlgorithmSHA384) // TPM_ALG_SHA384
HashAlgorithmSHA512 HashAlgorithmId = HashAlgorithmId(AlgorithmSHA512) // TPM_ALG_SHA512
HashAlgorithmSHA256_192 HashAlgorithmId = HashAlgorithmId(AlgorithmSHA256_192) // TPM_ALG_SHA256_192
HashAlgorithmSM3_256 HashAlgorithmId = HashAlgorithmId(AlgorithmSM3_256) // TPM_ALG_SM3_256
HashAlgorithmSHA3_256 HashAlgorithmId = HashAlgorithmId(AlgorithmSHA3_256) // TPM_ALG_SHA3_256
HashAlgorithmSHA3_384 HashAlgorithmId = HashAlgorithmId(AlgorithmSHA3_384) // TPM_ALG_SHA3_384
HashAlgorithmSHA3_512 HashAlgorithmId = HashAlgorithmId(AlgorithmSHA3_512) // TPM_ALG_SHA3_512
HashAlgorithmSHAKE256_192 HashAlgorithmId = HashAlgorithmId(AlgorithmSHAKE256_192) // TPM_ALG_SHAKE256_192
HashAlgorithmSHAKE256_256 HashAlgorithmId = HashAlgorithmId(AlgorithmSHAKE256_256) // TPM_ALG_SHAKE256_256
HashAlgorithmSHAKE256_512 HashAlgorithmId = HashAlgorithmId(AlgorithmSHAKE256_512) // TPM_ALG_SHAKE256_512
)
// SymAlgorithmId corresponds to the TPMI_ALG_SYM type
type SymAlgorithmId AlgorithmId
// IsValidBlockCipher determines if this algorithm is a valid block cipher.
// This should be checked by code that deserializes an algorithm before
// calling [SymAlgorithmId.BlockSize] if it does not want to panic.
func (a SymAlgorithmId) IsValidBlockCipher() bool {
switch a {
case SymAlgorithmTDES:
case SymAlgorithmAES:
case SymAlgorithmSM4:
case SymAlgorithmCamellia:
default:
return false
}
return true
}
// Available indicates whether the TPM symmetric cipher has a registered
// go implementation.
func (a SymAlgorithmId) Available() bool {
_, ok := symmetricAlgs[a]
return ok
}
// BlockSize indicates the block size of the symmetric cipher. This will
// panic if [SymAlgorithmId.IsValidBlockCipher] returns false.
func (a SymAlgorithmId) BlockSize() int {
switch a {
case SymAlgorithmTDES:
return 8
case SymAlgorithmAES:
return 16
case SymAlgorithmSM4:
return 16
case SymAlgorithmCamellia:
return 16
default:
panic("invalid symmetric algorithm")
}
}
// NewCipher constructs a new symmetric cipher with the supplied key, if
// there is a go implementation registered.
func (a SymAlgorithmId) NewCipher(key []byte) (cipher.Block, error) {
if !a.IsValidBlockCipher() {
return nil, fmt.Errorf("%v is not a valid block cipher", a)
}
fn, ok := symmetricAlgs[a]
if !ok {
return nil, fmt.Errorf("unavailable cipher %v", a)
}
return fn(key)
}
const (
SymAlgorithmTDES SymAlgorithmId = SymAlgorithmId(AlgorithmTDES) // TPM_ALG_TDES
SymAlgorithmAES SymAlgorithmId = SymAlgorithmId(AlgorithmAES) // TPM_ALG_AES
SymAlgorithmXOR SymAlgorithmId = SymAlgorithmId(AlgorithmXOR) // TPM_ALG_XOR
SymAlgorithmNull SymAlgorithmId = SymAlgorithmId(AlgorithmNull) // TPM_ALG_NULL
SymAlgorithmSM4 SymAlgorithmId = SymAlgorithmId(AlgorithmSM4) // TPM_ALG_SM4
SymAlgorithmCamellia SymAlgorithmId = SymAlgorithmId(AlgorithmCamellia) // TPM_ALG_CAMELLIA
)
// SymObjectAlgorithmId corresponds to the TPMI_ALG_SYM_OBJECT type
type SymObjectAlgorithmId AlgorithmId
// IsValidBlockCipher determines if this algorithm is a valid block cipher.
// This should be checked by code that deserializes an algorithm before
// calling [SymObjectAlgorithmId.BlockSize] if it does not want to panic.
func (a SymObjectAlgorithmId) IsValidBlockCipher() bool {
return SymAlgorithmId(a).IsValidBlockCipher()
}
// Available indicates whether the TPM symmetric cipher has a registered
// go implementation.
func (a SymObjectAlgorithmId) Available() bool {
return SymAlgorithmId(a).Available()
}
// BlockSize indicates the block size of the symmetric cipher. This will
// panic if [SymObjectAlgorithmId.IsValidBlockCipher] returns false.
func (a SymObjectAlgorithmId) BlockSize() int {
return SymAlgorithmId(a).BlockSize()
}
// NewCipher constructs a new symmetric cipher with the supplied key, if
// there is a go implementation registered.
func (a SymObjectAlgorithmId) NewCipher(key []byte) (cipher.Block, error) {
return SymAlgorithmId(a).NewCipher(key)
}
const (
SymObjectAlgorithmAES SymObjectAlgorithmId = SymObjectAlgorithmId(AlgorithmAES) // TPM_ALG_AES
SymObjectAlgorithmNull SymObjectAlgorithmId = SymObjectAlgorithmId(AlgorithmNull) // TPM_ALG_NULL
SymObjectAlgorithmSM4 SymObjectAlgorithmId = SymObjectAlgorithmId(AlgorithmSM4) // TPM_ALG_SM4
SymObjectAlgorithmCamellia SymObjectAlgorithmId = SymObjectAlgorithmId(AlgorithmCamellia) // TPM_ALG_CAMELLIA
)
// SymModeId corresponds to the TPMI_ALG_SYM_MODE type
type SymModeId AlgorithmId
const (
SymModeNull SymModeId = SymModeId(AlgorithmNull) // TPM_ALG_NULL
SymModeCTR SymModeId = SymModeId(AlgorithmCTR) // TPM_ALG_CTR
SymModeOFB SymModeId = SymModeId(AlgorithmOFB) // TPM_ALG_OFB
SymModeCBC SymModeId = SymModeId(AlgorithmCBC) // TPM_ALG_CBC
SymModeCFB SymModeId = SymModeId(AlgorithmCFB) // TPM_ALG_CFB
SymModeECB SymModeId = SymModeId(AlgorithmECB) // TPM_ALG_ECB
)
// KDFAlgorithmId corresppnds to the TPMI_ALG_KDF type
type KDFAlgorithmId AlgorithmId
const (
KDFAlgorithmMGF1 KDFAlgorithmId = KDFAlgorithmId(AlgorithmMGF1) // TPM_ALG_MGF1
KDFAlgorithmNull KDFAlgorithmId = KDFAlgorithmId(AlgorithmNull) // TPM_ALG_NULL
KDFAlgorithmKDF1_SP800_56A KDFAlgorithmId = KDFAlgorithmId(AlgorithmKDF1_SP800_56A) // TPM_ALG_KDF1_SP800_56A
KDFAlgorithmKDF2 KDFAlgorithmId = KDFAlgorithmId(AlgorithmKDF2) // TPM_ALG_KDF2
KDFAlgorithmKDF1_SP800_108 KDFAlgorithmId = KDFAlgorithmId(AlgorithmKDF1_SP800_108) // TPM_ALG_KDF1_SP800_108
)
// SigSchemeId corresponds to the TPMI_ALG_SIG_SCHEME type
type SigSchemeId AlgorithmId
// IsValid determines if the scheme is a valid signature scheme.
func (s SigSchemeId) IsValid() bool {
switch s {
case SigSchemeAlgHMAC:
case SigSchemeAlgRSASSA:
case SigSchemeAlgRSAPSS:
case SigSchemeAlgECDSA:
case SigSchemeAlgECDAA:
case SigSchemeAlgSM2:
case SigSchemeAlgECSchnorr:
case SigSchemeAlgEDDSA:
case SigSchemeAlgEDDSA_PH:
default:
return false
}
return true
}
const (
SigSchemeAlgHMAC SigSchemeId = SigSchemeId(AlgorithmHMAC) // TPM_ALG_HMAC
SigSchemeAlgNull SigSchemeId = SigSchemeId(AlgorithmNull) // TPM_ALG_NULL
SigSchemeAlgRSASSA SigSchemeId = SigSchemeId(AlgorithmRSASSA) // TPM_ALG_RSASSA
SigSchemeAlgRSAPSS SigSchemeId = SigSchemeId(AlgorithmRSAPSS) // TPM_ALG_RSAPSS
SigSchemeAlgECDSA SigSchemeId = SigSchemeId(AlgorithmECDSA) // TPM_ALG_ECDSA
SigSchemeAlgECDAA SigSchemeId = SigSchemeId(AlgorithmECDAA) // TPM_ALG_ECDAA
SigSchemeAlgSM2 SigSchemeId = SigSchemeId(AlgorithmSM2) // TPM_ALG_SM2
SigSchemeAlgECSchnorr SigSchemeId = SigSchemeId(AlgorithmECSchnorr) // TPM_ALG_ECSCHNORR
SigSchemeAlgEDDSA SigSchemeId = SigSchemeId(AlgorithmEDDSA) // TPM_ALG_EDDSA
SigSchemeAlgEDDSA_PH SigSchemeId = SigSchemeId(AlgorithmEDDSA_PH) // TPM_ALG_EDDSA
SigSchemeAlgLMS SigSchemeId = SigSchemeId(AlgorithmLMS) // TPM_ALG_LMS
SigSchemeAlgXMSS SigSchemeId = SigSchemeId(AlgorithmXMSS) // TPM_ALG_XMSS
)