1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package crypto11
23
24 import (
25 "errors"
26
27 "github.com/miekg/pkcs11"
28 )
29
30
31 type SymmetricGenParams struct {
32
33 KeyType uint
34
35
36 GenMech uint
37 }
38
39
40 type SymmetricCipher struct {
41
42
43 GenParams []SymmetricGenParams
44
45
46 BlockSize int
47
48
49 Encrypt bool
50
51
52 MAC bool
53
54
55 ECBMech uint
56
57
58 CBCMech uint
59
60
61 CBCPKCSMech uint
62
63
64 GCMMech uint
65 }
66
67
68
69 var CipherAES = &SymmetricCipher{
70 GenParams: []SymmetricGenParams{
71 {
72 KeyType: pkcs11.CKK_AES,
73 GenMech: pkcs11.CKM_AES_KEY_GEN,
74 },
75 },
76 BlockSize: 16,
77 Encrypt: true,
78 MAC: false,
79 ECBMech: pkcs11.CKM_AES_ECB,
80 CBCMech: pkcs11.CKM_AES_CBC,
81 CBCPKCSMech: pkcs11.CKM_AES_CBC_PAD,
82 GCMMech: pkcs11.CKM_AES_GCM,
83 }
84
85
86
87 var CipherDES3 = &SymmetricCipher{
88 GenParams: []SymmetricGenParams{
89 {
90 KeyType: pkcs11.CKK_DES3,
91 GenMech: pkcs11.CKM_DES3_KEY_GEN,
92 },
93 },
94 BlockSize: 8,
95 Encrypt: true,
96 MAC: false,
97 ECBMech: pkcs11.CKM_DES3_ECB,
98 CBCMech: pkcs11.CKM_DES3_CBC,
99 CBCPKCSMech: pkcs11.CKM_DES3_CBC_PAD,
100 GCMMech: 0,
101 }
102
103
104
105
106
107
108
109 var CipherGeneric = &SymmetricCipher{
110 GenParams: []SymmetricGenParams{
111 {
112 KeyType: pkcs11.CKK_GENERIC_SECRET,
113 GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN,
114 },
115 },
116 BlockSize: 64,
117 Encrypt: false,
118 MAC: true,
119 ECBMech: 0,
120 CBCMech: 0,
121 GCMMech: 0,
122 }
123
124
125
126 var CipherHMACSHA1 = &SymmetricCipher{
127 GenParams: []SymmetricGenParams{
128 {
129 KeyType: pkcs11.CKK_SHA_1_HMAC,
130 GenMech: CKM_NC_SHA_1_HMAC_KEY_GEN,
131 },
132 {
133 KeyType: pkcs11.CKK_GENERIC_SECRET,
134 GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN,
135 },
136 },
137 BlockSize: 64,
138 Encrypt: false,
139 MAC: true,
140 ECBMech: 0,
141 CBCMech: 0,
142 GCMMech: 0,
143 }
144
145
146
147 var CipherHMACSHA224 = &SymmetricCipher{
148 GenParams: []SymmetricGenParams{
149 {
150 KeyType: pkcs11.CKK_SHA224_HMAC,
151 GenMech: CKM_NC_SHA224_HMAC_KEY_GEN,
152 },
153 {
154 KeyType: pkcs11.CKK_GENERIC_SECRET,
155 GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN,
156 },
157 },
158 BlockSize: 64,
159 Encrypt: false,
160 MAC: true,
161 ECBMech: 0,
162 CBCMech: 0,
163 GCMMech: 0,
164 }
165
166
167
168 var CipherHMACSHA256 = &SymmetricCipher{
169 GenParams: []SymmetricGenParams{
170 {
171 KeyType: pkcs11.CKK_SHA256_HMAC,
172 GenMech: CKM_NC_SHA256_HMAC_KEY_GEN,
173 },
174 {
175 KeyType: pkcs11.CKK_GENERIC_SECRET,
176 GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN,
177 },
178 },
179 BlockSize: 64,
180 Encrypt: false,
181 MAC: true,
182 ECBMech: 0,
183 CBCMech: 0,
184 GCMMech: 0,
185 }
186
187
188
189 var CipherHMACSHA384 = &SymmetricCipher{
190 GenParams: []SymmetricGenParams{
191 {
192 KeyType: pkcs11.CKK_SHA384_HMAC,
193 GenMech: CKM_NC_SHA384_HMAC_KEY_GEN,
194 },
195 {
196 KeyType: pkcs11.CKK_GENERIC_SECRET,
197 GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN,
198 },
199 },
200 BlockSize: 64,
201 Encrypt: false,
202 MAC: true,
203 ECBMech: 0,
204 CBCMech: 0,
205 GCMMech: 0,
206 }
207
208
209
210 var CipherHMACSHA512 = &SymmetricCipher{
211 GenParams: []SymmetricGenParams{
212 {
213 KeyType: pkcs11.CKK_SHA512_HMAC,
214 GenMech: CKM_NC_SHA512_HMAC_KEY_GEN,
215 },
216 {
217 KeyType: pkcs11.CKK_GENERIC_SECRET,
218 GenMech: pkcs11.CKM_GENERIC_SECRET_KEY_GEN,
219 },
220 },
221 BlockSize: 128,
222 Encrypt: false,
223 MAC: true,
224 ECBMech: 0,
225 CBCMech: 0,
226 GCMMech: 0,
227 }
228
229
230 var Ciphers = map[int]*SymmetricCipher{
231 pkcs11.CKK_AES: CipherAES,
232 pkcs11.CKK_DES3: CipherDES3,
233 pkcs11.CKK_GENERIC_SECRET: CipherGeneric,
234 pkcs11.CKK_SHA_1_HMAC: CipherHMACSHA1,
235 pkcs11.CKK_SHA224_HMAC: CipherHMACSHA224,
236 pkcs11.CKK_SHA256_HMAC: CipherHMACSHA256,
237 pkcs11.CKK_SHA384_HMAC: CipherHMACSHA384,
238 pkcs11.CKK_SHA512_HMAC: CipherHMACSHA512,
239 }
240
241
242
243
244
245
246
247
248 type SecretKey struct {
249 pkcs11Object
250
251
252 Cipher *SymmetricCipher
253 }
254
255
256
257 func (c *Context) GenerateSecretKey(id []byte, bits int, cipher *SymmetricCipher) (*SecretKey, error) {
258 if c.closed.Get() {
259 return nil, errClosed
260 }
261
262 template, err := NewAttributeSetWithID(id)
263 if err != nil {
264 return nil, err
265 }
266 return c.GenerateSecretKeyWithAttributes(template, bits, cipher)
267 }
268
269
270
271 func (c *Context) GenerateSecretKeyWithLabel(id, label []byte, bits int, cipher *SymmetricCipher) (*SecretKey, error) {
272 if c.closed.Get() {
273 return nil, errClosed
274 }
275
276 template, err := NewAttributeSetWithIDAndLabel(id, label)
277 if err != nil {
278 return nil, err
279 }
280 return c.GenerateSecretKeyWithAttributes(template, bits, cipher)
281
282 }
283
284
285
286
287 func (c *Context) GenerateSecretKeyWithAttributes(template AttributeSet, bits int, cipher *SymmetricCipher) (k *SecretKey, err error) {
288 if c.closed.Get() {
289 return nil, errClosed
290 }
291
292 err = c.withSession(func(session *pkcs11Session) error {
293
294
295
296
297
298 template.AddIfNotPresent([]*pkcs11.Attribute{
299 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_SECRET_KEY),
300 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
301 pkcs11.NewAttribute(pkcs11.CKA_SIGN, cipher.MAC),
302 pkcs11.NewAttribute(pkcs11.CKA_VERIFY, cipher.MAC),
303 pkcs11.NewAttribute(pkcs11.CKA_ENCRYPT, cipher.Encrypt),
304 pkcs11.NewAttribute(pkcs11.CKA_DECRYPT, cipher.Encrypt),
305 pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true),
306 pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, false),
307 })
308 if bits > 0 {
309 _ = template.Set(pkcs11.CKA_VALUE_LEN, bits/8)
310 }
311
312 for n, genMech := range cipher.GenParams {
313
314 _ = template.Set(CkaKeyType, genMech.KeyType)
315
316 mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(genMech.GenMech, nil)}
317
318 privHandle, err := session.ctx.GenerateKey(session.handle, mech, template.ToSlice())
319 if err == nil {
320 k = &SecretKey{pkcs11Object{privHandle, c}, cipher}
321 return nil
322 }
323
324
325
326 if e, ok := err.(pkcs11.Error); ok && e == pkcs11.CKR_ARGUMENTS_BAD && genMech.GenMech == pkcs11.CKM_GENERIC_SECRET_KEY_GEN {
327 adjustedTemplate := template.Copy()
328 adjustedTemplate.Unset(CkaEncrypt)
329 adjustedTemplate.Unset(CkaDecrypt)
330
331 privHandle, err = session.ctx.GenerateKey(session.handle, mech, adjustedTemplate.ToSlice())
332 if err == nil {
333
334 template.cloneFrom(adjustedTemplate)
335
336 k = &SecretKey{pkcs11Object{privHandle, c}, cipher}
337 return nil
338 }
339 }
340
341 if n == len(cipher.GenParams)-1 {
342
343
344 return err
345 }
346
347
348
349 if e, ok := err.(pkcs11.Error); ok &&
350 e == pkcs11.CKR_TEMPLATE_INCONSISTENT || e == pkcs11.CKR_ATTRIBUTE_VALUE_INVALID {
351 continue
352 }
353
354 return err
355 }
356
357
358 return errors.New("cipher must have GenParams")
359 })
360 return
361 }
362
363
364 func (key *SecretKey) Delete() error {
365 return key.pkcs11Object.Delete()
366 }
367
View as plain text