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 */
55CK_RV
56soft_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 */
135CK_RV
136soft_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 */
287CK_RV
288soft_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 */
359CK_RV
360soft_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
483CK_RV
484soft_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
502CK_RV
503soft_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