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 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <sys/types.h>
32 #include <security/cryptoki.h>
33 #include "softObject.h"
34 #include "softOps.h"
35 #include "softSession.h"
36 #include "softMAC.h"
37 #include "softRSA.h"
38 #include "softDSA.h"
39 #include "softEC.h"
40 #include "softCrypt.h"
41
42 /*
43 * soft_verify_init()
44 *
45 * Arguments:
46 * session_p: pointer to soft_session_t struct
47 * pMechanism: pointer to CK_MECHANISM struct provided by application
48 * key_p: pointer to key soft_object_t struct
49 *
50 * Description:
51 * called by C_VerifyInit(). This function calls the corresponding
52 * verify init routine based on the mechanism.
53 *
54 */
55 CK_RV
soft_verify_init(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)56 soft_verify_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
57 soft_object_t *key_p)
58 {
59
60 switch (pMechanism->mechanism) {
61
62 case CKM_SSL3_MD5_MAC:
63 case CKM_SSL3_SHA1_MAC:
64 case CKM_MD5_HMAC_GENERAL:
65 case CKM_MD5_HMAC:
66 case CKM_SHA_1_HMAC_GENERAL:
67 case CKM_SHA_1_HMAC:
68 case CKM_SHA256_HMAC_GENERAL:
69 case CKM_SHA256_HMAC:
70 case CKM_SHA384_HMAC_GENERAL:
71 case CKM_SHA384_HMAC:
72 case CKM_SHA512_HMAC_GENERAL:
73 case CKM_SHA512_HMAC:
74
75 return (soft_hmac_sign_verify_init_common(session_p,
76 pMechanism, key_p, B_FALSE));
77
78 case CKM_RSA_X_509:
79 case CKM_RSA_PKCS:
80 case CKM_MD5_RSA_PKCS:
81 case CKM_SHA1_RSA_PKCS:
82 case CKM_SHA256_RSA_PKCS:
83 case CKM_SHA384_RSA_PKCS:
84 case CKM_SHA512_RSA_PKCS:
85
86 return (soft_rsa_sign_verify_init_common(session_p, pMechanism,
87 key_p, B_FALSE));
88
89 case CKM_DSA:
90 case CKM_DSA_SHA1:
91
92 return (soft_dsa_sign_verify_init_common(session_p, pMechanism,
93 key_p, B_FALSE));
94
95 case CKM_ECDSA:
96 case CKM_ECDSA_SHA1:
97
98 return (soft_ecc_sign_verify_init_common(session_p, pMechanism,
99 key_p, B_FALSE));
100
101 case CKM_DES_MAC_GENERAL:
102 case CKM_DES_MAC:
103
104 return (soft_des_sign_verify_init_common(session_p, pMechanism,
105 key_p, B_FALSE));
106
107 default:
108 return (CKR_MECHANISM_INVALID);
109 }
110
111 }
112
113
114 /*
115 * soft_verify()
116 *
117 * Arguments:
118 * session_p: pointer to soft_session_t struct
119 * pData: pointer to the input data
120 * ulDataLen: length of the input data
121 * pSignature: pointer to the signature
122 * ulSignatureLen: length of the signature
123 *
124 * Description:
125 * called by C_Verify(). This function calls the corresponding
126 * verify routine based on the mechanism.
127 *
128 */
129 CK_RV
soft_verify(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)130 soft_verify(soft_session_t *session_p, CK_BYTE_PTR pData,
131 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
132 CK_ULONG ulSignatureLen)
133 {
134
135 CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
136 CK_RV rv = CKR_OK;
137
138 switch (mechanism) {
139
140 case CKM_SSL3_MD5_MAC:
141 case CKM_SSL3_SHA1_MAC:
142 case CKM_MD5_HMAC_GENERAL:
143 case CKM_MD5_HMAC:
144 case CKM_SHA_1_HMAC_GENERAL:
145 case CKM_SHA_1_HMAC:
146 case CKM_SHA256_HMAC_GENERAL:
147 case CKM_SHA256_HMAC:
148 case CKM_SHA384_HMAC_GENERAL:
149 case CKM_SHA384_HMAC:
150 case CKM_SHA512_HMAC_GENERAL:
151 case CKM_SHA512_HMAC:
152 {
153 CK_ULONG len;
154 CK_BYTE hmac[SHA512_DIGEST_LENGTH]; /* use the maximum size */
155 soft_hmac_ctx_t *hmac_ctx;
156
157 hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
158 len = hmac_ctx->hmac_len;
159
160 rv = soft_hmac_sign_verify_common(session_p, pData,
161 ulDataLen, hmac, &len, B_FALSE);
162
163 if (rv == CKR_OK) {
164 if (len != ulSignatureLen) {
165 rv = CKR_SIGNATURE_LEN_RANGE;
166 }
167
168 if (memcmp(hmac, pSignature, len) != 0) {
169 rv = CKR_SIGNATURE_INVALID;
170 }
171 }
172
173 return (rv);
174 }
175 case CKM_DES_MAC_GENERAL:
176 case CKM_DES_MAC:
177 {
178 CK_ULONG len;
179 CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */
180 soft_des_ctx_t *des_ctx;
181
182 des_ctx = (soft_des_ctx_t *)session_p->verify.context;
183 len = des_ctx->mac_len;
184
185 /* Pass local buffer to avoid overflow. */
186 rv = soft_des_sign_verify_common(session_p, pData,
187 ulDataLen, signature, &len, B_FALSE, B_FALSE);
188
189 if (rv == CKR_OK) {
190 if (len != ulSignatureLen) {
191 rv = CKR_SIGNATURE_LEN_RANGE;
192 }
193
194 if (memcmp(signature, pSignature, len) != 0) {
195 rv = CKR_SIGNATURE_INVALID;
196 }
197 }
198
199 return (rv);
200 }
201 case CKM_RSA_X_509:
202 case CKM_RSA_PKCS:
203
204 return (soft_rsa_verify_common(session_p, pData, ulDataLen,
205 pSignature, ulSignatureLen, mechanism));
206
207 case CKM_MD5_RSA_PKCS:
208 case CKM_SHA1_RSA_PKCS:
209 case CKM_SHA256_RSA_PKCS:
210 case CKM_SHA384_RSA_PKCS:
211 case CKM_SHA512_RSA_PKCS:
212
213 return (soft_rsa_digest_verify_common(session_p, pData,
214 ulDataLen, pSignature, ulSignatureLen, mechanism, B_FALSE));
215
216 case CKM_DSA:
217
218 return (soft_dsa_verify(session_p, pData, ulDataLen,
219 pSignature, ulSignatureLen));
220
221 case CKM_DSA_SHA1:
222
223 return (soft_dsa_digest_verify_common(session_p, pData,
224 ulDataLen, pSignature, ulSignatureLen, B_FALSE));
225
226 case CKM_ECDSA:
227
228 return (soft_ecc_verify(session_p, pData, ulDataLen,
229 pSignature, ulSignatureLen));
230
231 case CKM_ECDSA_SHA1:
232
233 return (soft_ecc_digest_verify_common(session_p, pData,
234 ulDataLen, pSignature, ulSignatureLen, B_FALSE));
235
236 default:
237 return (CKR_MECHANISM_INVALID);
238 }
239 }
240
241
242 /*
243 * soft_verify_update()
244 *
245 * Arguments:
246 * session_p: pointer to soft_session_t struct
247 * pPart: pointer to the input data
248 * ulPartLen: length of the input data
249 *
250 * Description:
251 * called by C_VerifyUpdate(). This function calls the corresponding
252 * verify update routine based on the mechanism.
253 *
254 */
255 CK_RV
soft_verify_update(soft_session_t * session_p,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)256 soft_verify_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
257 CK_ULONG ulPartLen)
258 {
259 CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
260
261 switch (mechanism) {
262
263 case CKM_SSL3_MD5_MAC:
264 case CKM_SSL3_SHA1_MAC:
265 case CKM_MD5_HMAC_GENERAL:
266 case CKM_MD5_HMAC:
267 case CKM_SHA_1_HMAC_GENERAL:
268 case CKM_SHA_1_HMAC:
269 case CKM_SHA256_HMAC_GENERAL:
270 case CKM_SHA256_HMAC:
271 case CKM_SHA384_HMAC_GENERAL:
272 case CKM_SHA384_HMAC:
273 case CKM_SHA512_HMAC_GENERAL:
274 case CKM_SHA512_HMAC:
275
276 return (soft_hmac_sign_verify_update(session_p, pPart,
277 ulPartLen, B_FALSE));
278
279 case CKM_DES_MAC_GENERAL:
280 case CKM_DES_MAC:
281
282 return (soft_des_mac_sign_verify_update(session_p, pPart,
283 ulPartLen));
284
285 case CKM_MD5_RSA_PKCS:
286 case CKM_SHA1_RSA_PKCS:
287 case CKM_SHA256_RSA_PKCS:
288 case CKM_SHA384_RSA_PKCS:
289 case CKM_SHA512_RSA_PKCS:
290 /*
291 * The MD5/SHA1 digest value is accumulated in the context
292 * of the multiple-part digesting operation. In the final
293 * operation, the digest is encoded and then perform RSA
294 * verification.
295 */
296 case CKM_DSA_SHA1:
297 case CKM_ECDSA_SHA1:
298
299 return (soft_digest_update(session_p, pPart, ulPartLen));
300
301 default:
302 /* PKCS11: The mechanism only supports single-part operation. */
303 return (CKR_MECHANISM_INVALID);
304 }
305 }
306
307
308 /*
309 * soft_verify_final()
310 *
311 * Arguments:
312 * session_p: pointer to soft_session_t struct
313 * pSignature: pointer to the signature
314 * ulSignatureLen: length of the signature
315 *
316 * Description:
317 * called by C_VerifyFinal(). This function calls the corresponding
318 * verify final routine based on the mechanism.
319 *
320 */
321 CK_RV
soft_verify_final(soft_session_t * session_p,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)322 soft_verify_final(soft_session_t *session_p, CK_BYTE_PTR pSignature,
323 CK_ULONG ulSignatureLen)
324 {
325
326 CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
327 CK_RV rv = CKR_OK;
328
329 switch (mechanism) {
330
331 case CKM_SSL3_MD5_MAC:
332 case CKM_SSL3_SHA1_MAC:
333 case CKM_MD5_HMAC_GENERAL:
334 case CKM_MD5_HMAC:
335 case CKM_SHA_1_HMAC_GENERAL:
336 case CKM_SHA_1_HMAC:
337 case CKM_SHA256_HMAC_GENERAL:
338 case CKM_SHA256_HMAC:
339 case CKM_SHA384_HMAC_GENERAL:
340 case CKM_SHA384_HMAC:
341 case CKM_SHA512_HMAC_GENERAL:
342 case CKM_SHA512_HMAC:
343 {
344 CK_ULONG len;
345 CK_BYTE hmac[SHA512_DIGEST_LENGTH];
346 soft_hmac_ctx_t *hmac_ctx;
347
348 hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
349 len = hmac_ctx->hmac_len;
350
351 rv = soft_hmac_sign_verify_common(session_p, NULL, 0,
352 hmac, &len, B_FALSE);
353
354 if (rv == CKR_OK) {
355 if (len != ulSignatureLen) {
356 rv = CKR_SIGNATURE_LEN_RANGE;
357 }
358
359 if (memcmp(hmac, pSignature, len) != 0) {
360 rv = CKR_SIGNATURE_INVALID;
361 }
362 }
363
364 return (rv);
365 }
366 case CKM_DES_MAC_GENERAL:
367 case CKM_DES_MAC:
368 {
369 CK_ULONG len;
370 CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */
371 soft_des_ctx_t *des_ctx;
372
373 des_ctx = (soft_des_ctx_t *)session_p->verify.context;
374 len = des_ctx->mac_len;
375
376 /* Pass local buffer to avoid overflow. */
377 rv = soft_des_sign_verify_common(session_p, NULL, 0,
378 signature, &len, B_FALSE, B_TRUE);
379
380 if (rv == CKR_OK) {
381 if (len != ulSignatureLen) {
382 rv = CKR_SIGNATURE_LEN_RANGE;
383 }
384
385 if (memcmp(signature, pSignature, len) != 0) {
386 rv = CKR_SIGNATURE_INVALID;
387 }
388 }
389
390 return (rv);
391 }
392 case CKM_MD5_RSA_PKCS:
393 case CKM_SHA1_RSA_PKCS:
394 case CKM_SHA256_RSA_PKCS:
395 case CKM_SHA384_RSA_PKCS:
396 case CKM_SHA512_RSA_PKCS:
397
398 return (soft_rsa_digest_verify_common(session_p, NULL, 0,
399 pSignature, ulSignatureLen, mechanism, B_TRUE));
400
401 case CKM_DSA_SHA1:
402
403 return (soft_dsa_digest_verify_common(session_p, NULL, 0,
404 pSignature, ulSignatureLen, B_TRUE));
405
406 case CKM_ECDSA_SHA1:
407
408 return (soft_ecc_digest_verify_common(session_p, NULL, 0,
409 pSignature, ulSignatureLen, B_TRUE));
410
411 default:
412 /* PKCS11: The mechanism only supports single-part operation. */
413 return (CKR_MECHANISM_INVALID);
414
415 }
416 }
417
418
419 CK_RV
soft_verify_recover_init(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)420 soft_verify_recover_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
421 soft_object_t *key_p)
422 {
423
424 switch (pMechanism->mechanism) {
425
426 case CKM_RSA_X_509:
427 case CKM_RSA_PKCS:
428
429 return (soft_rsa_sign_verify_init_common(session_p, pMechanism,
430 key_p, B_FALSE));
431
432 default:
433 return (CKR_MECHANISM_INVALID);
434 }
435 }
436
437
438 CK_RV
soft_verify_recover(soft_session_t * session_p,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)439 soft_verify_recover(soft_session_t *session_p, CK_BYTE_PTR pSignature,
440 CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
441 {
442
443 CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
444
445 switch (mechanism) {
446
447 case CKM_RSA_X_509:
448 case CKM_RSA_PKCS:
449
450 return (soft_rsa_verify_recover(session_p, pSignature,
451 ulSignatureLen, pData, pulDataLen));
452
453 default:
454 return (CKR_MECHANISM_INVALID);
455 }
456 }
457