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