1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2018, Joyent, Inc.
25 * Copyright 2017 Jason King.
26 */
27
28 #include <pthread.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <strings.h>
32 #include <sys/types.h>
33 #include <security/cryptoki.h>
34 #include <modes/modes.h>
35 #include <arcfour.h>
36 #include "softSession.h"
37 #include "softObject.h"
38 #include "softOps.h"
39 #include "softCrypt.h"
40 #include "softRSA.h"
41
42 /*
43 * Remove padding bytes.
44 */
45 CK_RV
soft_remove_pkcs7_padding(CK_BYTE * pData,CK_ULONG padded_len,CK_ULONG * pulDataLen)46 soft_remove_pkcs7_padding(CK_BYTE *pData, CK_ULONG padded_len,
47 CK_ULONG *pulDataLen)
48 {
49 CK_RV rv;
50
51 #ifdef __sparcv9
52 if ((rv = pkcs7_decode(pData, (&padded_len))) != CKR_OK)
53 #else /* !__sparcv9 */
54 if ((rv = pkcs7_decode(pData, (size_t *)(&padded_len))) != CKR_OK)
55 #endif /* __sparcv9 */
56 return (rv);
57
58 *pulDataLen = padded_len;
59 return (CKR_OK);
60 }
61
62
63 /*
64 * soft_decrypt_init()
65 *
66 * Arguments:
67 * session_p: pointer to soft_session_t struct
68 * pMechanism: pointer to CK_MECHANISM struct provided by application
69 * key_p: pointer to key soft_object_t struct
70 *
71 * Description:
72 * called by C_DecryptInit(). This function calls the corresponding
73 * decrypt init routine based on the mechanism.
74 *
75 * Returns:
76 * CKR_OK: success
77 * CKR_HOST_MEMORY: run out of system memory
78 * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism
79 * CKR_MECHANISM_INVALID: invalid mechanism type
80 * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use
81 * with the specified mechanism
82 */
83 CK_RV
soft_decrypt_init(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)84 soft_decrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
85 soft_object_t *key_p)
86 {
87
88 CK_RV rv;
89
90 switch (pMechanism->mechanism) {
91
92 case CKM_DES_ECB:
93
94 if (key_p->key_type != CKK_DES) {
95 return (CKR_KEY_TYPE_INCONSISTENT);
96 }
97
98 goto ecb_common;
99
100 case CKM_DES3_ECB:
101
102 if ((key_p->key_type != CKK_DES2) &&
103 (key_p->key_type != CKK_DES3)) {
104 return (CKR_KEY_TYPE_INCONSISTENT);
105 }
106
107 ecb_common:
108
109 return (soft_des_crypt_init_common(session_p, pMechanism,
110 key_p, B_FALSE));
111
112 case CKM_DES_CBC:
113 case CKM_DES_CBC_PAD:
114
115 if (key_p->key_type != CKK_DES) {
116 return (CKR_KEY_TYPE_INCONSISTENT);
117 }
118
119 goto cbc_common;
120
121 case CKM_DES3_CBC:
122 case CKM_DES3_CBC_PAD:
123 {
124 soft_des_ctx_t *soft_des_ctx;
125
126 if ((key_p->key_type != CKK_DES2) &&
127 (key_p->key_type != CKK_DES3)) {
128 return (CKR_KEY_TYPE_INCONSISTENT);
129 }
130
131 cbc_common:
132 if ((pMechanism->pParameter == NULL) ||
133 (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
134 return (CKR_MECHANISM_PARAM_INVALID);
135 }
136
137 rv = soft_des_crypt_init_common(session_p, pMechanism,
138 key_p, B_FALSE);
139
140 if (rv != CKR_OK)
141 return (rv);
142
143 (void) pthread_mutex_lock(&session_p->session_mutex);
144
145 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
146 /* Save Initialization Vector (IV) in the context. */
147 (void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter,
148 DES_BLOCK_LEN);
149
150 /* Allocate a context for DES cipher-block chaining. */
151 soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init(
152 soft_des_ctx->key_sched, soft_des_ctx->keysched_len,
153 soft_des_ctx->ivec, key_p->key_type);
154
155 if (soft_des_ctx->des_cbc == NULL) {
156 freezero(soft_des_ctx->key_sched,
157 soft_des_ctx->keysched_len);
158 freezero(session_p->decrypt.context,
159 sizeof (soft_des_ctx_t));
160 session_p->decrypt.context = NULL;
161 (void) pthread_mutex_unlock(&session_p->session_mutex);
162 return (CKR_HOST_MEMORY);
163 }
164
165 (void) pthread_mutex_unlock(&session_p->session_mutex);
166
167 return (rv);
168 }
169 case CKM_AES_ECB:
170 case CKM_AES_CBC:
171 case CKM_AES_CBC_PAD:
172 case CKM_AES_CTR:
173 case CKM_AES_CCM:
174 case CKM_AES_GCM:
175 case CKM_AES_GMAC:
176 return (soft_aes_crypt_init_common(session_p, pMechanism,
177 key_p, B_FALSE));
178
179 case CKM_BLOWFISH_CBC:
180 {
181 soft_blowfish_ctx_t *soft_blowfish_ctx;
182
183 if (key_p->key_type != CKK_BLOWFISH)
184 return (CKR_KEY_TYPE_INCONSISTENT);
185
186 if ((pMechanism->pParameter == NULL) ||
187 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN))
188 return (CKR_MECHANISM_PARAM_INVALID);
189
190 rv = soft_blowfish_crypt_init_common(session_p, pMechanism,
191 key_p, B_FALSE);
192
193 if (rv != CKR_OK)
194 return (rv);
195
196 (void) pthread_mutex_lock(&session_p->session_mutex);
197
198 soft_blowfish_ctx =
199 (soft_blowfish_ctx_t *)session_p->decrypt.context;
200
201 /* Save Initialization Vector in the context. */
202 (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter,
203 BLOWFISH_BLOCK_LEN);
204
205 /* Allocate a context for CBC */
206 soft_blowfish_ctx->blowfish_cbc =
207 (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched,
208 soft_blowfish_ctx->keysched_len,
209 soft_blowfish_ctx->ivec);
210
211 if (soft_blowfish_ctx->blowfish_cbc == NULL) {
212 freezero(soft_blowfish_ctx->key_sched,
213 soft_blowfish_ctx->keysched_len);
214 freezero(session_p->decrypt.context,
215 sizeof (soft_blowfish_ctx_t));
216 session_p->decrypt.context = NULL;
217 (void) pthread_mutex_unlock(&session_p->session_mutex);
218 return (CKR_HOST_MEMORY);
219 }
220
221 (void) pthread_mutex_unlock(&session_p->session_mutex);
222 return (rv);
223 }
224
225 case CKM_RC4:
226
227 if (key_p->key_type != CKK_RC4) {
228 return (CKR_KEY_TYPE_INCONSISTENT);
229 }
230
231 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
232 B_FALSE));
233
234 case CKM_RSA_X_509:
235 case CKM_RSA_PKCS:
236
237 if (key_p->key_type != CKK_RSA) {
238 return (CKR_KEY_TYPE_INCONSISTENT);
239 }
240
241 return (soft_rsa_crypt_init_common(session_p, pMechanism,
242 key_p, B_FALSE));
243
244 default:
245 return (CKR_MECHANISM_INVALID);
246 }
247 }
248
249
250 /*
251 * soft_decrypt_common()
252 *
253 * Arguments:
254 * session_p: pointer to soft_session_t struct
255 * pEncrypted: pointer to the encrypted data as input
256 * ulEncryptedLen: length of the input data
257 * pData: pointer to the output data contains plaintext
258 * pulDataLen: pointer to the length of the output data
259 * Update: boolean flag indicates caller is soft_decrypt
260 * or soft_decrypt_update
261 *
262 * Description:
263 * This function calls the corresponding decrypt routine based
264 * on the mechanism.
265 *
266 * Returns:
267 * see soft_decrypt_common().
268 */
269 CK_RV
soft_decrypt_common(soft_session_t * session_p,CK_BYTE_PTR pEncrypted,CK_ULONG ulEncryptedLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen,boolean_t Update)270 soft_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted,
271 CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData,
272 CK_ULONG_PTR pulDataLen, boolean_t Update)
273 {
274
275 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
276
277 switch (mechanism) {
278
279 case CKM_DES_ECB:
280 case CKM_DES_CBC:
281 case CKM_DES3_ECB:
282 case CKM_DES3_CBC:
283
284 if (ulEncryptedLen == 0) {
285 *pulDataLen = 0;
286 return (CKR_OK);
287 }
288 /* FALLTHROUGH */
289
290 case CKM_DES_CBC_PAD:
291 case CKM_DES3_CBC_PAD:
292
293 return (soft_des_decrypt_common(session_p, pEncrypted,
294 ulEncryptedLen, pData, pulDataLen, Update));
295
296 case CKM_AES_ECB:
297 case CKM_AES_CBC:
298 case CKM_AES_CBC_PAD:
299 case CKM_AES_CTR:
300 case CKM_AES_CCM:
301 case CKM_AES_GCM:
302 case CKM_AES_GMAC:
303 if (Update) {
304 return (soft_aes_decrypt_update(session_p, pEncrypted,
305 ulEncryptedLen, pData, pulDataLen));
306 } else {
307 return (soft_aes_decrypt(session_p, pEncrypted,
308 ulEncryptedLen, pData, pulDataLen));
309 }
310
311 case CKM_BLOWFISH_CBC:
312
313 if (ulEncryptedLen == 0) {
314 *pulDataLen = 0;
315 return (CKR_OK);
316 }
317
318 return (soft_blowfish_decrypt_common(session_p, pEncrypted,
319 ulEncryptedLen, pData, pulDataLen, Update));
320
321 case CKM_RC4:
322
323 if (ulEncryptedLen == 0) {
324 *pulDataLen = 0;
325 return (CKR_OK);
326 }
327
328
329 return (soft_arcfour_crypt(&(session_p->decrypt), pEncrypted,
330 ulEncryptedLen, pData, pulDataLen));
331
332 case CKM_RSA_X_509:
333 case CKM_RSA_PKCS:
334
335 return (soft_rsa_decrypt_common(session_p, pEncrypted,
336 ulEncryptedLen, pData, pulDataLen, mechanism));
337
338 default:
339 return (CKR_MECHANISM_INVALID);
340
341 }
342 }
343
344
345 /*
346 * soft_decrypt()
347 *
348 * Arguments:
349 * session_p: pointer to soft_session_t struct
350 * pEncryptedData: pointer to the encrypted data as input
351 * ulEncryptedDataLen: length of the input data
352 * pData: pointer to the output data contains plaintext
353 * pulDataLen: pointer to the length of the output data
354 *
355 * Description:
356 * called by C_Decrypt(). This function calls the soft_decrypt_common
357 * routine.
358 *
359 * Returns:
360 * see soft_decrypt_common().
361 */
362 CK_RV
soft_decrypt(soft_session_t * session_p,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)363 soft_decrypt(soft_session_t *session_p, CK_BYTE_PTR pEncryptedData,
364 CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData,
365 CK_ULONG_PTR pulDataLen)
366 {
367
368 return (soft_decrypt_common(session_p, pEncryptedData,
369 ulEncryptedDataLen, pData, pulDataLen, B_FALSE));
370 }
371
372
373 /*
374 * soft_decrypt_update()
375 *
376 * Arguments:
377 * session_p: pointer to soft_session_t struct
378 * pEncryptedPart: pointer to the encrypted data as input
379 * ulEncryptedPartLen: length of the input data
380 * pPart: pointer to the output data contains plaintext
381 * pulPartLen: pointer to the length of the output data
382 *
383 * Description:
384 * called by C_DecryptUpdate(). This function calls the
385 * soft_decrypt_common routine (with update flag on).
386 *
387 * Returns:
388 * see soft_decrypt_common().
389 */
390 CK_RV
soft_decrypt_update(soft_session_t * session_p,CK_BYTE_PTR pEncryptedPart,CK_ULONG ulEncryptedPartLen,CK_BYTE_PTR pPart,CK_ULONG_PTR pulPartLen)391 soft_decrypt_update(soft_session_t *session_p, CK_BYTE_PTR pEncryptedPart,
392 CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
393 {
394 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
395
396 switch (mechanism) {
397
398 case CKM_DES_ECB:
399 case CKM_DES_CBC:
400 case CKM_DES_CBC_PAD:
401 case CKM_DES3_ECB:
402 case CKM_DES3_CBC:
403 case CKM_DES3_CBC_PAD:
404 case CKM_AES_ECB:
405 case CKM_AES_CBC:
406 case CKM_AES_CBC_PAD:
407 case CKM_AES_CTR:
408 case CKM_AES_CCM:
409 case CKM_AES_GCM:
410 case CKM_AES_GMAC:
411 case CKM_BLOWFISH_CBC:
412 case CKM_RC4:
413
414 return (soft_decrypt_common(session_p, pEncryptedPart,
415 ulEncryptedPartLen, pPart, pulPartLen, B_TRUE));
416
417 default:
418 /* PKCS11: The mechanism only supports single-part operation. */
419 return (CKR_MECHANISM_INVALID);
420 }
421
422 }
423
424
425 /*
426 * soft_decrypt_final()
427 *
428 * Arguments:
429 * session_p: pointer to soft_session_t struct
430 * pLastPart: pointer to the last recovered data part
431 * pulLastPartLen: pointer to the length of the last recovered data part
432 *
433 * Description:
434 * called by C_DecryptFinal().
435 *
436 * Returns:
437 * CKR_OK: success
438 * CKR_FUNCTION_FAILED: decrypt final function failed
439 * CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length
440 */
441 CK_RV
soft_decrypt_final(soft_session_t * session_p,CK_BYTE_PTR pLastPart,CK_ULONG_PTR pulLastPartLen)442 soft_decrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastPart,
443 CK_ULONG_PTR pulLastPartLen)
444 {
445
446 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
447 CK_ULONG out_len;
448 CK_RV rv = CKR_OK;
449 int rc;
450
451 (void) pthread_mutex_lock(&session_p->session_mutex);
452
453 if (session_p->decrypt.context == NULL) {
454 rv = CKR_OPERATION_NOT_INITIALIZED;
455 *pulLastPartLen = 0;
456 goto clean2;
457 }
458 switch (mechanism) {
459
460 case CKM_DES_CBC_PAD:
461 case CKM_DES3_CBC_PAD:
462 {
463
464 soft_des_ctx_t *soft_des_ctx;
465
466 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
467
468 /*
469 * We should have only one block of data left in the
470 * remaining buffer.
471 */
472 if (soft_des_ctx->remain_len != DES_BLOCK_LEN) {
473 *pulLastPartLen = 0;
474 rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
475 /* Cleanup memory space. */
476 free(soft_des_ctx->des_cbc);
477 freezero(soft_des_ctx->key_sched,
478 soft_des_ctx->keysched_len);
479
480 goto clean1;
481 }
482
483 out_len = DES_BLOCK_LEN;
484
485 /*
486 * If application asks for the length of the output buffer
487 * to hold the plaintext?
488 */
489 if (pLastPart == NULL) {
490 *pulLastPartLen = out_len;
491 rv = CKR_OK;
492 goto clean2;
493 } else {
494 crypto_data_t out;
495
496 /* Copy remaining data to the output buffer. */
497 (void) memcpy(pLastPart, soft_des_ctx->data,
498 DES_BLOCK_LEN);
499
500 out.cd_format = CRYPTO_DATA_RAW;
501 out.cd_offset = 0;
502 out.cd_length = DES_BLOCK_LEN;
503 out.cd_raw.iov_base = (char *)pLastPart;
504 out.cd_raw.iov_len = DES_BLOCK_LEN;
505
506 /* Decrypt final block of data. */
507 rc = des_decrypt_contiguous_blocks(
508 (des_ctx_t *)soft_des_ctx->des_cbc,
509 (char *)pLastPart, DES_BLOCK_LEN, &out);
510
511 if (rc == 0) {
512 /*
513 * Remove padding bytes after decryption of
514 * ciphertext block to produce the original
515 * plaintext.
516 */
517 rv = soft_remove_pkcs7_padding(pLastPart,
518 DES_BLOCK_LEN, &out_len);
519 if (rv != CKR_OK)
520 *pulLastPartLen = 0;
521 else
522 *pulLastPartLen = out_len;
523 } else {
524 *pulLastPartLen = 0;
525 rv = CKR_FUNCTION_FAILED;
526 }
527
528 /* Cleanup memory space. */
529 free(soft_des_ctx->des_cbc);
530 freezero(soft_des_ctx->key_sched,
531 soft_des_ctx->keysched_len);
532
533 }
534
535 break;
536 }
537
538 case CKM_DES_CBC:
539 case CKM_DES_ECB:
540 case CKM_DES3_CBC:
541 case CKM_DES3_ECB:
542 {
543
544 soft_des_ctx_t *soft_des_ctx;
545
546 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
547 /*
548 * CKM_DES_CBC and CKM_DES_ECB does not do any padding,
549 * so when the final is called, the remaining buffer
550 * should not contain any more data.
551 */
552 *pulLastPartLen = 0;
553 if (soft_des_ctx->remain_len != 0) {
554 rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
555 } else {
556 if (pLastPart == NULL)
557 goto clean2;
558 }
559
560 /* Cleanup memory space. */
561 free(soft_des_ctx->des_cbc);
562 freezero(soft_des_ctx->key_sched,
563 soft_des_ctx->keysched_len);
564
565 break;
566 }
567
568 case CKM_AES_CBC_PAD:
569 case CKM_AES_CBC:
570 case CKM_AES_ECB:
571 case CKM_AES_CTR:
572 case CKM_AES_CCM:
573 case CKM_AES_GCM:
574 case CKM_AES_GMAC:
575 rv = soft_aes_decrypt_final(session_p, pLastPart,
576 pulLastPartLen);
577 break;
578
579 case CKM_BLOWFISH_CBC:
580 {
581 soft_blowfish_ctx_t *soft_blowfish_ctx;
582
583 soft_blowfish_ctx =
584 (soft_blowfish_ctx_t *)session_p->decrypt.context;
585
586 *pulLastPartLen = 0;
587 if (soft_blowfish_ctx->remain_len != 0)
588 rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
589 else {
590 if (pLastPart == NULL)
591 goto clean2;
592 }
593
594 free(soft_blowfish_ctx->blowfish_cbc);
595 freezero(soft_blowfish_ctx->key_sched,
596 soft_blowfish_ctx->keysched_len);
597
598 break;
599 }
600
601 case CKM_RC4:
602 {
603 ARCFour_key *key = (ARCFour_key *)session_p->decrypt.context;
604 explicit_bzero(key, sizeof (*key));
605 *pulLastPartLen = 0;
606 break;
607 }
608
609 default:
610 /* PKCS11: The mechanism only supports single-part operation. */
611 rv = CKR_MECHANISM_INVALID;
612 break;
613 }
614
615 clean1:
616 free(session_p->decrypt.context);
617 session_p->decrypt.context = NULL;
618
619 clean2:
620 (void) pthread_mutex_unlock(&session_p->session_mutex);
621
622 return (rv);
623
624 }
625