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