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