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