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.
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.
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]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * Key Management Functions
28 * (as defined in PKCS#11 spec section 11.14)
31 #include "metaGlobal.h"
39 meta_GenerateKey(CK_SESSION_HANDLE hSession
, CK_MECHANISM_PTR pMechanism
,
40 CK_ATTRIBUTE_PTR pTemplate
, CK_ULONG ulCount
, CK_OBJECT_HANDLE_PTR phKey
)
43 meta_session_t
*session
;
44 meta_object_t
*key
= NULL
;
46 if (pMechanism
== NULL
|| phKey
== NULL
)
47 return (CKR_ARGUMENTS_BAD
);
49 rv
= meta_handle2session(hSession
, &session
);
54 rv
= meta_object_alloc(session
, &key
);
58 rv
= meta_generate_keys(session
, pMechanism
, pTemplate
, ulCount
, key
,
63 meta_object_activate(key
);
65 *phKey
= (CK_OBJECT_HANDLE
) key
;
70 (void) meta_object_dealloc(session
, key
, B_TRUE
);
80 * meta_GenerateKeyPair
84 meta_GenerateKeyPair(CK_SESSION_HANDLE hSession
, CK_MECHANISM_PTR pMechanism
,
85 CK_ATTRIBUTE_PTR pPublicKeyTemplate
, CK_ULONG ulPublicKeyAttributeCount
,
86 CK_ATTRIBUTE_PTR pPrivateKeyTemplate
, CK_ULONG ulPrivateKeyAttributeCount
,
87 CK_OBJECT_HANDLE_PTR phPublicKey
, CK_OBJECT_HANDLE_PTR phPrivateKey
)
90 meta_session_t
*session
;
91 meta_object_t
*key1
= NULL
, *key2
= NULL
;
93 if (pMechanism
== NULL
|| phPublicKey
== NULL
|| phPrivateKey
== NULL
)
94 return (CKR_ARGUMENTS_BAD
);
96 rv
= meta_handle2session(hSession
, &session
);
101 rv
= meta_object_alloc(session
, &key1
);
105 rv
= meta_object_alloc(session
, &key2
);
109 rv
= meta_generate_keys(session
, pMechanism
,
110 pPublicKeyTemplate
, ulPublicKeyAttributeCount
, key1
,
111 pPrivateKeyTemplate
, ulPrivateKeyAttributeCount
, key2
);
115 meta_object_activate(key1
);
116 meta_object_activate(key2
);
118 *phPublicKey
= (CK_OBJECT_HANDLE
) key1
;
119 *phPrivateKey
= (CK_OBJECT_HANDLE
) key2
;
124 (void) meta_object_dealloc(session
, key1
, B_TRUE
);
126 (void) meta_object_dealloc(session
, key2
, B_TRUE
);
140 meta_WrapKey(CK_SESSION_HANDLE hSession
, CK_MECHANISM_PTR pMechanism
,
141 CK_OBJECT_HANDLE hWrappingKey
, CK_OBJECT_HANDLE hKey
,
142 CK_BYTE_PTR pWrappedKey
, CK_ULONG_PTR pulWrappedKeyLen
)
145 meta_session_t
*session
;
146 meta_object_t
*wrappingKey
, *inputKey
;
148 if (pMechanism
== NULL
|| pulWrappedKeyLen
== NULL
)
149 return (CKR_ARGUMENTS_BAD
);
151 rv
= meta_handle2session(hSession
, &session
);
155 rv
= meta_handle2object(hKey
, &inputKey
);
161 rv
= meta_handle2object(hWrappingKey
, &wrappingKey
);
163 OBJRELEASE(inputKey
);
168 rv
= meta_wrap_key(session
, pMechanism
, wrappingKey
,
169 inputKey
, pWrappedKey
, pulWrappedKeyLen
);
172 OBJRELEASE(inputKey
);
173 OBJRELEASE(wrappingKey
);
185 meta_UnwrapKey(CK_SESSION_HANDLE hSession
, CK_MECHANISM_PTR pMechanism
,
186 CK_OBJECT_HANDLE hUnwrappingKey
, CK_BYTE_PTR pWrappedKey
,
187 CK_ULONG ulWrappedKeyLen
, CK_ATTRIBUTE_PTR pTemplate
,
188 CK_ULONG ulAttributeCount
, CK_OBJECT_HANDLE_PTR phKey
)
191 meta_session_t
*session
;
192 meta_object_t
*unwrappingKey
, *outputKey
= NULL
;
194 if (pMechanism
== NULL
|| pWrappedKey
== NULL
|| phKey
== NULL
)
195 return (CKR_ARGUMENTS_BAD
);
197 rv
= meta_handle2session(hSession
, &session
);
201 rv
= meta_handle2object(hUnwrappingKey
, &unwrappingKey
);
207 rv
= meta_object_alloc(session
, &outputKey
);
211 (void) get_template_boolean(CKA_TOKEN
, pTemplate
, ulAttributeCount
,
212 &(outputKey
->isToken
));
214 rv
= meta_unwrap_key(session
, pMechanism
, unwrappingKey
,
215 pWrappedKey
, ulWrappedKeyLen
,
216 pTemplate
, ulAttributeCount
, outputKey
);
220 meta_object_activate(outputKey
);
222 *phKey
= (CK_OBJECT_HANDLE
) outputKey
;
227 (void) meta_object_dealloc(session
, outputKey
, B_TRUE
);
230 OBJRELEASE(unwrappingKey
);
240 * This function is a bit gross because of PKCS#11 kludges that pass extra
241 * object handles in some mechanism parameters. It probably needs to be
242 * broken up into more managable pieces.
245 meta_DeriveKey(CK_SESSION_HANDLE hSession
, CK_MECHANISM_PTR pMechanism
,
246 CK_OBJECT_HANDLE hBaseKey
, CK_ATTRIBUTE_PTR pTemplate
,
247 CK_ULONG ulAttributeCount
, CK_OBJECT_HANDLE_PTR phKey
)
250 CK_MECHANISM
*pMech
= pMechanism
;
251 meta_session_t
*session
;
252 meta_object_t
*basekey1
= NULL
, *basekey2
= NULL
;
253 meta_object_t
*newKey1
= NULL
, *newKey2
= NULL
, *newKey3
= NULL
,
255 boolean_t ssl_keys
= B_FALSE
;
256 boolean_t tlsprf
= B_FALSE
;
258 CK_MECHANISM metaMech
;
259 CK_OBJECT_HANDLE
*phBaseKey2
= NULL
;
260 CK_X9_42_DH2_DERIVE_PARAMS x942_params
, *x9_tmpptr
;
261 CK_ECDH2_DERIVE_PARAMS ecdh_params
, *ec_tmpptr
;
262 CK_SSL3_KEY_MAT_OUT
*ssl_key_mat
;
263 CK_SSL3_KEY_MAT_PARAMS
*keyparams
;
266 return (CKR_ARGUMENTS_BAD
);
270 * Special case: Normally, the caller must always provide storage
271 * for the derived key handle at phKey. Two (related) mechanisms
272 * are special, in that multiple keys are instead returned via
273 * pMech->pParameter. In these cases the spec says (see 12.38.4
274 * and 12.39.4) that phKey should be a NULL pointer, as it is not used.
276 switch (pMech
->mechanism
) {
277 case CKM_SSL3_KEY_AND_MAC_DERIVE
:
278 case CKM_TLS_KEY_AND_MAC_DERIVE
:
279 keyparams
= (CK_SSL3_KEY_MAT_PARAMS
*)pMech
->pParameter
;
281 if ((keyparams
== NULL
) || (pMech
->ulParameterLen
282 != sizeof (CK_SSL3_KEY_MAT_PARAMS
)))
283 return (CKR_ARGUMENTS_BAD
);
285 ssl_key_mat
= keyparams
->pReturnedKeyMaterial
;
286 if (ssl_key_mat
== NULL
)
287 return (CKR_ARGUMENTS_BAD
);
298 return (CKR_ARGUMENTS_BAD
);
301 rv
= meta_handle2session(hSession
, &session
);
305 rv
= meta_handle2object(hBaseKey
, &basekey1
);
311 * A few oddball mechanisms pass a 2nd object handle in the parameters.
312 * Here we validate that handle, and create a duplicate copy of the
313 * mechanism and parameters. This is done because the application
314 * does not expect these values to be changing, and could be using the
315 * same data in multiple threads (eg concurrent calls to C_DeriveKey).
316 * We copy the data to make sure there are no MT-Safe problems.
318 switch (pMech
->mechanism
) {
320 case CKM_ECMQV_DERIVE
:
321 /* uses CK_ECDH2_DERIVE_PARAMS struct as the parameter */
323 if ((pMech
->pParameter
== NULL
) || (pMech
->ulParameterLen
324 != sizeof (CK_ECDH2_DERIVE_PARAMS
))) {
325 rv
= CKR_ARGUMENTS_BAD
;
329 /* Duplicate the mechanism and paramaters */
330 ec_tmpptr
= (CK_ECDH2_DERIVE_PARAMS
*)pMech
->pParameter
;
331 ecdh_params
= *ec_tmpptr
;
333 metaMech
.pParameter
= &ecdh_params
;
336 /* Get the key the application is providing */
337 phBaseKey2
= &ecdh_params
.hPrivateData
;
340 case CKM_X9_42_DH_HYBRID_DERIVE
:
341 case CKM_X9_42_MQV_DERIVE
:
342 /* both use CK_X9_42_DH2_DERIVE_PARAMS as the parameter */
344 if ((pMech
->pParameter
== NULL
) || (pMech
->ulParameterLen
345 != sizeof (CK_X9_42_DH2_DERIVE_PARAMS
))) {
346 rv
= CKR_ARGUMENTS_BAD
;
350 /* Duplicate the mechanism and paramaters */
351 x9_tmpptr
= (CK_X9_42_DH2_DERIVE_PARAMS
*)pMech
->pParameter
;
352 x942_params
= *x9_tmpptr
;
354 metaMech
.pParameter
= &x942_params
;
357 /* Get the key the application is providing */
358 phBaseKey2
= &x942_params
.hPrivateData
;
361 case CKM_CONCATENATE_BASE_AND_KEY
:
362 /* uses a CK_OBJECT_HANDLE as the parameter */
364 if ((pMech
->pParameter
== NULL
) || (pMech
->ulParameterLen
365 != sizeof (CK_OBJECT_HANDLE
))) {
366 rv
= CKR_ARGUMENTS_BAD
;
370 /* Duplicate the mechanism and paramaters */
374 /* Get the key the application is providing */
375 phBaseKey2
= (CK_OBJECT_HANDLE
*) &metaMech
.pParameter
;
379 /* nothing special to do. */
384 rv
= meta_handle2object(*phBaseKey2
, &basekey2
);
390 * Allocate meta objects to store the derived key(s). Normally just
391 * a single key is created, but the SSL/TLS mechanisms generate four.
393 rv
= meta_object_alloc(session
, &newKey1
);
398 rv
= meta_object_alloc(session
, &newKey2
);
401 rv
= meta_object_alloc(session
, &newKey3
);
404 rv
= meta_object_alloc(session
, &newKey4
);
410 /* Perform the actual key derive operation. */
411 rv
= meta_derive_key(session
, pMech
, basekey1
, basekey2
, phBaseKey2
,
412 pTemplate
, ulAttributeCount
, newKey1
, newKey2
, newKey3
, newKey4
);
417 (void) meta_object_dealloc(session
, newKey1
, B_TRUE
);
419 /* phKey isn't used (is NULL) for mechanism CKM_TLS_PRF. */
422 /* Make derived key(s) active and visible to other threads. */
423 meta_object_activate(newKey1
);
425 meta_object_activate(newKey2
);
426 meta_object_activate(newKey3
);
427 meta_object_activate(newKey4
);
429 ssl_key_mat
->hClientMacSecret
430 = (CK_OBJECT_HANDLE
) newKey1
;
431 ssl_key_mat
->hServerMacSecret
432 = (CK_OBJECT_HANDLE
) newKey2
;
433 ssl_key_mat
->hClientKey
= (CK_OBJECT_HANDLE
) newKey3
;
434 ssl_key_mat
->hServerKey
= (CK_OBJECT_HANDLE
) newKey4
;
435 /* phKey isn't used (is NULL) for these SSL/TLS mechs */
438 *phKey
= (CK_OBJECT_HANDLE
) newKey1
;
445 (void) meta_object_dealloc(session
, newKey1
, B_TRUE
);
447 (void) meta_object_dealloc(session
, newKey2
, B_TRUE
);
449 (void) meta_object_dealloc(session
, newKey3
, B_TRUE
);
451 (void) meta_object_dealloc(session
, newKey4
, B_TRUE
);
455 OBJRELEASE(basekey1
);
457 OBJRELEASE(basekey2
);