Print this page
9642 PKCS#11 softtoken should use explicit_bzero
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Alex Wilson <alex.wilson@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDESCrypt.c
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDESCrypt.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 + * Copyright (c) 2018, Joyent, Inc.
24 25 */
25 26
26 27 #include <pthread.h>
27 28 #include <stdlib.h>
28 29 #include <string.h>
29 30 #include <strings.h>
30 31 #include <sys/types.h>
31 32 #include <security/cryptoki.h>
32 33 #include <modes/modes.h>
33 34 #include <des_impl.h>
34 35 #include "softSession.h"
35 36 #include "softObject.h"
36 37 #include "softCrypt.h"
37 38 #include "softOps.h"
38 39
39 40 /*
40 41 * Allocate context for the active encryption or decryption operation, and
41 42 * generate DES or DES3 key schedule to speed up the operation.
42 43 */
43 44 CK_RV
44 45 soft_des_crypt_init_common(soft_session_t *session_p,
45 46 CK_MECHANISM_PTR pMechanism, soft_object_t *key_p,
46 47 boolean_t encrypt)
47 48 {
48 49
49 50 size_t size;
50 51 soft_des_ctx_t *soft_des_ctx;
51 52
52 53 soft_des_ctx = calloc(1, sizeof (soft_des_ctx_t));
53 54 if (soft_des_ctx == NULL) {
54 55 return (CKR_HOST_MEMORY);
55 56 }
56 57
57 58 /* Allocate key schedule for DES or DES3 based on key type. */
58 59 if (key_p->key_type == CKK_DES)
59 60 soft_des_ctx->key_sched = des_alloc_keysched(&size, DES, 0);
60 61 else
61 62 soft_des_ctx->key_sched = des_alloc_keysched(&size, DES3, 0);
62 63
63 64 if (soft_des_ctx->key_sched == NULL) {
64 65 free(soft_des_ctx);
65 66 return (CKR_HOST_MEMORY);
66 67 }
67 68
68 69 soft_des_ctx->keysched_len = size;
69 70 soft_des_ctx->key_type = key_p->key_type;
70 71
71 72 (void) pthread_mutex_lock(&session_p->session_mutex);
72 73 if (encrypt) {
73 74 /* Called by C_EncryptInit. */
74 75 session_p->encrypt.context = soft_des_ctx;
75 76 session_p->encrypt.mech.mechanism = pMechanism->mechanism;
76 77 } else {
77 78 /* Called by C_DecryptInit. */
78 79 session_p->decrypt.context = soft_des_ctx;
79 80 session_p->decrypt.mech.mechanism = pMechanism->mechanism;
80 81 }
81 82 (void) pthread_mutex_unlock(&session_p->session_mutex);
82 83
83 84 /*
84 85 * If this is a non-sensitive key and it does NOT have
85 86 * a key schedule yet, then allocate one and expand it.
86 87 * Otherwise, if its a non-sensitive key, and it DOES have
87 88 * a key schedule already attached to it, just copy the
88 89 * pre-expanded schedule to the context and avoid the
89 90 * extra key schedule expansion operation.
90 91 */
91 92 if (!(key_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
92 93 if (OBJ_KEY_SCHED(key_p) == NULL) {
93 94 void *ks;
94 95 (void) pthread_mutex_lock(&key_p->object_mutex);
95 96 if (OBJ_KEY_SCHED(key_p) == NULL) {
96 97 if (key_p->key_type == CKK_DES)
97 98 ks = des_alloc_keysched(&size, DES, 0);
98 99 else
99 100 ks = des_alloc_keysched(&size, DES3, 0);
100 101 if (ks == NULL) {
101 102 (void) pthread_mutex_unlock(
102 103 &key_p->object_mutex);
103 104 free(soft_des_ctx);
104 105 return (CKR_HOST_MEMORY);
105 106 }
106 107 /* Initialize key schedule for DES or DES3. */
107 108 if (key_p->key_type == CKK_DES)
108 109 des_init_keysched(
109 110 OBJ_SEC(key_p)->sk_value, DES, ks);
110 111 else if (key_p->key_type == CKK_DES2)
111 112 /*
112 113 * DES3 encryption/decryption needs to
113 114 * support a DES2 key.
114 115 */
115 116 des_init_keysched(
116 117 OBJ_SEC(key_p)->sk_value, DES2, ks);
117 118 else
118 119 des_init_keysched(
119 120 OBJ_SEC(key_p)->sk_value, DES3, ks);
120 121
121 122 OBJ_KEY_SCHED_LEN(key_p) = size;
122 123 OBJ_KEY_SCHED(key_p) = ks;
123 124 }
124 125 (void) pthread_mutex_unlock(&key_p->object_mutex);
125 126 }
126 127
127 128 /* Copy the pre-expanded key schedule from the key object */
128 129 (void) memcpy(soft_des_ctx->key_sched, OBJ_KEY_SCHED(key_p),
129 130 OBJ_KEY_SCHED_LEN(key_p));
130 131 soft_des_ctx->keysched_len = OBJ_KEY_SCHED_LEN(key_p);
131 132 } else {
132 133 /* for sensitive keys, we cannot cache the key schedule */
133 134 if (key_p->key_type == CKK_DES)
134 135 des_init_keysched(OBJ_SEC(key_p)->sk_value,
135 136 DES, soft_des_ctx->key_sched);
136 137 else if (key_p->key_type == CKK_DES2)
137 138 /*
138 139 * DES3 encryption/decryption needs to
139 140 * support a DES2 key.
140 141 */
141 142 des_init_keysched(OBJ_SEC(key_p)->sk_value,
142 143 DES2, soft_des_ctx->key_sched);
143 144 else
144 145 des_init_keysched(OBJ_SEC(key_p)->sk_value,
145 146 DES3, soft_des_ctx->key_sched);
146 147 }
147 148
148 149 return (CKR_OK);
149 150 }
150 151
151 152
152 153 /*
153 154 * soft_des_encrypt_common()
154 155 *
155 156 * Arguments:
156 157 * session_p: pointer to soft_session_t struct
157 158 * pData: pointer to the input data to be encrypted
158 159 * ulDataLen: length of the input data
159 160 * pEncrypted: pointer to the output data after encryption
160 161 * pulEncryptedLen: pointer to the length of the output data
161 162 * update: boolean flag indicates caller is soft_encrypt
162 163 * or soft_encrypt_update
163 164 *
164 165 * Description:
165 166 * This function calls the corresponding encrypt routine based
166 167 * on the mechanism.
167 168 *
168 169 * Returns:
169 170 * CKR_OK: success
170 171 * CKR_BUFFER_TOO_SMALL: the output buffer provided by application
171 172 * is too small
172 173 * CKR_FUNCTION_FAILED: encrypt function failed
173 174 * CKR_DATA_LEN_RANGE: the input data is not a multiple of blocksize
174 175 */
175 176 CK_RV
176 177 soft_des_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData,
177 178 CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted,
178 179 CK_ULONG_PTR pulEncryptedLen, boolean_t update)
179 180 {
180 181 int rc = 0;
181 182 CK_RV rv = CKR_OK;
182 183 soft_des_ctx_t *soft_des_ctx =
183 184 (soft_des_ctx_t *)session_p->encrypt.context;
184 185 des_ctx_t *des_ctx;
185 186 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
186 187 CK_BYTE *in_buf = NULL;
187 188 CK_BYTE *out_buf = NULL;
188 189 CK_ULONG out_len;
189 190 CK_ULONG total_len;
190 191 CK_ULONG remain;
191 192 boolean_t pad_mechanism = B_FALSE;
192 193
193 194 pad_mechanism = (mechanism == CKM_DES_CBC_PAD ||
194 195 mechanism == CKM_DES3_CBC_PAD);
195 196 /*
196 197 * DES only takes input length that is a multiple of blocksize
197 198 * for C_Encrypt function with the mechanism CKM_DES<n>_ECB or
198 199 * CKM_DES<n>_CBC.
199 200 *
200 201 * DES allows any input length for C_Encrypt function with the
201 202 * mechanism CKM_DES<n>_CBC_PAD and for C_EncryptUpdate function.
202 203 */
203 204 if (!update && !pad_mechanism) {
204 205 if ((ulDataLen % DES_BLOCK_LEN) != 0) {
205 206 rv = CKR_DATA_LEN_RANGE;
206 207 goto cleanup;
207 208 }
208 209 }
209 210
210 211 if (!update) {
211 212 /*
212 213 * Called by C_Encrypt
213 214 */
214 215 if (pad_mechanism) {
215 216 /*
216 217 * For CKM_DES<n>_CBC_PAD, compute output length to
217 218 * count for the padding. If the length of input
218 219 * data is a multiple of blocksize, then make output
219 220 * length to be the sum of the input length and
220 221 * one blocksize. Otherwise, output length will
221 222 * be rounded up to the next multiple of blocksize.
222 223 */
223 224 out_len = DES_BLOCK_LEN *
224 225 (ulDataLen / DES_BLOCK_LEN + 1);
225 226 } else {
226 227 /*
227 228 * For non-padding mode, the output length will
228 229 * be same as the input length.
229 230 */
230 231 out_len = ulDataLen;
231 232 }
232 233
233 234 /*
234 235 * If application asks for the length of the output buffer
235 236 * to hold the ciphertext?
236 237 */
237 238 if (pEncrypted == NULL) {
238 239 *pulEncryptedLen = out_len;
239 240 return (CKR_OK);
240 241 }
241 242
242 243 /* Is the application-supplied buffer large enough? */
243 244 if (*pulEncryptedLen < out_len) {
244 245 *pulEncryptedLen = out_len;
245 246 return (CKR_BUFFER_TOO_SMALL);
246 247 }
247 248
248 249 /* Encrypt pad bytes in a separate operation */
249 250 if (pad_mechanism) {
250 251 out_len -= DES_BLOCK_LEN;
251 252 }
252 253
253 254 in_buf = pData;
254 255 out_buf = pEncrypted;
255 256 } else {
256 257 /*
257 258 * Called by C_EncryptUpdate
258 259 *
259 260 * Add the lengths of last remaining data and current
260 261 * plaintext together to get the total input length.
261 262 */
262 263 total_len = soft_des_ctx->remain_len + ulDataLen;
263 264
264 265 /*
265 266 * If the total input length is less than one blocksize,
266 267 * or if the total input length is just one blocksize and
267 268 * the mechanism is CKM_DES<n>_CBC_PAD, we will need to delay
268 269 * encryption until when more data comes in next
269 270 * C_EncryptUpdate or when C_EncryptFinal is called.
270 271 */
271 272 if ((total_len < DES_BLOCK_LEN) ||
272 273 (pad_mechanism && (total_len == DES_BLOCK_LEN))) {
273 274 if (pData != NULL) {
274 275 /*
275 276 * Save input data and its length in
276 277 * the remaining buffer of DES context.
277 278 */
278 279 (void) memcpy(soft_des_ctx->data +
279 280 soft_des_ctx->remain_len, pData, ulDataLen);
280 281 soft_des_ctx->remain_len += ulDataLen;
281 282 }
282 283
283 284 /* Set encrypted data length to 0. */
284 285 *pulEncryptedLen = 0;
285 286 return (CKR_OK);
286 287 }
287 288
288 289 /* Compute the length of remaing data. */
289 290 remain = total_len % DES_BLOCK_LEN;
290 291
291 292 /*
292 293 * Make sure that the output length is a multiple of
293 294 * blocksize.
294 295 */
295 296 out_len = total_len - remain;
296 297
297 298 /*
298 299 * If application asks for the length of the output buffer
299 300 * to hold the ciphertext?
300 301 */
301 302 if (pEncrypted == NULL) {
302 303 *pulEncryptedLen = out_len;
303 304 return (CKR_OK);
304 305 }
305 306
306 307 /* Is the application-supplied buffer large enough? */
307 308 if (*pulEncryptedLen < out_len) {
308 309 *pulEncryptedLen = out_len;
309 310 return (CKR_BUFFER_TOO_SMALL);
310 311 }
311 312
312 313 if (soft_des_ctx->remain_len != 0) {
313 314 /*
314 315 * Copy last remaining data and current input data
315 316 * to the output buffer.
316 317 */
317 318 (void) memmove(pEncrypted + soft_des_ctx->remain_len,
318 319 pData, out_len - soft_des_ctx->remain_len);
319 320 (void) memcpy(pEncrypted, soft_des_ctx->data,
320 321 soft_des_ctx->remain_len);
321 322 bzero(soft_des_ctx->data, soft_des_ctx->remain_len);
322 323
323 324 in_buf = pEncrypted;
324 325 } else {
325 326 in_buf = pData;
326 327 }
327 328 out_buf = pEncrypted;
328 329 }
329 330
330 331 /*
331 332 * Begin Encryption now.
332 333 */
333 334 switch (mechanism) {
334 335
335 336 case CKM_DES_ECB:
336 337 case CKM_DES3_ECB:
337 338 {
338 339
339 340 ulong_t i;
340 341 uint8_t *tmp_inbuf;
341 342 uint8_t *tmp_outbuf;
342 343
343 344 for (i = 0; i < out_len; i += DES_BLOCK_LEN) {
344 345 tmp_inbuf = &in_buf[i];
345 346 tmp_outbuf = &out_buf[i];
346 347 /* Crunch one block of data for DES. */
347 348 if (soft_des_ctx->key_type == CKK_DES)
348 349 (void) des_crunch_block(
349 350 soft_des_ctx->key_sched,
350 351 tmp_inbuf, tmp_outbuf, B_FALSE);
351 352 else
352 353 (void) des3_crunch_block(
353 354 soft_des_ctx->key_sched,
354 355 tmp_inbuf, tmp_outbuf, B_FALSE);
355 356 }
356 357
357 358 if (update) {
358 359 /*
359 360 * For encrypt update, if there is remaining
360 361 * data, save it and its length in the context.
361 362 */
362 363 if (remain != 0)
363 364 (void) memcpy(soft_des_ctx->data, pData +
364 365 (ulDataLen - remain), remain);
365 366 soft_des_ctx->remain_len = remain;
366 367 }
367 368
368 369 *pulEncryptedLen = out_len;
369 370 break;
370 371 }
371 372
372 373 case CKM_DES_CBC:
373 374 case CKM_DES_CBC_PAD:
374 375 case CKM_DES3_CBC:
375 376 case CKM_DES3_CBC_PAD:
376 377 {
377 378 crypto_data_t out;
378 379
379 380 out.cd_format = CRYPTO_DATA_RAW;
380 381 out.cd_offset = 0;
381 382 out.cd_length = out_len;
382 383 out.cd_raw.iov_base = (char *)out_buf;
383 384 out.cd_raw.iov_len = out_len;
384 385
385 386 /* Encrypt multiple blocks of data. */
386 387 rc = des_encrypt_contiguous_blocks(
387 388 (des_ctx_t *)soft_des_ctx->des_cbc,
388 389 (char *)in_buf, out_len, &out);
389 390
390 391 if (rc != 0)
391 392 goto encrypt_failed;
392 393
393 394 if (update) {
394 395 /*
395 396 * For encrypt update, if there is remaining data,
396 397 * save it and its length in the context.
397 398 */
398 399 if (remain != 0)
399 400 (void) memcpy(soft_des_ctx->data, pData +
400 401 (ulDataLen - remain), remain);
401 402 soft_des_ctx->remain_len = remain;
402 403 } else if (pad_mechanism) {
403 404 /*
404 405 * Save the remainder of the input
405 406 * block in a temporary block because
406 407 * we don't want to overrun the input buffer
407 408 * by tacking on pad bytes.
408 409 */
409 410 CK_BYTE tmpblock[DES_BLOCK_LEN];
410 411 (void) memcpy(tmpblock, in_buf + out_len,
411 412 ulDataLen - out_len);
412 413 soft_add_pkcs7_padding(tmpblock +
413 414 (ulDataLen - out_len),
414 415 DES_BLOCK_LEN, ulDataLen - out_len);
415 416
416 417 out.cd_offset = out_len;
417 418 out.cd_length = DES_BLOCK_LEN;
418 419 out.cd_raw.iov_base = (char *)out_buf;
419 420 out.cd_raw.iov_len = out_len + DES_BLOCK_LEN;
420 421
421 422 /* Encrypt last block containing pad bytes. */
422 423 rc = des_encrypt_contiguous_blocks(
423 424 (des_ctx_t *)soft_des_ctx->des_cbc,
424 425 (char *)tmpblock, DES_BLOCK_LEN, &out);
425 426 out_len += DES_BLOCK_LEN;
426 427 }
427 428
428 429 if (rc == 0) {
429 430 *pulEncryptedLen = out_len;
430 431 break;
431 432 }
432 433 encrypt_failed:
433 434 *pulEncryptedLen = 0;
434 435 rv = CKR_FUNCTION_FAILED;
435 436 goto cleanup;
436 437
437 438 }
438 439 } /* end switch */
439 440
440 441 if (update)
↓ open down ↓ |
407 lines elided |
↑ open up ↑ |
441 442 return (CKR_OK);
442 443
443 444 /*
444 445 * The following code will be executed if the caller is
445 446 * soft_encrypt() or an error occurred. The encryption
446 447 * operation will be terminated so we need to do some cleanup.
447 448 */
448 449 cleanup:
449 450 (void) pthread_mutex_lock(&session_p->session_mutex);
450 451 des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc;
451 - if (des_ctx != NULL) {
452 - bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len);
453 - free(soft_des_ctx->des_cbc);
454 - }
455 -
456 - bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
457 - free(soft_des_ctx->key_sched);
458 - free(session_p->encrypt.context);
452 + free(des_ctx);
453 + freezero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
454 + freezero(session_p->encrypt.context, sizeof (soft_des_ctx_t));
459 455 session_p->encrypt.context = NULL;
460 456 (void) pthread_mutex_unlock(&session_p->session_mutex);
461 457
462 458 return (rv);
463 459 }
464 460
465 461
466 462 /*
467 463 * soft_des_decrypt_common()
468 464 *
469 465 * Arguments:
470 466 * session_p: pointer to soft_session_t struct
471 467 * pEncrypted: pointer to the input data to be decrypted
472 468 * ulEncryptedLen: length of the input data
473 469 * pData: pointer to the output data
474 470 * pulDataLen: pointer to the length of the output data
475 471 * Update: boolean flag indicates caller is soft_decrypt
476 472 * or soft_decrypt_update
477 473 *
478 474 * Description:
479 475 * This function calls the corresponding decrypt routine based
480 476 * on the mechanism.
481 477 *
482 478 * Returns:
483 479 * CKR_OK: success
484 480 * CKR_BUFFER_TOO_SMALL: the output buffer provided by application
485 481 * is too small
486 482 * CKR_ENCRYPTED_DATA_LEN_RANGE: the input data is not a multiple
487 483 * of blocksize
488 484 * CKR_FUNCTION_FAILED: decrypt function failed
489 485 */
490 486 CK_RV
491 487 soft_des_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted,
492 488 CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData,
493 489 CK_ULONG_PTR pulDataLen, boolean_t update)
494 490 {
495 491
496 492 int rc = 0;
497 493 CK_RV rv = CKR_OK;
498 494 soft_des_ctx_t *soft_des_ctx =
499 495 (soft_des_ctx_t *)session_p->decrypt.context;
500 496 des_ctx_t *des_ctx;
501 497 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
502 498 CK_BYTE *in_buf = NULL;
503 499 CK_BYTE *out_buf = NULL;
504 500 CK_ULONG out_len;
505 501 CK_ULONG total_len;
506 502 CK_ULONG remain;
507 503 boolean_t pad_mechanism = B_FALSE;
508 504
509 505 pad_mechanism = (mechanism == CKM_DES_CBC_PAD ||
510 506 mechanism == CKM_DES3_CBC_PAD);
511 507 /*
512 508 * DES only takes input length that is a multiple of 8 bytes
513 509 * for C_Decrypt function with the mechanism CKM_DES<n>_ECB,
514 510 * CKM_DES<n>_CBC or CKM_DES<n>_CBC_PAD.
515 511 *
516 512 * DES allows any input length for C_DecryptUpdate function.
517 513 */
518 514 if (!update) {
519 515 /*
520 516 * Called by C_Decrypt
521 517 */
522 518 if ((ulEncryptedLen % DES_BLOCK_LEN) != 0) {
523 519 rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
524 520 goto cleanup;
525 521 }
526 522
527 523 /*
528 524 * If application asks for the length of the output buffer
529 525 * to hold the plaintext?
530 526 */
531 527 if (pData == NULL) {
532 528 *pulDataLen = ulEncryptedLen;
533 529 return (CKR_OK);
534 530 }
535 531
536 532 /* Is the application-supplied buffer large enough? */
537 533 if (!pad_mechanism) {
538 534 if (*pulDataLen < ulEncryptedLen) {
539 535 *pulDataLen = ulEncryptedLen;
540 536 return (CKR_BUFFER_TOO_SMALL);
541 537 }
542 538
543 539 /* Set output length same as input length. */
544 540 out_len = ulEncryptedLen;
545 541 } else {
546 542 /*
547 543 * For CKM_DES<n>_CBC_PAD, we don't know how
548 544 * many bytes for padding at this time, so
549 545 * we'd assume one block was padded.
550 546 */
551 547 if (*pulDataLen < (ulEncryptedLen - DES_BLOCK_LEN)) {
552 548 *pulDataLen = ulEncryptedLen - DES_BLOCK_LEN;
553 549 return (CKR_BUFFER_TOO_SMALL);
554 550 }
555 551 out_len = ulEncryptedLen - DES_BLOCK_LEN;
556 552 }
557 553 in_buf = pEncrypted;
558 554 out_buf = pData;
559 555 } else {
560 556 /*
561 557 * Called by C_DecryptUpdate
562 558 *
563 559 * Add the lengths of last remaining data and current
564 560 * input data together to get the total input length.
565 561 */
566 562 total_len = soft_des_ctx->remain_len + ulEncryptedLen;
567 563
568 564 /*
569 565 * If the total input length is less than one blocksize,
570 566 * or if the total input length is just one blocksize and
571 567 * the mechanism is CKM_DES<n>_CBC_PAD, we will need to delay
572 568 * decryption until when more data comes in next
573 569 * C_DecryptUpdate or when C_DecryptFinal is called.
574 570 */
575 571 if ((total_len < DES_BLOCK_LEN) ||
576 572 (pad_mechanism && (total_len == DES_BLOCK_LEN))) {
577 573 if (pEncrypted != NULL) {
578 574 /*
579 575 * Save input data and its length in
580 576 * the remaining buffer of DES context.
581 577 */
582 578 (void) memcpy(soft_des_ctx->data +
583 579 soft_des_ctx->remain_len,
584 580 pEncrypted, ulEncryptedLen);
585 581 soft_des_ctx->remain_len += ulEncryptedLen;
586 582 }
587 583
588 584 /* Set output data length to 0. */
589 585 *pulDataLen = 0;
590 586 return (CKR_OK);
591 587 }
592 588
593 589 /* Compute the length of remaing data. */
594 590 remain = total_len % DES_BLOCK_LEN;
595 591
596 592 /*
597 593 * Make sure that the output length is a multiple of
598 594 * blocksize.
599 595 */
600 596 out_len = total_len - remain;
601 597
602 598 if (pad_mechanism) {
603 599 /*
604 600 * If the input data length is a multiple of
605 601 * blocksize, then save the last block of input
606 602 * data in the remaining buffer. C_DecryptFinal
607 603 * will handle this last block of data.
608 604 */
609 605 if (remain == 0) {
610 606 remain = DES_BLOCK_LEN;
611 607 out_len -= DES_BLOCK_LEN;
612 608 }
613 609 }
614 610
615 611 /*
616 612 * If application asks for the length of the output buffer
617 613 * to hold the plaintext?
618 614 */
619 615 if (pData == NULL) {
620 616 *pulDataLen = out_len;
621 617 return (CKR_OK);
622 618 }
623 619
624 620 /*
625 621 * Is the application-supplied buffer large enough?
626 622 */
627 623 if (*pulDataLen < out_len) {
628 624 *pulDataLen = out_len;
629 625 return (CKR_BUFFER_TOO_SMALL);
630 626 }
631 627
632 628 if (soft_des_ctx->remain_len != 0) {
633 629 /*
634 630 * Copy last remaining data and current input data
635 631 * to the output buffer.
636 632 */
637 633 (void) memmove(pData + soft_des_ctx->remain_len,
638 634 pEncrypted, out_len - soft_des_ctx->remain_len);
639 635 (void) memcpy(pData, soft_des_ctx->data,
640 636 soft_des_ctx->remain_len);
641 637 bzero(soft_des_ctx->data, soft_des_ctx->remain_len);
642 638
643 639 in_buf = pData;
644 640 } else {
645 641 in_buf = pEncrypted;
646 642 }
647 643 out_buf = pData;
648 644 }
649 645
650 646 /*
651 647 * Begin Decryption.
652 648 */
653 649 switch (mechanism) {
654 650
655 651 case CKM_DES_ECB:
656 652 case CKM_DES3_ECB:
657 653 {
658 654 uint8_t *tmp_inbuf;
659 655 uint8_t *tmp_outbuf;
660 656 ulong_t i;
661 657
662 658 for (i = 0; i < out_len; i += DES_BLOCK_LEN) {
663 659 tmp_inbuf = &in_buf[i];
664 660 tmp_outbuf = &out_buf[i];
665 661 /* Crunch one block of data for DES. */
666 662 if (soft_des_ctx->key_type == CKK_DES)
667 663 (void) des_crunch_block(
668 664 soft_des_ctx->key_sched,
669 665 tmp_inbuf, tmp_outbuf, B_TRUE);
670 666 else
671 667 (void) des3_crunch_block(
672 668 soft_des_ctx->key_sched,
673 669 tmp_inbuf, tmp_outbuf, B_TRUE);
674 670 }
675 671
676 672 if (update) {
677 673 /*
678 674 * For decrypt update, if there is remaining
679 675 * data, save it and its length in the context.
680 676 */
681 677 if (remain != 0)
682 678 (void) memcpy(soft_des_ctx->data, pEncrypted +
683 679 (ulEncryptedLen - remain), remain);
684 680 soft_des_ctx->remain_len = remain;
685 681 }
686 682
687 683 *pulDataLen = out_len;
688 684 break;
689 685 }
690 686
691 687 case CKM_DES_CBC:
692 688 case CKM_DES_CBC_PAD:
693 689 case CKM_DES3_CBC:
694 690 case CKM_DES3_CBC_PAD:
695 691 {
696 692 crypto_data_t out;
697 693 CK_ULONG rem_len;
698 694 uint8_t last_block[DES_BLOCK_LEN];
699 695
700 696 out.cd_format = CRYPTO_DATA_RAW;
701 697 out.cd_offset = 0;
702 698 out.cd_length = out_len;
703 699 out.cd_raw.iov_base = (char *)out_buf;
704 700 out.cd_raw.iov_len = out_len;
705 701
706 702 /* Decrypt multiple blocks of data. */
707 703 rc = des_decrypt_contiguous_blocks(
708 704 (des_ctx_t *)soft_des_ctx->des_cbc,
709 705 (char *)in_buf, out_len, &out);
710 706
711 707 if (rc != 0)
712 708 goto decrypt_failed;
713 709
714 710 if (pad_mechanism && !update) {
715 711 /* Decrypt last block containing pad bytes. */
716 712 out.cd_offset = 0;
717 713 out.cd_length = DES_BLOCK_LEN;
718 714 out.cd_raw.iov_base = (char *)last_block;
719 715 out.cd_raw.iov_len = DES_BLOCK_LEN;
720 716
721 717 /* Decrypt last block containing pad bytes. */
722 718 rc = des_decrypt_contiguous_blocks(
723 719 (des_ctx_t *)soft_des_ctx->des_cbc,
724 720 (char *)in_buf + out_len, DES_BLOCK_LEN, &out);
725 721
726 722 if (rc != 0)
727 723 goto decrypt_failed;
728 724
729 725 /*
730 726 * Remove padding bytes after decryption of
731 727 * ciphertext block to produce the original
732 728 * plaintext.
733 729 */
734 730 rv = soft_remove_pkcs7_padding(last_block,
735 731 DES_BLOCK_LEN, &rem_len);
736 732 if (rv == CKR_OK) {
737 733 if (rem_len != 0)
738 734 (void) memcpy(out_buf + out_len,
739 735 last_block, rem_len);
740 736 *pulDataLen = out_len + rem_len;
741 737 } else {
742 738 *pulDataLen = 0;
743 739 goto cleanup;
744 740 }
745 741 } else {
746 742 *pulDataLen = out_len;
747 743 }
748 744
749 745 if (update) {
750 746 /*
751 747 * For decrypt update, if there is remaining data,
752 748 * save it and its length in the context.
753 749 */
754 750 if (remain != 0)
755 751 (void) memcpy(soft_des_ctx->data, pEncrypted +
756 752 (ulEncryptedLen - remain), remain);
757 753 soft_des_ctx->remain_len = remain;
758 754 }
759 755
760 756 if (rc == 0)
761 757 break;
762 758 decrypt_failed:
763 759 *pulDataLen = 0;
764 760 rv = CKR_FUNCTION_FAILED;
765 761 goto cleanup;
766 762 }
767 763 } /* end switch */
768 764
769 765 if (update)
↓ open down ↓ |
301 lines elided |
↑ open up ↑ |
770 766 return (CKR_OK);
771 767
772 768 /*
773 769 * The following code will be executed if the caller is
774 770 * soft_decrypt() or an error occurred. The decryption
775 771 * operation will be terminated so we need to do some cleanup.
776 772 */
777 773 cleanup:
778 774 (void) pthread_mutex_lock(&session_p->session_mutex);
779 775 des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc;
780 - if (des_ctx != NULL) {
781 - bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len);
782 - free(soft_des_ctx->des_cbc);
783 - }
784 -
785 - bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
786 - free(soft_des_ctx->key_sched);
787 - free(session_p->decrypt.context);
788 - session_p->decrypt.context = NULL;
776 + free(des_ctx);
777 + freezero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
778 + freezero(session_p->decrypt.context, sizeof (soft_des_ctx_t));
789 779 (void) pthread_mutex_unlock(&session_p->session_mutex);
790 780
791 781 return (rv);
792 782 }
793 783
794 784
795 785 /*
796 786 * Allocate and initialize a context for DES CBC mode of operation.
797 787 */
798 788 void *
799 789 des_cbc_ctx_init(void *key_sched, size_t size, uint8_t *ivec, CK_KEY_TYPE type)
800 790 {
801 791
802 792 cbc_ctx_t *cbc_ctx;
803 793
804 794 if ((cbc_ctx = calloc(1, sizeof (cbc_ctx_t))) == NULL)
805 795 return (NULL);
806 796
807 797 cbc_ctx->cbc_keysched = key_sched;
808 798
809 799 (void) memcpy(&cbc_ctx->cbc_iv[0], ivec, DES_BLOCK_LEN);
810 800
811 801 cbc_ctx->cbc_lastp = (uint8_t *)&cbc_ctx->cbc_iv[0];
812 802 cbc_ctx->cbc_keysched_len = size;
813 803 if (type == CKK_DES)
814 804 cbc_ctx->cbc_flags |= CBC_MODE;
815 805 else
816 806 cbc_ctx->cbc_flags |= CBC_MODE | DES3_STRENGTH;
817 807
818 808 return (cbc_ctx);
819 809
820 810 }
821 811
822 812 /*
823 813 * Allocate and initialize DES contexts for both signing and encrypting,
824 814 * saving both context pointers in the session struct. For general-length DES
825 815 * MAC, check the length in the parameter to see if it is in the right range.
826 816 */
827 817 CK_RV
828 818 soft_des_sign_verify_init_common(soft_session_t *session_p,
829 819 CK_MECHANISM_PTR pMechanism, soft_object_t *key_p, boolean_t sign_op)
830 820 {
831 821 soft_des_ctx_t *soft_des_ctx;
832 822 CK_MECHANISM encrypt_mech;
833 823 CK_RV rv;
834 824
835 825 if ((key_p->class != CKO_SECRET_KEY) || (key_p->key_type != CKK_DES)) {
836 826 return (CKR_KEY_TYPE_INCONSISTENT);
837 827 }
838 828
839 829 /* allocate memory for the sign/verify context */
840 830 soft_des_ctx = malloc(sizeof (soft_des_ctx_t));
841 831 if (soft_des_ctx == NULL) {
842 832 return (CKR_HOST_MEMORY);
843 833 }
844 834
845 835 soft_des_ctx->key_type = key_p->key_type;
846 836
847 837 /* initialization vector is zero for DES MAC */
848 838 bzero(soft_des_ctx->ivec, DES_BLOCK_LEN);
849 839
850 840 switch (pMechanism->mechanism) {
851 841
852 842 case CKM_DES_MAC_GENERAL:
853 843
854 844 if (pMechanism->ulParameterLen !=
855 845 sizeof (CK_MAC_GENERAL_PARAMS)) {
856 846 free(soft_des_ctx);
857 847 return (CKR_MECHANISM_PARAM_INVALID);
858 848 }
859 849
860 850 if (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
861 851 DES_BLOCK_LEN) {
862 852 free(soft_des_ctx);
863 853 return (CKR_MECHANISM_PARAM_INVALID);
864 854 }
865 855
866 856 soft_des_ctx->mac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
867 857 pMechanism->pParameter);
868 858
869 859 /*FALLTHRU*/
870 860 case CKM_DES_MAC:
871 861
872 862 /*
873 863 * For non-general DES MAC, output is always half as
874 864 * large as block size
875 865 */
876 866 if (pMechanism->mechanism == CKM_DES_MAC) {
877 867 soft_des_ctx->mac_len = DES_MAC_LEN;
878 868 }
879 869
880 870 /* allocate a context for DES encryption */
881 871 encrypt_mech.mechanism = CKM_DES_CBC_PAD;
882 872 encrypt_mech.pParameter = (void *)soft_des_ctx->ivec;
883 873 encrypt_mech.ulParameterLen = DES_BLOCK_LEN;
884 874 rv = soft_encrypt_init_internal(session_p, &encrypt_mech,
885 875 key_p);
886 876 if (rv != CKR_OK) {
887 877 free(soft_des_ctx);
888 878 return (rv);
889 879 }
890 880
891 881 (void) pthread_mutex_lock(&session_p->session_mutex);
892 882
893 883 if (sign_op) {
894 884 session_p->sign.context = soft_des_ctx;
895 885 session_p->sign.mech.mechanism = pMechanism->mechanism;
896 886 } else {
897 887 session_p->verify.context = soft_des_ctx;
898 888 session_p->verify.mech.mechanism =
899 889 pMechanism->mechanism;
900 890 }
901 891
902 892 (void) pthread_mutex_unlock(&session_p->session_mutex);
903 893
904 894 break;
905 895 }
906 896 return (CKR_OK);
907 897 }
908 898
909 899 /*
910 900 * Called by soft_sign(), soft_sign_final(), soft_verify() or
911 901 * soft_verify_final().
912 902 */
913 903 CK_RV
914 904 soft_des_sign_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
915 905 CK_ULONG ulDataLen, CK_BYTE_PTR pSigned, CK_ULONG_PTR pulSignedLen,
916 906 boolean_t sign_op, boolean_t Final)
917 907 {
918 908 soft_des_ctx_t *soft_des_ctx_sign_verify;
919 909 soft_des_ctx_t *soft_des_ctx_encrypt;
920 910 CK_RV rv;
921 911 CK_BYTE *pEncrypted = NULL;
922 912 CK_ULONG ulEncryptedLen = 0;
923 913 uint8_t remainder;
924 914 CK_BYTE last_block[DES_BLOCK_LEN];
925 915 des_ctx_t *des_ctx = NULL;
926 916
927 917 if (sign_op) {
928 918 soft_des_ctx_sign_verify =
929 919 (soft_des_ctx_t *)session_p->sign.context;
930 920
931 921 if (soft_des_ctx_sign_verify->mac_len == 0) {
932 922 *pulSignedLen = 0;
933 923 goto clean_exit;
934 924 }
935 925
936 926 /* Application asks for the length of the output buffer. */
937 927 if (pSigned == NULL) {
938 928 *pulSignedLen = soft_des_ctx_sign_verify->mac_len;
939 929 return (CKR_OK);
940 930 }
941 931
942 932 /* Is the application-supplied buffer large enough? */
943 933 if (*pulSignedLen < soft_des_ctx_sign_verify->mac_len) {
944 934 *pulSignedLen = soft_des_ctx_sign_verify->mac_len;
945 935 return (CKR_BUFFER_TOO_SMALL);
946 936 }
947 937 } else {
948 938 soft_des_ctx_sign_verify =
949 939 (soft_des_ctx_t *)session_p->verify.context;
950 940 }
951 941
952 942 if (Final) {
953 943 soft_des_ctx_encrypt =
954 944 (soft_des_ctx_t *)session_p->encrypt.context;
955 945
956 946 /*
957 947 * If there is data left in the buffer from a previous
958 948 * SignUpdate() call, pass enough zeroed data to a
959 949 * soft_sign_update call to pad the remainder
960 950 */
961 951 if (soft_des_ctx_encrypt->remain_len != 0) {
962 952 bzero(last_block, DES_BLOCK_LEN);
963 953 ulEncryptedLen = DES_BLOCK_LEN;
964 954
965 955 /*
966 956 * By passing a buffer to soft_encrypt_final,
967 957 * we force it to pad the remaining block
968 958 * and encrypt it.
969 959 */
970 960 rv = soft_encrypt_final(session_p, last_block,
971 961 &ulEncryptedLen);
972 962 if (rv != CKR_OK) {
973 963 goto clean_exit;
974 964 }
975 965 } else {
976 966 /*
977 967 * The last block of enciphered data is stored in:
978 968 * soft_des_ctx_encrypt->des_cbc->des_ctx->dc_lastp
979 969 * Copy that data to last_block
980 970 */
981 971 soft_des_ctx_encrypt =
982 972 (soft_des_ctx_t *)session_p->encrypt.context;
983 973 des_ctx = (des_ctx_t *)soft_des_ctx_encrypt->des_cbc;
984 974 (void) memcpy(last_block, des_ctx->dc_lastp,
985 975 DES_BLOCK_LEN);
986 976
987 977 /*
988 978 * Passing a NULL output buffer here
989 979 * forces the routine to just return.
990 980 */
991 981 rv = soft_encrypt_final(session_p, NULL,
992 982 &ulEncryptedLen);
993 983 }
994 984
995 985 } else {
996 986 /*
997 987 * If the input length is not multiple of block size, then
998 988 * determine the correct encrypted data length by rounding
999 989 */
1000 990 remainder = ulDataLen % DES_BLOCK_LEN;
1001 991 /*
1002 992 * Because we always use DES_CBC_PAD mechanism
1003 993 * for sign/verify operations, the input will
1004 994 * be padded to the next 8 byte boundary.
1005 995 * Adjust the length fields here accordingly.
1006 996 */
1007 997 ulEncryptedLen = ulDataLen + (DES_BLOCK_LEN - remainder);
1008 998
1009 999 pEncrypted = malloc(sizeof (CK_BYTE) * ulEncryptedLen);
1010 1000 if (pEncrypted == NULL) {
1011 1001 rv = CKR_HOST_MEMORY;
1012 1002 goto clean_exit;
1013 1003 }
1014 1004
1015 1005 /*
1016 1006 * Pad the last block with zeros by copying pData into a zeroed
1017 1007 * pEncrypted. Then pass pEncrypted into soft_encrypt as input
1018 1008 */
1019 1009 bzero(pEncrypted, ulEncryptedLen);
1020 1010 (void) memcpy(pEncrypted, pData, ulDataLen);
1021 1011
1022 1012 rv = soft_encrypt(session_p, pEncrypted, ulDataLen,
1023 1013 pEncrypted, &ulEncryptedLen);
1024 1014 (void) memcpy(last_block,
1025 1015 &pEncrypted[ulEncryptedLen - DES_BLOCK_LEN], DES_BLOCK_LEN);
1026 1016 }
1027 1017
1028 1018 if (rv == CKR_OK) {
1029 1019 *pulSignedLen = soft_des_ctx_sign_verify->mac_len;
1030 1020
1031 1021 /* the leftmost mac_len bytes of last_block is our MAC */
1032 1022 (void) memcpy(pSigned, last_block, *pulSignedLen);
1033 1023 }
1034 1024
1035 1025 clean_exit:
1036 1026
1037 1027 (void) pthread_mutex_lock(&session_p->session_mutex);
1038 1028
1039 1029 /* soft_encrypt_common() has freed the encrypt context */
1040 1030 if (sign_op) {
1041 1031 free(session_p->sign.context);
1042 1032 session_p->sign.context = NULL;
1043 1033 } else {
1044 1034 free(session_p->verify.context);
1045 1035 session_p->verify.context = NULL;
1046 1036 }
1047 1037 session_p->encrypt.flags = 0;
1048 1038
1049 1039 (void) pthread_mutex_unlock(&session_p->session_mutex);
1050 1040
1051 1041 if (pEncrypted) {
1052 1042 free(pEncrypted);
1053 1043 }
1054 1044
1055 1045 return (rv);
1056 1046 }
1057 1047
1058 1048 /*
1059 1049 * Called by soft_sign_update()
1060 1050 */
1061 1051 CK_RV
1062 1052 soft_des_mac_sign_verify_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
1063 1053 CK_ULONG ulPartLen)
1064 1054 {
1065 1055 /*
1066 1056 * The DES MAC is calculated by taking the specified number of
1067 1057 * left-most bytes within the last block of
1068 1058 * encrypted data, while the context of the multi-part
1069 1059 * encryption stores the block necessary for XORing with the
1070 1060 * input as per cipher block chaining . Therefore, none of the
1071 1061 * intermediary encrypted blocks of data are necessary for
1072 1062 * the DES MAC, and we can create a placeholder local buffer
1073 1063 * for the encrypted data, which is immediately throw away.
1074 1064 */
1075 1065
1076 1066 soft_des_ctx_t *soft_des_ctx_encrypt;
1077 1067 CK_BYTE *pEncrypted = NULL;
1078 1068 CK_ULONG ulEncryptedLen;
1079 1069 CK_ULONG total_len;
1080 1070 uint8_t remainder;
1081 1071 CK_RV rv;
1082 1072
1083 1073 soft_des_ctx_encrypt = (soft_des_ctx_t *)session_p->encrypt.context;
1084 1074
1085 1075 /* Avoid the malloc if we won't be encrypting any data */
1086 1076 total_len = soft_des_ctx_encrypt->remain_len + ulPartLen;
1087 1077
1088 1078 if (total_len < DES_BLOCK_LEN) {
1089 1079 rv = soft_encrypt_update(session_p, pPart, ulPartLen, NULL,
1090 1080 &ulEncryptedLen);
1091 1081 } else {
1092 1082 remainder = ulPartLen % DES_BLOCK_LEN;
1093 1083
1094 1084 /* round up to the nearest multiple of block size */
1095 1085 ulEncryptedLen = ulPartLen + (DES_BLOCK_LEN - remainder);
1096 1086 pEncrypted = malloc(sizeof (CK_BYTE) * ulEncryptedLen);
1097 1087
1098 1088 if (pEncrypted != NULL) {
1099 1089 rv = soft_encrypt_update(session_p, pPart, ulPartLen,
1100 1090 pEncrypted, &ulEncryptedLen);
1101 1091 free(pEncrypted);
1102 1092 } else {
1103 1093 rv = CKR_HOST_MEMORY;
1104 1094 }
1105 1095 }
1106 1096 return (rv);
1107 1097 }
↓ open down ↓ |
309 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX