xref: /titanic_44/usr/src/lib/pkcs11/pkcs11_softtoken/common/softVerifyUtil.c (revision 8eea8e29cc4374d1ee24c25a07f45af132db3499)
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 2003 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 
69 		return (soft_hmac_sign_verify_init_common(session_p,
70 		    pMechanism, key_p, B_FALSE));
71 
72 	case CKM_RSA_X_509:
73 	case CKM_RSA_PKCS:
74 	case CKM_MD5_RSA_PKCS:
75 	case CKM_SHA1_RSA_PKCS:
76 
77 		return (soft_rsa_sign_verify_init_common(session_p, pMechanism,
78 		    key_p, B_FALSE));
79 
80 	case CKM_DSA:
81 	case CKM_DSA_SHA1:
82 
83 		return (soft_dsa_sign_verify_init_common(session_p, pMechanism,
84 		    key_p, B_FALSE));
85 
86 	case CKM_DES_MAC_GENERAL:
87 	case CKM_DES_MAC:
88 
89 		return (soft_des_sign_verify_init_common(session_p, pMechanism,
90 		    key_p, B_FALSE));
91 
92 	default:
93 		return (CKR_MECHANISM_INVALID);
94 	}
95 
96 }
97 
98 
99 /*
100  * soft_verify()
101  *
102  * Arguments:
103  *      session_p:	pointer to soft_session_t struct
104  *	pData:		pointer to the input data
105  *	ulDataLen:	length of the input data
106  *	pSignature:	pointer to the signature
107  *	ulSignatureLen:	length of the signature
108  *
109  * Description:
110  *      called by C_Verify(). This function calls the corresponding
111  *	verify routine based on the mechanism.
112  *
113  */
114 CK_RV
115 soft_verify(soft_session_t *session_p, CK_BYTE_PTR pData,
116     CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
117     CK_ULONG ulSignatureLen)
118 {
119 
120 	CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
121 	CK_RV rv = CKR_OK;
122 
123 	switch (mechanism) {
124 
125 	case CKM_SSL3_MD5_MAC:
126 	case CKM_SSL3_SHA1_MAC:
127 	case CKM_MD5_HMAC_GENERAL:
128 	case CKM_MD5_HMAC:
129 	case CKM_SHA_1_HMAC_GENERAL:
130 	case CKM_SHA_1_HMAC:
131 	{
132 		CK_ULONG len;
133 		CK_BYTE hmac[SHA1_HASH_SIZE]; /* use the maximum size */
134 		soft_hmac_ctx_t *hmac_ctx;
135 
136 		hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
137 		len = hmac_ctx->hmac_len;
138 
139 		rv = soft_hmac_sign_verify_common(session_p, pData,
140 		    ulDataLen, hmac, &len, B_FALSE);
141 
142 		if (rv == CKR_OK) {
143 			if (len != ulSignatureLen) {
144 				rv = CKR_SIGNATURE_LEN_RANGE;
145 			}
146 
147 			if (memcmp(hmac, pSignature, len) != 0) {
148 				rv = CKR_SIGNATURE_INVALID;
149 			}
150 		}
151 
152 		return (rv);
153 	}
154 	case CKM_DES_MAC_GENERAL:
155 	case CKM_DES_MAC:
156 	{
157 		CK_ULONG len;
158 		CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */
159 		soft_des_ctx_t *des_ctx;
160 
161 		des_ctx = (soft_des_ctx_t *)session_p->verify.context;
162 		len = des_ctx->mac_len;
163 
164 		/* Pass local buffer to avoid overflow. */
165 		rv = soft_des_sign_verify_common(session_p, pData,
166 		    ulDataLen, signature, &len, B_FALSE, B_FALSE);
167 
168 		if (rv == CKR_OK) {
169 			if (len != ulSignatureLen) {
170 				rv = CKR_SIGNATURE_LEN_RANGE;
171 			}
172 
173 			if (memcmp(signature, pSignature, len) != 0) {
174 				rv = CKR_SIGNATURE_INVALID;
175 			}
176 		}
177 
178 		return (rv);
179 	}
180 	case CKM_RSA_X_509:
181 	case CKM_RSA_PKCS:
182 
183 		return (soft_rsa_verify_common(session_p, pData, ulDataLen,
184 		    pSignature, ulSignatureLen, mechanism));
185 
186 	case CKM_MD5_RSA_PKCS:
187 	case CKM_SHA1_RSA_PKCS:
188 
189 		return (soft_rsa_digest_verify_common(session_p, pData,
190 		    ulDataLen, pSignature, ulSignatureLen, mechanism, B_FALSE));
191 
192 	case CKM_DSA:
193 
194 		return (soft_dsa_verify(session_p, pData, ulDataLen,
195 		    pSignature, ulSignatureLen));
196 
197 	case CKM_DSA_SHA1:
198 
199 		return (soft_dsa_digest_verify_common(session_p, pData,
200 		    ulDataLen, pSignature, ulSignatureLen, B_FALSE));
201 
202 	default:
203 		return (CKR_MECHANISM_INVALID);
204 	}
205 }
206 
207 
208 /*
209  * soft_verify_update()
210  *
211  * Arguments:
212  *      session_p:	pointer to soft_session_t struct
213  *      pPart:		pointer to the input data
214  *      ulPartLen:	length of the input data
215  *
216  * Description:
217  *      called by C_VerifyUpdate(). This function calls the corresponding
218  *	verify update routine based on the mechanism.
219  *
220  */
221 CK_RV
222 soft_verify_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
223     CK_ULONG ulPartLen)
224 {
225 	CK_MECHANISM_TYPE	mechanism = session_p->verify.mech.mechanism;
226 
227 	switch (mechanism) {
228 
229 	case CKM_SSL3_MD5_MAC:
230 	case CKM_SSL3_SHA1_MAC:
231 	case CKM_MD5_HMAC_GENERAL:
232 	case CKM_MD5_HMAC:
233 	case CKM_SHA_1_HMAC_GENERAL:
234 	case CKM_SHA_1_HMAC:
235 
236 		return (soft_hmac_sign_verify_update(session_p, pPart,
237 		    ulPartLen, B_FALSE));
238 
239 	case CKM_DES_MAC_GENERAL:
240 	case CKM_DES_MAC:
241 
242 		return (soft_des_mac_sign_verify_update(session_p, pPart,
243 			ulPartLen));
244 
245 	case CKM_MD5_RSA_PKCS:
246 	case CKM_SHA1_RSA_PKCS:
247 		/*
248 		 * The MD5/SHA1 digest value is accumulated in the context
249 		 * of the multiple-part digesting operation. In the final
250 		 * operation, the digest is encoded and then perform RSA
251 		 * verification.
252 		 */
253 	case CKM_DSA_SHA1:
254 
255 		return (soft_digest_update(session_p, pPart, ulPartLen));
256 
257 	default:
258 		/* PKCS11: The mechanism only supports single-part operation. */
259 		return (CKR_MECHANISM_INVALID);
260 	}
261 }
262 
263 
264 /*
265  * soft_verify_final()
266  *
267  * Arguments:
268  *      session_p:	pointer to soft_session_t struct
269  *      pSignature:	pointer to the signature
270  *      ulSignatureLen:	length of the signature
271  *
272  * Description:
273  *      called by C_VerifyFinal().  This function calls the corresponding
274  *	verify final routine based on the mechanism.
275  *
276  */
277 CK_RV
278 soft_verify_final(soft_session_t *session_p, CK_BYTE_PTR pSignature,
279     CK_ULONG ulSignatureLen)
280 {
281 
282 	CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
283 	CK_RV rv = CKR_OK;
284 
285 	switch (mechanism) {
286 
287 	case CKM_SSL3_MD5_MAC:
288 	case CKM_SSL3_SHA1_MAC:
289 	case CKM_MD5_HMAC_GENERAL:
290 	case CKM_MD5_HMAC:
291 	case CKM_SHA_1_HMAC_GENERAL:
292 	case CKM_SHA_1_HMAC:
293 	{
294 		CK_ULONG len;
295 		CK_BYTE hmac[SHA1_HASH_SIZE];
296 		soft_hmac_ctx_t *hmac_ctx;
297 
298 		hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context;
299 		len = hmac_ctx->hmac_len;
300 
301 		rv = soft_hmac_sign_verify_common(session_p, NULL, 0,
302 		    hmac, &len, B_FALSE);
303 
304 		if (rv == CKR_OK) {
305 			if (len != ulSignatureLen) {
306 				rv = CKR_SIGNATURE_LEN_RANGE;
307 			}
308 
309 			if (memcmp(hmac, pSignature, len) != 0) {
310 				rv = CKR_SIGNATURE_INVALID;
311 			}
312 		}
313 
314 		return (rv);
315 	}
316 	case CKM_DES_MAC_GENERAL:
317 	case CKM_DES_MAC:
318 	{
319 		CK_ULONG len;
320 		CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */
321 		soft_des_ctx_t *des_ctx;
322 
323 		des_ctx = (soft_des_ctx_t *)session_p->verify.context;
324 		len = des_ctx->mac_len;
325 
326 		/* Pass local buffer to avoid overflow. */
327 		rv = soft_des_sign_verify_common(session_p, NULL, 0,
328 			signature, &len, B_FALSE, B_TRUE);
329 
330 		if (rv == CKR_OK) {
331 			if (len != ulSignatureLen) {
332 				rv = CKR_SIGNATURE_LEN_RANGE;
333 			}
334 
335 			if (memcmp(signature, pSignature, len) != 0) {
336 				rv = CKR_SIGNATURE_INVALID;
337 			}
338 		}
339 
340 		return (rv);
341 	}
342 	case CKM_MD5_RSA_PKCS:
343 	case CKM_SHA1_RSA_PKCS:
344 
345 		return (soft_rsa_digest_verify_common(session_p, NULL, 0,
346 		    pSignature, ulSignatureLen, mechanism, B_TRUE));
347 
348 	case CKM_DSA_SHA1:
349 
350 		return (soft_dsa_digest_verify_common(session_p, NULL, 0,
351 		    pSignature, ulSignatureLen, B_TRUE));
352 
353 	default:
354 		/* PKCS11: The mechanism only supports single-part operation. */
355 		return (CKR_MECHANISM_INVALID);
356 
357 	}
358 }
359 
360 
361 CK_RV
362 soft_verify_recover_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
363     soft_object_t *key_p)
364 {
365 
366 	switch (pMechanism->mechanism) {
367 
368 	case CKM_RSA_X_509:
369 	case CKM_RSA_PKCS:
370 
371 		return (soft_rsa_sign_verify_init_common(session_p, pMechanism,
372 		    key_p, B_FALSE));
373 
374 	default:
375 		return (CKR_MECHANISM_INVALID);
376 	}
377 }
378 
379 
380 CK_RV
381 soft_verify_recover(soft_session_t *session_p, CK_BYTE_PTR pSignature,
382     CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
383 {
384 
385 	CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
386 
387 	switch (mechanism) {
388 
389 	case CKM_RSA_X_509:
390 	case CKM_RSA_PKCS:
391 
392 		return (soft_rsa_verify_recover(session_p, pSignature,
393 		    ulSignatureLen, pData, pulDataLen));
394 
395 	default:
396 		return (CKR_MECHANISM_INVALID);
397 	}
398 }
399