xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_tpm/common/decr_mgr.c (revision e5803b76927480e8f9b67b22201c484ccf4c2bcf)
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 
29 #include "tpmtok_int.h"
30 
31 CK_RV
32 decr_mgr_init(
33 	SESSION		*sess,
34 	ENCR_DECR_CONTEXT *ctx,
35 	CK_ULONG	operation,
36 	CK_MECHANISM	*mech,
37 	CK_OBJECT_HANDLE	key_handle)
38 {
39 	OBJECT	* key_obj = NULL;
40 	CK_ATTRIBUTE  * attr    = NULL;
41 	CK_BYTE	*ptr = NULL;
42 	CK_KEY_TYPE   keytype;
43 	CK_BBOOL flag;
44 	CK_RV rc;
45 
46 	if (! sess) {
47 		return (CKR_FUNCTION_FAILED);
48 	}
49 	if (ctx->active != FALSE) {
50 		return (CKR_OPERATION_ACTIVE);
51 	}
52 
53 	if (operation == OP_DECRYPT_INIT) {
54 		rc = object_mgr_find_in_map1(sess->hContext, key_handle,
55 		    &key_obj);
56 		if (rc != CKR_OK) {
57 			return (CKR_KEY_HANDLE_INVALID);
58 		}
59 		rc = template_attribute_find(key_obj->template,
60 		    CKA_DECRYPT, &attr);
61 		if (rc == FALSE) {
62 			return (CKR_KEY_FUNCTION_NOT_PERMITTED);
63 		} else {
64 			flag = *(CK_BBOOL *)attr->pValue;
65 			if (flag != TRUE) {
66 				return (CKR_KEY_FUNCTION_NOT_PERMITTED);
67 			}
68 		}
69 	} else if (operation == OP_UNWRAP) {
70 		rc = object_mgr_find_in_map1(sess->hContext, key_handle,
71 		    &key_obj);
72 		if (rc != CKR_OK) {
73 			return (CKR_WRAPPING_KEY_HANDLE_INVALID);
74 		}
75 		rc = template_attribute_find(key_obj->template,
76 		    CKA_UNWRAP, &attr);
77 		if (rc == FALSE) {
78 			return (CKR_FUNCTION_FAILED);
79 		} else {
80 			flag = *(CK_BBOOL *)(attr->pValue);
81 			if (flag == FALSE) {
82 				return (CKR_FUNCTION_FAILED);
83 			}
84 		}
85 	} else {
86 		return (CKR_FUNCTION_FAILED);
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 		}
109 		break;
110 		default:
111 			return (CKR_MECHANISM_INVALID);
112 	}
113 
114 
115 	if (mech->ulParameterLen > 0) {
116 		ptr = (CK_BYTE *)malloc(mech->ulParameterLen);
117 		if (! ptr) {
118 			return (CKR_HOST_MEMORY);
119 		}
120 		(void) memcpy(ptr, mech->pParameter, mech->ulParameterLen);
121 	}
122 
123 	ctx->key		 = key_handle;
124 	ctx->mech.ulParameterLen = mech->ulParameterLen;
125 	ctx->mech.mechanism	= mech->mechanism;
126 	ctx->mech.pParameter	= ptr;
127 	ctx->multi		= FALSE;
128 	ctx->active		= TRUE;
129 
130 	return (CKR_OK);
131 }
132 
133 CK_RV
134 decr_mgr_cleanup(ENCR_DECR_CONTEXT *ctx)
135 {
136 	if (! ctx) {
137 		return (CKR_FUNCTION_FAILED);
138 	}
139 	ctx->key		= 0;
140 	ctx->mech.ulParameterLen = 0;
141 	ctx->mech.mechanism	= 0;
142 	ctx->multi		= FALSE;
143 	ctx->active		= FALSE;
144 	ctx->context_len	= 0;
145 
146 	if (ctx->mech.pParameter) {
147 		free(ctx->mech.pParameter);
148 		ctx->mech.pParameter = NULL;
149 	}
150 
151 	if (ctx->context) {
152 		free(ctx->context);
153 		ctx->context = NULL;
154 	}
155 
156 	return (CKR_OK);
157 }
158 
159 CK_RV
160 decr_mgr_decrypt(SESSION	   *sess,
161 	CK_BBOOL	length_only,
162 	ENCR_DECR_CONTEXT *ctx,
163 	CK_BYTE		*in_data,
164 	CK_ULONG	in_data_len,
165 	CK_BYTE		*out_data,
166 	CK_ULONG	*out_data_len)
167 {
168 	if (! sess || ! ctx) {
169 		return (CKR_FUNCTION_FAILED);
170 	}
171 	if (ctx->active == FALSE) {
172 		return (CKR_OPERATION_NOT_INITIALIZED);
173 	}
174 	if ((length_only == FALSE) && (! in_data || ! out_data)) {
175 		return (CKR_FUNCTION_FAILED);
176 	}
177 	if (ctx->multi == TRUE) {
178 		return (CKR_OPERATION_ACTIVE);
179 	}
180 	switch (ctx->mech.mechanism) {
181 		case CKM_RSA_PKCS:
182 			return (rsa_pkcs_decrypt(sess, length_only,
183 			    ctx, in_data,  in_data_len, out_data,
184 			    out_data_len));
185 
186 		default:
187 			return (CKR_MECHANISM_INVALID);
188 	}
189 }
190