1
2
3
4
5
6
7 package boring
8
9
10 import "C"
11 import (
12 "crypto"
13 "crypto/subtle"
14 "errors"
15 "hash"
16 "runtime"
17 "strconv"
18 "unsafe"
19 )
20
21 func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) {
22 bad := func(e error) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) {
23 return nil, nil, nil, nil, nil, nil, nil, nil, e
24 }
25
26 key := C._goboringcrypto_RSA_new()
27 if key == nil {
28 return bad(fail("RSA_new"))
29 }
30 defer C._goboringcrypto_RSA_free(key)
31
32 if C._goboringcrypto_RSA_generate_key_fips(key, C.int(bits), nil) == 0 {
33 return bad(fail("RSA_generate_key_fips"))
34 }
35
36 var n, e, d, p, q, dp, dq, qinv *C.GO_BIGNUM
37 C._goboringcrypto_RSA_get0_key(key, &n, &e, &d)
38 C._goboringcrypto_RSA_get0_factors(key, &p, &q)
39 C._goboringcrypto_RSA_get0_crt_params(key, &dp, &dq, &qinv)
40 return bnToBig(n), bnToBig(e), bnToBig(d), bnToBig(p), bnToBig(q), bnToBig(dp), bnToBig(dq), bnToBig(qinv), nil
41 }
42
43 type PublicKeyRSA struct {
44
45 _key *C.GO_RSA
46 }
47
48 func NewPublicKeyRSA(N, E BigInt) (*PublicKeyRSA, error) {
49 key := C._goboringcrypto_RSA_new()
50 if key == nil {
51 return nil, fail("RSA_new")
52 }
53 if !bigToBn(&key.n, N) ||
54 !bigToBn(&key.e, E) {
55 return nil, fail("BN_bin2bn")
56 }
57 k := &PublicKeyRSA{_key: key}
58 runtime.SetFinalizer(k, (*PublicKeyRSA).finalize)
59 return k, nil
60 }
61
62 func (k *PublicKeyRSA) finalize() {
63 C._goboringcrypto_RSA_free(k._key)
64 }
65
66 func (k *PublicKeyRSA) withKey(f func(*C.GO_RSA) C.int) C.int {
67
68
69
70 defer runtime.KeepAlive(k)
71 return f(k._key)
72 }
73
74 type PrivateKeyRSA struct {
75
76 _key *C.GO_RSA
77 }
78
79 func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv BigInt) (*PrivateKeyRSA, error) {
80 key := C._goboringcrypto_RSA_new()
81 if key == nil {
82 return nil, fail("RSA_new")
83 }
84 if !bigToBn(&key.n, N) ||
85 !bigToBn(&key.e, E) ||
86 !bigToBn(&key.d, D) ||
87 !bigToBn(&key.p, P) ||
88 !bigToBn(&key.q, Q) ||
89 !bigToBn(&key.dmp1, Dp) ||
90 !bigToBn(&key.dmq1, Dq) ||
91 !bigToBn(&key.iqmp, Qinv) {
92 return nil, fail("BN_bin2bn")
93 }
94 k := &PrivateKeyRSA{_key: key}
95 runtime.SetFinalizer(k, (*PrivateKeyRSA).finalize)
96 return k, nil
97 }
98
99 func (k *PrivateKeyRSA) finalize() {
100 C._goboringcrypto_RSA_free(k._key)
101 }
102
103 func (k *PrivateKeyRSA) withKey(f func(*C.GO_RSA) C.int) C.int {
104
105
106
107 defer runtime.KeepAlive(k)
108 return f(k._key)
109 }
110
111 func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int,
112 padding C.int, h, mgfHash hash.Hash, label []byte, saltLen int, ch crypto.Hash,
113 init func(*C.GO_EVP_PKEY_CTX) C.int) (pkey *C.GO_EVP_PKEY, ctx *C.GO_EVP_PKEY_CTX, err error) {
114 defer func() {
115 if err != nil {
116 if pkey != nil {
117 C._goboringcrypto_EVP_PKEY_free(pkey)
118 pkey = nil
119 }
120 if ctx != nil {
121 C._goboringcrypto_EVP_PKEY_CTX_free(ctx)
122 ctx = nil
123 }
124 }
125 }()
126
127 pkey = C._goboringcrypto_EVP_PKEY_new()
128 if pkey == nil {
129 return pkey, ctx, fail("EVP_PKEY_new")
130 }
131 if withKey(func(key *C.GO_RSA) C.int {
132 return C._goboringcrypto_EVP_PKEY_set1_RSA(pkey, key)
133 }) == 0 {
134 return pkey, ctx, fail("EVP_PKEY_set1_RSA")
135 }
136 ctx = C._goboringcrypto_EVP_PKEY_CTX_new(pkey, nil)
137 if ctx == nil {
138 return pkey, ctx, fail("EVP_PKEY_CTX_new")
139 }
140 if init(ctx) == 0 {
141 return pkey, ctx, fail("EVP_PKEY_operation_init")
142 }
143 if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, padding) == 0 {
144 return pkey, ctx, fail("EVP_PKEY_CTX_set_rsa_padding")
145 }
146 if padding == C.GO_RSA_PKCS1_OAEP_PADDING {
147 md := hashToMD(h)
148 if md == nil {
149 return pkey, ctx, errors.New("crypto/rsa: unsupported hash function")
150 }
151 mgfMD := hashToMD(mgfHash)
152 if mgfMD == nil {
153 return pkey, ctx, errors.New("crypto/rsa: unsupported hash function")
154 }
155 if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) == 0 {
156 return pkey, ctx, fail("EVP_PKEY_set_rsa_oaep_md")
157 }
158 if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgfMD) == 0 {
159 return pkey, ctx, fail("EVP_PKEY_set_rsa_mgf1_md")
160 }
161
162 clabel := (*C.uint8_t)(C._goboringcrypto_OPENSSL_malloc(C.size_t(len(label))))
163 if clabel == nil {
164 return pkey, ctx, fail("OPENSSL_malloc")
165 }
166 copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label)
167 if C._goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, C.size_t(len(label))) == 0 {
168 return pkey, ctx, fail("EVP_PKEY_CTX_set0_rsa_oaep_label")
169 }
170 }
171 if padding == C.GO_RSA_PKCS1_PSS_PADDING {
172 if saltLen != 0 {
173 if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, C.int(saltLen)) == 0 {
174 return pkey, ctx, fail("EVP_PKEY_set_rsa_pss_saltlen")
175 }
176 }
177 md := cryptoHashToMD(ch)
178 if md == nil {
179 return pkey, ctx, errors.New("crypto/rsa: unsupported hash function")
180 }
181 if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) == 0 {
182 return pkey, ctx, fail("EVP_PKEY_set_rsa_mgf1_md")
183 }
184 }
185
186 return pkey, ctx, nil
187 }
188
189 func cryptRSA(withKey func(func(*C.GO_RSA) C.int) C.int,
190 padding C.int, h, mgfHash hash.Hash, label []byte, saltLen int, ch crypto.Hash,
191 init func(*C.GO_EVP_PKEY_CTX) C.int,
192 crypt func(*C.GO_EVP_PKEY_CTX, *C.uint8_t, *C.size_t, *C.uint8_t, C.size_t) C.int,
193 in []byte) ([]byte, error) {
194
195 pkey, ctx, err := setupRSA(withKey, padding, h, mgfHash, label, saltLen, ch, init)
196 if err != nil {
197 return nil, err
198 }
199 defer C._goboringcrypto_EVP_PKEY_free(pkey)
200 defer C._goboringcrypto_EVP_PKEY_CTX_free(ctx)
201
202 var outLen C.size_t
203 if crypt(ctx, nil, &outLen, base(in), C.size_t(len(in))) == 0 {
204 return nil, fail("EVP_PKEY_decrypt/encrypt")
205 }
206 out := make([]byte, outLen)
207 if crypt(ctx, base(out), &outLen, base(in), C.size_t(len(in))) == 0 {
208 return nil, fail("EVP_PKEY_decrypt/encrypt")
209 }
210 return out[:outLen], nil
211 }
212
213 func DecryptRSAOAEP(h, mgfHash hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) {
214 return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, 0, 0, decryptInit, decrypt, ciphertext)
215 }
216
217 func EncryptRSAOAEP(h, mgfHash hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) {
218 return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, 0, 0, encryptInit, encrypt, msg)
219 }
220
221 func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) {
222 return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, 0, 0, decryptInit, decrypt, ciphertext)
223 }
224
225 func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) {
226 return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, 0, 0, encryptInit, encrypt, msg)
227 }
228
229 func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) {
230 return cryptRSA(priv.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, 0, 0, decryptInit, decrypt, ciphertext)
231 }
232
233 func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) {
234 return cryptRSA(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, 0, 0, encryptInit, encrypt, msg)
235 }
236
237
238
239 func decryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int {
240 return C._goboringcrypto_EVP_PKEY_decrypt_init(ctx)
241 }
242
243 func decrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.size_t, in *C.uint8_t, inLen C.size_t) C.int {
244 return C._goboringcrypto_EVP_PKEY_decrypt(ctx, out, outLen, in, inLen)
245 }
246
247 func encryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int {
248 return C._goboringcrypto_EVP_PKEY_encrypt_init(ctx)
249 }
250
251 func encrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.size_t, in *C.uint8_t, inLen C.size_t) C.int {
252 return C._goboringcrypto_EVP_PKEY_encrypt(ctx, out, outLen, in, inLen)
253 }
254
255 var invalidSaltLenErr = errors.New("crypto/rsa: PSSOptions.SaltLength cannot be negative")
256
257 func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) {
258 md := cryptoHashToMD(h)
259 if md == nil {
260 return nil, errors.New("crypto/rsa: unsupported hash function")
261 }
262
263
264
265 if saltLen <= -2 {
266 return nil, invalidSaltLenErr
267 }
268
269
270
271
272
273 if saltLen == 0 {
274 saltLen = -2
275 }
276
277 var out []byte
278 var outLen C.size_t
279 if priv.withKey(func(key *C.GO_RSA) C.int {
280 out = make([]byte, C._goboringcrypto_RSA_size(key))
281 return C._goboringcrypto_RSA_sign_pss_mgf1(key, &outLen, base(out), C.size_t(len(out)),
282 base(hashed), C.size_t(len(hashed)), md, nil, C.int(saltLen))
283 }) == 0 {
284 return nil, fail("RSA_sign_pss_mgf1")
285 }
286
287 return out[:outLen], nil
288 }
289
290 func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error {
291 md := cryptoHashToMD(h)
292 if md == nil {
293 return errors.New("crypto/rsa: unsupported hash function")
294 }
295
296
297
298 if saltLen <= -2 {
299 return invalidSaltLenErr
300 }
301
302
303
304
305
306 if saltLen == 0 {
307 saltLen = -2
308 }
309
310 if pub.withKey(func(key *C.GO_RSA) C.int {
311 return C._goboringcrypto_RSA_verify_pss_mgf1(key, base(hashed), C.size_t(len(hashed)),
312 md, nil, C.int(saltLen), base(sig), C.size_t(len(sig)))
313 }) == 0 {
314 return fail("RSA_verify_pss_mgf1")
315 }
316 return nil
317 }
318
319 func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) {
320 if h == 0 {
321
322 var out []byte
323 var outLen C.size_t
324 if priv.withKey(func(key *C.GO_RSA) C.int {
325 out = make([]byte, C._goboringcrypto_RSA_size(key))
326 return C._goboringcrypto_RSA_sign_raw(key, &outLen, base(out), C.size_t(len(out)),
327 base(hashed), C.size_t(len(hashed)), C.GO_RSA_PKCS1_PADDING)
328 }) == 0 {
329 return nil, fail("RSA_sign_raw")
330 }
331 return out[:outLen], nil
332 }
333
334 md := cryptoHashToMD(h)
335 if md == nil {
336 return nil, errors.New("crypto/rsa: unsupported hash function: " + strconv.Itoa(int(h)))
337 }
338 nid := C._goboringcrypto_EVP_MD_type(md)
339 var out []byte
340 var outLen C.uint
341 if priv.withKey(func(key *C.GO_RSA) C.int {
342 out = make([]byte, C._goboringcrypto_RSA_size(key))
343 return C._goboringcrypto_RSA_sign(nid, base(hashed), C.uint(len(hashed)),
344 base(out), &outLen, key)
345 }) == 0 {
346 return nil, fail("RSA_sign")
347 }
348 return out[:outLen], nil
349 }
350
351 func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error {
352 if h == 0 {
353 var out []byte
354 var outLen C.size_t
355 if pub.withKey(func(key *C.GO_RSA) C.int {
356 out = make([]byte, C._goboringcrypto_RSA_size(key))
357 return C._goboringcrypto_RSA_verify_raw(key, &outLen, base(out),
358 C.size_t(len(out)), base(sig), C.size_t(len(sig)), C.GO_RSA_PKCS1_PADDING)
359 }) == 0 {
360 return fail("RSA_verify")
361 }
362 if subtle.ConstantTimeCompare(hashed, out[:outLen]) != 1 {
363 return fail("RSA_verify")
364 }
365 return nil
366 }
367 md := cryptoHashToMD(h)
368 if md == nil {
369 return errors.New("crypto/rsa: unsupported hash function")
370 }
371 nid := C._goboringcrypto_EVP_MD_type(md)
372 if pub.withKey(func(key *C.GO_RSA) C.int {
373 return C._goboringcrypto_RSA_verify(nid, base(hashed), C.size_t(len(hashed)),
374 base(sig), C.size_t(len(sig)), key)
375 }) == 0 {
376 return fail("RSA_verify")
377 }
378 return nil
379 }
380
View as plain text