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 "crypto/cipher"
26 "errors"
27 "fmt"
28
29 "github.com/miekg/pkcs11"
30 )
31
32
33
34
35 type PaddingMode int
36
37 const (
38
39 PaddingNone PaddingMode = iota
40
41
42 PaddingPKCS
43 )
44
45 var errBadGCMNonceSize = errors.New("nonce slice too small to hold IV")
46
47 type genericAead struct {
48 key *SecretKey
49
50 overhead int
51
52 nonceSize int
53
54
55
56 makeMech func(nonce []byte, additionalData []byte, encrypt bool) ([]*pkcs11.Mechanism, *pkcs11.GCMParams, error)
57 }
58
59
60
61
62
63
64 func (key *SecretKey) NewGCM() (cipher.AEAD, error) {
65 if key.Cipher.GCMMech == 0 {
66 return nil, fmt.Errorf("GCM not implemented for key type %#x", key.Cipher.GenParams[0].KeyType)
67 }
68
69 g := genericAead{
70 key: key,
71 overhead: 16,
72 nonceSize: key.context.cfg.GCMIVLength,
73 makeMech: func(nonce []byte, additionalData []byte, encrypt bool) ([]*pkcs11.Mechanism, *pkcs11.GCMParams, error) {
74 var params *pkcs11.GCMParams
75
76 if (encrypt && key.context.cfg.UseGCMIVFromHSM &&
77 !key.context.cfg.GCMIVFromHSMControl.SupplyIvForHSMGCMEncrypt) || (!encrypt &&
78 key.context.cfg.UseGCMIVFromHSM && !key.context.cfg.GCMIVFromHSMControl.SupplyIvForHSMGCMDecrypt) {
79 params = pkcs11.NewGCMParams(nil, additionalData, 16*8 )
80 } else {
81 params = pkcs11.NewGCMParams(nonce, additionalData, 16*8 )
82 }
83 return []*pkcs11.Mechanism{pkcs11.NewMechanism(key.Cipher.GCMMech, params)}, params, nil
84 },
85 }
86 return g, nil
87 }
88
89
90
91
92
93
94 func (key *SecretKey) NewCBC(paddingMode PaddingMode) (cipher.AEAD, error) {
95
96 var pkcsMech uint
97
98 switch paddingMode {
99 case PaddingNone:
100 pkcsMech = key.Cipher.CBCMech
101 case PaddingPKCS:
102 pkcsMech = key.Cipher.CBCPKCSMech
103 default:
104 return nil, errors.New("unrecognized padding mode")
105 }
106
107 g := genericAead{
108 key: key,
109 overhead: 0,
110 nonceSize: key.BlockSize(),
111 makeMech: func(nonce []byte, additionalData []byte, encrypt bool) ([]*pkcs11.Mechanism, *pkcs11.GCMParams, error) {
112 if len(additionalData) > 0 {
113 return nil, nil, errors.New("additional data not supported for CBC mode")
114 }
115
116 return []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcsMech, nonce)}, nil, nil
117 },
118 }
119
120 return g, nil
121 }
122
123 func (g genericAead) NonceSize() int {
124 return g.nonceSize
125 }
126
127 func (g genericAead) Overhead() int {
128 return g.overhead
129 }
130
131 func (g genericAead) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
132
133 var result []byte
134 if err := g.key.context.withSession(func(session *pkcs11Session) (err error) {
135 mech, params, err := g.makeMech(nonce, additionalData, true)
136
137 if err != nil {
138 return err
139 }
140 defer params.Free()
141
142 if err = session.ctx.EncryptInit(session.handle, mech, g.key.handle); err != nil {
143 err = fmt.Errorf("C_EncryptInit: %v", err)
144 return
145 }
146 if result, err = session.ctx.Encrypt(session.handle, plaintext); err != nil {
147 err = fmt.Errorf("C_Encrypt: %v", err)
148 return
149 }
150
151 if g.key.context.cfg.UseGCMIVFromHSM && g.key.context.cfg.GCMIVFromHSMControl.SupplyIvForHSMGCMEncrypt {
152 if len(nonce) != len(params.IV()) {
153 return errBadGCMNonceSize
154 }
155 }
156
157 return
158 }); err != nil {
159 panic(err)
160 } else {
161 dst = append(dst, result...)
162 }
163 return dst
164 }
165
166 func (g genericAead) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
167 var result []byte
168 if err := g.key.context.withSession(func(session *pkcs11Session) (err error) {
169 mech, params, err := g.makeMech(nonce, additionalData, false)
170 if err != nil {
171 return
172 }
173 defer params.Free()
174
175 if err = session.ctx.DecryptInit(session.handle, mech, g.key.handle); err != nil {
176 err = fmt.Errorf("C_DecryptInit: %v", err)
177 return
178 }
179 if result, err = session.ctx.Decrypt(session.handle, ciphertext); err != nil {
180 err = fmt.Errorf("C_Decrypt: %v", err)
181 return
182 }
183 return
184 }); err != nil {
185 return nil, err
186 }
187 dst = append(dst, result...)
188 return dst, nil
189 }
190
View as plain text