2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A * This files contains the implementation of the following PKCS#11 2N/A * mechanisms needed by SSL: 2N/A * CKM_SSL3_MASTER_KEY_DERIVE 2N/A * CKM_SSL3_MASTER_KEY_DERIVE_DH 2N/A * CKM_SSL3_KEY_AND_DERIVE 2N/A * CKM_TLS_MASTER_KEY_DERIVE 2N/A * CKM_TLS_MASTER_KEY_DERIVE_DH 2N/A * CKM_TLS_KEY_AND_DERIVE 2N/A * SSL refers to common functions between SSL v3.0 and SSL v3.1 (a.k.a TLS.) 2N/A * Called for derivation of the master secret from the pre-master secret, 2N/A * and for the derivation of the key_block in an SSL3 handshake 2N/A * result is assumed to be larger than rounds * MD5_DIGEST_LENGTH. 2N/A * This TLS generic Pseudo Random Function expands a triplet 2N/A * {secret, label, seed} into any arbitrary length string of pseudo 2N/A * Here, it is called for the derivation of the master secret from the 2N/A * pre-master secret, and for the derivation of the key_block in a TLS 2N/A /* secret is NULL for IV's in exportable ciphersuites */ 2N/A /* Reduce the half secrets if bigger than the HASH's block size */ 2N/A * PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR 2N/A * P_SHA-1(S2, label + seed); 2N/A * the 'seed' here is rand1 + rand2 2N/A /* The first one writes directly to the result */ 2N/A /* The second one XOR's with the result. */ 2N/A * These two expansion routines are very similar. (they can merge one day). 2N/A * They implement the P_HASH() function for MD5 and for SHA1, as defined in 2N/A * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) + 2N/A * HMAC_hash(secret, A(2) + seed) + 2N/A * HMAC_hash(secret, A(3) + seed) + ... 2N/A * Where + indicates concatenation. 2N/A * A() is defined as: 2N/A * A(i) = HMAC_hash(secret, A(i-1)) 2N/A * The seed is the concatenation of 'babel', 'rand1', and 'rand2'. 2N/A /* good compilers will leverage the alignment */ 2N/A /* A(1) = HMAC_MD5(secret, rand1 + rand2) */ 2N/A * Compute HMAC_MD5(secret, A(i) + seed); 2N/A * The secret is already expanded in the ictx and octx, so 2N/A * we can call the SOFT_MAC_INIT_CTX() directly. 2N/A /* A(i) = HMAC_MD5(secret, A(i-1) */ 2N/A /* good compilers will leverage the alignment */ 2N/A /* A(1) = HMAC_SHA1(secret, rand1 + rand2) */ 2N/A * Compute HMAC_SHA1(secret, A(i) + seed); 2N/A * The secret is already expanded in the ictx and octx, so 2N/A * we can call the SOFT_MAC_INIT_CTX() directly. 2N/A /* A(i) = HMAC_SHA1(secret, A(i-1) */ 2N/A/* This function handles the call from C_DeriveKey for CKM_TLS_PRF */ 2N/A * soft_ssl_master_key_derive() 2N/A * . mech_p: key derivation mechanism. the mechanism parameter carries the 2N/A * client and master random from the Hello handshake messages. 2N/A * . basekey_p: The pre-master secret key. 2N/A * . pTemplate & ulAttributeCount: Any extra attributes for the key to be 2N/A * . phKey: store for handle to the derived key. 2N/A * Derive the SSL master secret from the pre-master secret, the client 2N/A * and server random. 2N/A * In SSL 3.0, master_secret = 2N/A * MD5(pre_master_secret + SHA('A' + pre_master_secret + 2N/A * ClientHello.random + ServerHello.random)) + 2N/A * MD5(pre_master_secret + SHA('BB' + pre_master_secret + 2N/A * ClientHello.random + ServerHello.random)) + 2N/A * MD5(pre_master_secret + SHA('CCC' + pre_master_secret + 2N/A * ClientHello.random + ServerHello.random)); 2N/A * In TLS 1.0 (a.k.a. SSL 3.1), master_secret = 2N/A * PRF(pre_master_secret, "master secret", 2N/A * ClientHello.random + ServerHello.random) 2N/A#
else /* __sparcv9 */ 2N/A#
endif /* __sparcv9 */ 2N/A /* Check the validity of the mechanism's parameter */ 2N/A /* Invalid pre-master key length. What else to return? */ 2N/A /* Get the SSL version number from the premaster secret */ 2N/A * Strip leading zeroes as defined in TLS 1.1 specification 2N/A * (RFC 4346) in section 8.1.2. 2N/A#
else /* __sparcv9 */ 2N/A#
endif /* __sparcv9 */ 2N/A /* Now the actual secret derivation */ 2N/A * The object creation attributes need to be in one contiguous 2N/A * array. In addition to the attrs from the application supplied 2N/A * pTemplates, We need to add the class, type, value, valuelen and 2N/A * In the most likely case, the application passes between zero and 2N/A * handful of attributes, We optimize for that case by allocating 2N/A * the new template on the stack. Otherwise we malloc() it. 2N/A * Fill in the new template. 2N/A * We put the attributes contributed by the mechanism first 2N/A * so that they override the application supplied ones. 2N/A /* Any attributes left? */ 2N/A /* Validate the default class and type attributes */ 2N/A /* The caller is responsible for proper alignment */ 2N/A * soft_ssl3_key_and_mac_derive() 2N/A * . mech_p: key derivation mechanism. the mechanism parameter carries the 2N/A * client and master random from the Hello handshake messages, 2N/A * the specification of the key and IV sizes, and the location 2N/A * for the resulting keys and IVs. 2N/A * . basekey_p: The master secret key. 2N/A * . pTemplate & ulAttributeCount: Any extra attributes for the key to be 2N/A * Derive the SSL key material (Client and server MAC secrets, symmetric 2N/A * keys and IVs), from the master secret and the client 2N/A * and server random. 2N/A * First a keyblock is generated using the following formula: 2N/A * MD5(master_secret + SHA(`A' + master_secret + 2N/A * ServerHello.random + 2N/A * ClientHello.random)) + 2N/A * MD5(master_secret + SHA(`BB' + master_secret + 2N/A * ServerHello.random + 2N/A * ClientHello.random)) + 2N/A * MD5(master_secret + SHA(`CCC' + master_secret + 2N/A * ServerHello.random + 2N/A * ClientHello.random)) + [...]; 2N/A * In TLS 1.0 (a.k.a. SSL 3.1), key_block = 2N/A * PRF(master_secret, "key expansion", 2N/A * ServerHello.random + ClientHello.random) 2N/A * Then the keys materials are taken from the keyblock. 2N/A#
else /* __sparcv9 */ 2N/A#
endif /* __sparcv9 */ 2N/A /* Check the validity of the mechanism's parameter */ 2N/A#
else /* __sparcv9 */ 2N/A#
endif /* __sparcv9 */ 2N/A * For exportable ciphersuites, the IV's aren't taken from the 2N/A * key block. They are directly derived from the client and 2N/A * server random data. 2N/A * client_write_IV = MD5(ClientHello.random + ServerHello.random); 2N/A * server_write_IV = MD5(ServerHello.random + ClientHello.random); 2N/A * iv_block = PRF("", "IV block", client_random + 2N/A * server_random)[0..15] 2N/A * client_write_IV = iv_block[0..7] 2N/A * server_write_IV = iv_block[8..15] 2N/A /* there's room in key_block. use it */ 2N/A /* so we won't allocate a key_block bigger than needed */ 2N/A /* Now the actual secret derivation */ 2N/A#
else /* __sparcv9 */ 2N/A#
endif /* __sparcv9 */ 2N/A /* Need to handle this better */ 2N/A /* Now create the objects */ 2N/A /* First the MAC secrets */ 2N/A /* Then the symmetric ciphers keys */ 2N/A * The keyType comes from the application's template, and depends 2N/A * on the ciphersuite. The only exception is authentication only 2N/A * ciphersuites which do not use cipher keys. 2N/A /* Finally, the IVs */ 2N/A * Add the derived key to the session, and, if it's a token object, 2N/A * write it to the token. 2N/A /* Set the sensitivity and extractability attributes as a needed */ 2N/A /* Initialize the rest of stuffs in soft_object_t. */ 2N/A /* ... and, if it needs to persist, write on the token */ 2N/A /* Add the new object to the session's object list. */ 2N/A * Delete the derived key from the session, and, if it's a token object, 2N/A * remove it from the token. 2N/A /* session_handle is the creating session. It's NULL for token objs */ 2N/A * soft_ssl_weaken_key() 2N/A * Reduce the key length to an exportable size. 2N/A * final_client_write_key = MD5(client_write_key + 2N/A * ClientHello.random + 2N/A * ServerHello.random); 2N/A * final_server_write_key = MD5(server_write_key + 2N/A * ServerHello.random + 2N/A * ClientHello.random); 2N/A * "client write key", 2N/A * "server write key",