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