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