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/softDigestUtil.c
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDigestUtil.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 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + * Copyright (c) 2018, Joyent, Inc.
24 25 */
25 26
26 27 #include <strings.h>
27 28 #include <md5.h>
28 29 #include <pthread.h>
29 30 #include <stdlib.h>
30 31 #include <sys/sha1.h>
31 32 #include <sys/sha2.h>
32 33 #include <sys/types.h>
33 34 #include <security/cryptoki.h>
34 35 #include "softGlobal.h"
35 36 #include "softOps.h"
36 37 #include "softSession.h"
37 38 #include "softObject.h"
38 39
39 40
40 41 /*
41 42 * soft_digest_init()
42 43 *
43 44 * Arguments:
44 45 * session_p: pointer to soft_session_t struct
45 46 * pMechanism: pointer to CK_MECHANISM struct provided by application
46 47 *
47 48 * Description:
48 49 * called by C_DigestInit(). This function allocates space for
49 50 * context, then calls the corresponding software provided digest
50 51 * init routine based on the mechanism.
51 52 *
52 53 * Returns:
53 54 * CKR_OK: success
54 55 * CKR_HOST_MEMORY: run out of system memory
55 56 * CKR_MECHANISM_INVALID: invalid mechanism type
56 57 */
57 58 CK_RV
58 59 soft_digest_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism)
59 60 {
60 61
61 62 switch (pMechanism->mechanism) {
62 63
63 64 case CKM_MD5:
64 65 (void) pthread_mutex_lock(&session_p->session_mutex);
65 66
66 67 session_p->digest.context = malloc(sizeof (MD5_CTX));
67 68
68 69 if (session_p->digest.context == NULL) {
69 70 (void) pthread_mutex_unlock(&session_p->session_mutex);
70 71 return (CKR_HOST_MEMORY);
71 72 }
72 73
73 74 session_p->digest.mech.mechanism = CKM_MD5;
74 75 (void) pthread_mutex_unlock(&session_p->session_mutex);
75 76
76 77 MD5Init((MD5_CTX *)session_p->digest.context);
77 78
78 79 break;
79 80
80 81 case CKM_SHA_1:
81 82
82 83 (void) pthread_mutex_lock(&session_p->session_mutex);
83 84
84 85 session_p->digest.context = malloc(sizeof (SHA1_CTX));
85 86
86 87 if (session_p->digest.context == NULL) {
87 88 (void) pthread_mutex_unlock(&session_p->session_mutex);
88 89 return (CKR_HOST_MEMORY);
89 90 }
90 91
91 92 session_p->digest.mech.mechanism = CKM_SHA_1;
92 93 session_p->digest.mech.pParameter = pMechanism->pParameter;
93 94 session_p->digest.mech.ulParameterLen =
94 95 pMechanism->ulParameterLen;
95 96 (void) pthread_mutex_unlock(&session_p->session_mutex);
96 97
97 98 SHA1Init((SHA1_CTX *)session_p->digest.context);
98 99
99 100 break;
100 101
101 102 case CKM_SHA256:
102 103 case CKM_SHA384:
103 104 case CKM_SHA512:
104 105
105 106 (void) pthread_mutex_lock(&session_p->session_mutex);
106 107
107 108 session_p->digest.context = malloc(sizeof (SHA2_CTX));
108 109
109 110 if (session_p->digest.context == NULL) {
110 111 (void) pthread_mutex_unlock(&session_p->session_mutex);
111 112 return (CKR_HOST_MEMORY);
112 113 }
113 114
114 115 switch (pMechanism->mechanism) {
115 116 case CKM_SHA256:
116 117 session_p->digest.mech.mechanism = CKM_SHA256;
117 118 (void) pthread_mutex_unlock(&session_p->session_mutex);
118 119 SHA2Init(SHA256,
119 120 (SHA2_CTX *)session_p->digest.context);
120 121 break;
121 122
122 123 case CKM_SHA384:
123 124 session_p->digest.mech.mechanism = CKM_SHA384;
124 125 (void) pthread_mutex_unlock(&session_p->session_mutex);
125 126 SHA2Init(SHA384,
126 127 (SHA2_CTX *)session_p->digest.context);
127 128 break;
128 129
129 130 case CKM_SHA512:
130 131 session_p->digest.mech.mechanism = CKM_SHA512;
131 132 (void) pthread_mutex_unlock(&session_p->session_mutex);
132 133 SHA2Init(SHA512,
133 134 (SHA2_CTX *)session_p->digest.context);
134 135 break;
135 136 }
136 137 break;
137 138
138 139 default:
139 140 return (CKR_MECHANISM_INVALID);
140 141 }
141 142
142 143 return (CKR_OK);
143 144 }
144 145
145 146
146 147 /*
147 148 * soft_digest_common()
148 149 *
149 150 * Arguments:
150 151 * session_p: pointer to soft_session_t struct
151 152 * pData: pointer to the input data to be digested
152 153 * ulDataLen: length of the input data
153 154 * pDigest: pointer to the output data after digesting
154 155 * pulDigestLen: length of the output data
155 156 *
156 157 * Description:
157 158 * called by soft_digest() or soft_digest_final(). This function
158 159 * determines the length of output buffer and calls the corresponding
159 160 * software provided digest routine based on the mechanism.
160 161 *
161 162 * Returns:
162 163 * CKR_OK: success
163 164 * CKR_MECHANISM_INVALID: invalid mechanism type
164 165 * CKR_BUFFER_TOO_SMALL: the output buffer provided by application
165 166 * is too small
166 167 */
167 168 CK_RV
168 169 soft_digest_common(soft_session_t *session_p, CK_BYTE_PTR pData,
169 170 CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
170 171 {
171 172
172 173 CK_ULONG digestLen = 0;
173 174 size_t len = 0;
174 175
175 176 /*
176 177 * Determine the output data length based on the mechanism
177 178 */
178 179 switch (session_p->digest.mech.mechanism) {
179 180
180 181 case CKM_MD5:
181 182 digestLen = 16;
182 183 break;
183 184
184 185 case CKM_SHA_1:
185 186 digestLen = 20;
186 187 break;
187 188
188 189 case CKM_SHA256:
189 190 digestLen = 32;
190 191 break;
191 192
192 193 case CKM_SHA384:
193 194 digestLen = 48;
194 195 break;
195 196
196 197 case CKM_SHA512:
197 198 digestLen = 64;
198 199 break;
199 200
200 201 default:
201 202 return (CKR_MECHANISM_INVALID);
202 203 }
203 204
204 205 if (pDigest == NULL) {
205 206 /*
206 207 * Application only wants to know the length of the
207 208 * buffer needed to hold the message digest.
208 209 */
209 210 *pulDigestLen = digestLen;
210 211 return (CKR_OK);
211 212 }
212 213
213 214 if (*pulDigestLen < digestLen) {
214 215 /*
215 216 * Application provides buffer too small to hold the
216 217 * digest message. Return the length of buffer needed
217 218 * to the application.
218 219 */
219 220 *pulDigestLen = digestLen;
220 221 return (CKR_BUFFER_TOO_SMALL);
221 222 }
222 223
223 224 /*
224 225 * Call the corresponding system provided software digest routine.
225 226 * If the soft_digest_common() is called by soft_digest_final()
226 227 * the pData is NULL, and the ulDataLen is zero.
227 228 */
228 229 switch (session_p->digest.mech.mechanism) {
229 230
230 231 case CKM_MD5:
231 232 if (pData != NULL) {
232 233 /*
233 234 * this is called by soft_digest()
234 235 */
235 236 #ifdef __sparcv9
236 237 MD5Update((MD5_CTX *)session_p->digest.context,
237 238 /* LINTED */
238 239 pData, (uint_t)ulDataLen);
239 240 #else /* !__sparcv9 */
240 241 MD5Update((MD5_CTX *)session_p->digest.context,
241 242 pData, ulDataLen);
242 243 #endif /* __sparcv9 */
243 244 MD5Final(pDigest, (MD5_CTX *)session_p->digest.context);
244 245 } else {
245 246 /*
246 247 * this is called by soft_digest_final()
247 248 */
248 249 MD5Final(pDigest, (MD5_CTX *)session_p->digest.context);
249 250 len = sizeof (MD5_CTX);
250 251 }
251 252 break;
252 253
253 254 case CKM_SHA_1:
254 255 if (pData != NULL) {
255 256 /*
256 257 * this is called by soft_digest()
257 258 */
258 259
259 260 #ifdef __sparcv9
260 261 SHA1Update((SHA1_CTX *)session_p->digest.context,
261 262 /* LINTED */
262 263 pData, (uint32_t)ulDataLen);
263 264 #else /* !__sparcv9 */
264 265 SHA1Update((SHA1_CTX *)session_p->digest.context,
265 266 pData, ulDataLen);
266 267 #endif /* __sparcv9 */
267 268 SHA1Final(pDigest,
268 269 (SHA1_CTX *)session_p->digest.context);
269 270 } else {
270 271 /*
271 272 * this is called by soft_digest_final()
272 273 */
273 274 SHA1Final(pDigest,
274 275 (SHA1_CTX *)session_p->digest.context);
275 276 len = sizeof (SHA1_CTX);
276 277 }
277 278 break;
278 279 case CKM_SHA256:
279 280 case CKM_SHA384:
280 281 case CKM_SHA512:
281 282 if (pData != NULL) {
282 283 /*
283 284 * this is called by soft_digest()
284 285 */
285 286
286 287 SHA2Update((SHA2_CTX *)session_p->digest.context,
287 288 pData, ulDataLen);
288 289
289 290 SHA2Final(pDigest,
290 291 (SHA2_CTX *)session_p->digest.context);
291 292 } else {
292 293 /*
293 294 * this is called by soft_digest_final()
294 295 */
↓ open down ↓ |
261 lines elided |
↑ open up ↑ |
295 296 SHA2Final(pDigest,
296 297 (SHA2_CTX *)session_p->digest.context);
297 298 len = sizeof (SHA2_CTX);
298 299 }
299 300
300 301 break;
301 302 }
302 303
303 304 /* Paranoia on behalf of C_DigestKey callers: bzero the context */
304 305 if (session_p->digest.flags & CRYPTO_KEY_DIGESTED) {
305 - bzero(session_p->digest.context, len);
306 + explicit_bzero(session_p->digest.context, len);
306 307 session_p->digest.flags &= ~CRYPTO_KEY_DIGESTED;
307 308 }
308 309 *pulDigestLen = digestLen;
309 310 (void) pthread_mutex_lock(&session_p->session_mutex);
310 311 free(session_p->digest.context);
311 312 session_p->digest.context = NULL;
312 313 (void) pthread_mutex_unlock(&session_p->session_mutex);
313 314
314 315 return (CKR_OK);
315 316 }
316 317
317 318
318 319 /*
319 320 * soft_digest()
320 321 *
321 322 * Arguments:
322 323 * session_p: pointer to soft_session_t struct
323 324 * pData: pointer to the input data to be digested
324 325 * ulDataLen: length of the input data
325 326 * pDigest: pointer to the output data after digesting
326 327 * pulDigestLen: length of the output data
327 328 *
328 329 * Description:
329 330 * called by C_Digest(). This function calls soft_digest_common().
330 331 *
331 332 * Returns:
332 333 * see return values in soft_digest_common().
333 334 */
334 335 CK_RV
335 336 soft_digest(soft_session_t *session_p, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
336 337 CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
337 338 {
338 339
339 340 return (soft_digest_common(session_p, pData, ulDataLen,
340 341 pDigest, pulDigestLen));
341 342 }
342 343
343 344
344 345 /*
345 346 * soft_digest_update()
346 347 *
347 348 * Arguments:
348 349 * session_p: pointer to soft_session_t struct
349 350 * pPart: pointer to the input data to be digested
350 351 * ulPartLen: length of the input data
351 352 *
352 353 * Description:
353 354 * called by C_DigestUpdate(). This function calls the corresponding
354 355 * software provided digest update routine based on the mechanism.
355 356 *
356 357 * Returns:
357 358 * CKR_OK: success
358 359 * CKR_MECHANISM_INVALID: invalid MECHANISM type.
359 360 */
360 361 CK_RV
361 362 soft_digest_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
362 363 CK_ULONG ulPartLen)
363 364 {
364 365
365 366 switch (session_p->digest.mech.mechanism) {
366 367
367 368 case CKM_MD5:
368 369 #ifdef __sparcv9
369 370 MD5Update((MD5_CTX *)session_p->digest.context,
370 371 /* LINTED */
371 372 pPart, (uint_t)ulPartLen);
372 373 #else /* !__sparcv9 */
373 374 MD5Update((MD5_CTX *)session_p->digest.context,
374 375 pPart, ulPartLen);
375 376 #endif /* __sparcv9 */
376 377 break;
377 378
378 379 case CKM_SHA_1:
379 380 #ifdef __sparcv9
380 381 SHA1Update((SHA1_CTX *)session_p->digest.context,
381 382 /* LINTED */
382 383 pPart, (uint32_t)ulPartLen);
383 384 #else /* !__sparcv9 */
384 385 SHA1Update((SHA1_CTX *)session_p->digest.context,
385 386 pPart, ulPartLen);
386 387 #endif /* __sparcv9 */
387 388 break;
388 389
389 390 case CKM_SHA256:
390 391 case CKM_SHA384:
391 392 case CKM_SHA512:
392 393 SHA2Update((SHA2_CTX *)session_p->digest.context,
393 394 pPart, ulPartLen);
394 395 break;
395 396
396 397 default:
397 398 return (CKR_MECHANISM_INVALID);
398 399 }
399 400
400 401 return (CKR_OK);
401 402 }
402 403
403 404
404 405 /*
405 406 * soft_digest_final()
406 407 *
407 408 * Arguments:
408 409 * session_p: pointer to soft_session_t struct
409 410 * pDigest: pointer to the output data after digesting
410 411 * pulDigestLen: length of the output data
411 412 *
412 413 * Description:
413 414 * called by C_DigestFinal(). This function calls soft_digest_common().
414 415 *
415 416 * Returns:
416 417 * see return values in soft_digest_common().
417 418 */
418 419 CK_RV
419 420 soft_digest_final(soft_session_t *session_p, CK_BYTE_PTR pDigest,
420 421 CK_ULONG_PTR pulDigestLen)
421 422 {
422 423
423 424 return (soft_digest_common(session_p, NULL, 0,
424 425 pDigest, pulDigestLen));
425 426 }
426 427
427 428 /*
428 429 * Perform digest init operation internally for the support of
429 430 * CKM_MD5_RSA_PKCS, CKM_SHA1_RSA_PKCS, CKM_SHA1_KEY_DERIVATION
430 431 * and CKM_MD5_KEY_DERIVATION mechanisms.
431 432 *
432 433 * This function is called with the session being held, and without
433 434 * its mutex taken.
434 435 */
435 436 CK_RV
436 437 soft_digest_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR
437 438 pMechanism)
438 439 {
439 440
440 441 CK_RV rv;
441 442
442 443 (void) pthread_mutex_lock(&session_p->session_mutex);
443 444
444 445 /* Check to see if digest operation is already active */
445 446 if (session_p->digest.flags & CRYPTO_OPERATION_ACTIVE) {
446 447 (void) pthread_mutex_unlock(&session_p->session_mutex);
447 448 return (CKR_OPERATION_ACTIVE);
448 449 }
449 450
450 451 session_p->digest.flags = CRYPTO_OPERATION_ACTIVE;
451 452
452 453 (void) pthread_mutex_unlock(&session_p->session_mutex);
453 454
454 455 rv = soft_digest_init(session_p, pMechanism);
455 456
456 457 if (rv != CKR_OK) {
457 458 (void) pthread_mutex_lock(&session_p->session_mutex);
458 459 session_p->digest.flags &= ~CRYPTO_OPERATION_ACTIVE;
459 460 (void) pthread_mutex_unlock(&session_p->session_mutex);
460 461 }
461 462
462 463 return (rv);
463 464 }
464 465
465 466 /*
466 467 * Call soft_digest_update() function with the value of a secret key.
467 468 */
468 469 CK_RV
469 470 soft_digest_key(soft_session_t *session_p, soft_object_t *key_p)
470 471 {
471 472
472 473 CK_RV rv;
473 474
474 475 /* Only secret key is allowed to be digested */
475 476 if (key_p->class != CKO_SECRET_KEY)
476 477 return (CKR_KEY_INDIGESTIBLE);
477 478
478 479 if ((OBJ_SEC_VALUE(key_p) == NULL) ||
479 480 (OBJ_SEC_VALUE_LEN(key_p) == 0))
480 481 return (CKR_KEY_SIZE_RANGE);
481 482
482 483 rv = soft_digest_update(session_p, OBJ_SEC_VALUE(key_p),
483 484 OBJ_SEC_VALUE_LEN(key_p));
484 485
485 486 return (rv);
486 487
487 488 }
488 489
489 490 /*
490 491 * This function releases allocated digest context. The caller
491 492 * may (lock_held == B_TRUE) or may not (lock_held == B_FALSE)
492 493 * hold a session mutex.
493 494 */
494 495 void
495 496 soft_digest_cleanup(soft_session_t *session_p, boolean_t lock_held)
496 497 {
497 498 boolean_t lock_true = B_TRUE;
498 499
499 500 if (!lock_held)
500 501 (void) pthread_mutex_lock(&session_p->session_mutex);
501 502
502 503 if (session_p->digest.context != NULL) {
503 504 free(session_p->digest.context);
504 505 session_p->digest.context = NULL;
505 506 }
506 507
507 508 session_p->digest.flags = 0;
508 509
509 510 if (!lock_held)
510 511 SES_REFRELE(session_p, lock_true);
511 512
512 513 }
↓ open down ↓ |
197 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX