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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25#include <strings.h>
26#include <errno.h>
27#include <security/cryptoki.h>
28#include <cryptoutil.h>
29#include "kmsGlobal.h"
30#include "kmsSession.h"
31#include "kmsObject.h"
32#include "kmsKeystoreUtil.h"
33
34static CK_RV
35kms_generate_softkey(kms_object_t *keyp)
36{
37	if ((OBJ_SEC_VALUE(keyp) = malloc(OBJ_SEC_VALUE_LEN(keyp))) == NULL)
38		return (CKR_HOST_MEMORY);
39
40	if (pkcs11_get_urandom(OBJ_SEC_VALUE(keyp),
41	    OBJ_SEC_VALUE_LEN(keyp)) < 0)
42		return (CKR_DEVICE_ERROR);
43
44	return (CKR_OK);
45}
46
47CK_RV
48C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
49    CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
50{
51	CK_RV			rv = CKR_OK;
52	kms_session_t		*session_p;
53	kms_object_t		*new_objp = NULL;
54	kms_slot_t		*pslot;
55	boolean_t		ses_lock_held = B_FALSE;
56
57	if (!kms_initialized)
58		return (CKR_CRYPTOKI_NOT_INITIALIZED);
59
60	/* Obtain the session pointer */
61	rv = handle2session(hSession, &session_p);
62	if (rv != CKR_OK)
63		return (rv);
64
65	if ((pMechanism == NULL) || (phKey == NULL)) {
66		rv = CKR_ARGUMENTS_BAD;
67		goto failed_exit;
68	}
69
70	if ((pTemplate == NULL) && (ulCount != 0)) {
71		rv = CKR_ARGUMENTS_BAD;
72		goto failed_exit;
73	}
74
75	switch (pMechanism->mechanism) {
76		case CKM_AES_KEY_GEN:
77			break;
78		default:
79			rv = CKR_MECHANISM_INVALID;
80			goto failed_exit;
81			break;
82	}
83
84	/* Create an object record */
85	new_objp = kms_new_object();
86	if (new_objp == NULL)
87		return (CKR_HOST_MEMORY);
88
89	new_objp->mechanism = pMechanism->mechanism;
90	rv = kms_build_object(pTemplate, ulCount, new_objp);
91	if (rv != CKR_OK)
92		goto failed_exit;
93
94	/*
95	 * Generate the KMS key.
96	 *
97	 * This will put the AES key value from the KMS key into the
98	 * key object record.
99	 */
100	if (new_objp->bool_attr_mask & TOKEN_BOOL_ON)
101		rv = KMS_GenerateKey(session_p, new_objp);
102	else
103		rv = kms_generate_softkey(new_objp);
104
105	if (rv != CKR_OK)
106		goto failed_exit;
107
108	if (new_objp->bool_attr_mask & TOKEN_BOOL_ON) {
109		pslot = get_slotinfo();
110		if (pslot == NULL) {
111			rv = CKR_GENERAL_ERROR;
112			goto failed_exit;
113		}
114		kms_add_token_object_to_slot(new_objp, pslot);
115	} else {
116		kms_add_object_to_session(new_objp, session_p);
117	}
118
119	*phKey = (CK_OBJECT_HANDLE)new_objp;
120	REFRELE(session_p, ses_lock_held);
121	return (rv);
122
123failed_exit:
124	if (new_objp != NULL)
125		(void) free(new_objp);
126
127	REFRELE(session_p, ses_lock_held);
128	return (rv);
129}
130
131/*ARGSUSED*/
132CK_RV
133C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
134    CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount,
135    CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount,
136    CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)
137{
138	if (!kms_initialized)
139		return (CKR_CRYPTOKI_NOT_INITIALIZED);
140
141	return (CKR_FUNCTION_NOT_SUPPORTED);
142}
143
144/*ARGSUSED*/
145CK_RV
146C_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
147    CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey,
148    CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
149{
150	if (!kms_initialized)
151		return (CKR_CRYPTOKI_NOT_INITIALIZED);
152
153	return (CKR_FUNCTION_NOT_SUPPORTED);
154}
155
156/*ARGSUSED*/
157CK_RV
158C_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
159    CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey,
160    CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate,
161    CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
162{
163	if (!kms_initialized)
164		return (CKR_CRYPTOKI_NOT_INITIALIZED);
165
166	return (CKR_FUNCTION_NOT_SUPPORTED);
167}
168
169/*ARGSUSED*/
170CK_RV
171C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
172    CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
173    CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
174{
175	if (!kms_initialized)
176		return (CKR_CRYPTOKI_NOT_INITIALIZED);
177
178	return (CKR_FUNCTION_NOT_SUPPORTED);
179}
180