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