xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_softtoken/common/softVerifyUtil.c (revision 445f2479fe3d7435daab18bf2cdc310b86cd6738)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <stdlib.h>
30 #include <string.h>
31 #include <strings.h>
32 #include <sys/types.h>
33 #include <security/cryptoki.h>
34 #include "softObject.h"
35 #include "softOps.h"
36 #include "softSession.h"
37 #include "softMAC.h"
38 #include "softRSA.h"
39 #include "softDSA.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_DES_MAC_GENERAL:
96 	case CKM_DES_MAC:
97 
98 		return (soft_des_sign_verify_init_common(session_p, pMechanism,
99 		    key_p, B_FALSE));
100 
101 	default:
102 		return (CKR_MECHANISM_INVALID);
103 	}
104 
105 }
106 
107 
108 /*
109  * soft_verify()
110  *
111  * Arguments:
112  *      session_p:	pointer to soft_session_t struct
113  *	pData:		pointer to the input data
114  *	ulDataLen:	length of the input data
115  *	pSignature:	pointer to the signature
116  *	ulSignatureLen:	length of the signature
117  *
118  * Description:
119  *      called by C_Verify(). This function calls the corresponding
120  *	verify routine based on the mechanism.
121  *
122  */
123 CK_RV
124 soft_verify(soft_session_t *session_p, CK_BYTE_PTR pData,
125     CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
126     CK_ULONG ulSignatureLen)
127 {
128 
129 	CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
130 	CK_RV rv = CKR_OK;
131 
132 	switch (mechanism) {
133 
134 	case CKM_SSL3_MD5_MAC:
135 	case CKM_SSL3_SHA1_MAC:
136 	case CKM_MD5_HMAC_GENERAL:
137 	case CKM_MD5_HMAC:
138 	case CKM_SHA_1_HMAC_GENERAL:
139 	case CKM_SHA_1_HMAC:
140 	case CKM_SHA256_HMAC_GENERAL:
141 	case CKM_SHA256_HMAC:
142 	case CKM_SHA384_HMAC_GENERAL:
143 	case CKM_SHA384_HMAC:
144 	case CKM_SHA512_HMAC_GENERAL:
145 	case CKM_SHA512_HMAC:
146 	{
147 		CK_ULONG len;
148 		CK_BYTE hmac[SHA512_DIGEST_LENGTH]; /* use the maximum size */
149 		soft_hmac_ctx_t *hmac_ctx;
150 
151 		hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
152 		len = hmac_ctx->hmac_len;
153 
154 		rv = soft_hmac_sign_verify_common(session_p, pData,
155 		    ulDataLen, hmac, &len, B_FALSE);
156 
157 		if (rv == CKR_OK) {
158 			if (len != ulSignatureLen) {
159 				rv = CKR_SIGNATURE_LEN_RANGE;
160 			}
161 
162 			if (memcmp(hmac, pSignature, len) != 0) {
163 				rv = CKR_SIGNATURE_INVALID;
164 			}
165 		}
166 
167 		return (rv);
168 	}
169 	case CKM_DES_MAC_GENERAL:
170 	case CKM_DES_MAC:
171 	{
172 		CK_ULONG len;
173 		CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */
174 		soft_des_ctx_t *des_ctx;
175 
176 		des_ctx = (soft_des_ctx_t *)session_p->verify.context;
177 		len = des_ctx->mac_len;
178 
179 		/* Pass local buffer to avoid overflow. */
180 		rv = soft_des_sign_verify_common(session_p, pData,
181 		    ulDataLen, signature, &len, B_FALSE, B_FALSE);
182 
183 		if (rv == CKR_OK) {
184 			if (len != ulSignatureLen) {
185 				rv = CKR_SIGNATURE_LEN_RANGE;
186 			}
187 
188 			if (memcmp(signature, pSignature, len) != 0) {
189 				rv = CKR_SIGNATURE_INVALID;
190 			}
191 		}
192 
193 		return (rv);
194 	}
195 	case CKM_RSA_X_509:
196 	case CKM_RSA_PKCS:
197 
198 		return (soft_rsa_verify_common(session_p, pData, ulDataLen,
199 		    pSignature, ulSignatureLen, mechanism));
200 
201 	case CKM_MD5_RSA_PKCS:
202 	case CKM_SHA1_RSA_PKCS:
203 	case CKM_SHA256_RSA_PKCS:
204 	case CKM_SHA384_RSA_PKCS:
205 	case CKM_SHA512_RSA_PKCS:
206 
207 		return (soft_rsa_digest_verify_common(session_p, pData,
208 		    ulDataLen, pSignature, ulSignatureLen, mechanism, B_FALSE));
209 
210 	case CKM_DSA:
211 
212 		return (soft_dsa_verify(session_p, pData, ulDataLen,
213 		    pSignature, ulSignatureLen));
214 
215 	case CKM_DSA_SHA1:
216 
217 		return (soft_dsa_digest_verify_common(session_p, pData,
218 		    ulDataLen, pSignature, ulSignatureLen, B_FALSE));
219 
220 	default:
221 		return (CKR_MECHANISM_INVALID);
222 	}
223 }
224 
225 
226 /*
227  * soft_verify_update()
228  *
229  * Arguments:
230  *      session_p:	pointer to soft_session_t struct
231  *      pPart:		pointer to the input data
232  *      ulPartLen:	length of the input data
233  *
234  * Description:
235  *      called by C_VerifyUpdate(). This function calls the corresponding
236  *	verify update routine based on the mechanism.
237  *
238  */
239 CK_RV
240 soft_verify_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
241     CK_ULONG ulPartLen)
242 {
243 	CK_MECHANISM_TYPE	mechanism = session_p->verify.mech.mechanism;
244 
245 	switch (mechanism) {
246 
247 	case CKM_SSL3_MD5_MAC:
248 	case CKM_SSL3_SHA1_MAC:
249 	case CKM_MD5_HMAC_GENERAL:
250 	case CKM_MD5_HMAC:
251 	case CKM_SHA_1_HMAC_GENERAL:
252 	case CKM_SHA_1_HMAC:
253 	case CKM_SHA256_HMAC_GENERAL:
254 	case CKM_SHA256_HMAC:
255 	case CKM_SHA384_HMAC_GENERAL:
256 	case CKM_SHA384_HMAC:
257 	case CKM_SHA512_HMAC_GENERAL:
258 	case CKM_SHA512_HMAC:
259 
260 		return (soft_hmac_sign_verify_update(session_p, pPart,
261 		    ulPartLen, B_FALSE));
262 
263 	case CKM_DES_MAC_GENERAL:
264 	case CKM_DES_MAC:
265 
266 		return (soft_des_mac_sign_verify_update(session_p, pPart,
267 			ulPartLen));
268 
269 	case CKM_MD5_RSA_PKCS:
270 	case CKM_SHA1_RSA_PKCS:
271 	case CKM_SHA256_RSA_PKCS:
272 	case CKM_SHA384_RSA_PKCS:
273 	case CKM_SHA512_RSA_PKCS:
274 		/*
275 		 * The MD5/SHA1 digest value is accumulated in the context
276 		 * of the multiple-part digesting operation. In the final
277 		 * operation, the digest is encoded and then perform RSA
278 		 * verification.
279 		 */
280 	case CKM_DSA_SHA1:
281 
282 		return (soft_digest_update(session_p, pPart, ulPartLen));
283 
284 	default:
285 		/* PKCS11: The mechanism only supports single-part operation. */
286 		return (CKR_MECHANISM_INVALID);
287 	}
288 }
289 
290 
291 /*
292  * soft_verify_final()
293  *
294  * Arguments:
295  *      session_p:	pointer to soft_session_t struct
296  *      pSignature:	pointer to the signature
297  *      ulSignatureLen:	length of the signature
298  *
299  * Description:
300  *      called by C_VerifyFinal().  This function calls the corresponding
301  *	verify final routine based on the mechanism.
302  *
303  */
304 CK_RV
305 soft_verify_final(soft_session_t *session_p, CK_BYTE_PTR pSignature,
306     CK_ULONG ulSignatureLen)
307 {
308 
309 	CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
310 	CK_RV rv = CKR_OK;
311 
312 	switch (mechanism) {
313 
314 	case CKM_SSL3_MD5_MAC:
315 	case CKM_SSL3_SHA1_MAC:
316 	case CKM_MD5_HMAC_GENERAL:
317 	case CKM_MD5_HMAC:
318 	case CKM_SHA_1_HMAC_GENERAL:
319 	case CKM_SHA_1_HMAC:
320 	case CKM_SHA256_HMAC_GENERAL:
321 	case CKM_SHA256_HMAC:
322 	case CKM_SHA384_HMAC_GENERAL:
323 	case CKM_SHA384_HMAC:
324 	case CKM_SHA512_HMAC_GENERAL:
325 	case CKM_SHA512_HMAC:
326 	{
327 		CK_ULONG len;
328 		CK_BYTE hmac[SHA512_DIGEST_LENGTH];
329 		soft_hmac_ctx_t *hmac_ctx;
330 
331 		hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
332 		len = hmac_ctx->hmac_len;
333 
334 		rv = soft_hmac_sign_verify_common(session_p, NULL, 0,
335 		    hmac, &len, B_FALSE);
336 
337 		if (rv == CKR_OK) {
338 			if (len != ulSignatureLen) {
339 				rv = CKR_SIGNATURE_LEN_RANGE;
340 			}
341 
342 			if (memcmp(hmac, pSignature, len) != 0) {
343 				rv = CKR_SIGNATURE_INVALID;
344 			}
345 		}
346 
347 		return (rv);
348 	}
349 	case CKM_DES_MAC_GENERAL:
350 	case CKM_DES_MAC:
351 	{
352 		CK_ULONG len;
353 		CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */
354 		soft_des_ctx_t *des_ctx;
355 
356 		des_ctx = (soft_des_ctx_t *)session_p->verify.context;
357 		len = des_ctx->mac_len;
358 
359 		/* Pass local buffer to avoid overflow. */
360 		rv = soft_des_sign_verify_common(session_p, NULL, 0,
361 			signature, &len, B_FALSE, B_TRUE);
362 
363 		if (rv == CKR_OK) {
364 			if (len != ulSignatureLen) {
365 				rv = CKR_SIGNATURE_LEN_RANGE;
366 			}
367 
368 			if (memcmp(signature, pSignature, len) != 0) {
369 				rv = CKR_SIGNATURE_INVALID;
370 			}
371 		}
372 
373 		return (rv);
374 	}
375 	case CKM_MD5_RSA_PKCS:
376 	case CKM_SHA1_RSA_PKCS:
377 	case CKM_SHA256_RSA_PKCS:
378 	case CKM_SHA384_RSA_PKCS:
379 	case CKM_SHA512_RSA_PKCS:
380 
381 		return (soft_rsa_digest_verify_common(session_p, NULL, 0,
382 		    pSignature, ulSignatureLen, mechanism, B_TRUE));
383 
384 	case CKM_DSA_SHA1:
385 
386 		return (soft_dsa_digest_verify_common(session_p, NULL, 0,
387 		    pSignature, ulSignatureLen, B_TRUE));
388 
389 	default:
390 		/* PKCS11: The mechanism only supports single-part operation. */
391 		return (CKR_MECHANISM_INVALID);
392 
393 	}
394 }
395 
396 
397 CK_RV
398 soft_verify_recover_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
399     soft_object_t *key_p)
400 {
401 
402 	switch (pMechanism->mechanism) {
403 
404 	case CKM_RSA_X_509:
405 	case CKM_RSA_PKCS:
406 
407 		return (soft_rsa_sign_verify_init_common(session_p, pMechanism,
408 		    key_p, B_FALSE));
409 
410 	default:
411 		return (CKR_MECHANISM_INVALID);
412 	}
413 }
414 
415 
416 CK_RV
417 soft_verify_recover(soft_session_t *session_p, CK_BYTE_PTR pSignature,
418     CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
419 {
420 
421 	CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
422 
423 	switch (mechanism) {
424 
425 	case CKM_RSA_X_509:
426 	case CKM_RSA_PKCS:
427 
428 		return (soft_rsa_verify_recover(session_p, pSignature,
429 		    ulSignatureLen, pData, pulDataLen));
430 
431 	default:
432 		return (CKR_MECHANISM_INVALID);
433 	}
434 }
435