17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 58cae6764SAnthony Scarpino * Common Development and Distribution License (the "License"). 68cae6764SAnthony Scarpino * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*9217f8fdSDan OpenSolaris Anderson * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * Key Management Functions 287c478bd9Sstevel@tonic-gate * (as defined in PKCS#11 spec section 11.14) 297c478bd9Sstevel@tonic-gate */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #include "metaGlobal.h" 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate /* 357c478bd9Sstevel@tonic-gate * meta_GenerateKey 367c478bd9Sstevel@tonic-gate * 377c478bd9Sstevel@tonic-gate */ 387c478bd9Sstevel@tonic-gate CK_RV 397c478bd9Sstevel@tonic-gate meta_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 407c478bd9Sstevel@tonic-gate CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey) 417c478bd9Sstevel@tonic-gate { 427c478bd9Sstevel@tonic-gate CK_RV rv; 437c478bd9Sstevel@tonic-gate meta_session_t *session; 447c478bd9Sstevel@tonic-gate meta_object_t *key = NULL; 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate if (pMechanism == NULL || phKey == NULL) 477c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate rv = meta_handle2session(hSession, &session); 507c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 517c478bd9Sstevel@tonic-gate return (rv); 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate rv = meta_object_alloc(session, &key); 557c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 567c478bd9Sstevel@tonic-gate goto finish; 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate rv = meta_generate_keys(session, pMechanism, pTemplate, ulCount, key, 597c478bd9Sstevel@tonic-gate NULL, 0, NULL); 607c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 617c478bd9Sstevel@tonic-gate goto finish; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate meta_object_activate(key); 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate *phKey = (CK_OBJECT_HANDLE) key; 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate finish: 687c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 697c478bd9Sstevel@tonic-gate if (key) 708cae6764SAnthony Scarpino (void) meta_object_dealloc(session, key, B_TRUE); 717c478bd9Sstevel@tonic-gate } 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate REFRELEASE(session); 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate return (rv); 767c478bd9Sstevel@tonic-gate } 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate /* 807c478bd9Sstevel@tonic-gate * meta_GenerateKeyPair 817c478bd9Sstevel@tonic-gate * 827c478bd9Sstevel@tonic-gate */ 837c478bd9Sstevel@tonic-gate CK_RV 847c478bd9Sstevel@tonic-gate meta_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 857c478bd9Sstevel@tonic-gate CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, 867c478bd9Sstevel@tonic-gate CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, 877c478bd9Sstevel@tonic-gate CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey) 887c478bd9Sstevel@tonic-gate { 897c478bd9Sstevel@tonic-gate CK_RV rv; 907c478bd9Sstevel@tonic-gate meta_session_t *session; 917c478bd9Sstevel@tonic-gate meta_object_t *key1 = NULL, *key2 = NULL; 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate if (pMechanism == NULL || phPublicKey == NULL || phPrivateKey == NULL) 947c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate rv = meta_handle2session(hSession, &session); 977c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 987c478bd9Sstevel@tonic-gate return (rv); 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate rv = meta_object_alloc(session, &key1); 1027c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 1037c478bd9Sstevel@tonic-gate goto finish; 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate rv = meta_object_alloc(session, &key2); 1067c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 1077c478bd9Sstevel@tonic-gate goto finish; 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate rv = meta_generate_keys(session, pMechanism, 1107c478bd9Sstevel@tonic-gate pPublicKeyTemplate, ulPublicKeyAttributeCount, key1, 1117c478bd9Sstevel@tonic-gate pPrivateKeyTemplate, ulPrivateKeyAttributeCount, key2); 1127c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 1137c478bd9Sstevel@tonic-gate goto finish; 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate meta_object_activate(key1); 1167c478bd9Sstevel@tonic-gate meta_object_activate(key2); 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate *phPublicKey = (CK_OBJECT_HANDLE) key1; 1197c478bd9Sstevel@tonic-gate *phPrivateKey = (CK_OBJECT_HANDLE) key2; 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate finish: 1227c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1237c478bd9Sstevel@tonic-gate if (key1) 1248cae6764SAnthony Scarpino (void) meta_object_dealloc(session, key1, B_TRUE); 1257c478bd9Sstevel@tonic-gate if (key2) 1268cae6764SAnthony Scarpino (void) meta_object_dealloc(session, key2, B_TRUE); 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate REFRELEASE(session); 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate return (rv); 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate /* 1367c478bd9Sstevel@tonic-gate * meta_WrapKey 1377c478bd9Sstevel@tonic-gate * 1387c478bd9Sstevel@tonic-gate */ 1397c478bd9Sstevel@tonic-gate CK_RV 1407c478bd9Sstevel@tonic-gate meta_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 1417c478bd9Sstevel@tonic-gate CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, 1427c478bd9Sstevel@tonic-gate CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen) 1437c478bd9Sstevel@tonic-gate { 1447c478bd9Sstevel@tonic-gate CK_RV rv; 1457c478bd9Sstevel@tonic-gate meta_session_t *session; 1467c478bd9Sstevel@tonic-gate meta_object_t *wrappingKey, *inputKey; 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate if (pMechanism == NULL || pulWrappedKeyLen == NULL) 1497c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate rv = meta_handle2session(hSession, &session); 1527c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 1537c478bd9Sstevel@tonic-gate return (rv); 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate rv = meta_handle2object(hKey, &inputKey); 1567c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1577c478bd9Sstevel@tonic-gate REFRELEASE(session); 1587c478bd9Sstevel@tonic-gate return (rv); 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate rv = meta_handle2object(hWrappingKey, &wrappingKey); 1627c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1637c478bd9Sstevel@tonic-gate OBJRELEASE(inputKey); 1647c478bd9Sstevel@tonic-gate REFRELEASE(session); 1657c478bd9Sstevel@tonic-gate return (rv); 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate rv = meta_wrap_key(session, pMechanism, wrappingKey, 1697c478bd9Sstevel@tonic-gate inputKey, pWrappedKey, pulWrappedKeyLen); 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate finish: 1727c478bd9Sstevel@tonic-gate OBJRELEASE(inputKey); 1737c478bd9Sstevel@tonic-gate OBJRELEASE(wrappingKey); 1747c478bd9Sstevel@tonic-gate REFRELEASE(session); 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate return (rv); 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate /* 1817c478bd9Sstevel@tonic-gate * meta_UnwrapKey 1827c478bd9Sstevel@tonic-gate * 1837c478bd9Sstevel@tonic-gate */ 1847c478bd9Sstevel@tonic-gate CK_RV 1857c478bd9Sstevel@tonic-gate meta_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 1867c478bd9Sstevel@tonic-gate CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, 1877c478bd9Sstevel@tonic-gate CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, 1887c478bd9Sstevel@tonic-gate CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) 1897c478bd9Sstevel@tonic-gate { 1907c478bd9Sstevel@tonic-gate CK_RV rv; 1917c478bd9Sstevel@tonic-gate meta_session_t *session; 1927c478bd9Sstevel@tonic-gate meta_object_t *unwrappingKey, *outputKey = NULL; 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate if (pMechanism == NULL || pWrappedKey == NULL || phKey == NULL) 1957c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate rv = meta_handle2session(hSession, &session); 1987c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 1997c478bd9Sstevel@tonic-gate return (rv); 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate rv = meta_handle2object(hUnwrappingKey, &unwrappingKey); 2027c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 2037c478bd9Sstevel@tonic-gate REFRELEASE(session); 2047c478bd9Sstevel@tonic-gate return (rv); 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate rv = meta_object_alloc(session, &outputKey); 2087c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 2097c478bd9Sstevel@tonic-gate goto finish; 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate (void) get_template_boolean(CKA_TOKEN, pTemplate, ulAttributeCount, 2127c478bd9Sstevel@tonic-gate &(outputKey->isToken)); 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate rv = meta_unwrap_key(session, pMechanism, unwrappingKey, 2157c478bd9Sstevel@tonic-gate pWrappedKey, ulWrappedKeyLen, 2167c478bd9Sstevel@tonic-gate pTemplate, ulAttributeCount, outputKey); 2177c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 2187c478bd9Sstevel@tonic-gate goto finish; 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate meta_object_activate(outputKey); 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate *phKey = (CK_OBJECT_HANDLE) outputKey; 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate finish: 2257c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 2267c478bd9Sstevel@tonic-gate if (outputKey) 2278cae6764SAnthony Scarpino (void) meta_object_dealloc(session, outputKey, B_TRUE); 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate OBJRELEASE(unwrappingKey); 2317c478bd9Sstevel@tonic-gate REFRELEASE(session); 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate return (rv); 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate /* 2387c478bd9Sstevel@tonic-gate * meta_DeriveKey 2397c478bd9Sstevel@tonic-gate * 2407c478bd9Sstevel@tonic-gate * This function is a bit gross because of PKCS#11 kludges that pass extra 2417c478bd9Sstevel@tonic-gate * object handles in some mechanism parameters. It probably needs to be 2427c478bd9Sstevel@tonic-gate * broken up into more managable pieces. 2437c478bd9Sstevel@tonic-gate */ 2447c478bd9Sstevel@tonic-gate CK_RV 2457c478bd9Sstevel@tonic-gate meta_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 2467c478bd9Sstevel@tonic-gate CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, 2477c478bd9Sstevel@tonic-gate CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) 2487c478bd9Sstevel@tonic-gate { 2497c478bd9Sstevel@tonic-gate CK_RV rv; 2507c478bd9Sstevel@tonic-gate CK_MECHANISM *pMech = pMechanism; 2517c478bd9Sstevel@tonic-gate meta_session_t *session; 2527c478bd9Sstevel@tonic-gate meta_object_t *basekey1 = NULL, *basekey2 = NULL; 2537c478bd9Sstevel@tonic-gate meta_object_t *newKey1 = NULL, *newKey2 = NULL, *newKey3 = NULL, 2547c478bd9Sstevel@tonic-gate *newKey4 = NULL; 2557c478bd9Sstevel@tonic-gate boolean_t ssl_keys = B_FALSE; 25660722cc8Sizick boolean_t tlsprf = B_FALSE; 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate CK_MECHANISM metaMech; 2597c478bd9Sstevel@tonic-gate CK_OBJECT_HANDLE *phBaseKey2 = NULL; 2607c478bd9Sstevel@tonic-gate CK_X9_42_DH2_DERIVE_PARAMS x942_params, *x9_tmpptr; 2617c478bd9Sstevel@tonic-gate CK_ECDH2_DERIVE_PARAMS ecdh_params, *ec_tmpptr; 2627c478bd9Sstevel@tonic-gate CK_SSL3_KEY_MAT_OUT *ssl_key_mat; 26360722cc8Sizick CK_SSL3_KEY_MAT_PARAMS *keyparams; 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate if (pMech == NULL) { 2667c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate /* 2707c478bd9Sstevel@tonic-gate * Special case: Normally, the caller must always provide storage 2717c478bd9Sstevel@tonic-gate * for the derived key handle at phKey. Two (related) mechanisms 2727c478bd9Sstevel@tonic-gate * are special, in that multiple keys are instead returned via 2737c478bd9Sstevel@tonic-gate * pMech->pParameter. In these cases the spec says (see 12.38.4 2747c478bd9Sstevel@tonic-gate * and 12.39.4) that phKey should be a NULL pointer, as it is not used. 2757c478bd9Sstevel@tonic-gate */ 27660722cc8Sizick switch (pMech->mechanism) { 27760722cc8Sizick case CKM_SSL3_KEY_AND_MAC_DERIVE: 27860722cc8Sizick case CKM_TLS_KEY_AND_MAC_DERIVE: 27960722cc8Sizick keyparams = (CK_SSL3_KEY_MAT_PARAMS*)pMech->pParameter; 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate if ((keyparams == NULL) || (pMech->ulParameterLen 28260722cc8Sizick != sizeof (CK_SSL3_KEY_MAT_PARAMS))) 2837c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate ssl_key_mat = keyparams->pReturnedKeyMaterial; 28660722cc8Sizick if (ssl_key_mat == NULL) 2877c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate ssl_keys = B_TRUE; 29060722cc8Sizick break; 29160722cc8Sizick 29260722cc8Sizick case CKM_TLS_PRF: 29360722cc8Sizick tlsprf = B_TRUE; 29460722cc8Sizick break; 29560722cc8Sizick 29660722cc8Sizick default: 29760722cc8Sizick if (phKey == NULL) 2987c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD); 29960722cc8Sizick }; 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate rv = meta_handle2session(hSession, &session); 3027c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 3037c478bd9Sstevel@tonic-gate return (rv); 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate rv = meta_handle2object(hBaseKey, &basekey1); 3067c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 3077c478bd9Sstevel@tonic-gate goto finish; 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate /* 3117c478bd9Sstevel@tonic-gate * A few oddball mechanisms pass a 2nd object handle in the parameters. 3127c478bd9Sstevel@tonic-gate * Here we validate that handle, and create a duplicate copy of the 3137c478bd9Sstevel@tonic-gate * mechanism and parameters. This is done because the application 3147c478bd9Sstevel@tonic-gate * does not expect these values to be changing, and could be using the 3157c478bd9Sstevel@tonic-gate * same data in multiple threads (eg concurrent calls to C_DeriveKey). 3167c478bd9Sstevel@tonic-gate * We copy the data to make sure there are no MT-Safe problems. 3177c478bd9Sstevel@tonic-gate */ 3187c478bd9Sstevel@tonic-gate switch (pMech->mechanism) { 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate case CKM_ECMQV_DERIVE: 3217c478bd9Sstevel@tonic-gate /* uses CK_ECDH2_DERIVE_PARAMS struct as the parameter */ 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate if ((pMech->pParameter == NULL) || (pMech->ulParameterLen 3247c478bd9Sstevel@tonic-gate != sizeof (CK_ECDH2_DERIVE_PARAMS))) { 3257c478bd9Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD; 3267c478bd9Sstevel@tonic-gate goto finish; 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate /* Duplicate the mechanism and paramaters */ 3307c478bd9Sstevel@tonic-gate ec_tmpptr = (CK_ECDH2_DERIVE_PARAMS *)pMech->pParameter; 3317c478bd9Sstevel@tonic-gate ecdh_params = *ec_tmpptr; 3327c478bd9Sstevel@tonic-gate metaMech = *pMech; 3337c478bd9Sstevel@tonic-gate metaMech.pParameter = &ecdh_params; 3347c478bd9Sstevel@tonic-gate pMech = &metaMech; 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate /* Get the key the application is providing */ 3377c478bd9Sstevel@tonic-gate phBaseKey2 = &ecdh_params.hPrivateData; 3387c478bd9Sstevel@tonic-gate break; 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate case CKM_X9_42_DH_HYBRID_DERIVE: 3417c478bd9Sstevel@tonic-gate case CKM_X9_42_MQV_DERIVE: 3427c478bd9Sstevel@tonic-gate /* both use CK_X9_42_DH2_DERIVE_PARAMS as the parameter */ 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate if ((pMech->pParameter == NULL) || (pMech->ulParameterLen 3457c478bd9Sstevel@tonic-gate != sizeof (CK_X9_42_DH2_DERIVE_PARAMS))) { 3467c478bd9Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD; 3477c478bd9Sstevel@tonic-gate goto finish; 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate /* Duplicate the mechanism and paramaters */ 3517c478bd9Sstevel@tonic-gate x9_tmpptr = (CK_X9_42_DH2_DERIVE_PARAMS *)pMech->pParameter; 3527c478bd9Sstevel@tonic-gate x942_params = *x9_tmpptr; 3537c478bd9Sstevel@tonic-gate metaMech = *pMech; 3547c478bd9Sstevel@tonic-gate metaMech.pParameter = &x942_params; 3557c478bd9Sstevel@tonic-gate pMech = &metaMech; 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate /* Get the key the application is providing */ 3587c478bd9Sstevel@tonic-gate phBaseKey2 = &x942_params.hPrivateData; 3597c478bd9Sstevel@tonic-gate break; 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate case CKM_CONCATENATE_BASE_AND_KEY: 3627c478bd9Sstevel@tonic-gate /* uses a CK_OBJECT_HANDLE as the parameter */ 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate if ((pMech->pParameter == NULL) || (pMech->ulParameterLen 3657c478bd9Sstevel@tonic-gate != sizeof (CK_OBJECT_HANDLE))) { 3667c478bd9Sstevel@tonic-gate rv = CKR_ARGUMENTS_BAD; 3677c478bd9Sstevel@tonic-gate goto finish; 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate /* Duplicate the mechanism and paramaters */ 3717c478bd9Sstevel@tonic-gate metaMech = *pMech; 3727c478bd9Sstevel@tonic-gate pMech = &metaMech; 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate /* Get the key the application is providing */ 3757c478bd9Sstevel@tonic-gate phBaseKey2 = (CK_OBJECT_HANDLE *) &metaMech.pParameter; 3767c478bd9Sstevel@tonic-gate break; 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate default: 3797c478bd9Sstevel@tonic-gate /* nothing special to do. */ 3807c478bd9Sstevel@tonic-gate break; 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate if (phBaseKey2) { 3847c478bd9Sstevel@tonic-gate rv = meta_handle2object(*phBaseKey2, &basekey2); 3857c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 3867c478bd9Sstevel@tonic-gate goto finish; 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate /* 3907c478bd9Sstevel@tonic-gate * Allocate meta objects to store the derived key(s). Normally just 3917c478bd9Sstevel@tonic-gate * a single key is created, but the SSL/TLS mechanisms generate four. 3927c478bd9Sstevel@tonic-gate */ 3937c478bd9Sstevel@tonic-gate rv = meta_object_alloc(session, &newKey1); 3947c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 3957c478bd9Sstevel@tonic-gate goto finish; 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate if (ssl_keys) { 3987c478bd9Sstevel@tonic-gate rv = meta_object_alloc(session, &newKey2); 3997c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 4007c478bd9Sstevel@tonic-gate goto finish; 4017c478bd9Sstevel@tonic-gate rv = meta_object_alloc(session, &newKey3); 4027c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 4037c478bd9Sstevel@tonic-gate goto finish; 4047c478bd9Sstevel@tonic-gate rv = meta_object_alloc(session, &newKey4); 4057c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 4067c478bd9Sstevel@tonic-gate goto finish; 4077c478bd9Sstevel@tonic-gate } 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate /* Perform the actual key derive operation. */ 4117c478bd9Sstevel@tonic-gate rv = meta_derive_key(session, pMech, basekey1, basekey2, phBaseKey2, 4128cae6764SAnthony Scarpino pTemplate, ulAttributeCount, newKey1, newKey2, newKey3, newKey4); 4137c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 4147c478bd9Sstevel@tonic-gate goto finish; 4157c478bd9Sstevel@tonic-gate 416*9217f8fdSDan OpenSolaris Anderson if (tlsprf) { 417*9217f8fdSDan OpenSolaris Anderson (void) meta_object_dealloc(session, newKey1, B_TRUE); 418*9217f8fdSDan OpenSolaris Anderson newKey1 = NULL; 419*9217f8fdSDan OpenSolaris Anderson /* phKey isn't used (is NULL) for mechanism CKM_TLS_PRF. */ 420*9217f8fdSDan OpenSolaris Anderson 421*9217f8fdSDan OpenSolaris Anderson } else { 422*9217f8fdSDan OpenSolaris Anderson /* Make derived key(s) active and visible to other threads. */ 4237c478bd9Sstevel@tonic-gate meta_object_activate(newKey1); 4247c478bd9Sstevel@tonic-gate if (ssl_keys) { 4257c478bd9Sstevel@tonic-gate meta_object_activate(newKey2); 4267c478bd9Sstevel@tonic-gate meta_object_activate(newKey3); 4277c478bd9Sstevel@tonic-gate meta_object_activate(newKey4); 4287c478bd9Sstevel@tonic-gate 429*9217f8fdSDan OpenSolaris Anderson ssl_key_mat->hClientMacSecret 430*9217f8fdSDan OpenSolaris Anderson = (CK_OBJECT_HANDLE) newKey1; 431*9217f8fdSDan OpenSolaris Anderson ssl_key_mat->hServerMacSecret 432*9217f8fdSDan OpenSolaris Anderson = (CK_OBJECT_HANDLE) newKey2; 4337c478bd9Sstevel@tonic-gate ssl_key_mat->hClientKey = (CK_OBJECT_HANDLE) newKey3; 4347c478bd9Sstevel@tonic-gate ssl_key_mat->hServerKey = (CK_OBJECT_HANDLE) newKey4; 435*9217f8fdSDan OpenSolaris Anderson /* phKey isn't used (is NULL) for these SSL/TLS mechs */ 43660722cc8Sizick 437*9217f8fdSDan OpenSolaris Anderson } else { 4387c478bd9Sstevel@tonic-gate *phKey = (CK_OBJECT_HANDLE) newKey1; 4397c478bd9Sstevel@tonic-gate } 440*9217f8fdSDan OpenSolaris Anderson } 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate finish: 4437c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 4447c478bd9Sstevel@tonic-gate if (newKey1) 4458cae6764SAnthony Scarpino (void) meta_object_dealloc(session, newKey1, B_TRUE); 4467c478bd9Sstevel@tonic-gate if (newKey2) 4478cae6764SAnthony Scarpino (void) meta_object_dealloc(session, newKey2, B_TRUE); 4487c478bd9Sstevel@tonic-gate if (newKey3) 4498cae6764SAnthony Scarpino (void) meta_object_dealloc(session, newKey3, B_TRUE); 4507c478bd9Sstevel@tonic-gate if (newKey4) 4518cae6764SAnthony Scarpino (void) meta_object_dealloc(session, newKey4, B_TRUE); 4527c478bd9Sstevel@tonic-gate } 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate if (basekey1) 4557c478bd9Sstevel@tonic-gate OBJRELEASE(basekey1); 4567c478bd9Sstevel@tonic-gate if (basekey2) 4577c478bd9Sstevel@tonic-gate OBJRELEASE(basekey2); 4587c478bd9Sstevel@tonic-gate REFRELEASE(session); 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate return (rv); 4617c478bd9Sstevel@tonic-gate } 462