147e946e7SWyllys Ingersoll /*
247e946e7SWyllys Ingersoll  * The Initial Developer of the Original Code is International
347e946e7SWyllys Ingersoll  * Business Machines Corporation. Portions created by IBM
447e946e7SWyllys Ingersoll  * Corporation are Copyright (C) 2005 International Business
547e946e7SWyllys Ingersoll  * Machines Corporation. All Rights Reserved.
647e946e7SWyllys Ingersoll  *
747e946e7SWyllys Ingersoll  * This program is free software; you can redistribute it and/or modify
847e946e7SWyllys Ingersoll  * it under the terms of the Common Public License as published by
947e946e7SWyllys Ingersoll  * IBM Corporation; either version 1 of the License, or (at your option)
1047e946e7SWyllys Ingersoll  * any later version.
1147e946e7SWyllys Ingersoll  *
1247e946e7SWyllys Ingersoll  * This program is distributed in the hope that it will be useful,
1347e946e7SWyllys Ingersoll  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1447e946e7SWyllys Ingersoll  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1547e946e7SWyllys Ingersoll  * Common Public License for more details.
1647e946e7SWyllys Ingersoll  *
1747e946e7SWyllys Ingersoll  * You should have received a copy of the Common Public License
1847e946e7SWyllys Ingersoll  * along with this program; if not, a copy can be viewed at
1947e946e7SWyllys Ingersoll  * http://www.opensource.org/licenses/cpl1.0.php.
2047e946e7SWyllys Ingersoll  */
2147e946e7SWyllys Ingersoll 
2247e946e7SWyllys Ingersoll /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */
2347e946e7SWyllys Ingersoll /*
2447e946e7SWyllys Ingersoll  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2547e946e7SWyllys Ingersoll  * Use is subject to license terms.
2647e946e7SWyllys Ingersoll  */
2747e946e7SWyllys Ingersoll 
2847e946e7SWyllys Ingersoll #include "tpmtok_int.h"
2947e946e7SWyllys Ingersoll 
3047e946e7SWyllys Ingersoll CK_RV
sign_mgr_init(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_MECHANISM * mech,CK_BBOOL recover_mode,CK_OBJECT_HANDLE key)3147e946e7SWyllys Ingersoll sign_mgr_init(SESSION		* sess,
3247e946e7SWyllys Ingersoll 	SIGN_VERIFY_CONTEXT    * ctx,
3347e946e7SWyllys Ingersoll 	CK_MECHANISM	   * mech,
3447e946e7SWyllys Ingersoll 	CK_BBOOL		 recover_mode,
3547e946e7SWyllys Ingersoll 	CK_OBJECT_HANDLE	 key)
3647e946e7SWyllys Ingersoll {
3747e946e7SWyllys Ingersoll 	OBJECT	  * key_obj = NULL;
3847e946e7SWyllys Ingersoll 	CK_ATTRIBUTE    * attr    = NULL;
3947e946e7SWyllys Ingersoll 	CK_BYTE	 * ptr	= NULL;
4047e946e7SWyllys Ingersoll 	CK_KEY_TYPE	keytype;
4147e946e7SWyllys Ingersoll 	CK_OBJECT_CLASS   class;
4247e946e7SWyllys Ingersoll 	CK_BBOOL	  flag;
4347e946e7SWyllys Ingersoll 	CK_RV		rc;
4447e946e7SWyllys Ingersoll 
4547e946e7SWyllys Ingersoll 	if (! sess || ! ctx) {
4647e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
4747e946e7SWyllys Ingersoll 	}
4847e946e7SWyllys Ingersoll 	if (ctx->active != FALSE) {
4947e946e7SWyllys Ingersoll 		return (CKR_OPERATION_ACTIVE);
5047e946e7SWyllys Ingersoll 	}
5147e946e7SWyllys Ingersoll 
5247e946e7SWyllys Ingersoll 	rc = object_mgr_find_in_map1(sess->hContext, key, &key_obj);
5347e946e7SWyllys Ingersoll 	if (rc != CKR_OK) {
5447e946e7SWyllys Ingersoll 		return (CKR_KEY_HANDLE_INVALID);
5547e946e7SWyllys Ingersoll 	}
5647e946e7SWyllys Ingersoll 	rc = template_attribute_find(key_obj->template, CKA_SIGN, &attr);
5747e946e7SWyllys Ingersoll 	if (rc == FALSE) {
5847e946e7SWyllys Ingersoll 		return (CKR_KEY_TYPE_INCONSISTENT);
5947e946e7SWyllys Ingersoll 	} else {
6047e946e7SWyllys Ingersoll 		flag = *(CK_BBOOL *)attr->pValue;
6147e946e7SWyllys Ingersoll 		if (flag != TRUE) {
6247e946e7SWyllys Ingersoll 			return (CKR_KEY_FUNCTION_NOT_PERMITTED);
6347e946e7SWyllys Ingersoll 		}
6447e946e7SWyllys Ingersoll 	}
6547e946e7SWyllys Ingersoll 
6647e946e7SWyllys Ingersoll 	switch (mech->mechanism) {
6747e946e7SWyllys Ingersoll 		case CKM_RSA_PKCS:
6847e946e7SWyllys Ingersoll 		{
6947e946e7SWyllys Ingersoll 			rc = template_attribute_find(key_obj->template,
7047e946e7SWyllys Ingersoll 			    CKA_KEY_TYPE, &attr);
7147e946e7SWyllys Ingersoll 			if (rc == FALSE) {
7247e946e7SWyllys Ingersoll 				return (CKR_KEY_TYPE_INCONSISTENT);
7347e946e7SWyllys Ingersoll 			} else {
7447e946e7SWyllys Ingersoll 				keytype = *(CK_KEY_TYPE *)attr->pValue;
7547e946e7SWyllys Ingersoll 				if (keytype != CKK_RSA) {
7647e946e7SWyllys Ingersoll 					return (CKR_KEY_TYPE_INCONSISTENT);
7747e946e7SWyllys Ingersoll 				}
7847e946e7SWyllys Ingersoll 			}
7947e946e7SWyllys Ingersoll 
8047e946e7SWyllys Ingersoll 			// must be a PRIVATE key
8147e946e7SWyllys Ingersoll 			//
8247e946e7SWyllys Ingersoll 			flag = template_attribute_find(key_obj->template,
8347e946e7SWyllys Ingersoll 			    CKA_CLASS, &attr);
8447e946e7SWyllys Ingersoll 			if (flag == FALSE) {
8547e946e7SWyllys Ingersoll 				return (CKR_KEY_TYPE_INCONSISTENT);
8647e946e7SWyllys Ingersoll 			}
8747e946e7SWyllys Ingersoll 			else
8847e946e7SWyllys Ingersoll 				class = *(CK_OBJECT_CLASS *)attr->pValue;
8947e946e7SWyllys Ingersoll 
9047e946e7SWyllys Ingersoll 			if (class != CKO_PRIVATE_KEY) {
9147e946e7SWyllys Ingersoll 				return (CKR_KEY_TYPE_INCONSISTENT);
9247e946e7SWyllys Ingersoll 			}
9347e946e7SWyllys Ingersoll 			// PKCS #11 doesn't allow multi - part RSA operations
9447e946e7SWyllys Ingersoll 			//
9547e946e7SWyllys Ingersoll 			ctx->context_len = 0;
9647e946e7SWyllys Ingersoll 			ctx->context	= NULL;
9747e946e7SWyllys Ingersoll 		}
9847e946e7SWyllys Ingersoll 		break;
9947e946e7SWyllys Ingersoll 		case CKM_MD5_RSA_PKCS:
10047e946e7SWyllys Ingersoll 		case CKM_SHA1_RSA_PKCS:
10147e946e7SWyllys Ingersoll 		{
10247e946e7SWyllys Ingersoll 			rc = template_attribute_find(key_obj->template,
10347e946e7SWyllys Ingersoll 			    CKA_KEY_TYPE, &attr);
10447e946e7SWyllys Ingersoll 			if (rc == FALSE) {
10547e946e7SWyllys Ingersoll 				return (CKR_KEY_TYPE_INCONSISTENT);
10647e946e7SWyllys Ingersoll 			} else {
10747e946e7SWyllys Ingersoll 				keytype = *(CK_KEY_TYPE *)attr->pValue;
10847e946e7SWyllys Ingersoll 				if (keytype != CKK_RSA) {
10947e946e7SWyllys Ingersoll 					return (CKR_KEY_TYPE_INCONSISTENT);
11047e946e7SWyllys Ingersoll 				}
11147e946e7SWyllys Ingersoll 			}
11247e946e7SWyllys Ingersoll 
11347e946e7SWyllys Ingersoll 			// must be a PRIVATE key operation
11447e946e7SWyllys Ingersoll 			//
11547e946e7SWyllys Ingersoll 			flag = template_attribute_find(key_obj->template,
11647e946e7SWyllys Ingersoll 			    CKA_CLASS, &attr);
11747e946e7SWyllys Ingersoll 			if (flag == FALSE) {
11847e946e7SWyllys Ingersoll 				return (CKR_FUNCTION_FAILED);
11947e946e7SWyllys Ingersoll 			}
12047e946e7SWyllys Ingersoll 			else
12147e946e7SWyllys Ingersoll 				class = *(CK_OBJECT_CLASS *)attr->pValue;
12247e946e7SWyllys Ingersoll 
12347e946e7SWyllys Ingersoll 			if (class != CKO_PRIVATE_KEY) {
12447e946e7SWyllys Ingersoll 				return (CKR_FUNCTION_FAILED);
12547e946e7SWyllys Ingersoll 			}
12647e946e7SWyllys Ingersoll 			ctx->context_len = sizeof (RSA_DIGEST_CONTEXT);
12747e946e7SWyllys Ingersoll 			ctx->context = (CK_BYTE *)malloc(
12847e946e7SWyllys Ingersoll 			    sizeof (RSA_DIGEST_CONTEXT));
12947e946e7SWyllys Ingersoll 			if (! ctx->context) {
13047e946e7SWyllys Ingersoll 				return (CKR_HOST_MEMORY);
13147e946e7SWyllys Ingersoll 			}
13247e946e7SWyllys Ingersoll 			(void) memset(ctx->context, 0x0,
13347e946e7SWyllys Ingersoll 			    sizeof (RSA_DIGEST_CONTEXT));
13447e946e7SWyllys Ingersoll 		}
13547e946e7SWyllys Ingersoll 		break;
13647e946e7SWyllys Ingersoll 		case CKM_MD5_HMAC:
13747e946e7SWyllys Ingersoll 		case CKM_SHA_1_HMAC:
13847e946e7SWyllys Ingersoll 		{
13947e946e7SWyllys Ingersoll 			if (mech->ulParameterLen != 0) {
14047e946e7SWyllys Ingersoll 				return (CKR_MECHANISM_PARAM_INVALID);
14147e946e7SWyllys Ingersoll 			}
14247e946e7SWyllys Ingersoll 			rc = template_attribute_find(key_obj->template,
14347e946e7SWyllys Ingersoll 			    CKA_KEY_TYPE, &attr);
14447e946e7SWyllys Ingersoll 			if (rc == FALSE) {
14547e946e7SWyllys Ingersoll 				return (CKR_KEY_TYPE_INCONSISTENT);
14647e946e7SWyllys Ingersoll 			} else {
14747e946e7SWyllys Ingersoll 				keytype = *(CK_KEY_TYPE *)attr->pValue;
14847e946e7SWyllys Ingersoll 				if (keytype != CKK_GENERIC_SECRET) {
14947e946e7SWyllys Ingersoll 					return (CKR_KEY_TYPE_INCONSISTENT);
15047e946e7SWyllys Ingersoll 				}
15147e946e7SWyllys Ingersoll 			}
15247e946e7SWyllys Ingersoll 
15347e946e7SWyllys Ingersoll 			// PKCS #11 doesn't allow multi - part HMAC operations
15447e946e7SWyllys Ingersoll 			//
15547e946e7SWyllys Ingersoll 			ctx->context_len = 0;
15647e946e7SWyllys Ingersoll 			ctx->context	= NULL;
15747e946e7SWyllys Ingersoll 		}
15847e946e7SWyllys Ingersoll 		break;
15947e946e7SWyllys Ingersoll 
16047e946e7SWyllys Ingersoll 		case CKM_MD5_HMAC_GENERAL:
16147e946e7SWyllys Ingersoll 		case CKM_SHA_1_HMAC_GENERAL:
16247e946e7SWyllys Ingersoll 		{
16347e946e7SWyllys Ingersoll 			CK_MAC_GENERAL_PARAMS *param =
16447e946e7SWyllys Ingersoll 			    (CK_MAC_GENERAL_PARAMS *)mech->pParameter;
16547e946e7SWyllys Ingersoll 
16647e946e7SWyllys Ingersoll 			if (mech->ulParameterLen !=
16747e946e7SWyllys Ingersoll 			    sizeof (CK_MAC_GENERAL_PARAMS)) {
16847e946e7SWyllys Ingersoll 				return (CKR_MECHANISM_PARAM_INVALID);
16947e946e7SWyllys Ingersoll 			}
17047e946e7SWyllys Ingersoll 
17147e946e7SWyllys Ingersoll 			if ((mech->mechanism == CKM_MD5_HMAC_GENERAL) &&
17247e946e7SWyllys Ingersoll 			    (*param > 16)) {
17347e946e7SWyllys Ingersoll 				return (CKR_MECHANISM_PARAM_INVALID);
17447e946e7SWyllys Ingersoll 			}
17547e946e7SWyllys Ingersoll 			if ((mech->mechanism == CKM_SHA_1_HMAC_GENERAL) &&
17647e946e7SWyllys Ingersoll 			    (*param > 20)) {
17747e946e7SWyllys Ingersoll 				return (CKR_MECHANISM_PARAM_INVALID);
17847e946e7SWyllys Ingersoll 			}
17947e946e7SWyllys Ingersoll 			rc = template_attribute_find(key_obj->template,
18047e946e7SWyllys Ingersoll 			    CKA_KEY_TYPE, &attr);
18147e946e7SWyllys Ingersoll 			if (rc == FALSE) {
18247e946e7SWyllys Ingersoll 				return (CKR_KEY_TYPE_INCONSISTENT);
18347e946e7SWyllys Ingersoll 			} else {
18447e946e7SWyllys Ingersoll 				keytype = *(CK_KEY_TYPE *)attr->pValue;
18547e946e7SWyllys Ingersoll 				if (keytype != CKK_GENERIC_SECRET) {
18647e946e7SWyllys Ingersoll 					return (CKR_KEY_TYPE_INCONSISTENT);
18747e946e7SWyllys Ingersoll 				}
18847e946e7SWyllys Ingersoll 			}
18947e946e7SWyllys Ingersoll 
19047e946e7SWyllys Ingersoll 			// PKCS #11 doesn't allow multi - part HMAC operations
19147e946e7SWyllys Ingersoll 			//
19247e946e7SWyllys Ingersoll 			ctx->context_len = 0;
19347e946e7SWyllys Ingersoll 			ctx->context	= NULL;
19447e946e7SWyllys Ingersoll 		}
19547e946e7SWyllys Ingersoll 		break;
19647e946e7SWyllys Ingersoll 		default:
19747e946e7SWyllys Ingersoll 			return (CKR_MECHANISM_INVALID);
19847e946e7SWyllys Ingersoll 	}
19947e946e7SWyllys Ingersoll 
200*ab8176c2SWyllys Ingersoll 	if (mech->ulParameterLen > 0 && mech->pParameter == NULL)
201*ab8176c2SWyllys Ingersoll 		return (CKR_ARGUMENTS_BAD);
20247e946e7SWyllys Ingersoll 
20347e946e7SWyllys Ingersoll 	if (mech->ulParameterLen > 0) {
20447e946e7SWyllys Ingersoll 		ptr = (CK_BYTE *)malloc(mech->ulParameterLen);
20547e946e7SWyllys Ingersoll 		if (! ptr) {
20647e946e7SWyllys Ingersoll 			return (CKR_HOST_MEMORY);
20747e946e7SWyllys Ingersoll 		}
20847e946e7SWyllys Ingersoll 		(void) memcpy(ptr, mech->pParameter, mech->ulParameterLen);
20947e946e7SWyllys Ingersoll 	}
21047e946e7SWyllys Ingersoll 
21147e946e7SWyllys Ingersoll 	ctx->key		 = key;
21247e946e7SWyllys Ingersoll 	ctx->mech.ulParameterLen = mech->ulParameterLen;
21347e946e7SWyllys Ingersoll 	ctx->mech.mechanism	= mech->mechanism;
21447e946e7SWyllys Ingersoll 	ctx->mech.pParameter	= ptr;
21547e946e7SWyllys Ingersoll 	ctx->multi		= FALSE;
21647e946e7SWyllys Ingersoll 	ctx->active		= TRUE;
21747e946e7SWyllys Ingersoll 	ctx->recover		= recover_mode;
21847e946e7SWyllys Ingersoll 
21947e946e7SWyllys Ingersoll 	return (CKR_OK);
22047e946e7SWyllys Ingersoll }
22147e946e7SWyllys Ingersoll 
22247e946e7SWyllys Ingersoll CK_RV
sign_mgr_cleanup(SIGN_VERIFY_CONTEXT * ctx)22347e946e7SWyllys Ingersoll sign_mgr_cleanup(SIGN_VERIFY_CONTEXT *ctx)
22447e946e7SWyllys Ingersoll {
22547e946e7SWyllys Ingersoll 	if (! ctx) {
22647e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
22747e946e7SWyllys Ingersoll 	}
22847e946e7SWyllys Ingersoll 	ctx->key		 = 0;
22947e946e7SWyllys Ingersoll 	ctx->mech.ulParameterLen = 0;
23047e946e7SWyllys Ingersoll 	ctx->mech.mechanism	= 0;
23147e946e7SWyllys Ingersoll 	ctx->multi		= FALSE;
23247e946e7SWyllys Ingersoll 	ctx->active		= FALSE;
23347e946e7SWyllys Ingersoll 	ctx->recover		= FALSE;
23447e946e7SWyllys Ingersoll 	ctx->context_len	 = 0;
23547e946e7SWyllys Ingersoll 
23647e946e7SWyllys Ingersoll 	if (ctx->mech.pParameter) {
23747e946e7SWyllys Ingersoll 		free(ctx->mech.pParameter);
23847e946e7SWyllys Ingersoll 		ctx->mech.pParameter = NULL;
23947e946e7SWyllys Ingersoll 	}
24047e946e7SWyllys Ingersoll 
24147e946e7SWyllys Ingersoll 	if (ctx->context) {
24247e946e7SWyllys Ingersoll 		free(ctx->context);
24347e946e7SWyllys Ingersoll 		ctx->context = NULL;
24447e946e7SWyllys Ingersoll 	}
24547e946e7SWyllys Ingersoll 
24647e946e7SWyllys Ingersoll 	return (CKR_OK);
24747e946e7SWyllys Ingersoll }
24847e946e7SWyllys Ingersoll 
24947e946e7SWyllys Ingersoll CK_RV
sign_mgr_sign(SESSION * sess,CK_BBOOL length_only,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)25047e946e7SWyllys Ingersoll sign_mgr_sign(SESSION	* sess,
25147e946e7SWyllys Ingersoll 	CK_BBOOL	length_only,
25247e946e7SWyllys Ingersoll 	SIGN_VERIFY_CONTEXT  * ctx,
25347e946e7SWyllys Ingersoll 	CK_BYTE		* in_data,
25447e946e7SWyllys Ingersoll 	CK_ULONG	in_data_len,
25547e946e7SWyllys Ingersoll 	CK_BYTE		* out_data,
25647e946e7SWyllys Ingersoll 	CK_ULONG	* out_data_len)
25747e946e7SWyllys Ingersoll {
25847e946e7SWyllys Ingersoll 	if (! sess || ! ctx) {
25947e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
26047e946e7SWyllys Ingersoll 	}
26147e946e7SWyllys Ingersoll 	if (ctx->active == FALSE) {
26247e946e7SWyllys Ingersoll 		return (CKR_OPERATION_NOT_INITIALIZED);
26347e946e7SWyllys Ingersoll 	}
26447e946e7SWyllys Ingersoll 	if (ctx->recover == TRUE) {
26547e946e7SWyllys Ingersoll 		return (CKR_OPERATION_NOT_INITIALIZED);
26647e946e7SWyllys Ingersoll 	}
26747e946e7SWyllys Ingersoll 
26847e946e7SWyllys Ingersoll 	// if the caller just wants the signature length, there is no reason to
26947e946e7SWyllys Ingersoll 	// specify the input data.  I just need the input data length
27047e946e7SWyllys Ingersoll 	//
27147e946e7SWyllys Ingersoll 	if ((length_only == FALSE) && (! in_data || ! out_data)) {
27247e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
27347e946e7SWyllys Ingersoll 	}
27447e946e7SWyllys Ingersoll 	if (ctx->multi == TRUE) {
27547e946e7SWyllys Ingersoll 		return (CKR_OPERATION_ACTIVE);
27647e946e7SWyllys Ingersoll 	}
27747e946e7SWyllys Ingersoll 	switch (ctx->mech.mechanism) {
27847e946e7SWyllys Ingersoll 		case CKM_RSA_PKCS:
27947e946e7SWyllys Ingersoll 		return (rsa_pkcs_sign(sess,	length_only,  ctx,
28047e946e7SWyllys Ingersoll 		    in_data,  in_data_len,
28147e946e7SWyllys Ingersoll 		    out_data, out_data_len));
28247e946e7SWyllys Ingersoll 		case CKM_MD5_RSA_PKCS:
28347e946e7SWyllys Ingersoll 		case CKM_SHA1_RSA_PKCS:
28447e946e7SWyllys Ingersoll 		return (rsa_hash_pkcs_sign(sess,	length_only, ctx,
28547e946e7SWyllys Ingersoll 		    in_data,  in_data_len,
28647e946e7SWyllys Ingersoll 		    out_data, out_data_len));
28747e946e7SWyllys Ingersoll 
28847e946e7SWyllys Ingersoll 		case CKM_MD5_HMAC:
28947e946e7SWyllys Ingersoll 		case CKM_MD5_HMAC_GENERAL:
29047e946e7SWyllys Ingersoll 		return (md5_hmac_sign(sess,	length_only, ctx,
29147e946e7SWyllys Ingersoll 		    in_data,  in_data_len,
29247e946e7SWyllys Ingersoll 		    out_data, out_data_len));
29347e946e7SWyllys Ingersoll 		case CKM_SHA_1_HMAC:
29447e946e7SWyllys Ingersoll 		case CKM_SHA_1_HMAC_GENERAL:
29547e946e7SWyllys Ingersoll 		return (sha1_hmac_sign(sess,	length_only, ctx,
29647e946e7SWyllys Ingersoll 		    in_data,  in_data_len,
29747e946e7SWyllys Ingersoll 		    out_data, out_data_len));
29847e946e7SWyllys Ingersoll 		default:
29947e946e7SWyllys Ingersoll 			return (CKR_MECHANISM_INVALID);
30047e946e7SWyllys Ingersoll 	}
30147e946e7SWyllys Ingersoll }
30247e946e7SWyllys Ingersoll 
30347e946e7SWyllys Ingersoll CK_RV
sign_mgr_sign_update(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len)30447e946e7SWyllys Ingersoll sign_mgr_sign_update(SESSION		* sess,
30547e946e7SWyllys Ingersoll 	SIGN_VERIFY_CONTEXT * ctx,
30647e946e7SWyllys Ingersoll 	CK_BYTE		* in_data,
30747e946e7SWyllys Ingersoll 	CK_ULONG		in_data_len)
30847e946e7SWyllys Ingersoll {
30947e946e7SWyllys Ingersoll 	if (! sess || ! ctx || ! in_data) {
31047e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
31147e946e7SWyllys Ingersoll 	}
31247e946e7SWyllys Ingersoll 
31347e946e7SWyllys Ingersoll 	if (ctx->active == FALSE) {
31447e946e7SWyllys Ingersoll 		return (CKR_OPERATION_NOT_INITIALIZED);
31547e946e7SWyllys Ingersoll 	}
31647e946e7SWyllys Ingersoll 	if (ctx->recover == TRUE) {
31747e946e7SWyllys Ingersoll 		return (CKR_OPERATION_NOT_INITIALIZED);
31847e946e7SWyllys Ingersoll 	}
31947e946e7SWyllys Ingersoll 	ctx->multi = TRUE;
32047e946e7SWyllys Ingersoll 
32147e946e7SWyllys Ingersoll 	switch (ctx->mech.mechanism) {
32247e946e7SWyllys Ingersoll 		case CKM_MD5_RSA_PKCS:
32347e946e7SWyllys Ingersoll 		case CKM_SHA1_RSA_PKCS:
32447e946e7SWyllys Ingersoll 			return (rsa_hash_pkcs_sign_update(sess, ctx,
32547e946e7SWyllys Ingersoll 			    in_data, in_data_len));
32647e946e7SWyllys Ingersoll 		default:
32747e946e7SWyllys Ingersoll 			return (CKR_MECHANISM_INVALID);
32847e946e7SWyllys Ingersoll 	}
32947e946e7SWyllys Ingersoll }
33047e946e7SWyllys Ingersoll 
33147e946e7SWyllys Ingersoll CK_RV
sign_mgr_sign_final(SESSION * sess,CK_BBOOL length_only,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * signature,CK_ULONG * sig_len)33247e946e7SWyllys Ingersoll sign_mgr_sign_final(SESSION		* sess,
33347e946e7SWyllys Ingersoll 	CK_BBOOL		length_only,
33447e946e7SWyllys Ingersoll 	SIGN_VERIFY_CONTEXT * ctx,
33547e946e7SWyllys Ingersoll 	CK_BYTE		* signature,
33647e946e7SWyllys Ingersoll 	CK_ULONG	    * sig_len)
33747e946e7SWyllys Ingersoll {
33847e946e7SWyllys Ingersoll 	if (! sess || ! ctx) {
33947e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
34047e946e7SWyllys Ingersoll 	}
34147e946e7SWyllys Ingersoll 	if (ctx->active == FALSE) {
34247e946e7SWyllys Ingersoll 		return (CKR_OPERATION_NOT_INITIALIZED);
34347e946e7SWyllys Ingersoll 	}
34447e946e7SWyllys Ingersoll 	if (ctx->recover == TRUE) {
34547e946e7SWyllys Ingersoll 		return (CKR_OPERATION_NOT_INITIALIZED);
34647e946e7SWyllys Ingersoll 	}
34747e946e7SWyllys Ingersoll 	switch (ctx->mech.mechanism) {
34847e946e7SWyllys Ingersoll 		case CKM_MD5_RSA_PKCS:
34947e946e7SWyllys Ingersoll 		case CKM_SHA1_RSA_PKCS:
35047e946e7SWyllys Ingersoll 			return (rsa_hash_pkcs_sign_final(sess, length_only,
35147e946e7SWyllys Ingersoll 			    ctx, signature, sig_len));
35247e946e7SWyllys Ingersoll 		default:
35347e946e7SWyllys Ingersoll 		return (CKR_MECHANISM_INVALID);
35447e946e7SWyllys Ingersoll 	}
35547e946e7SWyllys Ingersoll }
35647e946e7SWyllys Ingersoll 
35747e946e7SWyllys Ingersoll CK_RV
sign_mgr_sign_recover(SESSION * sess,CK_BBOOL length_only,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)35847e946e7SWyllys Ingersoll sign_mgr_sign_recover(SESSION		* sess,
35947e946e7SWyllys Ingersoll 	CK_BBOOL		length_only,
36047e946e7SWyllys Ingersoll 	SIGN_VERIFY_CONTEXT * ctx,
36147e946e7SWyllys Ingersoll 	CK_BYTE		* in_data,
36247e946e7SWyllys Ingersoll 	CK_ULONG		in_data_len,
36347e946e7SWyllys Ingersoll 	CK_BYTE		* out_data,
36447e946e7SWyllys Ingersoll 	CK_ULONG	    * out_data_len)
36547e946e7SWyllys Ingersoll {
36647e946e7SWyllys Ingersoll 	if (! sess || ! ctx) {
36747e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
36847e946e7SWyllys Ingersoll 	}
36947e946e7SWyllys Ingersoll 	if (ctx->active == FALSE) {
37047e946e7SWyllys Ingersoll 		return (CKR_OPERATION_NOT_INITIALIZED);
37147e946e7SWyllys Ingersoll 	}
37247e946e7SWyllys Ingersoll 	if (ctx->recover == FALSE) {
37347e946e7SWyllys Ingersoll 		return (CKR_OPERATION_NOT_INITIALIZED);
37447e946e7SWyllys Ingersoll 	}
37547e946e7SWyllys Ingersoll 
37647e946e7SWyllys Ingersoll 	// if the caller just wants the signature length, there is no reason to
37747e946e7SWyllys Ingersoll 	// specify the input data.  I just need the input data length
37847e946e7SWyllys Ingersoll 	//
37947e946e7SWyllys Ingersoll 	if ((length_only == FALSE) && (! in_data || ! out_data)) {
38047e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
38147e946e7SWyllys Ingersoll 	}
38247e946e7SWyllys Ingersoll 	if (ctx->multi == TRUE) {
38347e946e7SWyllys Ingersoll 		return (CKR_OPERATION_ACTIVE);
38447e946e7SWyllys Ingersoll 	}
38547e946e7SWyllys Ingersoll 	switch (ctx->mech.mechanism) {
38647e946e7SWyllys Ingersoll 		case CKM_RSA_PKCS:
38747e946e7SWyllys Ingersoll 			return (rsa_pkcs_sign(sess,	length_only,  ctx,
38847e946e7SWyllys Ingersoll 			    in_data,  in_data_len,
38947e946e7SWyllys Ingersoll 			    out_data, out_data_len));
39047e946e7SWyllys Ingersoll 		default:
39147e946e7SWyllys Ingersoll 			return (CKR_MECHANISM_INVALID);
39247e946e7SWyllys Ingersoll 	}
39347e946e7SWyllys Ingersoll }
394