xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_tpm/common/encr_mgr.c (revision 2983dda76a6d296fdb560c88114fe41caad1b84f)
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 
30 CK_RV
31 encr_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 
132 CK_RV
133 encr_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 
158 CK_RV
159 encr_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