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/softSSL.c
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.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 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + * Copyright 2018, Joyent, Inc.
24 25 */
25 26
26 27 #include <fcntl.h>
27 28 #include <strings.h>
28 29 #include <sys/stat.h>
29 30 #include <sys/types.h>
30 31 #include <sys/sha1.h>
31 32 #include <sys/md5.h>
32 33 #include <sys/sysmacros.h>
33 34 #include <security/cryptoki.h>
34 35 #include "softGlobal.h"
35 36 #include "softKeys.h"
36 37 #include "softKeystore.h"
37 38 #include "softMAC.h"
38 39 #include "softObject.h"
39 40 #include "softSession.h"
40 41 #include "softSSL.h"
41 42
42 43 /*
43 44 * This files contains the implementation of the following PKCS#11
44 45 * mechanisms needed by SSL:
45 46 * CKM_SSL3_MASTER_KEY_DERIVE
46 47 * CKM_SSL3_MASTER_KEY_DERIVE_DH
47 48 * CKM_SSL3_KEY_AND_DERIVE
48 49 * CKM_TLS_MASTER_KEY_DERIVE
49 50 * CKM_TLS_MASTER_KEY_DERIVE_DH
50 51 * CKM_TLS_KEY_AND_DERIVE
51 52 *
52 53 * SSL refers to common functions between SSL v3.0 and SSL v3.1 (a.k.a TLS.)
53 54 */
54 55
55 56 #define MAX_KEYBLOCK 160 /* should be plenty for all known cipherspecs */
56 57
57 58 #define MAX_DEFAULT_ATTRS 10 /* Enough for major applicarions */
58 59
59 60 static char *ssl3_const_vals[] = {
60 61 "A",
61 62 "BB",
62 63 "CCC",
63 64 "DDDD",
64 65 "EEEEE",
65 66 "FFFFFF",
66 67 "GGGGGGG",
67 68 "HHHHHHHH",
68 69 "IIIIIIIII",
69 70 "JJJJJJJJJJ",
70 71 };
71 72 static uint_t ssl3_const_lens[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
72 73
73 74 static uchar_t TLS_MASTER_SECRET_LABEL[] = {"master secret"};
74 75 #define TLS_MASTER_SECRET_LABEL_LEN 13
75 76
76 77 static uchar_t TLS_KEY_EXPANSION_LABEL[] = {"key expansion"};
77 78 #define TLS_KEY_EXPANSION_LABEL_LEN 13
78 79
79 80 static uchar_t TLS_CLIENT_KEY_LABEL[] = {"client write key"};
80 81 #define TLS_CLIENT_KEY_LABEL_LEN 16
81 82
82 83 static uchar_t TLS_SERVER_KEY_LABEL[] = {"server write key"};
83 84 #define TLS_SERVER_KEY_LABEL_LEN 16
84 85
85 86 static uchar_t TLS_IV_BLOCK_LABEL[] = {"IV block"};
86 87 #define TLS_IV_BLOCK_LABEL_LEN 8
87 88
88 89 static void P_MD5(uchar_t *, uint_t, uchar_t *, uint_t, uchar_t *, uint_t,
89 90 uchar_t *, uint_t, uchar_t *, uint_t, boolean_t);
90 91 static void P_SHA1(uchar_t *, uint_t, uchar_t *, uint_t, uchar_t *, uint_t,
91 92 uchar_t *, uint_t, uchar_t *, uint_t, boolean_t);
92 93
93 94 static CK_RV soft_add_derived_key(CK_ATTRIBUTE_PTR, CK_ULONG,
94 95 CK_OBJECT_HANDLE_PTR, soft_session_t *, soft_object_t *);
95 96 static void soft_delete_derived_key(soft_session_t *, soft_object_t *);
96 97 static void soft_ssl_weaken_key(CK_MECHANISM_PTR, uchar_t *, uint_t,
97 98 uchar_t *, uint_t, uchar_t *, uint_t, uchar_t *, boolean_t);
98 99
99 100 /*
100 101 * soft_ssl3_churn()
101 102 * Called for derivation of the master secret from the pre-master secret,
102 103 * and for the derivation of the key_block in an SSL3 handshake
103 104 * result is assumed to be larger than rounds * MD5_HASH_SIZE.
104 105 */
105 106 static void
106 107 soft_ssl3_churn(uchar_t *secret, uint_t secretlen, uchar_t *rand1,
107 108 uint_t rand1len, uchar_t *rand2, uint_t rand2len, int rounds,
108 109 uchar_t *result)
109 110 {
110 111 SHA1_CTX sha1_ctx;
111 112 MD5_CTX md5_ctx;
112 113 uchar_t sha1_digest[SHA1_HASH_SIZE];
113 114 int i;
114 115 uchar_t *ms = result;
115 116 for (i = 0; i < rounds; i++) {
116 117 SHA1Init(&sha1_ctx);
117 118 SHA1Update(&sha1_ctx, (const uint8_t *)ssl3_const_vals[i],
118 119 ssl3_const_lens[i]);
119 120 SHA1Update(&sha1_ctx, secret, secretlen);
120 121 SHA1Update(&sha1_ctx, rand1, rand1len);
121 122 SHA1Update(&sha1_ctx, rand2, rand2len);
122 123 SHA1Final(sha1_digest, &sha1_ctx);
123 124
124 125 MD5Init(&md5_ctx);
125 126 MD5Update(&md5_ctx, secret, secretlen);
126 127 MD5Update(&md5_ctx, sha1_digest, SHA1_HASH_SIZE);
127 128 MD5Final(ms, &md5_ctx);
128 129 ms += MD5_HASH_SIZE;
129 130 }
130 131 }
131 132
132 133 /*
133 134 * This TLS generic Pseudo Random Function expands a triplet
134 135 * {secret, label, seed} into any arbitrary length string of pseudo
135 136 * random bytes.
136 137 * Here, it is called for the derivation of the master secret from the
137 138 * pre-master secret, and for the derivation of the key_block in a TLS
138 139 * handshake
139 140 */
140 141 static void
141 142 soft_tls_prf(uchar_t *secret, uint_t secretlen, uchar_t *label, uint_t labellen,
142 143 uchar_t *rand1, uint_t rand1len, uchar_t *rand2, uint_t rand2len,
143 144 uchar_t *result, uint_t resultlen)
144 145 {
145 146 uchar_t *S1, *S2;
146 147 uchar_t md5_digested_key[MD5_HASH_SIZE];
147 148 uchar_t sha1_digested_key[SHA1_HASH_SIZE];
148 149 uint_t L_S, L_S1, L_S2;
149 150
150 151 /* secret is NULL for IV's in exportable ciphersuites */
151 152 if (secret == NULL) {
152 153 L_S = 0;
153 154 L_S2 = L_S1 = 0;
154 155 S1 = NULL;
155 156 S2 = NULL;
156 157 goto do_P_HASH;
157 158 }
158 159
159 160 L_S = roundup(secretlen, 2) / 2;
160 161 L_S1 = L_S;
161 162 L_S2 = L_S;
162 163 S1 = secret;
163 164 S2 = secret + (secretlen / 2); /* Possible overlap of S1 and S2. */
164 165
165 166 /* Reduce the half secrets if bigger than the HASH's block size */
166 167 if (L_S > MD5_HMAC_BLOCK_SIZE) {
167 168 MD5_CTX md5_ctx;
168 169 SHA1_CTX sha1_ctx;
169 170
170 171 MD5Init(&md5_ctx);
171 172 MD5Update(&md5_ctx, S1, L_S);
172 173 MD5Final(md5_digested_key, &md5_ctx);
173 174 S1 = md5_digested_key;
174 175 L_S1 = MD5_HASH_SIZE;
175 176
176 177 SHA1Init(&sha1_ctx);
177 178 SHA1Update(&sha1_ctx, S2, L_S);
178 179 SHA1Final(sha1_digested_key, &sha1_ctx);
179 180 S2 = sha1_digested_key;
180 181 L_S2 = SHA1_HASH_SIZE;
181 182 }
182 183
183 184 /*
184 185 * PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
185 186 * P_SHA-1(S2, label + seed);
186 187 * the 'seed' here is rand1 + rand2
187 188 */
188 189 do_P_HASH:
189 190 /* The first one writes directly to the result */
190 191 P_MD5(S1, L_S1, label, labellen, rand1, rand1len, rand2, rand2len,
191 192 result, resultlen, B_FALSE);
192 193
193 194 /* The second one XOR's with the result. */
194 195 P_SHA1(S2, L_S2, label, labellen, rand1, rand1len, rand2, rand2len,
195 196 result, resultlen, B_TRUE);
196 197 }
197 198
198 199 /*
199 200 * These two expansion routines are very similar. (they can merge one day).
200 201 * They implement the P_HASH() function for MD5 and for SHA1, as defined in
201 202 * RFC2246:
202 203 *
203 204 * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
204 205 * HMAC_hash(secret, A(2) + seed) +
205 206 * HMAC_hash(secret, A(3) + seed) + ...
206 207 * Where + indicates concatenation.
207 208 * A() is defined as:
208 209 * A(0) = seed
209 210 * A(i) = HMAC_hash(secret, A(i-1))
210 211 *
211 212 * The seed is the concatenation of 'babel', 'rand1', and 'rand2'.
212 213 */
213 214 static void
214 215 P_MD5(uchar_t *secret, uint_t secretlen, uchar_t *label, uint_t labellen,
215 216 uchar_t *rand1, uint_t rand1len, uchar_t *rand2, uint_t rand2len,
216 217 uchar_t *result, uint_t resultlen, boolean_t xor_it)
217 218 {
218 219 uint32_t md5_ipad[MD5_HMAC_INTS_PER_BLOCK];
219 220 uint32_t md5_opad[MD5_HMAC_INTS_PER_BLOCK];
220 221 uchar_t md5_hmac[MD5_HASH_SIZE];
221 222 uchar_t A[MD5_HASH_SIZE];
222 223 md5_hc_ctx_t md5_hmac_ctx;
223 224 uchar_t *res, *cur;
224 225 uint_t left = resultlen;
225 226 int i;
226 227
227 228 /* good compilers will leverage the aligment */
228 229 bzero(md5_ipad, MD5_HMAC_BLOCK_SIZE);
229 230 bzero(md5_opad, MD5_HMAC_BLOCK_SIZE);
230 231
231 232 if (secretlen > 0) {
232 233 bcopy(secret, md5_ipad, secretlen);
233 234 bcopy(secret, md5_opad, secretlen);
234 235 }
235 236
236 237 /* A(1) = HMAC_MD5(secret, rand1 + rand2) */
237 238 md5_hmac_ctx_init(&md5_hmac_ctx, md5_ipad, md5_opad);
238 239 SOFT_MAC_UPDATE(MD5, &md5_hmac_ctx, label, labellen);
239 240 SOFT_MAC_UPDATE(MD5, &md5_hmac_ctx, rand1, rand1len);
240 241 SOFT_MAC_UPDATE(MD5, &md5_hmac_ctx, rand2, rand2len);
241 242 SOFT_MAC_FINAL(MD5, &md5_hmac_ctx, A);
242 243
243 244 if (xor_it) {
244 245 res = md5_hmac;
245 246 cur = result;
246 247 } else {
247 248 res = result;
248 249 }
249 250
250 251 while (left > 0) {
251 252 /*
252 253 * Compute HMAC_MD5(secret, A(i) + seed);
253 254 * The secret is already expanded in the ictx and octx, so
254 255 * we can call the SOFT_MAC_INIT_CTX() directly.
255 256 */
256 257 SOFT_MAC_INIT_CTX(MD5, &md5_hmac_ctx, md5_ipad, md5_opad,
257 258 MD5_HMAC_BLOCK_SIZE);
258 259 SOFT_MAC_UPDATE(MD5, &md5_hmac_ctx, A, MD5_HASH_SIZE);
259 260 SOFT_MAC_UPDATE(MD5, &md5_hmac_ctx, label, labellen);
260 261 SOFT_MAC_UPDATE(MD5, &md5_hmac_ctx, rand1, rand1len);
261 262 SOFT_MAC_UPDATE(MD5, &md5_hmac_ctx, rand2, rand2len);
262 263
263 264 if (left > MD5_HASH_SIZE) {
264 265 SOFT_MAC_FINAL(MD5, &md5_hmac_ctx, res);
265 266 if (xor_it) {
266 267 for (i = 0; i < MD5_HASH_SIZE; i++) {
267 268 *cur ^= res[i];
268 269 cur++;
269 270 }
270 271 } else {
271 272 res += MD5_HASH_SIZE;
272 273 }
273 274 left -= MD5_HASH_SIZE;
274 275 } else {
275 276 SOFT_MAC_FINAL(MD5, &md5_hmac_ctx, md5_hmac);
276 277 if (xor_it) {
277 278 for (i = 0; i < left; i++) {
278 279 *cur ^= md5_hmac[i];
279 280 cur++;
280 281 }
281 282 } else {
282 283 bcopy(md5_hmac, res, left);
283 284 }
284 285 break;
285 286 }
286 287 /* A(i) = HMAC_MD5(secret, A(i-1) */
287 288 SOFT_MAC_INIT_CTX(MD5, &md5_hmac_ctx, md5_ipad, md5_opad,
288 289 MD5_HMAC_BLOCK_SIZE);
289 290 SOFT_MAC_UPDATE(MD5, &md5_hmac_ctx, A, MD5_HASH_SIZE);
290 291 SOFT_MAC_FINAL(MD5, &md5_hmac_ctx, A);
291 292 }
292 293 }
293 294 static void
294 295 P_SHA1(uchar_t *secret, uint_t secretlen, uchar_t *label, uint_t labellen,
295 296 uchar_t *rand1, uint_t rand1len, uchar_t *rand2, uint_t rand2len,
296 297 uchar_t *result, uint_t resultlen, boolean_t xor_it)
297 298 {
298 299 uint32_t sha1_ipad[SHA1_HMAC_INTS_PER_BLOCK];
299 300 uint32_t sha1_opad[SHA1_HMAC_INTS_PER_BLOCK];
300 301 uchar_t sha1_hmac[SHA1_HASH_SIZE];
301 302 uchar_t A[SHA1_HASH_SIZE];
302 303 sha1_hc_ctx_t sha1_hmac_ctx;
303 304 uchar_t *res, *cur;
304 305 uint_t left = resultlen;
305 306 int i;
306 307
307 308 /* good compilers will leverage the aligment */
308 309 bzero(sha1_ipad, SHA1_HMAC_BLOCK_SIZE);
309 310 bzero(sha1_opad, SHA1_HMAC_BLOCK_SIZE);
310 311
311 312 if (secretlen > 0) {
312 313 bcopy(secret, sha1_ipad, secretlen);
313 314 bcopy(secret, sha1_opad, secretlen);
314 315 }
315 316
316 317 /* A(1) = HMAC_SHA1(secret, rand1 + rand2) */
317 318 sha1_hmac_ctx_init(&sha1_hmac_ctx, sha1_ipad, sha1_opad);
318 319 SOFT_MAC_UPDATE(SHA1, &sha1_hmac_ctx, label, labellen);
319 320 SOFT_MAC_UPDATE(SHA1, &sha1_hmac_ctx, rand1, rand1len);
320 321 SOFT_MAC_UPDATE(SHA1, &sha1_hmac_ctx, rand2, rand2len);
321 322 SOFT_MAC_FINAL(SHA1, &sha1_hmac_ctx, A);
322 323
323 324 if (xor_it) {
324 325 res = sha1_hmac;
325 326 cur = result;
326 327 } else {
327 328 res = result;
328 329 }
329 330
330 331 while (left > 0) {
331 332 /*
332 333 * Compute HMAC_SHA1(secret, A(i) + seed);
333 334 * The secret is already expanded in the ictx and octx, so
334 335 * we can call the SOFT_MAC_INIT_CTX() directly.
335 336 */
336 337 SOFT_MAC_INIT_CTX(SHA1, &sha1_hmac_ctx,
337 338 (const uchar_t *)sha1_ipad, (const uchar_t *)sha1_opad,
338 339 SHA1_HMAC_BLOCK_SIZE);
339 340 SOFT_MAC_UPDATE(SHA1, &sha1_hmac_ctx, A, SHA1_HASH_SIZE);
340 341 SOFT_MAC_UPDATE(SHA1, &sha1_hmac_ctx, label, labellen);
341 342 SOFT_MAC_UPDATE(SHA1, &sha1_hmac_ctx, rand1, rand1len);
342 343 SOFT_MAC_UPDATE(SHA1, &sha1_hmac_ctx, rand2, rand2len);
343 344
344 345 if (left > SHA1_HASH_SIZE) {
345 346 SOFT_MAC_FINAL(SHA1, &sha1_hmac_ctx, res);
346 347 if (xor_it) {
347 348 for (i = 0; i < SHA1_HASH_SIZE; i++) {
348 349 *cur ^= res[i];
349 350 cur++;
350 351 }
351 352 } else {
352 353 res += SHA1_HASH_SIZE;
353 354 }
354 355 left -= SHA1_HASH_SIZE;
355 356 } else {
356 357 SOFT_MAC_FINAL(SHA1, &sha1_hmac_ctx, sha1_hmac);
357 358 if (xor_it) {
358 359 for (i = 0; i < left; i++) {
359 360 *cur ^= sha1_hmac[i];
360 361 cur++;
361 362 }
362 363 } else {
363 364 bcopy(sha1_hmac, res, left);
364 365 }
365 366 break;
366 367 }
367 368 /* A(i) = HMAC_SHA1(secret, A(i-1) */
368 369 SOFT_MAC_INIT_CTX(SHA1, &sha1_hmac_ctx,
369 370 (const uchar_t *)sha1_ipad, (const uchar_t *)sha1_opad,
370 371 SHA1_HMAC_BLOCK_SIZE);
371 372 SOFT_MAC_UPDATE(SHA1, &sha1_hmac_ctx, A, SHA1_HASH_SIZE);
372 373 SOFT_MAC_FINAL(SHA1, &sha1_hmac_ctx, A);
373 374 }
374 375 }
375 376
376 377 /* This function handles the call from C_DeriveKey for CKM_TLS_PRF */
377 378 CK_RV
378 379 derive_tls_prf(CK_TLS_PRF_PARAMS_PTR param, soft_object_t *basekey_p)
379 380 {
380 381
381 382 if (param->pOutput == NULL || param->pulOutputLen == 0)
382 383 return (CKR_BUFFER_TOO_SMALL);
383 384
384 385 (void) soft_tls_prf(OBJ_SEC_VALUE(basekey_p),
385 386 OBJ_SEC_VALUE_LEN(basekey_p), param->pLabel, param->ulLabelLen,
386 387 param->pSeed, param->ulSeedLen, NULL, 0, param->pOutput,
387 388 *param->pulOutputLen);
388 389
389 390 return (CKR_OK);
390 391 }
391 392
392 393
393 394 /*
394 395 * soft_ssl_master_key_derive()
395 396 *
396 397 * Arguments:
397 398 * . session_p
398 399 * . mech_p: key derivation mechanism. the mechanism parameter carries the
399 400 * client and master random from the Hello handshake messages.
400 401 * . basekey_p: The pre-master secret key.
401 402 * . pTemplate & ulAttributeCount: Any extra attributes for the key to be
402 403 * created.
403 404 * . phKey: store for handle to the derived key.
404 405 *
405 406 * Description:
406 407 * Derive the SSL master secret from the pre-master secret, the client
407 408 * and server random.
408 409 * In SSL 3.0, master_secret =
409 410 * MD5(pre_master_secret + SHA('A' + pre_master_secret +
410 411 * ClientHello.random + ServerHello.random)) +
411 412 * MD5(pre_master_secret + SHA('BB' + pre_master_secret +
412 413 * ClientHello.random + ServerHello.random)) +
413 414 * MD5(pre_master_secret + SHA('CCC' + pre_master_secret +
414 415 * ClientHello.random + ServerHello.random));
415 416 *
416 417 * In TLS 1.0 (a.k.a. SSL 3.1), master_secret =
417 418 * PRF(pre_master_secret, "master secret",
418 419 * ClientHello.random + ServerHello.random)
419 420 */
420 421 CK_RV
421 422 soft_ssl_master_key_derive(soft_session_t *sp, CK_MECHANISM_PTR mech,
422 423 soft_object_t *basekey_p, CK_ATTRIBUTE_PTR pTemplate,
423 424 CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
424 425 {
425 426 uchar_t *pmsecret = OBJ_SEC_VALUE(basekey_p);
426 427 #ifdef __sparcv9
427 428 /* LINTED */
428 429 uint_t pmlen = (uint_t)OBJ_SEC_VALUE_LEN(basekey_p);
429 430 #else /* __sparcv9 */
430 431 uint_t pmlen = OBJ_SEC_VALUE_LEN(basekey_p);
431 432 #endif /* __sparcv9 */
432 433 CK_SSL3_MASTER_KEY_DERIVE_PARAMS *mkd_params;
433 434 CK_SSL3_RANDOM_DATA *random_data;
434 435 CK_VERSION_PTR pVersion;
435 436 uchar_t ssl_master_secret[48];
436 437 CK_OBJECT_CLASS class = CKO_SECRET_KEY;
437 438 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
438 439 CK_BBOOL true = TRUE;
439 440 CK_ATTRIBUTE obj_tmpl[MAX_DEFAULT_ATTRS];
440 441 CK_ATTRIBUTE_PTR new_tmpl;
441 442 CK_ULONG newattrcount;
442 443 boolean_t new_tmpl_allocated = B_FALSE, is_tls = B_FALSE;
443 444 ulong_t i;
444 445 CK_RV rv = CKR_OK;
445 446 uint_t ClientRandomLen, ServerRandomLen;
446 447
447 448 /* Check the validity of the mechanism's parameter */
448 449
449 450 mkd_params = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)mech->pParameter;
450 451
451 452 if (mkd_params == NULL ||
452 453 mech->ulParameterLen != sizeof (CK_SSL3_MASTER_KEY_DERIVE_PARAMS))
453 454 return (CKR_MECHANISM_PARAM_INVALID);
454 455
455 456 pVersion = mkd_params->pVersion;
456 457
457 458 switch (mech->mechanism) {
458 459 case CKM_TLS_MASTER_KEY_DERIVE:
459 460 is_tls = B_TRUE;
460 461 /* FALLTHRU */
461 462 case CKM_SSL3_MASTER_KEY_DERIVE:
462 463 /* Invalid pre-master key length. What else to return? */
463 464 if (pmlen != 48)
464 465 return (CKR_ARGUMENTS_BAD);
465 466
466 467 /* Get the SSL version number from the premaster secret */
467 468 if (pVersion == NULL_PTR)
468 469 return (CKR_MECHANISM_PARAM_INVALID);
469 470
470 471 bcopy(pmsecret, pVersion, sizeof (CK_VERSION));
471 472
472 473 break;
473 474 case CKM_TLS_MASTER_KEY_DERIVE_DH:
474 475 is_tls = B_TRUE;
475 476 /* FALLTHRU */
476 477 case CKM_SSL3_MASTER_KEY_DERIVE_DH:
477 478 if (pVersion != NULL_PTR)
478 479 return (CKR_MECHANISM_PARAM_INVALID);
479 480 }
480 481
481 482 random_data = &mkd_params->RandomInfo;
482 483 #ifdef __sparcv9
483 484 /* LINTED */
484 485 ClientRandomLen = (uint_t)random_data->ulClientRandomLen;
485 486 /* LINTED */
486 487 ServerRandomLen = (uint_t)random_data->ulServerRandomLen;
487 488 #else /* __sparcv9 */
488 489 ClientRandomLen = random_data->ulClientRandomLen;
489 490 ServerRandomLen = random_data->ulServerRandomLen;
490 491 #endif /* __sparcv9 */
491 492
492 493 if (random_data->pClientRandom == NULL_PTR || ClientRandomLen == 0 ||
493 494 random_data->pServerRandom == NULL_PTR || ServerRandomLen == 0) {
494 495 return (CKR_MECHANISM_PARAM_INVALID);
495 496 }
496 497
497 498 /* Now the actual secret derivation */
498 499 if (!is_tls) {
499 500 soft_ssl3_churn(pmsecret, pmlen, random_data->pClientRandom,
500 501 ClientRandomLen, random_data->pServerRandom,
501 502 ServerRandomLen, 3, ssl_master_secret);
502 503 } else {
503 504 soft_tls_prf(pmsecret, pmlen, TLS_MASTER_SECRET_LABEL,
504 505 TLS_MASTER_SECRET_LABEL_LEN, random_data->pClientRandom,
505 506 ClientRandomLen, random_data->pServerRandom,
506 507 ServerRandomLen, ssl_master_secret, 48);
507 508 }
508 509
509 510 /*
510 511 * The object creation attributes need to be in one contiguous
511 512 * array. In addition to the attrs from the application supplied
512 513 * pTemplates, We need to add the class, type, value, valuelen and
513 514 * CKA_DERIVE.
514 515 * In the most likely case, the application passes between zero and
515 516 * handful of attributes, We optimize for that case by allocating
516 517 * the new template on the stack. Oherwise we malloc() it.
517 518 */
518 519
519 520 newattrcount = ulAttributeCount + 4;
520 521 if (newattrcount > MAX_DEFAULT_ATTRS) {
521 522 new_tmpl = malloc(sizeof (CK_ATTRIBUTE) * newattrcount);
522 523
523 524 if (new_tmpl == NULL)
524 525 return (CKR_HOST_MEMORY);
525 526
526 527 new_tmpl_allocated = B_TRUE;
527 528 } else
528 529 new_tmpl = obj_tmpl;
529 530
530 531 /*
531 532 * Fill in the new template.
532 533 * We put the attributes contributed by the mechanism first
533 534 * so that they override the application supplied ones.
534 535 */
535 536 new_tmpl[0].type = CKA_CLASS;
536 537 new_tmpl[0].pValue = &class;
537 538 new_tmpl[0].ulValueLen = sizeof (class);
538 539 new_tmpl[1].type = CKA_KEY_TYPE;
539 540 new_tmpl[1].pValue = &keyType;
540 541 new_tmpl[1].ulValueLen = sizeof (keyType);
541 542 new_tmpl[2].type = CKA_DERIVE;
542 543 new_tmpl[2].pValue = &true;
543 544 new_tmpl[2].ulValueLen = sizeof (true);
544 545 new_tmpl[3].type = CKA_VALUE;
545 546 new_tmpl[3].pValue = ssl_master_secret;
546 547 new_tmpl[3].ulValueLen = 48;
547 548
548 549 /* Any attributes left? */
549 550 if (ulAttributeCount > 0) {
550 551
551 552 /* Validate the default class and type attributes */
552 553 for (i = 0; i < ulAttributeCount; i++) {
553 554 /* The caller is responsible for proper alignment */
554 555 if ((pTemplate[i].type == CKA_CLASS) &&
555 556 (*((CK_OBJECT_CLASS *)pTemplate[i].pValue) !=
556 557 CKO_SECRET_KEY)) {
557 558 rv = CKR_TEMPLATE_INCONSISTENT;
558 559 goto out;
559 560 }
560 561 if ((pTemplate[i].type == CKA_KEY_TYPE) &&
561 562 (*((CK_KEY_TYPE *)pTemplate[i].pValue) !=
562 563 CKK_GENERIC_SECRET)) {
563 564 rv = CKR_TEMPLATE_INCONSISTENT;
564 565 goto out;
565 566 }
566 567 }
567 568 bcopy(pTemplate, &new_tmpl[4],
568 569 ulAttributeCount * sizeof (CK_ATTRIBUTE));
569 570 }
570 571
571 572 rv = soft_add_derived_key(new_tmpl, newattrcount, phKey, sp, basekey_p);
572 573 out:
573 574 if (new_tmpl_allocated)
574 575 free(new_tmpl);
575 576
576 577 return (rv);
577 578 }
578 579
579 580 /*
580 581 * soft_ssl3_key_and_mac_derive()
581 582 *
582 583 * Arguments:
583 584 * . session_p
584 585 * . mech_p: key derivation mechanism. the mechanism parameter carries the
585 586 * client and mastter random from the Hello handshake messages,
586 587 * the specification of the key and IV sizes, and the location
587 588 * for the resulting keys and IVs.
588 589 * . basekey_p: The master secret key.
589 590 * . pTemplate & ulAttributeCount: Any extra attributes for the key to be
590 591 * created.
591 592 *
592 593 * Description:
593 594 * Derive the SSL key material (Client and server MAC secrets, symmetric
594 595 * keys and IVs), from the master secret and the client
595 596 * and server random.
596 597 * First a keyblock is generated usining the following formula:
597 598 * key_block =
598 599 * MD5(master_secret + SHA(`A' + master_secret +
599 600 * ServerHello.random +
600 601 * ClientHello.random)) +
601 602 * MD5(master_secret + SHA(`BB' + master_secret +
602 603 * ServerHello.random +
603 604 * ClientHello.random)) +
604 605 * MD5(master_secret + SHA(`CCC' + master_secret +
605 606 * ServerHello.random +
606 607 * ClientHello.random)) + [...];
607 608 *
608 609 * In TLS 1.0 (a.k.a. SSL 3.1), key_block =
609 610 * PRF(master_secret, "key expansion",
610 611 * ServerHello.random + ClientHello.random)
611 612 *
612 613 * Then the keys materials are taken from the keyblock.
613 614 */
614 615
615 616 CK_RV
616 617 soft_ssl_key_and_mac_derive(soft_session_t *sp, CK_MECHANISM_PTR mech,
617 618 soft_object_t *basekey_p, CK_ATTRIBUTE_PTR pTemplate,
618 619 CK_ULONG ulAttributeCount)
619 620 {
620 621 uchar_t *msecret = OBJ_SEC_VALUE(basekey_p);
621 622 #ifdef __sparcv9
622 623 /* LINTED */
623 624 uint_t mslen = (uint_t)OBJ_SEC_VALUE_LEN(basekey_p);
624 625 #else /* __sparcv9 */
625 626 uint_t mslen = OBJ_SEC_VALUE_LEN(basekey_p);
626 627 #endif /* __sparcv9 */
627 628 CK_SSL3_KEY_MAT_PARAMS *km_params;
628 629 CK_SSL3_RANDOM_DATA *random_data;
629 630 CK_SSL3_KEY_MAT_OUT *kmo;
630 631 uchar_t key_block[MAX_KEYBLOCK], *kb, *export_keys = NULL;
631 632 CK_OBJECT_CLASS class = CKO_SECRET_KEY;
632 633 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
633 634 CK_BBOOL true = TRUE;
634 635 CK_ATTRIBUTE obj_tmpl[MAX_DEFAULT_ATTRS];
635 636 CK_ATTRIBUTE_PTR new_tmpl;
636 637 ulong_t newattrcount, mac_key_bytes, secret_key_bytes, iv_bytes;
637 638 ulong_t extra_attr_count;
638 639 uint_t size;
639 640 int rounds, n = 0;
640 641 boolean_t new_tmpl_allocated = B_FALSE, isExport;
641 642 CK_RV rv = CKR_OK;
642 643 uint_t ClientRandomLen, ServerRandomLen;
643 644
644 645 /* Check the validity of the mechanism's parameter */
645 646
646 647 km_params = (CK_SSL3_KEY_MAT_PARAMS *)mech->pParameter;
647 648
648 649 if (km_params == NULL ||
649 650 mech->ulParameterLen != sizeof (CK_SSL3_KEY_MAT_PARAMS) ||
650 651 (kmo = km_params->pReturnedKeyMaterial) == NULL)
651 652 return (CKR_MECHANISM_PARAM_INVALID);
652 653
653 654 isExport = (km_params->bIsExport == TRUE);
654 655
655 656 random_data = &km_params->RandomInfo;
656 657 #ifdef __sparcv9
657 658 /* LINTED */
658 659 ClientRandomLen = (uint_t)random_data->ulClientRandomLen;
659 660 /* LINTED */
660 661 ServerRandomLen = (uint_t)random_data->ulServerRandomLen;
661 662 #else /* __sparcv9 */
662 663 ClientRandomLen = random_data->ulClientRandomLen;
663 664 ServerRandomLen = random_data->ulServerRandomLen;
664 665 #endif /* __sparcv9 */
665 666
666 667 if (random_data->pClientRandom == NULL_PTR || ClientRandomLen == 0 ||
667 668 random_data->pServerRandom == NULL_PTR || ServerRandomLen == 0) {
668 669 return (CKR_MECHANISM_PARAM_INVALID);
669 670 }
670 671
671 672 mac_key_bytes = km_params->ulMacSizeInBits / 8;
672 673 secret_key_bytes = km_params->ulKeySizeInBits / 8;
673 674 iv_bytes = km_params->ulIVSizeInBits / 8;
674 675
675 676 if ((iv_bytes > 0) &&
676 677 ((kmo->pIVClient == NULL) || (kmo->pIVServer == NULL)))
677 678 return (CKR_MECHANISM_PARAM_INVALID);
678 679
679 680 /*
680 681 * For exportable ciphersuites, the IV's aren't taken from the
681 682 * key block. They are directly derived from the client and
682 683 * server random data.
683 684 * For SSL3.0:
684 685 * client_write_IV = MD5(ClientHello.random + ServerHello.random);
685 686 * server_write_IV = MD5(ServerHello.random + ClientHello.random);
686 687 * For TLS1.0:
687 688 * iv_block = PRF("", "IV block", client_random +
688 689 * server_random)[0..15]
689 690 * client_write_IV = iv_block[0..7]
690 691 * server_write_IV = iv_block[8..15]
691 692 */
692 693 if ((isExport) && (iv_bytes > 0)) {
693 694
694 695 if (mech->mechanism == CKM_SSL3_KEY_AND_MAC_DERIVE) {
695 696 MD5_CTX exp_md5_ctx;
696 697
697 698 if (iv_bytes > MD5_HASH_SIZE)
698 699 return (CKR_MECHANISM_PARAM_INVALID);
699 700
700 701 MD5Init(&exp_md5_ctx);
701 702 MD5Update(&exp_md5_ctx, random_data->pClientRandom,
702 703 ClientRandomLen);
703 704 MD5Update(&exp_md5_ctx, random_data->pServerRandom,
704 705 ServerRandomLen);
705 706
706 707 /* there's room in key_block. use it */
707 708 MD5Final(key_block, &exp_md5_ctx);
708 709 bcopy(key_block, kmo->pIVClient, iv_bytes);
709 710
710 711 MD5Init(&exp_md5_ctx);
711 712 MD5Update(&exp_md5_ctx, random_data->pServerRandom,
712 713 ServerRandomLen);
713 714 MD5Update(&exp_md5_ctx, random_data->pClientRandom,
714 715 ClientRandomLen);
715 716 MD5Final(key_block, &exp_md5_ctx);
716 717 bcopy(key_block, kmo->pIVServer, iv_bytes);
717 718 } else {
718 719 uchar_t iv_block[16];
719 720
720 721 if (iv_bytes != 8)
721 722 return (CKR_MECHANISM_PARAM_INVALID);
722 723
723 724 soft_tls_prf(NULL, 0, TLS_IV_BLOCK_LABEL,
724 725 TLS_IV_BLOCK_LABEL_LEN,
725 726 random_data->pClientRandom, ClientRandomLen,
726 727 random_data->pServerRandom, ServerRandomLen,
727 728 iv_block, 16);
728 729 bcopy(iv_block, kmo->pIVClient, 8);
729 730 bcopy(iv_block + 8, kmo->pIVServer, 8);
730 731 }
731 732 /* so we won't allocate a key_block bigger than needed */
732 733 iv_bytes = 0;
733 734 }
734 735
735 736 /* Now the actual secret derivation */
736 737
737 738 #ifdef __sparcv9
738 739 /* LINTED */
739 740 size = (uint_t)((mac_key_bytes + secret_key_bytes + iv_bytes) * 2);
740 741 #else /* __sparcv9 */
741 742 size = (mac_key_bytes + secret_key_bytes + iv_bytes) * 2;
742 743 #endif /* __sparcv9 */
743 744
744 745 /* Need to handle this better */
745 746 if (size > MAX_KEYBLOCK)
746 747 return (CKR_MECHANISM_PARAM_INVALID);
747 748
748 749 rounds = howmany(size, MD5_HASH_SIZE);
749 750
750 751 kb = key_block;
751 752
752 753 if (mech->mechanism == CKM_SSL3_KEY_AND_MAC_DERIVE) {
753 754 soft_ssl3_churn(msecret, mslen, random_data->pServerRandom,
754 755 ServerRandomLen, random_data->pClientRandom,
755 756 ClientRandomLen, rounds, kb);
756 757 } else {
757 758 soft_tls_prf(msecret, mslen, TLS_KEY_EXPANSION_LABEL,
758 759 TLS_KEY_EXPANSION_LABEL_LEN,
759 760 random_data->pServerRandom, ServerRandomLen,
760 761 random_data->pClientRandom, ClientRandomLen,
761 762 kb, size);
762 763 }
763 764
764 765 /* Now create the objects */
765 766
766 767 kmo->hClientMacSecret = CK_INVALID_HANDLE;
767 768 kmo->hServerMacSecret = CK_INVALID_HANDLE;
768 769 kmo->hClientKey = CK_INVALID_HANDLE;
769 770 kmo->hServerKey = CK_INVALID_HANDLE;
770 771
771 772 /* First the MAC secrets */
772 773 if (mac_key_bytes > 0) {
773 774 obj_tmpl[0].type = CKA_CLASS;
774 775 obj_tmpl[0].pValue = &class; /* CKO_SECRET_KEY */
775 776 obj_tmpl[0].ulValueLen = sizeof (class);
776 777 obj_tmpl[1].type = CKA_KEY_TYPE;
777 778 obj_tmpl[1].pValue = &keyType; /* CKK_GENERIC_SECRET */
778 779 obj_tmpl[1].ulValueLen = sizeof (keyType);
779 780 obj_tmpl[2].type = CKA_DERIVE;
780 781 obj_tmpl[2].pValue = &true;
781 782 obj_tmpl[2].ulValueLen = sizeof (true);
782 783 obj_tmpl[3].type = CKA_SIGN;
783 784 obj_tmpl[3].pValue = &true;
784 785 obj_tmpl[3].ulValueLen = sizeof (true);
785 786 obj_tmpl[4].type = CKA_VERIFY;
786 787 obj_tmpl[4].pValue = &true;
787 788 obj_tmpl[4].ulValueLen = sizeof (true);
788 789 obj_tmpl[5].type = CKA_VALUE;
789 790 obj_tmpl[5].pValue = kb;
790 791 obj_tmpl[5].ulValueLen = mac_key_bytes;
791 792
792 793 rv = soft_add_derived_key(obj_tmpl, 6,
793 794 &(kmo->hClientMacSecret), sp, basekey_p);
794 795
795 796 if (rv != CKR_OK)
796 797 goto out_err;
797 798
798 799 kb += mac_key_bytes;
799 800
800 801 obj_tmpl[5].pValue = kb;
801 802 rv = soft_add_derived_key(obj_tmpl, 6,
802 803 &(kmo->hServerMacSecret), sp, basekey_p);
803 804
804 805 if (rv != CKR_OK)
805 806 goto out_err;
806 807
807 808 kb += mac_key_bytes;
808 809 }
809 810
810 811 /* Then the symmetric ciphers keys */
811 812
812 813 extra_attr_count = (secret_key_bytes == 0) ? 6 : 5;
813 814 newattrcount = ulAttributeCount + extra_attr_count;
814 815 if (newattrcount > MAX_DEFAULT_ATTRS) {
815 816 new_tmpl = malloc(sizeof (CK_ATTRIBUTE) * newattrcount);
816 817
817 818 if (new_tmpl == NULL)
818 819 return (CKR_HOST_MEMORY);
819 820
820 821 new_tmpl_allocated = B_TRUE;
821 822 } else
822 823 new_tmpl = obj_tmpl;
823 824
824 825 new_tmpl[n].type = CKA_CLASS;
825 826 new_tmpl[n].pValue = &class; /* CKO_SECRET_KEY */
826 827 new_tmpl[n].ulValueLen = sizeof (class);
827 828 ++n;
828 829 /*
829 830 * The keyType comes from the application's template, and depends
830 831 * on the ciphersuite. The only exception is authentication only
831 832 * ciphersuites which do not use cipher keys.
832 833 */
833 834 if (secret_key_bytes == 0) {
834 835 new_tmpl[n].type = CKA_KEY_TYPE;
835 836 new_tmpl[n].pValue = &keyType; /* CKK_GENERIC_SECRET */
836 837 new_tmpl[n].ulValueLen = sizeof (keyType);
837 838 n++;
838 839 }
839 840 new_tmpl[n].type = CKA_DERIVE;
840 841 new_tmpl[n].pValue = &true;
841 842 new_tmpl[n].ulValueLen = sizeof (true);
842 843 n++;
843 844 new_tmpl[n].type = CKA_ENCRYPT;
844 845 new_tmpl[n].pValue = &true;
845 846 new_tmpl[n].ulValueLen = sizeof (true);
846 847 n++;
847 848 new_tmpl[n].type = CKA_DECRYPT;
848 849 new_tmpl[n].pValue = &true;
849 850 new_tmpl[n].ulValueLen = sizeof (true);
850 851 n++;
851 852 new_tmpl[n].type = CKA_VALUE;
852 853 new_tmpl[n].pValue = NULL;
853 854 new_tmpl[n].ulValueLen = 0;
854 855
855 856 if (secret_key_bytes > 0) {
856 857 if (isExport) {
857 858 if (secret_key_bytes > MD5_HASH_SIZE) {
858 859 rv = CKR_MECHANISM_PARAM_INVALID;
859 860 goto out_err;
860 861 }
861 862 if ((export_keys = malloc(2 * MD5_HASH_SIZE)) == NULL) {
862 863 rv = CKR_HOST_MEMORY;
863 864 goto out_err;
864 865 }
865 866 #ifdef __sparcv9
866 867 /* LINTED */
867 868 soft_ssl_weaken_key(mech, kb, (uint_t)secret_key_bytes,
868 869 #else /* __sparcv9 */
869 870 soft_ssl_weaken_key(mech, kb, secret_key_bytes,
870 871 #endif /* __sparcv9 */
871 872 random_data->pClientRandom, ClientRandomLen,
872 873 random_data->pServerRandom, ServerRandomLen,
873 874 export_keys, B_TRUE);
874 875 new_tmpl[n].pValue = export_keys;
875 876 new_tmpl[n].ulValueLen = MD5_HASH_SIZE;
876 877 } else {
877 878 new_tmpl[n].pValue = kb;
878 879 new_tmpl[n].ulValueLen = secret_key_bytes;
879 880 }
880 881 }
881 882
882 883 if (ulAttributeCount > 0)
883 884 bcopy(pTemplate, &new_tmpl[extra_attr_count],
884 885 ulAttributeCount * sizeof (CK_ATTRIBUTE));
885 886
886 887 rv = soft_add_derived_key(new_tmpl, newattrcount,
887 888 &(kmo->hClientKey), sp, basekey_p);
888 889
889 890 if (rv != CKR_OK)
890 891 goto out_err;
891 892
892 893 kb += secret_key_bytes;
893 894
894 895 if (secret_key_bytes > 0) {
895 896 if (isExport) {
896 897 #ifdef __sparcv9
897 898 /* LINTED */
898 899 soft_ssl_weaken_key(mech, kb, (uint_t)secret_key_bytes,
899 900 #else /* __sparcv9 */
900 901 soft_ssl_weaken_key(mech, kb, secret_key_bytes,
901 902 #endif /* __sparcv9 */
902 903 random_data->pServerRandom, ServerRandomLen,
903 904 random_data->pClientRandom, ClientRandomLen,
904 905 export_keys + MD5_HASH_SIZE, B_FALSE);
905 906 new_tmpl[n].pValue = export_keys + MD5_HASH_SIZE;
906 907 } else
907 908 new_tmpl[n].pValue = kb;
908 909 }
909 910
910 911 rv = soft_add_derived_key(new_tmpl, newattrcount,
911 912 &(kmo->hServerKey), sp, basekey_p);
912 913
913 914 if (rv != CKR_OK)
914 915 goto out_err;
915 916
916 917 kb += secret_key_bytes;
917 918
↓ open down ↓ |
884 lines elided |
↑ open up ↑ |
918 919 /* Finally, the IVs */
919 920 if (iv_bytes > 0) {
920 921 bcopy(kb, kmo->pIVClient, iv_bytes);
921 922 kb += iv_bytes;
922 923 bcopy(kb, kmo->pIVServer, iv_bytes);
923 924 }
924 925
925 926 if (new_tmpl_allocated)
926 927 free(new_tmpl);
927 928
928 - if (export_keys != NULL)
929 - free(export_keys);
929 + freezero(export_keys, 2 * MD5_HASH_SIZE);
930 930
931 931 return (rv);
932 932
933 933 out_err:
934 934 if (kmo->hClientMacSecret != CK_INVALID_HANDLE) {
935 935 (void) soft_delete_derived_key(sp,
936 936 (soft_object_t *)(kmo->hClientMacSecret));
937 937 kmo->hClientMacSecret = CK_INVALID_HANDLE;
938 938 }
939 939 if (kmo->hServerMacSecret != CK_INVALID_HANDLE) {
940 940 (void) soft_delete_derived_key(sp,
941 941 (soft_object_t *)(kmo->hServerMacSecret));
942 942 kmo->hServerMacSecret = CK_INVALID_HANDLE;
943 943 }
944 944 if (kmo->hClientKey != CK_INVALID_HANDLE) {
945 945 (void) soft_delete_derived_key(sp,
946 946 (soft_object_t *)(kmo->hClientKey));
947 947 kmo->hClientKey = CK_INVALID_HANDLE;
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
948 948 }
949 949 if (kmo->hServerKey != CK_INVALID_HANDLE) {
950 950 (void) soft_delete_derived_key(sp,
951 951 (soft_object_t *)(kmo->hServerKey));
952 952 kmo->hServerKey = CK_INVALID_HANDLE;
953 953 }
954 954
955 955 if (new_tmpl_allocated)
956 956 free(new_tmpl);
957 957
958 - if (export_keys != NULL)
959 - free(export_keys);
958 + freezero(export_keys, 2 * MD5_HASH_SIZE);
960 959
961 960 return (rv);
962 961 }
963 962
964 963 /*
965 964 * Add the derived key to the session, and, if it's a token object,
966 965 * write it to the token.
967 966 */
968 967 static CK_RV
969 968 soft_add_derived_key(CK_ATTRIBUTE_PTR tmpl, CK_ULONG attrcount,
970 969 CK_OBJECT_HANDLE_PTR phKey, soft_session_t *sp, soft_object_t *basekey_p)
971 970 {
972 971 CK_RV rv;
973 972 soft_object_t *secret_key;
974 973
975 974 if ((secret_key = calloc(1, sizeof (soft_object_t))) == NULL) {
976 975 return (CKR_HOST_MEMORY);
977 976 }
978 977
979 978 if (((rv = soft_build_secret_key_object(tmpl, attrcount, secret_key,
980 979 SOFT_CREATE_OBJ_INT, 0, (CK_KEY_TYPE)~0UL)) != CKR_OK) ||
981 980 ((rv = soft_pin_expired_check(secret_key)) != CKR_OK) ||
982 981 ((rv = soft_object_write_access_check(sp, secret_key)) != CKR_OK)) {
983 982
984 983 free(secret_key);
985 984 return (rv);
986 985 }
987 986
988 987 /* Set the sensitivity and extractability attributes as a needed */
989 988 soft_derive_enforce_flags(basekey_p, secret_key);
990 989
991 990 /* Initialize the rest of stuffs in soft_object_t. */
992 991 (void) pthread_mutex_init(&secret_key->object_mutex, NULL);
993 992 secret_key->magic_marker = SOFTTOKEN_OBJECT_MAGIC;
994 993
995 994 /* ... and, if it needs to persist, write on the token */
996 995 if (IS_TOKEN_OBJECT(secret_key)) {
997 996 secret_key->session_handle = (CK_SESSION_HANDLE)NULL;
998 997 soft_add_token_object_to_slot(secret_key);
999 998 rv = soft_put_object_to_keystore(secret_key);
1000 999 if (rv != CKR_OK) {
1001 1000 soft_delete_token_object(secret_key, B_FALSE, B_FALSE);
1002 1001 return (rv);
1003 1002 }
1004 1003 *phKey = (CK_OBJECT_HANDLE)secret_key;
1005 1004
1006 1005 return (CKR_OK);
1007 1006 }
1008 1007
1009 1008 /* Add the new object to the session's object list. */
1010 1009 soft_add_object_to_session(secret_key, sp);
1011 1010 secret_key->session_handle = (CK_SESSION_HANDLE)sp;
1012 1011
1013 1012 *phKey = (CK_OBJECT_HANDLE)secret_key;
1014 1013
1015 1014 return (rv);
1016 1015 }
1017 1016
1018 1017 /*
1019 1018 * Delete the derived key from the session, and, if it's a token object,
1020 1019 * remove it from the token.
1021 1020 */
1022 1021 static void
1023 1022 soft_delete_derived_key(soft_session_t *sp, soft_object_t *key)
1024 1023 {
1025 1024 /* session_handle is the creating session. It's NULL for token objs */
1026 1025
1027 1026 if (IS_TOKEN_OBJECT(key))
1028 1027 soft_delete_token_object(key, B_FALSE, B_FALSE);
1029 1028 else
1030 1029 soft_delete_object(sp, key, B_FALSE, B_FALSE);
1031 1030 }
1032 1031
1033 1032 /*
1034 1033 * soft_ssl_weaken_key()
1035 1034 * Reduce the key length to an exportable size.
1036 1035 * For SSL3.0:
1037 1036 * final_client_write_key = MD5(client_write_key +
1038 1037 * ClientHello.random +
1039 1038 * ServerHello.random);
1040 1039 * final_server_write_key = MD5(server_write_key +
1041 1040 * ServerHello.random +
1042 1041 * ClientHello.random);
1043 1042 * For TLS1.0:
1044 1043 * final_client_write_key = PRF(SecurityParameters.client_write_key,
1045 1044 * "client write key",
1046 1045 * SecurityParameters.client_random +
1047 1046 * SecurityParameters.server_random)[0..15];
1048 1047 * final_server_write_key = PRF(SecurityParameters.server_write_key,
1049 1048 * "server write key",
1050 1049 * SecurityParameters.client_random +
1051 1050 * SecurityParameters.server_random)[0..15];
1052 1051 */
1053 1052 static void
1054 1053 soft_ssl_weaken_key(CK_MECHANISM_PTR mech, uchar_t *secret, uint_t secretlen,
1055 1054 uchar_t *rand1, uint_t rand1len, uchar_t *rand2, uint_t rand2len,
1056 1055 uchar_t *result, boolean_t isclient)
1057 1056 {
1058 1057 MD5_CTX exp_md5_ctx;
1059 1058 uchar_t *label;
1060 1059 uint_t labellen;
1061 1060
1062 1061 if (mech->mechanism == CKM_SSL3_KEY_AND_MAC_DERIVE) {
1063 1062 MD5Init(&exp_md5_ctx);
1064 1063 MD5Update(&exp_md5_ctx, secret, secretlen);
1065 1064 MD5Update(&exp_md5_ctx, rand1, rand1len);
1066 1065 MD5Update(&exp_md5_ctx, rand2, rand2len);
1067 1066 MD5Final(result, &exp_md5_ctx);
1068 1067 } else {
1069 1068 if (isclient) {
1070 1069 label = TLS_CLIENT_KEY_LABEL;
1071 1070 labellen = TLS_CLIENT_KEY_LABEL_LEN;
1072 1071 soft_tls_prf(secret, secretlen, label, labellen,
1073 1072 rand1, rand1len, rand2, rand2len, result, 16);
1074 1073 } else {
1075 1074 label = TLS_SERVER_KEY_LABEL;
1076 1075 labellen = TLS_SERVER_KEY_LABEL_LEN;
1077 1076 soft_tls_prf(secret, secretlen, label, labellen,
1078 1077 rand2, rand2len, rand1, rand1len, result, 16);
1079 1078 }
1080 1079 }
1081 1080 }
↓ open down ↓ |
112 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX