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