1 /*
2 * The Initial Developer of the Original Code is International
3 * Business Machines Corporation. Portions created by IBM
4 * Corporation are Copyright (C) 2005 International Business
5 * Machines Corporation. All Rights Reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the Common Public License as published by
9 * IBM Corporation; either version 1 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * Common Public License for more details.
16 *
17 * You should have received a copy of the Common Public License
18 * along with this program; if not, a copy can be viewed at
19 * http://www.opensource.org/licenses/cpl1.0.php.
20 */
21
22 /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */
23 /*
24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28 #include "tpmtok_int.h"
29
30 CK_RV
verify_mgr_init(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_MECHANISM * mech,CK_BBOOL recover_mode,CK_OBJECT_HANDLE key)31 verify_mgr_init(SESSION * sess,
32 SIGN_VERIFY_CONTEXT * ctx,
33 CK_MECHANISM * mech,
34 CK_BBOOL recover_mode,
35 CK_OBJECT_HANDLE key)
36 {
37 OBJECT * key_obj = NULL;
38 CK_ATTRIBUTE * attr = NULL;
39 CK_KEY_TYPE keytype;
40 CK_OBJECT_CLASS class;
41 CK_BBOOL flag;
42 CK_RV rc;
43
44
45 if (! sess || ! ctx) {
46 return (CKR_FUNCTION_FAILED);
47 }
48 if (ctx->active != FALSE) {
49 return (CKR_OPERATION_ACTIVE);
50 }
51
52 // key usage restrictions
53 //
54 rc = object_mgr_find_in_map1(sess->hContext, key, &key_obj);
55 if (rc != CKR_OK) {
56 return (CKR_KEY_HANDLE_INVALID);
57 }
58 // is key allowed to verify signatures?
59 //
60 rc = template_attribute_find(key_obj->template, CKA_VERIFY, &attr);
61 if (rc == FALSE) {
62 return (CKR_KEY_TYPE_INCONSISTENT);
63 } else {
64 flag = *(CK_BBOOL *)attr->pValue;
65 if (flag != TRUE) {
66 return (CKR_KEY_FUNCTION_NOT_PERMITTED);
67 }
68 }
69
70 switch (mech->mechanism) {
71 case CKM_RSA_PKCS:
72 {
73 rc = template_attribute_find(key_obj->template,
74 CKA_KEY_TYPE, &attr);
75 if (rc == FALSE) {
76 return (CKR_KEY_TYPE_INCONSISTENT);
77 } else {
78 keytype = *(CK_KEY_TYPE *)attr->pValue;
79 if (keytype != CKK_RSA) {
80 return (CKR_KEY_TYPE_INCONSISTENT);
81 }
82 }
83
84 flag = template_attribute_find(key_obj->template,
85 CKA_CLASS, &attr);
86 if (flag == FALSE) {
87 return (CKR_FUNCTION_FAILED);
88 }
89 else
90 class = *(CK_OBJECT_CLASS *)attr->pValue;
91
92 if (class != CKO_PUBLIC_KEY) {
93 return (CKR_FUNCTION_FAILED);
94 }
95 // PKCS #11 doesn't allow multi - part RSA operations
96 ctx->context_len = 0;
97 ctx->context = NULL;
98 }
99 break;
100
101 case CKM_MD5_RSA_PKCS:
102 case CKM_SHA1_RSA_PKCS:
103 {
104 rc = template_attribute_find(key_obj->template,
105 CKA_KEY_TYPE, &attr);
106 if (rc == FALSE) {
107 return (CKR_KEY_TYPE_INCONSISTENT);
108 } else {
109 keytype = *(CK_KEY_TYPE *)attr->pValue;
110 if (keytype != CKK_RSA) {
111 return (CKR_KEY_TYPE_INCONSISTENT);
112 }
113 }
114
115 flag = template_attribute_find(key_obj->template,
116 CKA_CLASS, &attr);
117 if (flag == FALSE) {
118 return (CKR_FUNCTION_FAILED);
119 }
120 else
121 class = *(CK_OBJECT_CLASS *)attr->pValue;
122
123 if (class != CKO_PUBLIC_KEY) {
124 return (CKR_FUNCTION_FAILED);
125 }
126 ctx->context_len = sizeof (RSA_DIGEST_CONTEXT);
127 ctx->context = (CK_BYTE *)malloc(
128 sizeof (RSA_DIGEST_CONTEXT));
129 if (! ctx->context) {
130 return (CKR_HOST_MEMORY);
131 }
132 (void) memset(ctx->context, 0x0,
133 sizeof (RSA_DIGEST_CONTEXT));
134 }
135 break;
136
137 case CKM_MD5_HMAC:
138 case CKM_SHA_1_HMAC:
139 {
140 rc = template_attribute_find(key_obj->template,
141 CKA_KEY_TYPE, &attr);
142 if (rc == FALSE) {
143 return (CKR_KEY_TYPE_INCONSISTENT);
144 } else {
145 keytype = *(CK_KEY_TYPE *)attr->pValue;
146 if (keytype != CKK_GENERIC_SECRET) {
147 return (CKR_KEY_TYPE_INCONSISTENT);
148 }
149 }
150
151 // PKCS #11 doesn't allow multi - part HMAC operations
152 ctx->context_len = 0;
153 ctx->context = NULL;
154 }
155 break;
156
157 case CKM_MD5_HMAC_GENERAL:
158 case CKM_SHA_1_HMAC_GENERAL:
159 {
160 CK_MAC_GENERAL_PARAMS *param =
161 (CK_MAC_GENERAL_PARAMS *)mech->pParameter;
162
163 if (mech->ulParameterLen !=
164 sizeof (CK_MAC_GENERAL_PARAMS)) {
165 return (CKR_MECHANISM_PARAM_INVALID);
166 }
167 if ((mech->mechanism == CKM_MD5_HMAC_GENERAL) &&
168 (*param > 16)) {
169 return (CKR_MECHANISM_PARAM_INVALID);
170 }
171 if ((mech->mechanism == CKM_SHA_1_HMAC_GENERAL) &&
172 (*param > 20)) {
173 return (CKR_MECHANISM_PARAM_INVALID);
174 }
175 rc = template_attribute_find(key_obj->template,
176 CKA_KEY_TYPE, &attr);
177 if (rc == FALSE) {
178 return (CKR_KEY_TYPE_INCONSISTENT);
179 } else {
180 keytype = *(CK_KEY_TYPE *)attr->pValue;
181 if (keytype != CKK_GENERIC_SECRET) {
182 return (CKR_KEY_TYPE_INCONSISTENT);
183 }
184 }
185
186 ctx->context_len = 0;
187 ctx->context = NULL;
188 }
189 break;
190
191 default:
192 return (CKR_MECHANISM_INVALID);
193 }
194
195
196 ctx->key = key;
197 ctx->mech.ulParameterLen = mech->ulParameterLen;
198 ctx->mech.mechanism = mech->mechanism;
199 ctx->mech.pParameter = mech->pParameter;
200 ctx->multi = FALSE;
201 ctx->active = TRUE;
202 ctx->recover = recover_mode;
203
204 return (CKR_OK);
205 }
206
207 CK_RV
verify_mgr_cleanup(SIGN_VERIFY_CONTEXT * ctx)208 verify_mgr_cleanup(SIGN_VERIFY_CONTEXT *ctx)
209 {
210 if (! ctx) {
211 return (CKR_FUNCTION_FAILED);
212 }
213 ctx->key = 0;
214 ctx->mech.ulParameterLen = 0;
215 ctx->mech.mechanism = 0;
216 ctx->multi = FALSE;
217 ctx->active = FALSE;
218 ctx->recover = FALSE;
219 ctx->context_len = 0;
220 ctx->mech.pParameter = NULL;
221
222 if (ctx->context) {
223 free(ctx->context);
224 ctx->context = NULL;
225 }
226
227 return (CKR_OK);
228 }
229
230 CK_RV
verify_mgr_verify(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * signature,CK_ULONG sig_len)231 verify_mgr_verify(SESSION * sess,
232 SIGN_VERIFY_CONTEXT * ctx,
233 CK_BYTE * in_data,
234 CK_ULONG in_data_len,
235 CK_BYTE * signature,
236 CK_ULONG sig_len)
237 {
238 if (! sess || ! ctx) {
239 return (CKR_FUNCTION_FAILED);
240 }
241 if (ctx->active == FALSE) {
242 return (CKR_OPERATION_NOT_INITIALIZED);
243 }
244 if (ctx->recover == TRUE) {
245 return (CKR_OPERATION_NOT_INITIALIZED);
246 }
247
248 if (! in_data || ! signature) {
249 return (CKR_FUNCTION_FAILED);
250 }
251 if (ctx->multi == TRUE) {
252 return (CKR_OPERATION_ACTIVE);
253 }
254
255 switch (ctx->mech.mechanism) {
256 case CKM_RSA_PKCS:
257 return (rsa_pkcs_verify(sess, ctx,
258 in_data, in_data_len,
259 signature, sig_len));
260 case CKM_MD5_RSA_PKCS:
261 case CKM_SHA1_RSA_PKCS:
262 return (rsa_hash_pkcs_verify(sess, ctx,
263 in_data, in_data_len,
264 signature, sig_len));
265
266 case CKM_MD5_HMAC:
267 case CKM_MD5_HMAC_GENERAL:
268 return (md5_hmac_verify(sess, ctx,
269 in_data, in_data_len,
270 signature, sig_len));
271 case CKM_SHA_1_HMAC:
272 case CKM_SHA_1_HMAC_GENERAL:
273 return (sha1_hmac_verify(sess, ctx,
274 in_data, in_data_len,
275 signature, sig_len));
276 default:
277 return (CKR_MECHANISM_INVALID);
278 }
279 }
280
281 CK_RV
verify_mgr_verify_update(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len)282 verify_mgr_verify_update(SESSION * sess,
283 SIGN_VERIFY_CONTEXT * ctx,
284 CK_BYTE * in_data,
285 CK_ULONG in_data_len)
286 {
287 if (! sess || ! ctx || ! in_data) {
288 return (CKR_FUNCTION_FAILED);
289 }
290 if (ctx->active == FALSE) {
291 return (CKR_OPERATION_NOT_INITIALIZED);
292 }
293 if (ctx->recover == TRUE) {
294 return (CKR_OPERATION_NOT_INITIALIZED);
295 }
296 ctx->multi = TRUE;
297
298
299 switch (ctx->mech.mechanism) {
300 case CKM_MD5_RSA_PKCS:
301 case CKM_SHA1_RSA_PKCS:
302 return (rsa_hash_pkcs_verify_update(sess, ctx,
303 in_data, in_data_len));
304 default:
305 return (CKR_MECHANISM_INVALID);
306 }
307 }
308
309 CK_RV
verify_mgr_verify_final(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * signature,CK_ULONG sig_len)310 verify_mgr_verify_final(SESSION * sess,
311 SIGN_VERIFY_CONTEXT * ctx,
312 CK_BYTE * signature,
313 CK_ULONG sig_len)
314 {
315 if (! sess || ! ctx) {
316 return (CKR_FUNCTION_FAILED);
317 }
318 if (ctx->active == FALSE) {
319 return (CKR_OPERATION_NOT_INITIALIZED);
320 }
321 if (ctx->recover == TRUE) {
322 return (CKR_OPERATION_NOT_INITIALIZED);
323 }
324 switch (ctx->mech.mechanism) {
325 case CKM_MD5_RSA_PKCS:
326 case CKM_SHA1_RSA_PKCS:
327 return (rsa_hash_pkcs_verify_final(sess, ctx,
328 signature, sig_len));
329 default:
330 return (CKR_MECHANISM_INVALID);
331 }
332 }
333
334 CK_RV
verify_mgr_verify_recover(SESSION * sess,CK_BBOOL length_only,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * signature,CK_ULONG sig_len,CK_BYTE * out_data,CK_ULONG * out_len)335 verify_mgr_verify_recover(SESSION * sess,
336 CK_BBOOL length_only,
337 SIGN_VERIFY_CONTEXT * ctx,
338 CK_BYTE * signature,
339 CK_ULONG sig_len,
340 CK_BYTE * out_data,
341 CK_ULONG * out_len)
342 {
343 if (! sess || ! ctx) {
344 return (CKR_FUNCTION_FAILED);
345 }
346 if (ctx->active == FALSE) {
347 return (CKR_OPERATION_NOT_INITIALIZED);
348 }
349 if (ctx->recover == FALSE) {
350 return (CKR_OPERATION_NOT_INITIALIZED);
351 }
352
353 if (! signature || ! out_len) {
354 return (CKR_FUNCTION_FAILED);
355 }
356 if (ctx->multi == TRUE) {
357 return (CKR_OPERATION_ACTIVE);
358 }
359
360 switch (ctx->mech.mechanism) {
361 case CKM_RSA_PKCS:
362 return (rsa_pkcs_verify_recover(sess, length_only,
363 ctx, signature, sig_len, out_data, out_len));
364 default:
365 return (CKR_MECHANISM_INVALID);
366 }
367 }
368