1/*
2 * The Initial Developer of the Original Code is International
3 * Business Machines Corporation. Portions created by IBM
4 * Corporation are Copyright (C) 2005 International Business
5 * Machines Corporation. All Rights Reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the Common Public License as published by
9 * IBM Corporation; either version 1 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * Common Public License for more details.
16 *
17 * You should have received a copy of the Common Public License
18 * along with this program; if not, a copy can be viewed at
19 * http://www.opensource.org/licenses/cpl1.0.php.
20 */
21
22/* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */
23/*
24 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
25 * Use is subject to license terms.
26 */
27
28#include "tpmtok_int.h"
29
30CK_RV
31encr_mgr_init(SESSION	   * sess,
32	ENCR_DECR_CONTEXT * ctx,
33	CK_ULONG	    operation,
34	CK_MECHANISM	* mech,
35	CK_OBJECT_HANDLE    key_handle)
36{
37	OBJECT	* key_obj = NULL;
38	CK_ATTRIBUTE  * attr    = NULL;
39	CK_BYTE	* ptr	= NULL;
40	CK_KEY_TYPE	keytype;
41	CK_BBOOL	flag;
42	CK_RV	   rc;
43
44
45	if (! sess || ! ctx || ! mech) {
46		return (CKR_FUNCTION_FAILED);
47	}
48	if (ctx->active != FALSE) {
49		return (CKR_OPERATION_ACTIVE);
50	}
51
52	if (operation == OP_ENCRYPT_INIT) {
53		rc = object_mgr_find_in_map1(sess->hContext, key_handle,
54		    &key_obj);
55		if (rc != CKR_OK) {
56			return (CKR_KEY_HANDLE_INVALID);
57		}
58		rc = template_attribute_find(key_obj->template,
59		    CKA_ENCRYPT, &attr);
60		if (rc == FALSE) {
61			return (CKR_KEY_FUNCTION_NOT_PERMITTED);
62		} else {
63			flag = *(CK_BBOOL *)attr->pValue;
64			if (flag != TRUE) {
65				return (CKR_KEY_FUNCTION_NOT_PERMITTED);
66			}
67		}
68	} else if (operation == OP_WRAP) {
69		rc = object_mgr_find_in_map1(sess->hContext, key_handle,
70		    &key_obj);
71		if (rc != CKR_OK) {
72			return (CKR_WRAPPING_KEY_HANDLE_INVALID);
73		}
74		rc = template_attribute_find(key_obj->template,
75		    CKA_WRAP, &attr);
76		if (rc == FALSE) {
77			return (CKR_KEY_NOT_WRAPPABLE);
78		} else {
79			flag = *(CK_BBOOL *)attr->pValue;
80			if (flag == FALSE) {
81				return (CKR_KEY_NOT_WRAPPABLE);
82			}
83		}
84	} else {
85		return (CKR_FUNCTION_FAILED);
86	}
87
88	switch (mech->mechanism) {
89		case CKM_RSA_PKCS:
90		{
91			if (mech->ulParameterLen != 0) {
92				return (CKR_MECHANISM_PARAM_INVALID);
93			}
94			rc = template_attribute_find(key_obj->template,
95			    CKA_KEY_TYPE, &attr);
96			if (rc == FALSE) {
97				return (CKR_KEY_TYPE_INCONSISTENT);
98			} else {
99				keytype = *(CK_KEY_TYPE *)attr->pValue;
100				if (keytype != CKK_RSA) {
101					return (CKR_KEY_TYPE_INCONSISTENT);
102				}
103			}
104
105			ctx->context_len = 0;
106			ctx->context	= NULL;
107		}
108		break;
109		default:
110			return (CKR_MECHANISM_INVALID);
111	}
112
113
114	if (mech->ulParameterLen > 0) {
115		ptr = (CK_BYTE *)malloc(mech->ulParameterLen);
116		if (! ptr) {
117			return (CKR_HOST_MEMORY);
118		}
119		(void) memcpy(ptr, mech->pParameter, mech->ulParameterLen);
120	}
121
122	ctx->key		 = key_handle;
123	ctx->mech.ulParameterLen = mech->ulParameterLen;
124	ctx->mech.mechanism	= mech->mechanism;
125	ctx->mech.pParameter	= ptr;
126	ctx->multi		= FALSE;
127	ctx->active		= TRUE;
128
129	return (CKR_OK);
130}
131
132CK_RV
133encr_mgr_cleanup(ENCR_DECR_CONTEXT *ctx)
134{
135	if (! ctx) {
136		return (CKR_FUNCTION_FAILED);
137	}
138	ctx->key		 = 0;
139	ctx->mech.ulParameterLen = 0;
140	ctx->mech.mechanism	= 0;
141	ctx->multi		= FALSE;
142	ctx->active		= FALSE;
143	ctx->context_len	 = 0;
144
145	if (ctx->mech.pParameter) {
146		free(ctx->mech.pParameter);
147		ctx->mech.pParameter = NULL;
148	}
149
150	if (ctx->context) {
151		free(ctx->context);
152		ctx->context = NULL;
153	}
154
155	return (CKR_OK);
156}
157
158CK_RV
159encr_mgr_encrypt(SESSION	   *sess,
160	CK_BBOOL	   length_only,
161	ENCR_DECR_CONTEXT *ctx,
162	CK_BYTE	   *in_data,
163	CK_ULONG	   in_data_len,
164	CK_BYTE	   *out_data,
165	CK_ULONG	  *out_data_len)
166{
167	if (! sess || ! ctx) {
168		return (CKR_FUNCTION_FAILED);
169	}
170	if (ctx->active == FALSE) {
171		return (CKR_OPERATION_NOT_INITIALIZED);
172	}
173	if ((length_only == FALSE) && (! in_data || ! out_data)) {
174		return (CKR_FUNCTION_FAILED);
175	}
176	if (ctx->multi == TRUE) {
177		return (CKR_OPERATION_ACTIVE);
178	}
179	switch (ctx->mech.mechanism) {
180		case CKM_RSA_PKCS:
181			return (rsa_pkcs_encrypt(sess,	length_only,
182			    ctx, in_data,  in_data_len, out_data,
183			    out_data_len));
184
185		default:
186			return (CKR_MECHANISM_INVALID);
187	}
188}
189