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 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  * Copyright 2018, Joyent, Inc.
25  */
26 
27 /*
28  * Message Digesting Functions
29  * (as defined in PKCS#11 spec section 11.10)
30  */
31 
32 #include "metaGlobal.h"
33 
34 
35 /*
36  * meta_DigestInit
37  *
38  */
39 CK_RV
meta_DigestInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism)40 meta_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism)
41 {
42 	CK_RV rv;
43 	meta_session_t *session;
44 
45 	if (pMechanism == NULL)
46 		return (CKR_ARGUMENTS_BAD);
47 
48 	rv = meta_handle2session(hSession, &session);
49 	if (rv != CKR_OK)
50 		return (rv);
51 
52 	rv = meta_operation_init_defer(CKF_DIGEST, session, pMechanism, NULL);
53 
54 	REFRELEASE(session);
55 
56 	return (rv);
57 }
58 
59 
60 /*
61  * meta_Digest
62  *
63  */
64 CK_RV
meta_Digest(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)65 meta_Digest(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
66     CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
67 {
68 	CK_RV rv;
69 	meta_session_t *session;
70 
71 
72 	if ((pData == NULL && ulDataLen != 0) || pulDigestLen == NULL)
73 		return (CKR_ARGUMENTS_BAD);
74 
75 	rv = meta_handle2session(hSession, &session);
76 	if (rv != CKR_OK)
77 		return (rv);
78 
79 	rv = meta_do_operation(CKF_DIGEST, MODE_SINGLE, session, NULL,
80 	    pData, ulDataLen, pDigest, pulDigestLen);
81 
82 	REFRELEASE(session);
83 
84 	return (rv);
85 }
86 
87 
88 /*
89  * meta_DigestUpdate
90  *
91  */
92 CK_RV
meta_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)93 meta_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
94     CK_ULONG ulPartLen)
95 {
96 	CK_RV rv;
97 	meta_session_t *session;
98 
99 
100 	if (pPart == NULL)
101 		return (CKR_ARGUMENTS_BAD);
102 
103 	rv = meta_handle2session(hSession, &session);
104 	if (rv != CKR_OK)
105 		return (rv);
106 
107 	rv = meta_do_operation(CKF_DIGEST, MODE_UPDATE, session, NULL,
108 	    pPart, ulPartLen, NULL, NULL);
109 
110 	REFRELEASE(session);
111 
112 	return (rv);
113 }
114 
115 
116 /*
117  * meta_DigestKey
118  *
119  * NOTE: This function can fail under certain circumstances!
120  * Unlike the other crypto functions, we didn't get the key object
121  * when the operation was initialized with C_DigestInit().
122  * Thus, the slot we're using for the digest operation may
123  * not be the slot containing the key -- if the key is extractible we can
124  * deal with it, but if it's not the operation will FAIL.
125  */
126 CK_RV
meta_DigestKey(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hKey)127 meta_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
128 {
129 	CK_RV rv;
130 	meta_session_t *session;
131 	meta_object_t *key;
132 
133 	rv = meta_handle2session(hSession, &session);
134 	if (rv != CKR_OK)
135 		return (rv);
136 
137 	rv = meta_handle2object(hKey, &key);
138 	if (rv != CKR_OK) {
139 		REFRELEASE(session);
140 		return (rv);
141 	}
142 
143 	/* meta_do_operation() will clone the key, if needed. */
144 	rv = meta_do_operation(CKF_DIGEST, MODE_UPDATE_WITHKEY, session, key,
145 	    NULL, 0, NULL, NULL);
146 
147 	OBJRELEASE(key);
148 	REFRELEASE(session);
149 
150 	return (rv);
151 }
152 
153 
154 /*
155  * meta_DigestFinal
156  *
157  */
158 CK_RV
meta_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)159 meta_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest,
160     CK_ULONG_PTR pulDigestLen)
161 {
162 	CK_RV rv;
163 	meta_session_t *session;
164 
165 	if (pulDigestLen == NULL)
166 		return (CKR_ARGUMENTS_BAD);
167 
168 	rv = meta_handle2session(hSession, &session);
169 	if (rv != CKR_OK)
170 		return (rv);
171 
172 	rv = meta_do_operation(CKF_DIGEST, MODE_FINAL, session, NULL,
173 	    NULL, 0, pDigest, pulDigestLen);
174 
175 	REFRELEASE(session);
176 
177 	return (rv);
178 }
179