1 /*
2 * COPYRIGHT (c) International Business Machines Corp. 2005-2017
3 *
4 * This program is provided under the terms of the Common Public License,
5 * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
6 * software constitutes recipient's acceptance of CPL-1.0 terms which can be
7 * found in the file LICENSE file or at
8 * https://opensource.org/licenses/cpl1.0.php
9 */
10
11 /*
12 * tpm_specific.c
13 *
14 * Feb 10, 2005
15 *
16 * Author: Kent Yoder <yoder1@us.ibm.com>
17 *
18 * Encryption routines are based on ../soft_stdll/soft_specific.c.
19 *
20 */
21
22 #define _GNU_SOURCE
23 #include <stdio.h>
24 #include <pthread.h>
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <errno.h>
33 #include <pwd.h>
34 #include <syslog.h>
35 #include <grp.h>
36
37 #include <openssl/des.h>
38 #include <openssl/rand.h>
39 #include <openssl/rsa.h>
40 #include <openssl/aes.h>
41 #include <openssl/evp.h>
42
43 #include <tss/platform.h>
44 #include <tss/tss_defines.h>
45 #include <tss/tss_typedef.h>
46 #include <tss/tss_structs.h>
47 #include <tss/tss_error.h>
48 #include <tss/tspi.h>
49
50 #include "pkcs11types.h"
51 #include "stdll.h"
52 #include "defs.h"
53 #include "host_defs.h"
54 #include "h_extern.h"
55 #include "tok_specific.h"
56 #include "tok_spec_struct.h"
57 #include "tok_struct.h"
58 #include "trace.h"
59 #include "ock_syslog.h"
60
61 #include "tpm_specific.h"
62
63 #include "../api/apiproto.h"
64
65 TSS_RESULT util_set_public_modulus(TSS_HKEY, unsigned long, unsigned char *);
66
67 const char manuf[] = "IBM Corp.";
68 const char model[] = "TPM v1.1 Token";
69 const char descr[] = "Token for the Trusted Platform Module";
70 const char label[] = "IBM PKCS#11 TPM Token";
71
72 MECH_LIST_ELEMENT mech_list[] = {
73 {CKM_RSA_PKCS_KEY_PAIR_GEN, {512, 2048, CKF_GENERATE_KEY_PAIR}},
74 {CKM_DES_KEY_GEN, {0, 0, CKF_GENERATE}},
75 {CKM_DES3_KEY_GEN, {0, 0, CKF_GENERATE}},
76 {CKM_RSA_PKCS, {512, 2048, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP |
77 CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER |
78 CKF_VERIFY_RECOVER}},
79 {CKM_MD5_RSA_PKCS, {512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY}},
80 {CKM_SHA1_RSA_PKCS, {512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY}},
81 {CKM_DES_ECB, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
82 {CKM_DES_CBC, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
83 {CKM_DES_CBC_PAD,
84 {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
85 {CKM_DES3_ECB, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
86 {CKM_DES3_CBC, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
87 {CKM_DES3_CBC_PAD,
88 {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
89 {CKM_SHA_1, {0, 0, CKF_DIGEST}},
90 {CKM_SHA_1_HMAC, {0, 0, CKF_SIGN | CKF_VERIFY}},
91 {CKM_SHA_1_HMAC_GENERAL, {0, 0, CKF_SIGN | CKF_VERIFY}},
92 {CKM_MD5, {0, 0, CKF_DIGEST}},
93 {CKM_MD5_HMAC, {0, 0, CKF_SIGN | CKF_VERIFY}},
94 {CKM_MD5_HMAC_GENERAL, {0, 0, CKF_SIGN | CKF_VERIFY}},
95 {CKM_SSL3_PRE_MASTER_KEY_GEN, {48, 48, CKF_GENERATE}},
96 {CKM_SSL3_MASTER_KEY_DERIVE, {48, 48, CKF_DERIVE}},
97 {CKM_SSL3_KEY_AND_MAC_DERIVE, {48, 48, CKF_DERIVE}},
98 {CKM_SSL3_MD5_MAC, {384, 384, CKF_SIGN | CKF_VERIFY}},
99 {CKM_SSL3_SHA1_MAC, {384, 384, CKF_SIGN | CKF_VERIFY}},
100 {CKM_AES_KEY_GEN, {16, 32, CKF_GENERATE}},
101 {CKM_AES_ECB, {16, 32, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
102 {CKM_AES_CBC, {16, 32, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
103 {CKM_AES_CBC_PAD, {16, 32, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP |
104 CKF_UNWRAP}},
105 };
106
107 CK_ULONG mech_list_len = (sizeof(mech_list) / sizeof(MECH_LIST_ELEMENT));
108
109 CK_BYTE master_key_private[MK_SIZE];
110
111 /* The context we'll use globally to connect to the TSP */
112 TSS_HCONTEXT tspContext = NULL_HCONTEXT;
113
114 /* TSP key handles */
115 TSS_HKEY hSRK = NULL_HKEY;
116 TSS_HKEY hPublicRootKey = NULL_HKEY;
117 TSS_HKEY hPublicLeafKey = NULL_HKEY;
118 TSS_HKEY hPrivateRootKey = NULL_HKEY;
119 TSS_HKEY hPrivateLeafKey = NULL_HKEY;
120
121 /* TSP policy handles */
122 TSS_HPOLICY hDefaultPolicy = NULL_HPOLICY;
123
124 /* PKCS#11 key handles */
125 CK_OBJECT_HANDLE ckPublicRootKey = 0;
126 CK_OBJECT_HANDLE ckPublicLeafKey = 0;
127 CK_OBJECT_HANDLE ckPrivateRootKey = 0;
128 CK_OBJECT_HANDLE ckPrivateLeafKey = 0;
129
130 int not_initialized = 0;
131
132 CK_BYTE current_user_pin_sha[SHA1_HASH_SIZE];
133 CK_BYTE current_so_pin_sha[SHA1_HASH_SIZE];
134
clear_internal_structures()135 static void clear_internal_structures()
136 {
137 hSRK = NULL_HKEY;
138 hPrivateLeafKey = NULL_HKEY;
139 hPublicLeafKey = NULL_HKEY;
140 hPrivateRootKey = NULL_HKEY;
141 hPublicRootKey = NULL_HKEY;
142
143 memset(master_key_private, 0, MK_SIZE);
144 memset(current_so_pin_sha, 0, SHA1_HASH_SIZE);
145 memset(current_user_pin_sha, 0, SHA1_HASH_SIZE);
146 }
147
token_specific_rng(STDLL_TokData_t * tokdata,CK_BYTE * output,CK_ULONG bytes)148 CK_RV token_specific_rng(STDLL_TokData_t * tokdata, CK_BYTE * output,
149 CK_ULONG bytes)
150 {
151 TSS_RESULT rc;
152 TSS_HTPM hTPM;
153 BYTE *random_bytes = NULL;
154
155 UNUSED(tokdata);
156
157 rc = Tspi_Context_GetTpmObject(tspContext, &hTPM);
158 if (rc) {
159 TRACE_ERROR("Tspi_Context_GetTpmObject: %x\n", rc);
160 return CKR_FUNCTION_FAILED;
161 }
162
163 rc = Tspi_TPM_GetRandom(hTPM, bytes, &random_bytes);
164 if (rc) {
165 TRACE_ERROR("Tspi_TPM_GetRandom failed. rc=0x%x\n", rc);
166 return CKR_FUNCTION_FAILED;
167 }
168
169 memcpy(output, random_bytes, bytes);
170 Tspi_Context_FreeMemory(tspContext, random_bytes);
171
172 return CKR_OK;
173 }
174
token_specific_init(STDLL_TokData_t * tokdata,CK_SLOT_ID SlotNumber,char * conf_name)175 CK_RV token_specific_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber,
176 char *conf_name)
177 {
178 TSS_RESULT result;
179 char path_buf[PATH_MAX], fname[PATH_MAX];
180 struct stat statbuf;
181
182 UNUSED(tokdata);
183 UNUSED(conf_name);
184
185 TRACE_INFO("tpm %s slot=%lu running\n", __func__, SlotNumber);
186
187 // if the user specific directory doesn't exist, create it
188 sprintf(path_buf, "%s", get_pk_dir(fname));
189 if (stat(path_buf, &statbuf) < 0) {
190 if (mkdir(path_buf, S_IRUSR | S_IWUSR | S_IXUSR) == -1) {
191 TRACE_ERROR("mkdir(%s): %s\n", path_buf, strerror(errno));
192 return CKR_FUNCTION_FAILED;
193 }
194 }
195 // now create userdir/TOK_OBJ if it doesn't exist
196 strncat(path_buf, "/", sizeof(path_buf) - (strlen(path_buf) + 1));
197 strncat(path_buf, PK_LITE_OBJ_DIR,
198 sizeof(path_buf) - (strlen(PK_LITE_OBJ_DIR) + 1));
199 if (stat(path_buf, &statbuf) < 0) {
200 if (mkdir(path_buf, S_IRUSR | S_IWUSR | S_IXUSR) == -1) {
201 TRACE_ERROR("mkdir(%s): %s\n", path_buf, strerror(errno));
202 return CKR_FUNCTION_FAILED;
203 }
204 }
205
206 result = Tspi_Context_Create(&tspContext);
207 if (result) {
208 TRACE_ERROR("Tspi_Context_Create failed. rc=0x%x\n", result);
209 return CKR_FUNCTION_FAILED;
210 }
211
212 result = Tspi_Context_Connect(tspContext, NULL);
213 if (result) {
214 TRACE_ERROR("Tspi_Context_Connect failed. rc=0x%x\n", result);
215 return CKR_FUNCTION_FAILED;
216 }
217
218 result = Tspi_Context_GetDefaultPolicy(tspContext, &hDefaultPolicy);
219 if (result) {
220 TRACE_ERROR("Tspi_Context_GetDefaultPolicy failed. rc=0x%x\n", result);
221 return CKR_FUNCTION_FAILED;
222 }
223
224 OpenSSL_add_all_algorithms();
225
226 return CKR_OK;
227 }
228
token_find_key(STDLL_TokData_t * tokdata,int key_type,CK_OBJECT_CLASS class,CK_OBJECT_HANDLE * handle)229 CK_RV token_find_key(STDLL_TokData_t * tokdata, int key_type,
230 CK_OBJECT_CLASS class, CK_OBJECT_HANDLE * handle)
231 {
232 CK_BYTE *key_id = util_create_id(key_type);
233 CK_RV rc = CKR_OK;
234 CK_BBOOL true = TRUE;
235 CK_ATTRIBUTE tmpl[] = {
236 {CKA_ID, key_id, strlen((char *) key_id)},
237 {CKA_CLASS, &class, sizeof(class)},
238 {CKA_HIDDEN, &true, sizeof(CK_BBOOL)}
239 };
240 CK_OBJECT_HANDLE hObj;
241 CK_ULONG ulObjCount;
242 SESSION dummy_sess;
243
244 /* init the dummy session state to something that will find any object on
245 * the token */
246 memset(&dummy_sess, 0, sizeof(SESSION));
247 dummy_sess.session_info.state = CKS_RO_USER_FUNCTIONS;
248
249 rc = object_mgr_find_init(tokdata, &dummy_sess, tmpl, 3);
250 if (rc != CKR_OK) {
251 goto done;
252 }
253
254 /* pulled from SC_FindObjects */
255 ulObjCount = MIN(1, (dummy_sess.find_count - dummy_sess.find_idx));
256 memcpy(&hObj, dummy_sess.find_list + dummy_sess.find_idx,
257 ulObjCount * sizeof(CK_OBJECT_HANDLE));
258 dummy_sess.find_idx += ulObjCount;
259
260 if (ulObjCount > 1) {
261 TRACE_INFO("More than one matching key found in the store!\n");
262 rc = CKR_KEY_NOT_FOUND;
263 goto done;
264 } else if (ulObjCount < 1) {
265 TRACE_INFO("key with ID=\"%s\" not found in the store!\n", key_id);
266 rc = CKR_KEY_NOT_FOUND;
267 goto done;
268 }
269
270 *handle = hObj;
271 done:
272 object_mgr_find_final(&dummy_sess);
273 free(key_id);
274
275 return rc;
276 }
277
token_get_key_blob(STDLL_TokData_t * tokdata,CK_OBJECT_HANDLE ckKey,CK_ULONG * blob_size,CK_BYTE ** ret_blob)278 CK_RV token_get_key_blob(STDLL_TokData_t * tokdata, CK_OBJECT_HANDLE ckKey,
279 CK_ULONG * blob_size, CK_BYTE ** ret_blob)
280 {
281 CK_RV rc = CKR_OK;
282 CK_BYTE_PTR blob = NULL;
283 CK_ATTRIBUTE tmpl[] = {
284 {CKA_IBM_OPAQUE, NULL_PTR, 0}
285 };
286 SESSION dummy_sess;
287
288 /* set up dummy session */
289 memset(&dummy_sess, 0, sizeof(SESSION));
290 dummy_sess.session_info.state = CKS_RO_USER_FUNCTIONS;
291
292 /* find object the first time to return the size of the buffer needed */
293 rc = object_mgr_get_attribute_values(tokdata, &dummy_sess, ckKey, tmpl, 1);
294 if (rc != CKR_OK) {
295 TRACE_DEVEL("object_mgr_get_attribute_values failed:rc=0x%lx\n", rc);
296 goto done;
297 }
298
299 blob = malloc(tmpl[0].ulValueLen);
300 if (blob == NULL) {
301 TRACE_ERROR("malloc %ld bytes failed.\n", tmpl[0].ulValueLen);
302 rc = CKR_HOST_MEMORY;
303 goto done;
304 }
305
306 tmpl[0].pValue = blob;
307 /* find object the 2nd time to fill the buffer with data */
308 rc = object_mgr_get_attribute_values(tokdata, &dummy_sess, ckKey, tmpl, 1);
309 if (rc != CKR_OK) {
310 TRACE_DEVEL("object_mgr_get_attribute_values failed:rc=0x%lx\n", rc);
311 goto done;
312 }
313
314 *ret_blob = blob;
315 *blob_size = tmpl[0].ulValueLen;
316
317 done:
318 return rc;
319 }
320
token_wrap_sw_key(int size_n,unsigned char * n,int size_p,unsigned char * p,TSS_HKEY hParentKey,TSS_FLAG initFlags,TSS_HKEY * phKey)321 CK_RV token_wrap_sw_key(int size_n, unsigned char *n, int size_p,
322 unsigned char *p, TSS_HKEY hParentKey,
323 TSS_FLAG initFlags, TSS_HKEY * phKey)
324 {
325 TSS_RESULT result;
326 TSS_HPOLICY hPolicy;
327 TSS_BOOL get_srk_pub_key = TRUE;
328 UINT32 key_size;
329
330 key_size = util_get_keysize_flag(size_n * 8);
331 if (initFlags == 0) {
332 TRACE_ERROR("Invalid key size.\n");
333 return CKR_FUNCTION_FAILED;
334 }
335
336 /* create the TSS key object */
337 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_RSAKEY,
338 TSS_KEY_MIGRATABLE | initFlags |
339 key_size, phKey);
340 if (result != TSS_SUCCESS) {
341 TRACE_ERROR("Tspi_Context_CreateObject failed: rc=0x%x\n", result);
342 return result;
343 }
344
345 result = util_set_public_modulus(*phKey, size_n, n);
346 if (result != TSS_SUCCESS) {
347 TRACE_DEVEL("util_set_public_modulus failed:rc=0x%x\n", result);
348 Tspi_Context_CloseObject(tspContext, *phKey);
349 *phKey = NULL_HKEY;
350 return result;
351 }
352
353 /* set the private key data in the TSS object */
354 result = Tspi_SetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB,
355 TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY, size_p, p);
356 if (result != TSS_SUCCESS) {
357 TRACE_ERROR("Tspi_SetAttribData failed: rc=0x%x\n", result);
358 Tspi_Context_CloseObject(tspContext, *phKey);
359 *phKey = NULL_HKEY;
360 return result;
361 }
362
363 /* if the parent wrapping key is the SRK, we need to manually pull
364 * out the SRK's pub key, which is not stored in persistent storage
365 * for privacy reasons */
366 if (hParentKey == hSRK && get_srk_pub_key == TRUE) {
367 UINT32 pubKeySize;
368 BYTE *pubKey;
369 result = Tspi_Key_GetPubKey(hParentKey, &pubKeySize, &pubKey);
370 if (result != TSS_SUCCESS) {
371 if (result == TPM_E_INVALID_KEYHANDLE) {
372 OCK_SYSLOG(LOG_WARNING,
373 "Warning: Your TPM is not configured to allow "
374 "reading the public SRK by anyone but the owner. "
375 "Use tpm_restrictsrk -a to allow reading the public "
376 "SRK");
377 } else {
378 OCK_SYSLOG(LOG_ERR, "Tspi_Key_GetPubKey failed: rc=0x%x",
379 result);
380 }
381 Tspi_Context_CloseObject(tspContext, *phKey);
382 *phKey = NULL_HKEY;
383 return result;
384 }
385 Tspi_Context_FreeMemory(tspContext, pubKey);
386 get_srk_pub_key = FALSE;
387 }
388
389 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_POLICY,
390 TSS_POLICY_MIGRATION, &hPolicy);
391 if (result != TSS_SUCCESS) {
392 TRACE_ERROR("Tspi_Context_CreateObject: 0x%x\n", result);
393 Tspi_Context_CloseObject(tspContext, *phKey);
394 *phKey = NULL_HKEY;
395 return result;
396 }
397
398 result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE, 0, NULL);
399 if (result != TSS_SUCCESS) {
400 TRACE_ERROR("Tspi_Policy_SetSecret failed. rc=0x%x\n", result);
401 Tspi_Context_CloseObject(tspContext, *phKey);
402 Tspi_Context_CloseObject(tspContext, hPolicy);
403 *phKey = NULL_HKEY;
404 return result;
405 }
406
407 result = Tspi_Policy_AssignToObject(hPolicy, *phKey);
408 if (result != TSS_SUCCESS) {
409 TRACE_ERROR("Tspi_Policy_AssignToObject: 0x%x\n", result);
410 Tspi_Context_CloseObject(tspContext, *phKey);
411 Tspi_Context_CloseObject(tspContext, hPolicy);
412 *phKey = NULL_HKEY;
413 return result;
414 }
415
416 if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) {
417 result = Tspi_SetAttribUint32(*phKey, TSS_TSPATTRIB_KEY_INFO,
418 TSS_TSPATTRIB_KEYINFO_ENCSCHEME,
419 TSS_ES_RSAESPKCSV15);
420 if (result) {
421 TRACE_ERROR("Tspi_SetAttribUint32 failed. rc=0x%x\n", result);
422 Tspi_Context_CloseObject(tspContext, *phKey);
423 Tspi_Context_CloseObject(tspContext, hPolicy);
424 return result;
425 }
426
427 result = Tspi_SetAttribUint32(*phKey, TSS_TSPATTRIB_KEY_INFO,
428 TSS_TSPATTRIB_KEYINFO_SIGSCHEME,
429 TSS_SS_RSASSAPKCS1V15_DER);
430 if (result) {
431 TRACE_ERROR("Tspi_SetAttribUint32 failed. rc=0x%x\n", result);
432 Tspi_Context_CloseObject(tspContext, *phKey);
433 Tspi_Context_CloseObject(tspContext, hPolicy);
434 return result;
435 }
436 }
437
438 result = Tspi_Key_WrapKey(*phKey, hParentKey, NULL_HPCRS);
439 if (result != TSS_SUCCESS) {
440 TRACE_ERROR("Tspi_Key_WrapKey failed: rc=0x%x\n", result);
441 Tspi_Context_CloseObject(tspContext, *phKey);
442 *phKey = NULL_HKEY;
443 }
444
445 return result;
446 }
447
448 /*
449 * Create a TPM key blob for an imported key. This function is only called when
450 * a key is in active use, so any failure should trickle through.
451 */
token_wrap_key_object(STDLL_TokData_t * tokdata,CK_OBJECT_HANDLE ckObject,TSS_HKEY hParentKey,TSS_HKEY * phKey)452 CK_RV token_wrap_key_object(STDLL_TokData_t * tokdata,
453 CK_OBJECT_HANDLE ckObject, TSS_HKEY hParentKey,
454 TSS_HKEY * phKey)
455 {
456 CK_RV rc = CKR_OK;
457 CK_ATTRIBUTE *attr = NULL, *new_attr, *prime_attr;
458 CK_ULONG class, key_type;
459 CK_BBOOL found;
460 OBJECT *obj;
461
462 TSS_RESULT result;
463 TSS_FLAG initFlags = 0;
464 BYTE *rgbBlob;
465 UINT32 ulBlobLen;
466
467 rc = object_mgr_find_in_map1(tokdata, ckObject, &obj);
468 if (rc != CKR_OK) {
469 TRACE_DEVEL("object_mgr_find_in_map1 failed. rc=0x%lx\n", rc);
470 return rc;
471 }
472
473 /* if the object isn't a key, fail */
474 found = template_attribute_find(obj->template, CKA_KEY_TYPE, &attr);
475 if (found == FALSE) {
476 TRACE_ERROR("template_attribute_find(CKA_KEY_TYPE) failed.\n");
477 return CKR_FUNCTION_FAILED;
478 }
479
480 key_type = *((CK_ULONG *) attr->pValue);
481
482 if (key_type != CKK_RSA) {
483 TRACE_ERROR("Bad key type!\n");
484 return CKR_FUNCTION_FAILED;
485 }
486
487 found = template_attribute_find(obj->template, CKA_CLASS, &attr);
488 if (found == FALSE) {
489 TRACE_ERROR("template_attribute_find(CKA_CLASS) failed.\n");
490 return CKR_FUNCTION_FAILED;
491 }
492
493 class = *((CK_ULONG *) attr->pValue);
494
495 if (class == CKO_PRIVATE_KEY) {
496 /* In order to create a full TSS key blob using a PKCS#11 private key
497 * object, we need one of the two primes, the modulus and the private
498 * exponent and we need the public exponent to be correct */
499
500 /* check the least likely attribute to exist first, the primes */
501 found = template_attribute_find(obj->template,
502 CKA_PRIME_1, &prime_attr);
503 if (found == FALSE) {
504 found = template_attribute_find(obj->template,
505 CKA_PRIME_2, &prime_attr);
506 if (found == FALSE) {
507 TRACE_ERROR("Couldn't find prime1 or prime2 of"
508 " key object to wrap\n");
509 return CKR_TEMPLATE_INCONSISTENT;
510 }
511 }
512
513 /* Make sure the public exponent is usable */
514 if ((util_check_public_exponent(obj->template))) {
515 TRACE_ERROR("Invalid public exponent\n");
516 return CKR_TEMPLATE_INCONSISTENT;
517 }
518
519 /* get the modulus */
520 found = template_attribute_find(obj->template, CKA_MODULUS, &attr);
521 if (found == FALSE) {
522 TRACE_ERROR("Couldn't find a required attribute of "
523 "key object\n");
524 return CKR_FUNCTION_FAILED;
525 }
526
527 /* make sure the key size is usable */
528 initFlags = util_get_keysize_flag(attr->ulValueLen * 8);
529 if (initFlags == 0) {
530 TRACE_ERROR("Invalid key size.\n");
531 return CKR_TEMPLATE_INCONSISTENT;
532 }
533
534 /* generate the software based key */
535 rc = token_wrap_sw_key((int) attr->ulValueLen, attr->pValue,
536 (int) prime_attr->ulValueLen,
537 prime_attr->pValue,
538 hParentKey,
539 TSS_KEY_TYPE_LEGACY | TSS_KEY_NO_AUTHORIZATION,
540 phKey);
541 if (rc != CKR_OK) {
542 TRACE_DEVEL("token_wrap_sw_key failed. rc=0x%lu\n", rc);
543 return rc;
544 }
545 } else if (class == CKO_PUBLIC_KEY) {
546 /* Make sure the public exponent is usable */
547 if ((util_check_public_exponent(obj->template))) {
548 TRACE_DEVEL("Invalid public exponent\n");
549 return CKR_TEMPLATE_INCONSISTENT;
550 }
551
552 /* grab the modulus to put into the TSS key object */
553 found = template_attribute_find(obj->template, CKA_MODULUS, &attr);
554 if (found == FALSE) {
555 TRACE_ERROR("Couldn't find a required attribute of "
556 "key object\n");
557 return CKR_TEMPLATE_INCONSISTENT;
558 }
559
560 /* make sure the key size is usable */
561 initFlags = util_get_keysize_flag(attr->ulValueLen * 8);
562 if (initFlags == 0) {
563 TRACE_ERROR("Invalid key size.\n");
564 return CKR_TEMPLATE_INCONSISTENT;
565 }
566
567 initFlags |=
568 TSS_KEY_TYPE_LEGACY | TSS_KEY_MIGRATABLE | TSS_KEY_NO_AUTHORIZATION;
569
570 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_RSAKEY,
571 initFlags, phKey);
572 if (result) {
573 TRACE_ERROR("Tspi_Context_CreateObject failed. " "rc=0x%x\n",
574 result);
575 return result;
576 }
577
578 result = util_set_public_modulus(*phKey,
579 attr->ulValueLen, attr->pValue);
580 if (result) {
581 TRACE_DEVEL("util_set_public_modulus failed: 0x%x\n", result);
582 Tspi_Context_CloseObject(tspContext, *phKey);
583 *phKey = NULL_HKEY;
584 return CKR_FUNCTION_FAILED;
585 }
586 } else {
587 TRACE_ERROR("Bad key class!\n");
588 return CKR_FUNCTION_FAILED;
589 }
590
591 /* grab the entire key blob to put into the PKCS#11 object */
592 result = Tspi_GetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB,
593 TSS_TSPATTRIB_KEYBLOB_BLOB,
594 &ulBlobLen, &rgbBlob);
595 if (result) {
596 TRACE_ERROR("Tspi_GetAttribData failed with rc: 0x%x\n", result);
597 return CKR_FUNCTION_FAILED;
598 }
599
600 /* insert the key blob into the object */
601 rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, &new_attr);
602 if (rc != CKR_OK) {
603 TRACE_DEVEL("build_atribute failed\n");
604 Tspi_Context_FreeMemory(tspContext, rgbBlob);
605 return rc;
606 }
607 template_update_attribute(obj->template, new_attr);
608 Tspi_Context_FreeMemory(tspContext, rgbBlob);
609
610 /* if this is a token object, save it with the new attribute so that we
611 * don't have to go down this path again */
612 if (!object_is_session_object(obj)) {
613 rc = XProcLock(tokdata);
614 if (rc != CKR_OK) {
615 TRACE_ERROR("Failed to get process lock.\n");
616 return rc;
617 }
618 rc = save_token_object(tokdata, obj);
619 if (rc != CKR_OK) {
620 XProcUnLock(tokdata);
621 } else {
622 rc = XProcUnLock(tokdata);
623 if (rc != CKR_OK) {
624 TRACE_ERROR("Failed to release process lock.\n");
625 return rc;
626 }
627 }
628 }
629
630 return rc;
631 }
632
633 /*
634 * load a key in the TSS hierarchy from its CK_OBJECT_HANDLE
635 */
token_load_key(STDLL_TokData_t * tokdata,CK_OBJECT_HANDLE ckKey,TSS_HKEY hParentKey,CK_CHAR_PTR passHash,TSS_HKEY * phKey)636 CK_RV token_load_key(STDLL_TokData_t * tokdata, CK_OBJECT_HANDLE ckKey,
637 TSS_HKEY hParentKey, CK_CHAR_PTR passHash,
638 TSS_HKEY * phKey)
639 {
640 TSS_RESULT result;
641 TSS_HPOLICY hPolicy;
642 CK_BYTE *blob = NULL;
643 CK_ULONG ulBlobSize = 0;
644 CK_RV rc;
645
646 rc = token_get_key_blob(tokdata, ckKey, &ulBlobSize, &blob);
647 if (rc != CKR_OK) {
648 if (rc != CKR_ATTRIBUTE_TYPE_INVALID) {
649 TRACE_DEVEL("token_get_key_blob failed. rc=0x%lx\n", rc);
650 return rc;
651 }
652 /* the key blob wasn't found, so check for a modulus
653 * to load */
654 TRACE_DEVEL("key blob not found, checking for modulus\n");
655 rc = token_wrap_key_object(tokdata, ckKey, hParentKey, phKey);
656 if (rc != CKR_OK) {
657 TRACE_DEVEL("token_wrap_key_object failed. rc=0x%lx\n", rc);
658 return rc;
659 }
660 }
661
662 if (blob != NULL) {
663 /* load the key inside the TSS */
664 result = Tspi_Context_LoadKeyByBlob(tspContext, hParentKey, ulBlobSize,
665 blob, phKey);
666 if (result) {
667 TRACE_ERROR("Tspi_Context_LoadKeyByBlob: 0x%x\n", result);
668 goto done;
669 }
670 }
671 #if 0
672 if ((result = Tspi_GetPolicyObject(*phKey, TSS_POLICY_USAGE, &hPolicy))) {
673 TRACE_ERROR("Tspi_GetPolicyObject: 0x%x\n", result);
674 goto done;
675 }
676 #else
677 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_POLICY,
678 TSS_POLICY_USAGE, &hPolicy);
679 if (result) {
680 TRACE_ERROR("Tspi_Context_CreateObject: 0x%x\n", result);
681 goto done;
682 }
683 #endif
684
685 if (passHash == NULL) {
686 result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE, 0, NULL);
687 } else {
688 result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
689 SHA1_HASH_SIZE, passHash);
690 }
691 if (result != TSS_SUCCESS) {
692 TRACE_ERROR("Tspi_Policy_SetSecret: 0x%x\n", result);
693 goto done;
694 }
695
696 result = Tspi_Policy_AssignToObject(hPolicy, *phKey);
697 if (result) {
698 TRACE_ERROR("Tspi_Policy_AssignToObject: 0x%x\n", result);
699 goto done;
700 }
701 done:
702 free(blob);
703
704 return result;
705 }
706
token_load_srk()707 TSS_RESULT token_load_srk()
708 {
709 TSS_HPOLICY hPolicy;
710 TSS_RESULT result;
711 TSS_UUID SRK_UUID = TSS_UUID_SRK;
712 struct srk_info srk;
713
714 if (hSRK != NULL_HKEY)
715 return TSS_SUCCESS;
716
717 /* load the SRK */
718 result = Tspi_Context_LoadKeyByUUID(tspContext,
719 TSS_PS_TYPE_SYSTEM, SRK_UUID, &hSRK);
720 if (result) {
721 TRACE_ERROR("Tspi_Context_LoadKeyByUUID failed. rc=0x%x\n", result);
722 goto done;
723 }
724 #if 0
725 if ((result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &hPolicy))) {
726 TRACE_ERROR("Tspi_GetPolicyObject failed. rc=0x%x\n", result);
727 goto done;
728 }
729 #else
730 result = Tspi_Context_CreateObject(tspContext,
731 TSS_OBJECT_TYPE_POLICY,
732 TSS_POLICY_USAGE, &hPolicy);
733 if (result) {
734 TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
735 goto done;
736 }
737
738 result = Tspi_Policy_AssignToObject(hPolicy, hSRK);
739 if (result) {
740 TRACE_ERROR("Tspi_Policy_AssignToObject failed. rc=0x%x\n", result);
741 goto done;
742 }
743 #endif
744
745 /* get the srk info */
746 memset(&srk, 0, sizeof(srk));
747 if (get_srk_info(&srk))
748 return -1;
749
750 result = Tspi_Policy_SetSecret(hPolicy, (TSS_FLAG) srk.mode,
751 srk.len, (BYTE *) srk.secret);
752 if (result)
753 TRACE_ERROR("Tspi_Policy_SetSecret failed. rc=0x%x\n", result);
754
755 if (srk.secret)
756 free(srk.secret);
757
758 done:
759 return result;
760 }
761
token_load_public_root_key(STDLL_TokData_t * tokdata)762 TSS_RESULT token_load_public_root_key(STDLL_TokData_t * tokdata)
763 {
764 TSS_RESULT result;
765 BYTE *blob;
766 CK_ULONG blob_size;
767
768 if (hPublicRootKey != NULL_HKEY)
769 return TSS_SUCCESS;
770
771 result = token_load_srk();
772 if (result) {
773 TRACE_DEVEL("token_load_srk failed. rc=0x%x\n", result);
774 return result;
775 }
776
777 result = token_find_key(tokdata, TPMTOK_PUBLIC_ROOT_KEY,
778 CKO_PRIVATE_KEY, &ckPublicRootKey);
779 if (result) {
780 TRACE_ERROR("token_find_key failed. rc=0x%x\n", result);
781 return CKR_FUNCTION_FAILED;
782 }
783
784 result = token_get_key_blob(tokdata, ckPublicRootKey, &blob_size, &blob);
785 if (result) {
786 TRACE_DEVEL("token_get_key_blob failed. rc=0x%x\n", result);
787 return CKR_FUNCTION_FAILED;
788 }
789
790 /* load the Public Root Key */
791 result = Tspi_Context_LoadKeyByBlob(tspContext, hSRK,
792 blob_size, blob, &hPublicRootKey);
793 if (result) {
794 TRACE_ERROR("Tspi_Context_LoadKeyByBlob failed. rc=0x%x\n", result);
795 free(blob);
796 return CKR_FUNCTION_FAILED;
797 }
798 free(blob);
799
800 return result;
801 }
802
tss_generate_key(TSS_FLAG initFlags,BYTE * passHash,TSS_HKEY hParentKey,TSS_HKEY * phKey)803 TSS_RESULT tss_generate_key(TSS_FLAG initFlags, BYTE * passHash,
804 TSS_HKEY hParentKey, TSS_HKEY * phKey)
805 {
806 TSS_RESULT result;
807 TSS_HPOLICY hPolicy, hMigPolicy = 0;
808
809 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_RSAKEY,
810 initFlags, phKey);
811 if (result) {
812 TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
813 return result;
814 }
815 #if 0
816 if ((result = Tspi_GetPolicyObject(*phKey, TSS_POLICY_USAGE, &hPolicy))) {
817 TRACE_ERROR("Tspi_GetPolicyObject failed. rc=0x%x\n", result);
818 Tspi_Context_CloseObject(tspContext, *phKey);
819 return result;
820 }
821 #else
822 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_POLICY,
823 TSS_POLICY_USAGE, &hPolicy);
824 if (result) {
825 TRACE_ERROR("Tspi_Context_CreateObject: 0x%x\n", result);
826 Tspi_Context_CloseObject(tspContext, *phKey);
827 return result;
828 }
829 #endif
830
831 if (passHash == NULL) {
832 result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE, 0, NULL);
833 } else {
834 result =
835 Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, 20, passHash);
836 }
837 if (result != TSS_SUCCESS) {
838 TRACE_ERROR("Tspi_Policy_SetSecret failed. rc=0x%x\n", result);
839 Tspi_Context_CloseObject(tspContext, *phKey);
840 Tspi_Context_CloseObject(tspContext, hPolicy);
841 return result;
842 }
843
844 result = Tspi_Policy_AssignToObject(hPolicy, *phKey);
845 if (result) {
846 TRACE_ERROR("Tspi_Policy_AssignToObject: 0x%x\n", result);
847 Tspi_Context_CloseObject(tspContext, *phKey);
848 Tspi_Context_CloseObject(tspContext, hPolicy);
849 return result;
850 }
851
852 if (TPMTOK_TSS_KEY_MIG_TYPE(initFlags) == TSS_KEY_MIGRATABLE) {
853 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_POLICY,
854 TSS_POLICY_MIGRATION, &hMigPolicy);
855 if (result) {
856 TRACE_ERROR("Tspi_Context_CreateObject: 0x%x\n", result);
857 Tspi_Context_CloseObject(tspContext, *phKey);
858 Tspi_Context_CloseObject(tspContext, hPolicy);
859 return result;
860 }
861
862 if (passHash == NULL) {
863 result =
864 Tspi_Policy_SetSecret(hMigPolicy, TSS_SECRET_MODE_NONE, 0,
865 NULL);
866 } else {
867 result = Tspi_Policy_SetSecret(hMigPolicy, TSS_SECRET_MODE_SHA1, 20,
868 passHash);
869 }
870
871 if (result != TSS_SUCCESS) {
872 TRACE_ERROR("Tspi_Policy_SetSecret failed. rc=0x%x\n", result);
873 Tspi_Context_CloseObject(tspContext, *phKey);
874 Tspi_Context_CloseObject(tspContext, hPolicy);
875 Tspi_Context_CloseObject(tspContext, hMigPolicy);
876 return result;
877 }
878
879 result = Tspi_Policy_AssignToObject(hMigPolicy, *phKey);
880 if (result) {
881 TRACE_ERROR("Tspi_Policy_AssignToObject: 0x%x\n", result);
882 Tspi_Context_CloseObject(tspContext, *phKey);
883 Tspi_Context_CloseObject(tspContext, hPolicy);
884 Tspi_Context_CloseObject(tspContext, hMigPolicy);
885 return result;
886 }
887 }
888
889 if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) {
890 result = Tspi_SetAttribUint32(*phKey, TSS_TSPATTRIB_KEY_INFO,
891 TSS_TSPATTRIB_KEYINFO_ENCSCHEME,
892 TSS_ES_RSAESPKCSV15);
893 if (result) {
894 TRACE_ERROR("Tspi_SetAttribUint32 failed. rc=0x%x\n", result);
895 Tspi_Context_CloseObject(tspContext, *phKey);
896 Tspi_Context_CloseObject(tspContext, hPolicy);
897 Tspi_Context_CloseObject(tspContext, hMigPolicy);
898 return result;
899 }
900
901 result = Tspi_SetAttribUint32(*phKey, TSS_TSPATTRIB_KEY_INFO,
902 TSS_TSPATTRIB_KEYINFO_SIGSCHEME,
903 TSS_SS_RSASSAPKCS1V15_DER);
904 if (result) {
905 TRACE_ERROR("Tspi_SetAttribUint32 failed. rc=0x%x\n", result);
906 Tspi_Context_CloseObject(tspContext, *phKey);
907 Tspi_Context_CloseObject(tspContext, hPolicy);
908 Tspi_Context_CloseObject(tspContext, hMigPolicy);
909 return result;
910 }
911 }
912
913 result = Tspi_Key_CreateKey(*phKey, hParentKey, 0);
914 if (result) {
915 TRACE_ERROR("Tspi_Key_CreateKey failed with rc: 0x%x\n", result);
916 Tspi_Context_CloseObject(tspContext, *phKey);
917 Tspi_Context_CloseObject(tspContext, hPolicy);
918 Tspi_Context_CloseObject(tspContext, hMigPolicy);
919 }
920
921 return result;
922 }
923
tss_change_auth(TSS_HKEY hObjectToChange,TSS_HKEY hParentObject,CK_CHAR * passHash)924 TSS_RESULT tss_change_auth(TSS_HKEY hObjectToChange, TSS_HKEY hParentObject,
925 CK_CHAR * passHash)
926 {
927 TSS_RESULT result;
928 TSS_HPOLICY hPolicy;
929
930 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_POLICY,
931 TSS_POLICY_USAGE, &hPolicy);
932 if (result) {
933 TRACE_ERROR("Tspi_Context_CreateObject failed: 0x%x\n", result);
934 return result;
935 }
936
937 result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
938 SHA1_HASH_SIZE, passHash);
939 if (result) {
940 TRACE_ERROR("Tspi_Policy_SetSecret failed: 0x%x\n", result);
941 return result;
942 }
943
944 result = Tspi_ChangeAuth(hObjectToChange, hParentObject, hPolicy);
945 if (result) {
946 TRACE_ERROR("Tspi_ChangeAuth failed: 0x%x\n", result);
947 }
948
949 return result;
950 }
951
token_store_priv_key(STDLL_TokData_t * tokdata,TSS_HKEY hKey,int key_type,CK_OBJECT_HANDLE * ckKey)952 CK_RV token_store_priv_key(STDLL_TokData_t * tokdata, TSS_HKEY hKey,
953 int key_type, CK_OBJECT_HANDLE * ckKey)
954 {
955 CK_ATTRIBUTE *new_attr = NULL;
956 OBJECT *priv_key_obj = NULL;
957 BYTE *rgbBlob = NULL, *rgbPrivBlob = NULL;
958 UINT32 ulBlobLen = 0, ulPrivBlobLen = 0;
959 CK_BBOOL flag;
960 CK_BYTE *key_id = util_create_id(key_type);
961 CK_RV rc;
962 SESSION dummy_sess;
963
964 /* set up dummy session */
965 memset(&dummy_sess, 0, sizeof(SESSION));
966 dummy_sess.session_info.state = CKS_RW_USER_FUNCTIONS;
967
968 /* grab the entire key blob to put into the PKCS#11 private key object */
969 rc = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
970 TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob);
971 if (rc) {
972 TRACE_ERROR("Tspi_GetAttribData failed with rc: 0x%lx\n", rc);
973 free(key_id);
974 return rc;
975 }
976
977 /* grab the encrypted provate key to put into the object */
978 rc = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
979 TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY,
980 &ulPrivBlobLen, &rgbPrivBlob);
981 if (rc) {
982 TRACE_ERROR("Tspi_GetAttribData failed with rc: 0x%lx\n", rc);
983 Tspi_Context_FreeMemory(tspContext, rgbBlob);
984 free(key_id);
985 return rc;
986 }
987
988 /* create skeleton for the private key object */
989 rc = object_create_skel(tokdata, NULL, 0, MODE_KEYGEN,
990 CKO_PRIVATE_KEY, CKK_RSA, &priv_key_obj);
991 if (rc != CKR_OK) {
992 TRACE_DEVEL("objectr_create_skel: 0x%lx\n", rc);
993 Tspi_Context_FreeMemory(tspContext, rgbBlob);
994 Tspi_Context_FreeMemory(tspContext, rgbPrivBlob);
995 free(key_id);
996 return rc;
997 }
998
999 /* add the ID attribute */
1000 rc = build_attribute(CKA_ID, key_id, strlen((char *) key_id), &new_attr);
1001 if (rc != CKR_OK) {
1002 TRACE_DEVEL("build_attribute failed\n");
1003 Tspi_Context_FreeMemory(tspContext, rgbBlob);
1004 Tspi_Context_FreeMemory(tspContext, rgbPrivBlob);
1005 free(key_id);
1006 return rc;
1007 }
1008 template_update_attribute(priv_key_obj->template, new_attr);
1009 free(key_id);
1010
1011 /* add the key blob to the PKCS#11 object template */
1012 rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, &new_attr);
1013 if (rc != CKR_OK) {
1014 TRACE_DEVEL("build_attribute failed\n");
1015 Tspi_Context_FreeMemory(tspContext, rgbBlob);
1016 Tspi_Context_FreeMemory(tspContext, rgbPrivBlob);
1017 return rc;
1018 }
1019 template_update_attribute(priv_key_obj->template, new_attr);
1020 Tspi_Context_FreeMemory(tspContext, rgbBlob);
1021
1022 /* add the private key blob to the PKCS#11 object template */
1023 rc = build_attribute(CKA_MODULUS, rgbPrivBlob, ulPrivBlobLen, &new_attr);
1024 if (rc != CKR_OK) {
1025 TRACE_DEVEL("build_attribute failed\n");
1026 Tspi_Context_FreeMemory(tspContext, rgbPrivBlob);
1027 return rc;
1028 }
1029 template_update_attribute(priv_key_obj->template, new_attr);
1030 Tspi_Context_FreeMemory(tspContext, rgbPrivBlob);
1031
1032 /* add the HIDDEN attribute */
1033 flag = TRUE;
1034 rc = build_attribute(CKA_HIDDEN, &flag, sizeof(CK_BBOOL), &new_attr);
1035 if (rc != CKR_OK) {
1036 TRACE_DEVEL("build_attribute failed\n");
1037 return rc;
1038 }
1039 template_update_attribute(priv_key_obj->template, new_attr);
1040
1041 /* set CKA_ALWAYS_SENSITIVE to true */
1042 rc = build_attribute(CKA_ALWAYS_SENSITIVE, &flag,
1043 sizeof(CK_BBOOL), &new_attr);
1044 if (rc != CKR_OK) {
1045 TRACE_DEVEL("build_attribute failed\n");
1046 return rc;
1047 }
1048 template_update_attribute(priv_key_obj->template, new_attr);
1049
1050 /* set CKA_NEVER_EXTRACTABLE to true */
1051 rc = build_attribute(CKA_NEVER_EXTRACTABLE,
1052 &flag, sizeof(CK_BBOOL), &new_attr);
1053 if (rc != CKR_OK) {
1054 TRACE_DEVEL("build_attribute failed\n");
1055 return rc;
1056 }
1057 template_update_attribute(priv_key_obj->template, new_attr);
1058
1059 /* make the object reside on the token, as if that were possible */
1060 rc = build_attribute(CKA_TOKEN, &flag, sizeof(CK_BBOOL), &new_attr);
1061 if (rc != CKR_OK) {
1062 TRACE_DEVEL("build_attribute failed\n");
1063 return rc;
1064 }
1065 template_update_attribute(priv_key_obj->template, new_attr);
1066
1067 flag = FALSE;
1068 rc = build_attribute(CKA_PRIVATE, &flag, sizeof(CK_BBOOL), &new_attr);
1069 if (rc != CKR_OK) {
1070 TRACE_DEVEL("build_attribute failed\n");
1071 return rc;
1072 }
1073 template_update_attribute(priv_key_obj->template, new_attr);
1074
1075 rc = object_mgr_create_final(tokdata, &dummy_sess, priv_key_obj, ckKey);
1076 if (rc != CKR_OK) {
1077 TRACE_DEVEL("object_mgr_create_final failed.\n");
1078 }
1079
1080 return rc;
1081 }
1082
token_store_pub_key(STDLL_TokData_t * tokdata,TSS_HKEY hKey,int key_type,CK_OBJECT_HANDLE * ckKey)1083 CK_RV token_store_pub_key(STDLL_TokData_t * tokdata, TSS_HKEY hKey,
1084 int key_type, CK_OBJECT_HANDLE * ckKey)
1085 {
1086 CK_RV rc;
1087 TSS_RESULT result;
1088 CK_ATTRIBUTE *new_attr = NULL;
1089 OBJECT *pub_key_obj;
1090 CK_BBOOL flag = TRUE;
1091 CK_OBJECT_CLASS pub_class = CKO_PUBLIC_KEY;
1092 CK_KEY_TYPE type = CKK_RSA;
1093 CK_BYTE *key_id = util_create_id(key_type);
1094 CK_BYTE pub_exp[] = { 1, 0, 1 }; // 65537
1095 CK_ATTRIBUTE pub_tmpl[] = {
1096 {CKA_CLASS, &pub_class, sizeof(pub_class)},
1097 {CKA_KEY_TYPE, &type, sizeof(type)},
1098 {CKA_ID, key_id, strlen((char *) key_id)},
1099 {CKA_PUBLIC_EXPONENT, pub_exp, sizeof(pub_exp)},
1100 {CKA_MODULUS, NULL_PTR, 0}
1101 };
1102 BYTE *rgbPubBlob = NULL;
1103 UINT32 ulBlobLen = 0;
1104 SESSION dummy_sess;
1105
1106 /* set up dummy session */
1107 memset(&dummy_sess, 0, sizeof(SESSION));
1108 dummy_sess.session_info.state = CKS_RW_USER_FUNCTIONS;
1109
1110 /* grab the public key to put into the PKCS#11 public key object */
1111 result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
1112 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS,
1113 &ulBlobLen, &rgbPubBlob);
1114 if (result) {
1115 TRACE_ERROR("Tspi_GetAttribData failed with rc: 0x%x\n", result);
1116 Tspi_Context_CloseObject(tspContext, hKey);
1117 free(key_id);
1118 return result;
1119 }
1120
1121 pub_tmpl[4].pValue = rgbPubBlob;
1122 pub_tmpl[4].ulValueLen = ulBlobLen;
1123
1124 /* create skeleton for the private key object */
1125 rc = object_create_skel(tokdata, pub_tmpl, 5, MODE_CREATE,
1126 CKO_PUBLIC_KEY, CKK_RSA, &pub_key_obj);
1127 if (rc != CKR_OK) {
1128 TRACE_DEVEL("object_create_skel: 0x%lx\n", rc);
1129 Tspi_Context_CloseObject(tspContext, hKey);
1130 free(key_id);
1131 return rc;
1132 }
1133 Tspi_Context_FreeMemory(tspContext, rgbPubBlob);
1134
1135 /* make the object reside on the token, as if that were possible */
1136 rc = build_attribute(CKA_TOKEN, &flag, sizeof(CK_BBOOL), &new_attr);
1137 if (rc != CKR_OK) {
1138 TRACE_DEVEL("build attribute failed.\n");
1139 goto done;
1140 }
1141 template_update_attribute(pub_key_obj->template, new_attr);
1142
1143 /* set the object to be hidden */
1144 rc = build_attribute(CKA_HIDDEN, &flag, sizeof(CK_BBOOL), &new_attr);
1145 if (rc != CKR_OK) {
1146 TRACE_DEVEL("build attribute failed.\n");
1147 goto done;
1148 }
1149 template_update_attribute(pub_key_obj->template, new_attr);
1150
1151 rc = object_mgr_create_final(tokdata, &dummy_sess, pub_key_obj, ckKey);
1152 if (rc != CKR_OK) {
1153 TRACE_DEVEL("object_mgr_create_final failed\n");
1154 goto done;
1155 }
1156
1157 done:
1158 return rc;
1159 }
1160
token_update_private_key(STDLL_TokData_t * tokdata,TSS_HKEY hKey,int key_type)1161 CK_RV token_update_private_key(STDLL_TokData_t * tokdata, TSS_HKEY hKey,
1162 int key_type)
1163 {
1164 CK_OBJECT_HANDLE ckHandle;
1165 CK_RV rc;
1166 SESSION dummy_sess;
1167
1168 /* set up dummy session */
1169 memset(&dummy_sess, 0, sizeof(SESSION));
1170 dummy_sess.session_info.state = CKS_RW_USER_FUNCTIONS;
1171
1172 /* find the private key portion of the key */
1173 rc = token_find_key(tokdata, key_type, CKO_PRIVATE_KEY, &ckHandle);
1174 if (rc != CKR_OK) {
1175 TRACE_ERROR("token_find_key failed: 0x%lx\n", rc);
1176 return rc;
1177 }
1178
1179 /* destroy the private key and create a new one */
1180 rc = object_mgr_destroy_object(tokdata, &dummy_sess, ckHandle);
1181 if (rc != CKR_OK) {
1182 TRACE_DEVEL("object_mgr_destroy_object failed: 0x%lx\n", rc);
1183 return rc;
1184 }
1185
1186 rc = token_store_priv_key(tokdata, hKey, key_type, &ckHandle);
1187 if (rc != CKR_OK) {
1188 TRACE_DEVEL("token_store_priv_key failed: 0x%lx\n", rc);
1189 }
1190
1191 return rc;
1192 }
1193
token_store_tss_key(STDLL_TokData_t * tokdata,TSS_HKEY hKey,int key_type,CK_OBJECT_HANDLE * ckKey)1194 CK_RV token_store_tss_key(STDLL_TokData_t * tokdata, TSS_HKEY hKey,
1195 int key_type, CK_OBJECT_HANDLE * ckKey)
1196 {
1197 CK_RV rc;
1198
1199 /* create a PKCS#11 pub key object for the key */
1200 rc = token_store_pub_key(tokdata, hKey, key_type, ckKey);
1201 if (rc != CKR_OK) {
1202 TRACE_DEVEL("token_store_pub_key failed. rc=0x%lx\n", rc);
1203 return rc;
1204 }
1205
1206 /* create a PKCS#11 private key object for the key */
1207 rc = token_store_priv_key(tokdata, hKey, key_type, ckKey);
1208 if (rc != CKR_OK) {
1209 TRACE_DEVEL("token_store_priv_key failed. rc=0x%lx\n", rc);
1210 }
1211
1212 return rc;
1213 }
1214
token_generate_leaf_key(STDLL_TokData_t * tokdata,int key_type,CK_CHAR_PTR passHash,TSS_HKEY * phKey)1215 CK_RV token_generate_leaf_key(STDLL_TokData_t * tokdata, int key_type,
1216 CK_CHAR_PTR passHash, TSS_HKEY * phKey)
1217 {
1218 CK_RV rc = CKR_FUNCTION_FAILED;
1219 TSS_RESULT result;
1220 TSS_HKEY hParentKey;
1221 CK_OBJECT_HANDLE *ckKey;
1222 TSS_FLAG initFlags = TSS_KEY_MIGRATABLE | TSS_KEY_TYPE_BIND |
1223 TSS_KEY_SIZE_2048 | TSS_KEY_AUTHORIZATION;
1224
1225 switch (key_type) {
1226 case TPMTOK_PUBLIC_LEAF_KEY:
1227 hParentKey = hPublicRootKey;
1228 ckKey = &ckPublicRootKey;
1229 break;
1230 case TPMTOK_PRIVATE_LEAF_KEY:
1231 hParentKey = hPrivateRootKey;
1232 ckKey = &ckPrivateRootKey;
1233 break;
1234 default:
1235 TRACE_ERROR("Unknown key type.\n");
1236 goto done;
1237 break;
1238 }
1239
1240 result = tss_generate_key(initFlags, passHash, hParentKey, phKey);
1241 if (result) {
1242 TRACE_ERROR("tss_generate_key returned 0x%x\n", result);
1243 return result;
1244 }
1245
1246 rc = token_store_tss_key(tokdata, *phKey, key_type, ckKey);
1247 if (rc != CKR_OK) {
1248 TRACE_DEVEL("token_store_tss_key failed. rc=0x%x\n", result);
1249 }
1250
1251 done:
1252 return rc;
1253 }
1254
token_verify_pin(TSS_HKEY hKey)1255 CK_RV token_verify_pin(TSS_HKEY hKey)
1256 {
1257 TSS_HENCDATA hEncData;
1258 UINT32 ulUnboundDataLen;
1259 BYTE *rgbUnboundData;
1260 char *rgbData = "CRAPPENFEST";
1261 TSS_RESULT result;
1262 CK_RV rc = CKR_FUNCTION_FAILED;
1263
1264 result = Tspi_Context_CreateObject(tspContext,
1265 TSS_OBJECT_TYPE_ENCDATA,
1266 TSS_ENCDATA_BIND, &hEncData);
1267 if (result) {
1268 TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
1269 goto done;
1270 }
1271
1272 result = Tspi_Data_Bind(hEncData, hKey, strlen(rgbData), (BYTE *) rgbData);
1273 if (result) {
1274 TRACE_ERROR("Tspi_Data_Bind returned 0x%x\n", result);
1275 goto done;
1276 }
1277
1278 /* unbind the junk data to test the key's auth data */
1279 result =
1280 Tspi_Data_Unbind(hEncData, hKey, &ulUnboundDataLen, &rgbUnboundData);
1281 if (result == TCPA_E_AUTHFAIL) {
1282 rc = CKR_PIN_INCORRECT;
1283 TRACE_ERROR("Tspi_Data_Unbind returned TCPA_AUTHFAIL\n");
1284 goto done;
1285 } else if (result != TSS_SUCCESS) {
1286 TRACE_ERROR("Tspi_Data_ Unbind returned 0x%x\n", result);
1287 goto done;
1288 }
1289
1290 rc = memcmp(rgbUnboundData, rgbData, ulUnboundDataLen);
1291
1292 Tspi_Context_FreeMemory(tspContext, rgbUnboundData);
1293 done:
1294 Tspi_Context_CloseObject(tspContext, hEncData);
1295
1296 return rc;
1297 }
1298
token_create_private_tree(STDLL_TokData_t * tokdata,CK_BYTE * pinHash,CK_BYTE * pPin)1299 CK_RV token_create_private_tree(STDLL_TokData_t * tokdata, CK_BYTE * pinHash,
1300 CK_BYTE * pPin)
1301 {
1302 CK_RV rc;
1303 TSS_RESULT result;
1304 RSA *rsa;
1305 unsigned int size_n, size_p;
1306 unsigned char n[256], p[256];
1307
1308 /* all sw generated keys are 2048 bits */
1309 if ((rsa = openssl_gen_key()) == NULL)
1310 return CKR_HOST_MEMORY;
1311
1312 if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) {
1313 TRACE_DEVEL("openssl_get_modulus_and_prime failed\n");
1314 return CKR_FUNCTION_FAILED;
1315 }
1316
1317 /* generate the software based user base key */
1318 rc = token_wrap_sw_key(size_n, n, size_p, p, hSRK,
1319 TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE,
1320 &hPrivateRootKey);
1321 if (rc != CKR_OK) {
1322 TRACE_DEVEL("token_wrap_sw_key failed. rc=0x%lu\n", rc);
1323 return rc;
1324 }
1325
1326 if (openssl_write_key(rsa, TPMTOK_PRIV_ROOT_KEY_FILE, pPin)) {
1327 TRACE_DEVEL("openssl_write_key failed.\n");
1328 RSA_free(rsa);
1329 return CKR_FUNCTION_FAILED;
1330 }
1331
1332 RSA_free(rsa);
1333
1334 /* store the user base key in a PKCS#11 object internally */
1335 rc = token_store_tss_key(tokdata, hPrivateRootKey,
1336 TPMTOK_PRIVATE_ROOT_KEY,
1337 &ckPrivateRootKey);
1338 if (rc != CKR_OK) {
1339 TRACE_DEVEL("token_store_tss_key failed. rc=0x%lx\n", rc);
1340 return rc;
1341 }
1342
1343 result = Tspi_Key_LoadKey(hPrivateRootKey, hSRK);
1344 if (result) {
1345 TRACE_ERROR("Tspi_Key_LoadKey: 0x%x\n", result);
1346 Tspi_Context_CloseObject(tspContext, hPrivateRootKey);
1347 hPrivateRootKey = NULL_HKEY;
1348 return CKR_FUNCTION_FAILED;
1349 }
1350
1351 /* generate the private leaf key */
1352 rc = token_generate_leaf_key(tokdata, TPMTOK_PRIVATE_LEAF_KEY,
1353 pinHash, &hPrivateLeafKey);
1354 if (rc != CKR_OK) {
1355 TRACE_DEVEL("token_generate_leaf_key failed. rc=0x%lx\n", rc);
1356 return rc;
1357 }
1358
1359 result = Tspi_Key_LoadKey(hPrivateLeafKey, hPrivateRootKey);
1360 if (result) {
1361 TRACE_ERROR("Tspi_Key_LoadKey: 0x%x\n", result);
1362 Tspi_Context_CloseObject(tspContext, hPrivateRootKey);
1363 hPrivateRootKey = NULL_HKEY;
1364 Tspi_Context_CloseObject(tspContext, hPrivateLeafKey);
1365 hPrivateRootKey = NULL_HKEY;
1366 return CKR_FUNCTION_FAILED;
1367 }
1368
1369 return rc;
1370 }
1371
token_create_public_tree(STDLL_TokData_t * tokdata,CK_BYTE * pinHash,CK_BYTE * pPin)1372 CK_RV token_create_public_tree(STDLL_TokData_t * tokdata, CK_BYTE * pinHash,
1373 CK_BYTE * pPin)
1374 {
1375 CK_RV rc;
1376 TSS_RESULT result;
1377 RSA *rsa;
1378 unsigned int size_n, size_p;
1379 unsigned char n[256], p[256];
1380
1381 /* all sw generated keys are 2048 bits */
1382 if ((rsa = openssl_gen_key()) == NULL)
1383 return CKR_HOST_MEMORY;
1384
1385 if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) {
1386 TRACE_DEVEL("openssl_get_modulus_and_prime failed\n");
1387 return CKR_FUNCTION_FAILED;
1388 }
1389
1390 /* create the public root key */
1391 rc = token_wrap_sw_key(size_n, n, size_p, p, hSRK,
1392 TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE,
1393 &hPublicRootKey);
1394 if (rc != CKR_OK) {
1395 TRACE_DEVEL("token_wrap_sw_key failed. rc=0x%lx\n", rc);
1396 return rc;
1397 }
1398
1399 if (openssl_write_key(rsa, TPMTOK_PUB_ROOT_KEY_FILE, pPin)) {
1400 TRACE_DEVEL("openssl_write_key\n");
1401 RSA_free(rsa);
1402 return CKR_FUNCTION_FAILED;
1403 }
1404
1405 RSA_free(rsa);
1406
1407 result = Tspi_Key_LoadKey(hPublicRootKey, hSRK);
1408 if (result) {
1409 TRACE_ERROR("Tspi_Key_LoadKey: 0x%x\n", result);
1410 Tspi_Context_CloseObject(tspContext, hPublicRootKey);
1411 hPublicRootKey = NULL_HKEY;
1412 return CKR_FUNCTION_FAILED;
1413 }
1414
1415 rc = token_store_tss_key(tokdata, hPublicRootKey,
1416 TPMTOK_PUBLIC_ROOT_KEY, &ckPublicRootKey);
1417 if (rc != CKR_OK) {
1418 TRACE_DEVEL("token_store_tss_key failed. rc=0x%lx\n", rc);
1419 return rc;
1420 }
1421
1422 /* create the SO's leaf key */
1423 rc = token_generate_leaf_key(tokdata, TPMTOK_PUBLIC_LEAF_KEY,
1424 pinHash, &hPublicLeafKey);
1425 if (rc != CKR_OK) {
1426 TRACE_DEVEL("token_generate_leaf_key failed. rc=0x%lx\n", rc);
1427 return rc;
1428 }
1429
1430 result = Tspi_Key_LoadKey(hPublicLeafKey, hPublicRootKey);
1431 if (result) {
1432 TRACE_ERROR("Tspi_Key_LoadKey: 0x%x\n", result);
1433 Tspi_Context_CloseObject(tspContext, hPublicRootKey);
1434 hPublicRootKey = NULL_HKEY;
1435 Tspi_Context_CloseObject(tspContext, hPublicLeafKey);
1436 hPublicLeafKey = NULL_HKEY;
1437 return CKR_FUNCTION_FAILED;
1438 }
1439
1440 return rc;
1441 }
1442
token_migrate(STDLL_TokData_t * tokdata,int key_type,CK_BYTE * pin)1443 CK_RV token_migrate(STDLL_TokData_t * tokdata, int key_type, CK_BYTE * pin)
1444 {
1445 RSA *rsa;
1446 char *backup_loc;
1447 unsigned int size_n, size_p;
1448 unsigned char n[256], p[256];
1449 TSS_RESULT result;
1450 TSS_HKEY *phKey;
1451 CK_RV rc;
1452 CK_OBJECT_HANDLE *ckHandle;
1453 SESSION dummy_sess;
1454
1455 /* set up dummy session */
1456 memset(&dummy_sess, 0, sizeof(SESSION));
1457 dummy_sess.session_info.state = CKS_RW_USER_FUNCTIONS;
1458
1459 if (key_type == TPMTOK_PUBLIC_ROOT_KEY) {
1460 backup_loc = TPMTOK_PUB_ROOT_KEY_FILE;
1461 phKey = &hPublicRootKey;
1462 ckHandle = &ckPublicRootKey;
1463 } else if (key_type == TPMTOK_PRIVATE_ROOT_KEY) {
1464 backup_loc = TPMTOK_PRIV_ROOT_KEY_FILE;
1465 phKey = &hPrivateRootKey;
1466 ckHandle = &ckPrivateRootKey;
1467 } else {
1468 TRACE_ERROR("Invalid key type.\n");
1469 return CKR_FUNCTION_FAILED;
1470 }
1471
1472 /* read the backup key with the old pin */
1473 if ((rc = openssl_read_key(backup_loc, pin, &rsa))) {
1474 if (rc == CKR_FILE_NOT_FOUND)
1475 rc = CKR_FUNCTION_FAILED;
1476 TRACE_DEVEL("openssl_read_key failed\n");
1477 return rc;
1478 }
1479
1480 /* So, reading the backup openssl key off disk succeeded with the SOs PIN.
1481 * We will now try to re-wrap that key with the current SRK
1482 */
1483 if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) {
1484 TRACE_DEVEL("openssl_get_modulus_and_prime failed\n");
1485 return CKR_FUNCTION_FAILED;
1486 }
1487
1488 rc = token_wrap_sw_key(size_n, n, size_p, p, hSRK,
1489 TSS_KEY_TYPE_STORAGE | TSS_KEY_NO_AUTHORIZATION,
1490 phKey);
1491 if (rc != CKR_OK) {
1492 TRACE_DEVEL("token_wrap_sw_key failed. rc=0x%lx\n", rc);
1493 RSA_free(rsa);
1494 return rc;
1495 }
1496 RSA_free(rsa);
1497
1498 result = Tspi_Key_LoadKey(*phKey, hSRK);
1499 if (result) {
1500 TRACE_ERROR("Tspi_Key_LoadKey: 0x%x\n", result);
1501 Tspi_Context_CloseObject(tspContext, *phKey);
1502 *phKey = NULL_HKEY;
1503 return CKR_FUNCTION_FAILED;
1504 }
1505
1506 /* Loading succeeded, so we need to get rid of the old PKCS#11 objects
1507 * and store them anew.
1508 */
1509 rc = token_find_key(tokdata, key_type, CKO_PUBLIC_KEY, ckHandle);
1510 if (rc != CKR_OK) {
1511 TRACE_ERROR("token_find_key failed. rc=0x%lx\n", rc);
1512 return CKR_FUNCTION_FAILED;
1513 }
1514
1515 rc = object_mgr_destroy_object(tokdata, &dummy_sess, *ckHandle);
1516 if (rc != CKR_OK) {
1517 TRACE_DEVEL("object_mgr_destroy_object failed: 0x%lx\n", rc);
1518 return rc;
1519 }
1520
1521 rc = token_find_key(tokdata, key_type, CKO_PRIVATE_KEY, ckHandle);
1522 if (rc != CKR_OK) {
1523 TRACE_ERROR("token_find_key failed. rc=0x%lx\n", rc);
1524 return CKR_FUNCTION_FAILED;
1525 }
1526
1527 rc = object_mgr_destroy_object(tokdata, &dummy_sess, *ckHandle);
1528 if (rc != CKR_OK) {
1529 TRACE_DEVEL("object_mgr_destroy_object failed: 0x%lx\n", rc);
1530 return rc;
1531 }
1532
1533 rc = token_store_tss_key(tokdata, *phKey, key_type, ckHandle);
1534 if (rc != CKR_OK) {
1535 TRACE_DEVEL("token_store_tss_key failed: 0x%lx\n", rc);
1536 return rc;
1537 }
1538
1539 return CKR_OK;
1540 }
1541
save_masterkey_private()1542 CK_RV save_masterkey_private()
1543 {
1544 char fname[PATH_MAX];
1545 struct stat file_stat;
1546 int err;
1547 FILE *fp = NULL;
1548 struct passwd *pw = NULL;
1549
1550 TSS_RESULT result;
1551 TSS_HENCDATA hEncData;
1552 BYTE *encrypted_masterkey;
1553 UINT32 encrypted_masterkey_size;
1554
1555 pw = getpwuid(getuid());
1556 if (pw == NULL) {
1557 TRACE_ERROR("getpwuid failed: %s\n", strerror(errno));
1558 return CKR_FUNCTION_FAILED;
1559 }
1560 //fp = fopen("/etc/pkcs11/tpm/MK_PRIVATE", "r");
1561 sprintf(fname, "%s/%s/%s", pk_dir, pw->pw_name,
1562 TPMTOK_MASTERKEY_PRIVATE);
1563
1564 /* if file exists, assume its been written correctly before */
1565 err = stat(fname, &file_stat);
1566 if (err == 0) {
1567 return CKR_OK;
1568 } else if (errno != ENOENT) {
1569 /* some error other than file doesn't exist */
1570 return CKR_FUNCTION_FAILED;
1571 }
1572
1573 /* encrypt the private masterkey using the private leaf key */
1574 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_ENCDATA,
1575 TSS_ENCDATA_BIND, &hEncData);
1576 if (result) {
1577 TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
1578 return CKR_FUNCTION_FAILED;
1579 }
1580
1581 result = Tspi_Data_Bind(hEncData, hPrivateLeafKey,
1582 MK_SIZE, master_key_private);
1583 if (result) {
1584 TRACE_ERROR("Tspi_Data_Bind failed. rc=0x%x\n", result);
1585 return CKR_FUNCTION_FAILED;
1586 }
1587
1588 result = Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
1589 TSS_TSPATTRIB_ENCDATABLOB_BLOB,
1590 &encrypted_masterkey_size,
1591 &encrypted_masterkey);
1592 if (result) {
1593 TRACE_ERROR("Tspi_GetAttribData failed. rc=0x%x\n", result);
1594 return CKR_FUNCTION_FAILED;
1595 }
1596
1597 if (encrypted_masterkey_size > 256) {
1598 Tspi_Context_FreeMemory(tspContext, encrypted_masterkey);
1599 return CKR_DATA_LEN_RANGE;
1600 }
1601
1602 /* write the encrypted key to disk */
1603 if ((fp = fopen(fname, "w")) == NULL) {
1604 TRACE_ERROR("Error opening %s for write: %s\n", fname, strerror(errno));
1605 Tspi_Context_FreeMemory(tspContext, encrypted_masterkey);
1606 return CKR_FUNCTION_FAILED;
1607 }
1608
1609 err = fwrite(encrypted_masterkey, encrypted_masterkey_size, 1, fp);
1610 if (err == 0) {
1611 TRACE_ERROR("Error writing %s: %s\n", fname, strerror(errno));
1612 Tspi_Context_FreeMemory(tspContext, encrypted_masterkey);
1613 fclose(fp);
1614 return CKR_FUNCTION_FAILED;
1615 }
1616
1617 Tspi_Context_FreeMemory(tspContext, encrypted_masterkey);
1618 fclose(fp);
1619
1620 return CKR_OK;
1621 }
1622
load_masterkey_private(STDLL_TokData_t * tokdata)1623 CK_RV load_masterkey_private(STDLL_TokData_t * tokdata)
1624 {
1625 FILE *fp = NULL;
1626 int err;
1627 struct stat file_stat;
1628 CK_BYTE encrypted_masterkey[256];
1629 char fname[PATH_MAX];
1630 CK_RV rc;
1631 struct passwd *pw = NULL;
1632
1633 TSS_RESULT result;
1634 TSS_HENCDATA hEncData;
1635 BYTE *masterkey;
1636 UINT32 masterkey_size, encrypted_masterkey_size = 256;
1637
1638 pw = getpwuid(getuid());
1639 if (pw == NULL) {
1640 TRACE_ERROR("getpwuid failed: %s\n", strerror(errno));
1641 return CKR_FUNCTION_FAILED;
1642 }
1643
1644 sprintf(fname, "%s/%s/%s", pk_dir, pw->pw_name,
1645 TPMTOK_MASTERKEY_PRIVATE);
1646
1647 /* if file exists, check its size */
1648 err = stat(fname, &file_stat);
1649 if (err == 0) {
1650 if (file_stat.st_size != 256) {
1651 TRACE_ERROR("Private master key has been corrupted\n");
1652 return CKR_FUNCTION_FAILED;
1653 }
1654 } else if (errno == ENOENT) {
1655 TRACE_INFO("Private master key doesn't exist, creating it...\n");
1656
1657 /* create the private master key, then save */
1658 rc = token_specific_rng(tokdata, master_key_private, MK_SIZE);
1659 if (rc != CKR_OK) {
1660 TRACE_DEVEL("token_rng failed. rc=0x%lx\n", rc);
1661 return rc;
1662 }
1663
1664 return save_masterkey_private();
1665 } else {
1666 /* some error other than file doesn't exist */
1667 TRACE_ERROR("stat of private masterkey failed: %s\n", strerror(errno));
1668 return CKR_FUNCTION_FAILED;
1669 }
1670
1671 //fp = fopen("/etc/pkcs11/tpm/MK_PUBLIC", "r");
1672 if ((fp = fopen(fname, "r")) == NULL) {
1673 TRACE_ERROR("Error opening %s: %s\n", fname, strerror(errno));
1674 return CKR_FUNCTION_FAILED;
1675 }
1676
1677 if (fread(encrypted_masterkey, encrypted_masterkey_size, 1, fp) == 0) {
1678 TRACE_ERROR("Error reading %s: %s\n", fname, strerror(errno));
1679 fclose(fp);
1680 return CKR_FUNCTION_FAILED;
1681 }
1682 fclose(fp);
1683
1684 /* decrypt the private masterkey using the private leaf key */
1685 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_ENCDATA,
1686 TSS_ENCDATA_BIND, &hEncData);
1687 if (result) {
1688 TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
1689 return CKR_FUNCTION_FAILED;
1690 }
1691
1692 result = Tspi_SetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
1693 TSS_TSPATTRIB_ENCDATABLOB_BLOB,
1694 encrypted_masterkey_size,
1695 encrypted_masterkey);
1696 if (result) {
1697 TRACE_ERROR("Tspi_SetAttribData failed. rc=0x%x\n", result);
1698 return CKR_FUNCTION_FAILED;
1699 }
1700
1701 result = Tspi_Data_Unbind(hEncData, hPrivateLeafKey,
1702 &masterkey_size, &masterkey);
1703 if (result) {
1704 TRACE_ERROR("Tspi_Data_Unbind failed. rc=0x%x\n", result);
1705 return CKR_FUNCTION_FAILED;
1706 }
1707
1708 if (masterkey_size != MK_SIZE) {
1709 TRACE_ERROR("decrypted private master key size is %u, "
1710 "should be %u\n", masterkey_size, MK_SIZE);
1711 Tspi_Context_FreeMemory(tspContext, masterkey);
1712 return CKR_FUNCTION_FAILED;
1713 }
1714
1715 memcpy(master_key_private, masterkey, MK_SIZE);
1716 Tspi_Context_FreeMemory(tspContext, masterkey);
1717
1718 return CKR_OK;
1719 }
1720
1721
token_specific_login(STDLL_TokData_t * tokdata,SESSION * sess,CK_USER_TYPE userType,CK_CHAR_PTR pPin,CK_ULONG ulPinLen)1722 CK_RV token_specific_login(STDLL_TokData_t * tokdata, SESSION * sess,
1723 CK_USER_TYPE userType, CK_CHAR_PTR pPin,
1724 CK_ULONG ulPinLen)
1725 {
1726 CK_RV rc;
1727 CK_BYTE hash_sha[SHA1_HASH_SIZE];
1728 TSS_RESULT result;
1729
1730 UNUSED(sess);
1731
1732 result = token_load_srk();
1733 if (result) {
1734 TRACE_DEVEL("token_load_srk failed. rc=0x%x\n", result);
1735 return CKR_FUNCTION_FAILED;
1736 }
1737
1738 rc = compute_sha1(tokdata, pPin, ulPinLen, hash_sha);
1739 if (rc != CKR_OK) {
1740 TRACE_ERROR("compute_sha1 failed. rc=0x%lx\n", rc);
1741 return CKR_FUNCTION_FAILED;
1742 }
1743
1744 if (userType == CKU_USER) {
1745 /* If the public root key doesn't exist yet, the SO hasn't init'd the
1746 * token */
1747 result = token_load_public_root_key(tokdata);
1748 if (result) {
1749 TRACE_DEVEL("token_load_public_root_key failed. "
1750 "rc=0x%x\n", result);
1751 return CKR_USER_PIN_NOT_INITIALIZED;
1752 }
1753
1754 /* find, load the private root key */
1755 rc = token_find_key(tokdata, TPMTOK_PRIVATE_ROOT_KEY,
1756 CKO_PRIVATE_KEY, &ckPrivateRootKey);
1757 if (rc != CKR_OK) {
1758 /* user's key chain not found, this must be the initial login */
1759 if (memcmp(hash_sha, default_user_pin_sha, SHA1_HASH_SIZE)) {
1760 TRACE_ERROR("token_find_key failed and PIN != default\n");
1761 return CKR_PIN_INCORRECT;
1762 }
1763
1764 not_initialized = 1;
1765 return CKR_OK;
1766 }
1767
1768 rc = token_load_key(tokdata, ckPrivateRootKey,
1769 hSRK, NULL, &hPrivateRootKey);
1770 if (rc != CKR_OK) {
1771 TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
1772
1773 /* Here, we've found the private root key, but its load failed.
1774 * This should only happen in a migration path, where we have
1775 * the PKCS#11 key store available, but the SRK is now
1776 * different. So, we will try to decrypt the PEM backup file
1777 * for the private root key using the given password. If that
1778 * succeeds, we will assume that we're in a migration path and
1779 * re-wrap the private root key to the new SRK.
1780 */
1781 if ((token_migrate(tokdata, TPMTOK_PRIVATE_ROOT_KEY, pPin))) {
1782 TRACE_DEVEL("token_migrate. rc=0x%lx\n", rc);
1783 return rc;
1784 }
1785
1786 /* At this point, the public root key has been successfully read
1787 * from backup, re-wrapped to the new SRK, loaded and the PKCS#11
1788 * objects have been updated. Proceed with login as normal.
1789 */
1790 }
1791
1792 /* find, load the user leaf key */
1793 rc = token_find_key(tokdata, TPMTOK_PRIVATE_LEAF_KEY,
1794 CKO_PRIVATE_KEY, &ckPrivateLeafKey);
1795 if (rc != CKR_OK) {
1796 TRACE_ERROR("token_find_key failed. rc=0x%lx\n", rc);
1797 return CKR_FUNCTION_FAILED;
1798 }
1799
1800 rc = token_load_key(tokdata, ckPrivateLeafKey,
1801 hPrivateRootKey,
1802 hash_sha, &hPrivateLeafKey);
1803 if (rc != CKR_OK) {
1804 TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
1805 return CKR_FUNCTION_FAILED;
1806 }
1807
1808 rc = token_verify_pin(hPrivateLeafKey);
1809 if (rc != CKR_OK) {
1810 TRACE_DEVEL("token_verify_pin failed. failed. rc=0x%lx\n", rc);
1811 return rc;
1812 }
1813
1814 memcpy(current_user_pin_sha, hash_sha, SHA1_HASH_SIZE);
1815
1816 /* load private data encryption key here */
1817 rc = load_masterkey_private(tokdata);
1818 if (rc != CKR_OK) {
1819 TRACE_DEVEL("load_masterkey_private failed. rc=0x%lx\n", rc);
1820 Tspi_Key_UnloadKey(hPrivateLeafKey);
1821 hPrivateLeafKey = NULL_HKEY;
1822 return rc;
1823 }
1824
1825 rc = XProcLock(tokdata);
1826 if (rc != CKR_OK) {
1827 TRACE_ERROR("Failed to get process lock.\n");
1828 return rc;
1829 }
1830
1831 rc = load_private_token_objects(tokdata);
1832
1833 if (rc != CKR_OK) {
1834 XProcUnLock(tokdata);
1835 return rc;
1836 }
1837
1838 tokdata->global_shm->priv_loaded = TRUE;
1839
1840 rc = XProcUnLock(tokdata);
1841 if (rc != CKR_OK) {
1842 TRACE_ERROR("Failed to release process lock.\n");
1843 return rc;
1844 }
1845 } else {
1846 /* SO path --
1847 */
1848 /* find, load the root key */
1849 rc = token_find_key(tokdata, TPMTOK_PUBLIC_ROOT_KEY,
1850 CKO_PRIVATE_KEY, &ckPublicRootKey);
1851 if (rc != CKR_OK) {
1852 /* The SO hasn't set her PIN yet, compare the login pin with
1853 * the hard-coded value */
1854 if (memcmp(default_so_pin_sha, hash_sha, SHA1_HASH_SIZE)) {
1855 TRACE_ERROR("token_find_key failed and PIN != default\n");
1856 return CKR_PIN_INCORRECT;
1857 }
1858
1859 not_initialized = 1;
1860 return CKR_OK;
1861 }
1862
1863 /* The SO's key hierarchy has previously been created, so load the key
1864 * hierarchy and verify the pin using the TPM. */
1865 rc = token_load_key(tokdata, ckPublicRootKey,
1866 hSRK, NULL, &hPublicRootKey);
1867 if (rc != CKR_OK) {
1868 TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
1869
1870 /* Here, we've found the public root key, but its load failed.
1871 * This should only happen in a migration path, where we have
1872 * the PKCS#11 key store available, but the SRK is now
1873 * different. So, we will try to decrypt the PEM backup file
1874 * for the public root key using the given password. If that
1875 * succeeds, we will assume that we're in a migration path and
1876 * re-wrap the public root key to the new SRK.
1877 */
1878 if ((token_migrate(tokdata, TPMTOK_PUBLIC_ROOT_KEY, pPin))) {
1879 TRACE_DEVEL("token_migrate. rc=0x%lx\n", rc);
1880 return rc;
1881 }
1882
1883 /* At this point, the public root key has been successfully read
1884 * from backup, re-wrapped to the new SRK, loaded and the PKCS#11
1885 * objects have been updated. Proceed with login as normal.
1886 */
1887 }
1888
1889 /* find, load the public leaf key */
1890 rc = token_find_key(tokdata, TPMTOK_PUBLIC_LEAF_KEY,
1891 CKO_PRIVATE_KEY, &ckPublicLeafKey);
1892 if (rc != CKR_OK) {
1893 TRACE_ERROR("token_find_key failed. rc=0x%lx\n", rc);
1894 return CKR_FUNCTION_FAILED;
1895 }
1896
1897 rc = token_load_key(tokdata, ckPublicLeafKey,
1898 hPublicRootKey, hash_sha, &hPublicLeafKey);
1899 if (rc != CKR_OK) {
1900 TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
1901 return CKR_FUNCTION_FAILED;
1902 }
1903
1904 rc = token_verify_pin(hPublicLeafKey);
1905 if (rc != CKR_OK) {
1906 TRACE_DEVEL("token_verify_pin failed. rc=0x%lx\n", rc);
1907 return rc;
1908 }
1909
1910 memcpy(current_so_pin_sha, hash_sha, SHA1_HASH_SIZE);
1911 }
1912
1913 return rc;
1914 }
1915
token_specific_logout()1916 CK_RV token_specific_logout()
1917 {
1918 if (hPrivateLeafKey != NULL_HKEY) {
1919 Tspi_Key_UnloadKey(hPrivateLeafKey);
1920 } else if (hPublicLeafKey != NULL_HKEY) {
1921 Tspi_Key_UnloadKey(hPublicLeafKey);
1922 }
1923
1924 clear_internal_structures();
1925
1926 return CKR_OK;
1927 }
1928
token_specific_init_pin(STDLL_TokData_t * tokdata,SESSION * sess,CK_CHAR_PTR pPin,CK_ULONG ulPinLen)1929 CK_RV token_specific_init_pin(STDLL_TokData_t * tokdata, SESSION * sess,
1930 CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
1931 {
1932 UNUSED(tokdata);
1933 UNUSED(sess);
1934 UNUSED(pPin);
1935 UNUSED(ulPinLen);
1936
1937 /* Since the SO must log in before calling C_InitPIN, we will
1938 * be able to return CKR_OK automatically here.
1939 * This is because the USER key structure is created at the
1940 * time of her first login, not at C_InitPIN time.
1941 */
1942 return CKR_OK;
1943 }
1944
check_pin_properties(CK_USER_TYPE userType,CK_BYTE * pinHash,CK_ULONG ulPinLen)1945 CK_RV check_pin_properties(CK_USER_TYPE userType, CK_BYTE * pinHash,
1946 CK_ULONG ulPinLen)
1947 {
1948 /* make sure the new PIN is different */
1949 if (userType == CKU_USER) {
1950 if (!memcmp(pinHash, default_user_pin_sha, SHA1_HASH_SIZE)) {
1951 TRACE_ERROR("new PIN must not be the default\n");
1952 return CKR_PIN_INVALID;
1953 }
1954 } else {
1955 if (!memcmp(pinHash, default_so_pin_sha, SHA1_HASH_SIZE)) {
1956 TRACE_ERROR("new PIN must not be the default\n");
1957 return CKR_PIN_INVALID;
1958 }
1959 }
1960
1961 if (ulPinLen > MAX_PIN_LEN || ulPinLen < MIN_PIN_LEN) {
1962 TRACE_ERROR("New PIN is out of size range\n");
1963 return CKR_PIN_LEN_RANGE;
1964 }
1965
1966 return CKR_OK;
1967 }
1968
1969 /* use this function call from set_pin only, where a not logged in public
1970 * session can provide the user pin which must be verified. This function
1971 * assumes that the pin has already been set once, so there's no migration
1972 * path option or checking of the default user pin.
1973 */
verify_user_pin(STDLL_TokData_t * tokdata,CK_BYTE * hash_sha)1974 CK_RV verify_user_pin(STDLL_TokData_t * tokdata, CK_BYTE * hash_sha)
1975 {
1976 CK_RV rc;
1977
1978 /* find, load the private root key */
1979 rc = token_find_key(tokdata, TPMTOK_PRIVATE_ROOT_KEY,
1980 CKO_PRIVATE_KEY, &ckPrivateRootKey);
1981 if (rc != CKR_OK) {
1982 TRACE_ERROR("token_find_key failed. rc=0x%lx\n", rc);
1983 return CKR_FUNCTION_FAILED;
1984 }
1985
1986 rc = token_load_key(tokdata, ckPrivateRootKey,
1987 hSRK, NULL, &hPrivateRootKey);
1988 if (rc != CKR_OK) {
1989 TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
1990 return CKR_FUNCTION_FAILED;
1991 }
1992
1993 /* find, load the user leaf key */
1994 rc = token_find_key(tokdata, TPMTOK_PRIVATE_LEAF_KEY,
1995 CKO_PRIVATE_KEY, &ckPrivateLeafKey);
1996 if (rc != CKR_OK) {
1997 TRACE_DEVEL("token_find_key failed. rc=0x%lx\n", rc);
1998 return CKR_FUNCTION_FAILED;
1999 }
2000
2001 rc = token_load_key(tokdata, ckPrivateLeafKey,
2002 hPrivateRootKey, hash_sha, &hPrivateLeafKey);
2003 if (rc != CKR_OK) {
2004 TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
2005 return CKR_FUNCTION_FAILED;
2006 }
2007
2008 rc = token_verify_pin(hPrivateLeafKey);
2009 if (rc != CKR_OK) {
2010 TRACE_DEVEL("token_verify_pin failed. failed. rc=0x%lx\n", rc);
2011 return rc;
2012 }
2013
2014 return CKR_OK;
2015 }
2016
token_specific_set_pin(STDLL_TokData_t * tokdata,SESSION * sess,CK_CHAR_PTR pOldPin,CK_ULONG ulOldPinLen,CK_CHAR_PTR pNewPin,CK_ULONG ulNewPinLen)2017 CK_RV token_specific_set_pin(STDLL_TokData_t * tokdata, SESSION * sess,
2018 CK_CHAR_PTR pOldPin, CK_ULONG ulOldPinLen,
2019 CK_CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
2020 {
2021 CK_BYTE oldpin_hash[SHA1_HASH_SIZE], newpin_hash[SHA1_HASH_SIZE];
2022 CK_RV rc;
2023 RSA *rsa_root;
2024 TSS_RESULT result;
2025
2026 if (!sess) {
2027 TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
2028 return CKR_SESSION_HANDLE_INVALID;
2029 }
2030
2031 rc = compute_sha1(tokdata, pOldPin, ulOldPinLen, oldpin_hash);
2032 if (rc != CKR_OK) {
2033 TRACE_ERROR("compute_sha1 failed. rc=0x%lx\n", rc);
2034 return CKR_FUNCTION_FAILED;
2035 }
2036
2037 rc = compute_sha1(tokdata, pNewPin, ulNewPinLen, newpin_hash);
2038 if (rc != CKR_OK) {
2039 TRACE_ERROR("compute_sha1 failed. rc=0x%lx\n", rc);
2040 return CKR_FUNCTION_FAILED;
2041 }
2042
2043 result = token_load_srk();
2044 if (result) {
2045 TRACE_DEVEL("token_load_srk failed. rc=0x%x\n", result);
2046 return CKR_FUNCTION_FAILED;
2047 }
2048
2049 /* From the PKCS#11 2.20 spec: "C_SetPIN modifies the PIN of the user that
2050 * is currently logged in, or the CKU_USER PIN if the session is not logged
2051 * in."
2052 * A non R/W session fails with CKR_SESSION_READ_ONLY.
2053 */
2054 if (sess->session_info.state == CKS_RW_USER_FUNCTIONS ||
2055 sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
2056 if (not_initialized) {
2057 if (memcmp(oldpin_hash, default_user_pin_sha, SHA1_HASH_SIZE)) {
2058 TRACE_ERROR("old PIN != default for an "
2059 "uninitialized user\n");
2060 return CKR_PIN_INCORRECT;
2061 }
2062
2063 rc = check_pin_properties(CKU_USER, newpin_hash, ulNewPinLen);
2064 if (rc != CKR_OK) {
2065 return rc;
2066 }
2067
2068 rc = token_create_private_tree(tokdata, newpin_hash, pNewPin);
2069 if (rc != CKR_OK) {
2070 TRACE_DEVEL("FAILED creating USER tree.\n");
2071 return CKR_FUNCTION_FAILED;
2072 }
2073
2074 tokdata->nv_token_data->token_info.flags &=
2075 ~(CKF_USER_PIN_TO_BE_CHANGED);
2076 tokdata->nv_token_data->token_info.flags |=
2077 CKF_USER_PIN_INITIALIZED;
2078
2079 return save_token_data(tokdata, sess->session_info.slotID);
2080 }
2081
2082 if (sess->session_info.state == CKS_RW_USER_FUNCTIONS) {
2083 /* if we're already logged in, just verify the hash */
2084 if (memcmp(current_user_pin_sha, oldpin_hash, SHA1_HASH_SIZE)) {
2085 TRACE_ERROR("USER pin incorrect\n");
2086 return CKR_PIN_INCORRECT;
2087 }
2088 } else {
2089 rc = verify_user_pin(tokdata, oldpin_hash);
2090 if (rc != CKR_OK) {
2091 return rc;
2092 }
2093 }
2094
2095 rc = check_pin_properties(CKU_USER, newpin_hash, ulNewPinLen);
2096 if (rc != CKR_OK) {
2097 return rc;
2098 }
2099
2100 /* change the auth on the TSS object */
2101 result = tss_change_auth(hPrivateLeafKey, hPrivateRootKey, newpin_hash);
2102 if (result) {
2103 TRACE_ERROR("tss_change_auth failed\n");
2104 return CKR_FUNCTION_FAILED;
2105 }
2106
2107 /* destroy the old PKCS#11 priv key object and create a new one */
2108 rc = token_update_private_key(tokdata, hPrivateLeafKey,
2109 TPMTOK_PRIVATE_LEAF_KEY);
2110 if (rc != CKR_OK) {
2111 TRACE_DEVEL("token_update_private_key failed.\n");
2112 return rc;
2113 }
2114
2115 /* read the backup key with the old pin */
2116 rc = openssl_read_key(TPMTOK_PRIV_ROOT_KEY_FILE, pOldPin, &rsa_root);
2117 if (rc != CKR_OK) {
2118 if (rc == CKR_FILE_NOT_FOUND) {
2119 /* If the user has moved his backup PEM file off site, allow a
2120 * change auth to succeed without updating it. */
2121 return CKR_OK;
2122 }
2123
2124 TRACE_DEVEL("openssl_read_key failed\n");
2125 return rc;
2126 }
2127
2128 /* write it out using the new pin */
2129 rc = openssl_write_key(rsa_root, TPMTOK_PRIV_ROOT_KEY_FILE, pNewPin);
2130 if (rc != CKR_OK) {
2131 RSA_free(rsa_root);
2132 TRACE_DEVEL("openssl_write_key failed\n");
2133 return CKR_FUNCTION_FAILED;
2134 }
2135 RSA_free(rsa_root);
2136 } else if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
2137 if (not_initialized) {
2138 if (memcmp(default_so_pin_sha, oldpin_hash, SHA1_HASH_SIZE)) {
2139 TRACE_ERROR("old PIN != default for an " "uninitialized SO\n");
2140 return CKR_PIN_INCORRECT;
2141 }
2142
2143 rc = check_pin_properties(CKU_SO, newpin_hash, ulNewPinLen);
2144 if (rc != CKR_OK) {
2145 return rc;
2146 }
2147
2148 rc = token_create_public_tree(tokdata, newpin_hash, pNewPin);
2149 if (rc != CKR_OK) {
2150 TRACE_DEVEL("FAILED creating SO tree.\n");
2151 return CKR_FUNCTION_FAILED;
2152 }
2153
2154 tokdata->nv_token_data->token_info.flags &=
2155 ~(CKF_SO_PIN_TO_BE_CHANGED);
2156
2157 return save_token_data(tokdata, sess->session_info.slotID);
2158 }
2159
2160 if (memcmp(current_so_pin_sha, oldpin_hash, SHA1_HASH_SIZE)) {
2161 TRACE_ERROR("SO PIN incorrect\n");
2162 return CKR_PIN_INCORRECT;
2163 }
2164
2165 rc = check_pin_properties(CKU_SO, newpin_hash, ulNewPinLen);
2166 if (rc != CKR_OK) {
2167 return rc;
2168 }
2169
2170 /* change auth on the SO's leaf key */
2171 result = tss_change_auth(hPublicLeafKey, hPublicRootKey, newpin_hash);
2172 if (result) {
2173 TRACE_ERROR("tss_change_auth failed\n");
2174 return CKR_FUNCTION_FAILED;
2175 }
2176
2177 rc = token_update_private_key(tokdata, hPublicLeafKey,
2178 TPMTOK_PUBLIC_LEAF_KEY);
2179 if (rc != CKR_OK) {
2180 TRACE_DEVEL("token_update_private_key failed.\n");
2181 return rc;
2182 }
2183
2184 /* change auth on the public root key's openssl backup */
2185 rc = openssl_read_key(TPMTOK_PUB_ROOT_KEY_FILE, pOldPin, &rsa_root);
2186 if (rc != CKR_OK) {
2187 if (rc == CKR_FILE_NOT_FOUND) {
2188 /* If the user has moved his backup PEM file off site, allow a
2189 * change auth to succeed without updating it. */
2190 return CKR_OK;
2191 }
2192
2193 TRACE_DEVEL("openssl_read_key failed\n");
2194 return rc;
2195 }
2196
2197 /* write it out using the new pin */
2198 rc = openssl_write_key(rsa_root, TPMTOK_PUB_ROOT_KEY_FILE, pNewPin);
2199 if (rc != CKR_OK) {
2200 RSA_free(rsa_root);
2201 TRACE_DEVEL("openssl_write_key failed\n");
2202 return CKR_FUNCTION_FAILED;
2203 }
2204 RSA_free(rsa_root);
2205 } else {
2206 TRACE_ERROR("%s\n", ock_err(ERR_SESSION_READ_ONLY));
2207 rc = CKR_SESSION_READ_ONLY;
2208 }
2209
2210 return rc;
2211 }
2212
delete_tpm_data()2213 static CK_RV delete_tpm_data()
2214 {
2215 char *cmd = NULL;
2216 struct passwd *pw = NULL;
2217
2218 pw = getpwuid(getuid());
2219 if (pw == NULL) {
2220 TRACE_ERROR("getpwuid failed: %s\n", strerror(errno));
2221 return CKR_FUNCTION_FAILED;
2222 }
2223 // delete the TOK_OBJ data files
2224 if (asprintf(&cmd, "%s %s/%s/%s/* > /dev/null 2>&1", DEL_CMD,
2225 pk_dir, pw->pw_name, PK_LITE_OBJ_DIR) < 0) {
2226 return CKR_HOST_MEMORY;
2227 }
2228 if (system(cmd) == -1)
2229 TRACE_ERROR("system() failed.\n");
2230
2231 free(cmd);
2232
2233 // delete the OpenSSL backup keys
2234 if (asprintf(&cmd, "%s %s/%s/%s > /dev/null 2>&1", DEL_CMD,
2235 pk_dir, pw->pw_name, TPMTOK_PUB_ROOT_KEY_FILE) < 0) {
2236 return CKR_HOST_MEMORY;
2237 }
2238 if (system(cmd) == -1)
2239 TRACE_ERROR("system() failed.\n");
2240
2241 free(cmd);
2242
2243 if (asprintf(&cmd, "%s %s/%s/%s > /dev/null 2>&1", DEL_CMD,
2244 pk_dir, pw->pw_name, TPMTOK_PRIV_ROOT_KEY_FILE) < 0) {
2245 return CKR_HOST_MEMORY;
2246 }
2247 if (system(cmd) == -1)
2248 TRACE_ERROR("system() failed.\n");
2249
2250 free(cmd);
2251
2252 // delete the masterkey
2253 if (asprintf(&cmd, "%s %s/%s/%s > /dev/null 2>&1", DEL_CMD,
2254 pk_dir, pw->pw_name, TPMTOK_MASTERKEY_PRIVATE) < 0) {
2255 return CKR_HOST_MEMORY;
2256 }
2257 if (system(cmd) == -1)
2258 TRACE_ERROR("system() failed.\n");
2259
2260 free(cmd);
2261
2262 return CKR_OK;
2263 }
2264
2265 /* only called at token init time */
token_specific_init_token(STDLL_TokData_t * tokdata,CK_SLOT_ID sid,CK_CHAR_PTR pPin,CK_ULONG ulPinLen,CK_CHAR_PTR pLabel)2266 CK_RV token_specific_init_token(STDLL_TokData_t * tokdata, CK_SLOT_ID sid,
2267 CK_CHAR_PTR pPin, CK_ULONG ulPinLen,
2268 CK_CHAR_PTR pLabel)
2269 {
2270 CK_BYTE hash_sha[SHA1_HASH_SIZE];
2271 CK_RV rc;
2272
2273 rc = compute_sha1(tokdata, pPin, ulPinLen, hash_sha);
2274 if (rc != CKR_OK) {
2275 TRACE_ERROR("compute_sha1 failed. rc=0x%lx\n", rc);
2276 return CKR_FUNCTION_FAILED;
2277 }
2278
2279 /* find, load the migratable root key */
2280 rc = token_find_key(tokdata, TPMTOK_PUBLIC_ROOT_KEY,
2281 CKO_PRIVATE_KEY, &ckPublicRootKey);
2282 if (rc != CKR_OK) {
2283 /* The SO hasn't set her PIN yet, compare the login pin with
2284 * the hard-coded value */
2285 if (memcmp(default_so_pin_sha, hash_sha, SHA1_HASH_SIZE)) {
2286 TRACE_ERROR("token_find_key failed and PIN != default\n");
2287 return CKR_PIN_INCORRECT;
2288 }
2289 goto done;
2290 }
2291
2292 rc = token_load_srk();
2293 if (rc != CKR_OK) {
2294 TRACE_DEVEL("token_load_srk failed. rc = 0x%lx\n", rc);
2295 return CKR_FUNCTION_FAILED;
2296 }
2297
2298 /* we found the root key, so check by loading the chain */
2299 rc = token_load_key(tokdata, ckPublicRootKey,
2300 hSRK, NULL, &hPublicRootKey);
2301 if (rc != CKR_OK) {
2302 TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
2303 return CKR_FUNCTION_FAILED;
2304 }
2305
2306 /* find, load the public leaf key */
2307 rc = token_find_key(tokdata, TPMTOK_PUBLIC_LEAF_KEY,
2308 CKO_PRIVATE_KEY, &ckPublicLeafKey);
2309 if (rc != CKR_OK) {
2310 TRACE_ERROR("token_find_key failed. rc=0x%lx\n", rc);
2311 return CKR_FUNCTION_FAILED;
2312 }
2313
2314 rc = token_load_key(tokdata, ckPublicLeafKey,
2315 hPublicRootKey, hash_sha, &hPublicLeafKey);
2316 if (rc != CKR_OK) {
2317 TRACE_DEVEL("token_load_key(MigLeafKey) Failed.\n");
2318 return CKR_FUNCTION_FAILED;
2319 }
2320
2321 rc = token_verify_pin(hPublicLeafKey);
2322 if (rc != CKR_OK) {
2323 TRACE_DEVEL("token_verify_pin failed. rc=0x%lx\n", rc);
2324 return rc;
2325 }
2326
2327 done:
2328 // Before we reconstruct all the data, we should delete the
2329 // token objects from the filesystem.
2330 object_mgr_destroy_token_objects(tokdata);
2331 rc = delete_tpm_data();
2332 if (rc != CKR_OK)
2333 return rc;
2334
2335 // META This should be fine since the open session checking should occur at
2336 // the API not the STDLL
2337 load_token_data(tokdata, sid);
2338 init_slotInfo(&tokdata->slot_info);
2339 memcpy(tokdata->nv_token_data->so_pin_sha, hash_sha, SHA1_HASH_SIZE);
2340 tokdata->nv_token_data->token_info.flags |= CKF_TOKEN_INITIALIZED;
2341 memcpy(tokdata->nv_token_data->token_info.label, pLabel, 32);
2342
2343 // New for v2.11 - KEY
2344 tokdata->nv_token_data->token_info.flags |= CKF_TOKEN_INITIALIZED;
2345
2346 rc = save_token_data(tokdata, sid);
2347 if (rc != CKR_OK) {
2348 TRACE_DEVEL("save_token_data failed.\n");
2349 return rc;
2350 }
2351
2352 return CKR_OK;
2353 }
2354
token_specific_final()2355 CK_RV token_specific_final()
2356 {
2357 TSS_RESULT result;
2358
2359 TRACE_INFO("tpm %s running\n", __func__);
2360
2361 result = Tspi_Context_Close(tspContext);
2362 if (result) {
2363 TRACE_ERROR("Tspi_Context_Close failed. rc=0x%x\n", result);
2364 return CKR_FUNCTION_FAILED;
2365 }
2366
2367 clear_internal_structures();
2368
2369 return CKR_OK;
2370 }
2371
token_specific_des_key_gen(STDLL_TokData_t * tokdata,CK_BYTE * des_key,CK_ULONG len,CK_ULONG keysize)2372 CK_RV token_specific_des_key_gen(STDLL_TokData_t * tokdata, CK_BYTE * des_key,
2373 CK_ULONG len, CK_ULONG keysize)
2374 {
2375 UNUSED(keysize);
2376
2377 // Nothing different to do for DES or TDES here as this is just
2378 // random data... Validation handles the rest
2379 // Only check for weak keys when DES.
2380 if (len == (3 * DES_KEY_SIZE)) {
2381 rng_generate(tokdata, des_key, len);
2382 } else {
2383 do {
2384 rng_generate(tokdata, des_key, len);
2385 } while (des_check_weak_key(des_key) == TRUE);
2386 }
2387
2388 // we really need to validate the key for parity etc...
2389 // we should do that here... The caller validates the single des keys
2390 // against the known and suspected poor keys..
2391 return CKR_OK;
2392 }
2393
token_specific_des_ecb(STDLL_TokData_t * tokdata,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key,CK_BYTE encrypt)2394 CK_RV token_specific_des_ecb(STDLL_TokData_t * tokdata,
2395 CK_BYTE * in_data,
2396 CK_ULONG in_data_len,
2397 CK_BYTE * out_data,
2398 CK_ULONG * out_data_len,
2399 OBJECT * key, CK_BYTE encrypt)
2400 {
2401 CK_ULONG rc;
2402 CK_ATTRIBUTE *attr = NULL;
2403
2404 DES_key_schedule des_key2;
2405 const_DES_cblock key_val_SSL, in_key_data;
2406 DES_cblock out_key_data;
2407 unsigned int i, j;
2408
2409 UNUSED(tokdata);
2410
2411 // get the key value
2412 if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
2413 TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
2414 return CKR_FUNCTION_FAILED;
2415 }
2416 // Create the key schedule
2417 memcpy(&key_val_SSL, attr->pValue, 8);
2418 DES_set_key_unchecked(&key_val_SSL, &des_key2);
2419
2420 // the des decrypt will only fail if the data length is not evenly divisible
2421 // by 8
2422 if (in_data_len % 8) {
2423 TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
2424 return CKR_DATA_LEN_RANGE;
2425 }
2426 // Both the encrypt and the decrypt are done 8 bytes at a time
2427 if (encrypt) {
2428 for (i = 0; i < in_data_len; i = i + 8) {
2429 memcpy(in_key_data, in_data + i, 8);
2430 DES_ecb_encrypt(&in_key_data, &out_key_data, &des_key2,
2431 DES_ENCRYPT);
2432 memcpy(out_data + i, out_key_data, 8);
2433 }
2434
2435 *out_data_len = in_data_len;
2436 rc = CKR_OK;
2437 } else {
2438
2439 for (j = 0; j < in_data_len; j = j + 8) {
2440 memcpy(in_key_data, in_data + j, 8);
2441 DES_ecb_encrypt(&in_key_data, &out_key_data, &des_key2,
2442 DES_DECRYPT);
2443 memcpy(out_data + j, out_key_data, 8);
2444 }
2445
2446 *out_data_len = in_data_len;
2447 rc = CKR_OK;
2448 }
2449
2450 return rc;
2451 }
2452
token_specific_des_cbc(STDLL_TokData_t * tokdata,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key,CK_BYTE * init_v,CK_BYTE encrypt)2453 CK_RV token_specific_des_cbc(STDLL_TokData_t * tokdata,
2454 CK_BYTE * in_data,
2455 CK_ULONG in_data_len,
2456 CK_BYTE * out_data,
2457 CK_ULONG * out_data_len,
2458 OBJECT * key, CK_BYTE * init_v, CK_BYTE encrypt)
2459 {
2460 CK_ULONG rc;
2461 CK_ATTRIBUTE *attr = NULL;
2462
2463 DES_cblock ivec;
2464
2465 DES_key_schedule des_key2;
2466 const_DES_cblock key_val_SSL;
2467
2468 UNUSED(tokdata);
2469
2470 // get the key value
2471 if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
2472 TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
2473 return CKR_FUNCTION_FAILED;
2474 }
2475 // Create the key schedule
2476 memcpy(&key_val_SSL, attr->pValue, 8);
2477 DES_set_key_unchecked(&key_val_SSL, &des_key2);
2478
2479 memcpy(&ivec, init_v, 8);
2480 // the des decrypt will only fail if the data length is not evenly divisible
2481 // by 8
2482 if (in_data_len % 8) {
2483 TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
2484 return CKR_DATA_LEN_RANGE;
2485 }
2486
2487
2488 if (encrypt) {
2489 DES_ncbc_encrypt(in_data, out_data, in_data_len, &des_key2, &ivec,
2490 DES_ENCRYPT);
2491 *out_data_len = in_data_len;
2492 rc = CKR_OK;
2493 } else {
2494 DES_ncbc_encrypt(in_data, out_data, in_data_len, &des_key2, &ivec,
2495 DES_DECRYPT);
2496 *out_data_len = in_data_len;
2497 rc = CKR_OK;
2498 }
2499 return rc;
2500 }
2501
token_specific_tdes_ecb(STDLL_TokData_t * tokdata,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key,CK_BYTE encrypt)2502 CK_RV token_specific_tdes_ecb(STDLL_TokData_t * tokdata,
2503 CK_BYTE * in_data,
2504 CK_ULONG in_data_len,
2505 CK_BYTE * out_data,
2506 CK_ULONG * out_data_len,
2507 OBJECT * key, CK_BYTE encrypt)
2508 {
2509 CK_RV rc;
2510 CK_ATTRIBUTE *attr = NULL;
2511 CK_KEY_TYPE keytype;
2512 CK_BYTE key_value[3 * DES_KEY_SIZE];
2513
2514 unsigned int k, j;
2515 DES_key_schedule des_key1;
2516 DES_key_schedule des_key2;
2517 DES_key_schedule des_key3;
2518
2519 const_DES_cblock key_SSL1, key_SSL2, key_SSL3, in_key_data;
2520 DES_cblock out_key_data;
2521
2522 UNUSED(tokdata);
2523
2524 // get the key type
2525 rc = template_attribute_find(key->template, CKA_KEY_TYPE, &attr);
2526 if (rc == FALSE) {
2527 TRACE_ERROR("template_attribute_find(CKA_KEY_TYPE) failed.\n");
2528 return CKR_FUNCTION_FAILED;
2529 }
2530 keytype = *(CK_KEY_TYPE *) attr->pValue;
2531
2532 // get the key value
2533 if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
2534 TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
2535 return CKR_FUNCTION_FAILED;
2536 }
2537 if (keytype == CKK_DES2) {
2538 memcpy(key_value, attr->pValue, 2 * DES_KEY_SIZE);
2539 memcpy(key_value + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE);
2540 } else {
2541 memcpy(key_value, attr->pValue, 3 * DES_KEY_SIZE);
2542 }
2543
2544 // The key as passed is a 24 byte long string containing three des keys
2545 // pick them apart and create the 3 corresponding key schedules
2546 memcpy(&key_SSL1, key_value, 8);
2547 memcpy(&key_SSL2, key_value + 8, 8);
2548 memcpy(&key_SSL3, key_value + 16, 8);
2549 DES_set_key_unchecked(&key_SSL1, &des_key1);
2550 DES_set_key_unchecked(&key_SSL2, &des_key2);
2551 DES_set_key_unchecked(&key_SSL3, &des_key3);
2552
2553 // the des decrypt will only fail if the data length is not evenly divisible
2554 // by 8
2555 if (in_data_len % 8) {
2556 TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
2557 return CKR_DATA_LEN_RANGE;
2558 }
2559 // the encrypt and decrypt are done 8 bytes at a time
2560 if (encrypt) {
2561 for (k = 0; k < in_data_len; k = k + 8) {
2562 memcpy(in_key_data, in_data + k, 8);
2563 DES_ecb3_encrypt((const_DES_cblock *) & in_key_data,
2564 (DES_cblock *) & out_key_data,
2565 &des_key1, &des_key2, &des_key3, DES_ENCRYPT);
2566 memcpy(out_data + k, out_key_data, 8);
2567 }
2568 *out_data_len = in_data_len;
2569 rc = CKR_OK;
2570 } else {
2571 for (j = 0; j < in_data_len; j = j + 8) {
2572 memcpy(in_key_data, in_data + j, 8);
2573 DES_ecb3_encrypt((const_DES_cblock *) & in_key_data,
2574 (DES_cblock *) & out_key_data,
2575 &des_key1, &des_key2, &des_key3, DES_DECRYPT);
2576 memcpy(out_data + j, out_key_data, 8);
2577 }
2578 *out_data_len = in_data_len;
2579 rc = CKR_OK;
2580 }
2581
2582 return rc;
2583 }
2584
token_specific_tdes_cbc(STDLL_TokData_t * tokdata,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key,CK_BYTE * init_v,CK_BYTE encrypt)2585 CK_RV token_specific_tdes_cbc(STDLL_TokData_t * tokdata,
2586 CK_BYTE * in_data,
2587 CK_ULONG in_data_len,
2588 CK_BYTE * out_data,
2589 CK_ULONG * out_data_len,
2590 OBJECT * key, CK_BYTE * init_v, CK_BYTE encrypt)
2591 {
2592 CK_RV rc = CKR_OK;
2593 CK_ATTRIBUTE *attr = NULL;
2594 CK_KEY_TYPE keytype;
2595 CK_BYTE key_value[3 * DES_KEY_SIZE];
2596
2597 DES_key_schedule des_key1;
2598 DES_key_schedule des_key2;
2599 DES_key_schedule des_key3;
2600
2601 const_DES_cblock key_SSL1, key_SSL2, key_SSL3;
2602 DES_cblock ivec;
2603
2604 UNUSED(tokdata);
2605
2606 // get the key type
2607 rc = template_attribute_find(key->template, CKA_KEY_TYPE, &attr);
2608 if (rc == FALSE) {
2609 TRACE_ERROR("template_attribute_find(CKA_KEY_TYPE) failed.\n");
2610 return CKR_FUNCTION_FAILED;
2611 }
2612 keytype = *(CK_KEY_TYPE *) attr->pValue;
2613
2614 // get the key value
2615 if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
2616 TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
2617 return CKR_FUNCTION_FAILED;
2618 }
2619 if (keytype == CKK_DES2) {
2620 memcpy(key_value, attr->pValue, 2 * DES_KEY_SIZE);
2621 memcpy(key_value + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE);
2622 } else {
2623 memcpy(key_value, attr->pValue, 3 * DES_KEY_SIZE);
2624 }
2625
2626 // The key as passed in is a 24 byte string containing 3 keys
2627 // pick it apart and create the key schedules
2628 memcpy(&key_SSL1, key_value, 8);
2629 memcpy(&key_SSL2, key_value + 8, 8);
2630 memcpy(&key_SSL3, key_value + 16, 8);
2631 DES_set_key_unchecked(&key_SSL1, &des_key1);
2632 DES_set_key_unchecked(&key_SSL2, &des_key2);
2633 DES_set_key_unchecked(&key_SSL3, &des_key3);
2634
2635 memcpy(ivec, init_v, sizeof(ivec));
2636
2637 // the des decrypt will only fail if the data length is not evenly divisible
2638 // by 8
2639 if (in_data_len % 8) {
2640 TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
2641 return CKR_DATA_LEN_RANGE;
2642 }
2643 // Encrypt or decrypt the data
2644 if (encrypt) {
2645 DES_ede3_cbc_encrypt(in_data,
2646 out_data,
2647 in_data_len,
2648 &des_key1,
2649 &des_key2, &des_key3, &ivec, DES_ENCRYPT);
2650 *out_data_len = in_data_len;
2651 rc = CKR_OK;
2652 } else {
2653 DES_ede3_cbc_encrypt(in_data,
2654 out_data,
2655 in_data_len,
2656 &des_key1,
2657 &des_key2, &des_key3, &ivec, DES_DECRYPT);
2658
2659 *out_data_len = in_data_len;
2660 rc = CKR_OK;
2661 }
2662
2663 return rc;
2664 }
2665
2666 /* wrap the 20 bytes of auth data @authData and store in an attribute of the two
2667 * keys.
2668 */
token_wrap_auth_data(CK_BYTE * authData,TEMPLATE * publ_tmpl,TEMPLATE * priv_tmpl)2669 CK_RV token_wrap_auth_data(CK_BYTE * authData, TEMPLATE * publ_tmpl,
2670 TEMPLATE * priv_tmpl)
2671 {
2672 CK_RV rc;
2673 CK_ATTRIBUTE *new_attr;
2674
2675 TSS_HKEY hParentKey;
2676 TSS_HENCDATA hEncData;
2677 BYTE *blob;
2678 UINT32 blob_size;
2679
2680 if ((hPrivateLeafKey == NULL_HKEY) && (hPublicLeafKey == NULL_HKEY)) {
2681 TRACE_ERROR("Shouldn't be wrapping auth data in a " "public path!\n");
2682 return CKR_FUNCTION_FAILED;
2683 } else if (hPublicLeafKey != NULL_HKEY) {
2684 hParentKey = hPublicLeafKey;
2685 } else {
2686 hParentKey = hPrivateLeafKey;
2687 }
2688
2689 /* create the encrypted data object */
2690 rc = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_ENCDATA,
2691 TSS_ENCDATA_BIND, &hEncData);
2692 if (rc != CKR_OK) {
2693 TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%lx\n", rc);
2694 return rc;
2695 }
2696
2697 rc = Tspi_Data_Bind(hEncData, hParentKey, SHA1_HASH_SIZE, authData);
2698 if (rc != CKR_OK) {
2699 TRACE_ERROR("Tspi_Data_Bind failed. rc=0x%lx\n", rc);
2700 return rc;
2701 }
2702
2703 /* pull the encrypted data out of the encrypted data object */
2704 rc = Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
2705 TSS_TSPATTRIB_ENCDATABLOB_BLOB, &blob_size, &blob);
2706 if (rc != CKR_OK) {
2707 TRACE_ERROR("Tspi_SetAttribData failed. rc=0x%lx\n", rc);
2708 return rc;
2709 }
2710
2711 rc = build_attribute(CKA_ENC_AUTHDATA, blob, blob_size, &new_attr);
2712 if (rc != CKR_OK) {
2713 TRACE_DEVEL("build_attribute failed.\n");
2714 return rc;
2715 }
2716 template_update_attribute(publ_tmpl, new_attr);
2717
2718 rc = build_attribute(CKA_ENC_AUTHDATA, blob, blob_size, &new_attr);
2719 if (rc != CKR_OK) {
2720 TRACE_DEVEL("build_attribute failed.\n");
2721 return rc;
2722 }
2723 template_update_attribute(priv_tmpl, new_attr);
2724
2725 return rc;
2726 }
2727
token_unwrap_auth_data(CK_BYTE * encAuthData,CK_ULONG encAuthDataLen,TSS_HKEY hKey,BYTE ** authData)2728 CK_RV token_unwrap_auth_data(CK_BYTE * encAuthData, CK_ULONG encAuthDataLen,
2729 TSS_HKEY hKey, BYTE ** authData)
2730 {
2731 TSS_RESULT result;
2732 TSS_HENCDATA hEncData;
2733 BYTE *buf;
2734 UINT32 buf_size;
2735
2736 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_ENCDATA,
2737 TSS_ENCDATA_BIND, &hEncData);
2738 if (result) {
2739 TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
2740 return CKR_FUNCTION_FAILED;
2741 }
2742
2743 result = Tspi_SetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
2744 TSS_TSPATTRIB_ENCDATABLOB_BLOB,
2745 encAuthDataLen, encAuthData);
2746 if (result) {
2747 TRACE_ERROR("Tspi_SetAttribData failed. rc=0x%x\n", result);
2748 return CKR_FUNCTION_FAILED;
2749 }
2750
2751 /* unbind the data, receiving the plaintext back */
2752 result = Tspi_Data_Unbind(hEncData, hKey, &buf_size, &buf);
2753 if (result) {
2754 TRACE_ERROR("Tspi_Data_Unbind failed: rc=0x%x\n", result);
2755 return CKR_FUNCTION_FAILED;
2756 }
2757
2758 if (buf_size != SHA1_HASH_SIZE) {
2759 TRACE_ERROR("auth data decrypt error.\n");
2760 return CKR_FUNCTION_FAILED;
2761 }
2762
2763 *authData = buf;
2764
2765 return CKR_OK;
2766 }
2767
2768 // convert from the local PKCS11 template representation to
2769 // the underlying requirement
2770 // returns the pointer to the local key representation
rsa_convert_public_key(OBJECT * key_obj)2771 CK_BYTE *rsa_convert_public_key(OBJECT * key_obj)
2772 {
2773 CK_ATTRIBUTE *modulus = NULL;
2774 CK_BYTE *ret;
2775 CK_RV rc;
2776
2777 rc = template_attribute_find(key_obj->template, CKA_MODULUS, &modulus);
2778 if (rc == FALSE) {
2779 return NULL;
2780 }
2781
2782 ret = malloc(modulus->ulValueLen);
2783 if (ret == NULL) {
2784 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2785 return NULL;
2786 }
2787
2788 memcpy(ret, modulus->pValue, modulus->ulValueLen);
2789
2790 return ret;
2791 }
2792
token_specific_rsa_generate_keypair(STDLL_TokData_t * tokdata,TEMPLATE * publ_tmpl,TEMPLATE * priv_tmpl)2793 CK_RV token_specific_rsa_generate_keypair(STDLL_TokData_t * tokdata,
2794 TEMPLATE * publ_tmpl,
2795 TEMPLATE * priv_tmpl)
2796 {
2797 CK_ATTRIBUTE *attr = NULL;
2798 CK_ULONG mod_bits = 0;
2799 CK_BBOOL flag;
2800 CK_RV rc;
2801 CK_BYTE tpm_pubexp[3] = { 1, 0, 1 }; // 65537
2802
2803 TSS_FLAG initFlags = 0;
2804 BYTE authHash[SHA1_HASH_SIZE];
2805 BYTE *authData = NULL;
2806 TSS_HKEY hKey = NULL_HKEY;
2807 TSS_HKEY hParentKey = NULL_HKEY;
2808 TSS_RESULT result;
2809 UINT32 ulBlobLen;
2810 BYTE *rgbBlob;
2811
2812 /* Make sure the public exponent is usable */
2813 if ((util_check_public_exponent(publ_tmpl))) {
2814 TRACE_DEVEL("Invalid public exponent\n");
2815 return CKR_TEMPLATE_INCONSISTENT;
2816 }
2817
2818 flag = template_attribute_find(publ_tmpl, CKA_MODULUS_BITS, &attr);
2819 if (!flag) {
2820 TRACE_ERROR("template_attribute_find(CKA_MODULUS_BITS) failed.\n");
2821 return CKR_TEMPLATE_INCOMPLETE; // should never happen
2822 }
2823 mod_bits = *(CK_ULONG *) attr->pValue;
2824
2825 if ((initFlags = util_get_keysize_flag(mod_bits)) == 0) {
2826 TRACE_ERROR("%s\n", ock_err(ERR_KEY_SIZE_RANGE));
2827 return CKR_KEY_SIZE_RANGE;
2828 }
2829
2830 /* If we're not logged in, hPrivateLeafKey and hPublicLeafKey
2831 * should be NULL */
2832 if ((hPrivateLeafKey == NULL_HKEY) && (hPublicLeafKey == NULL_HKEY)) {
2833 /* public session, wrap key with the PRK */
2834 initFlags |=
2835 TSS_KEY_TYPE_LEGACY | TSS_KEY_NO_AUTHORIZATION | TSS_KEY_MIGRATABLE;
2836
2837 if ((result = token_load_public_root_key(tokdata))) {
2838 TRACE_DEVEL("token_load_public_root_key failed. "
2839 "rc=%x\n", result);
2840 return CKR_FUNCTION_FAILED;
2841 }
2842
2843 hParentKey = hPublicRootKey;
2844 } else if (hPrivateLeafKey != NULL_HKEY) {
2845 /* logged in USER session */
2846 initFlags |=
2847 TSS_KEY_TYPE_LEGACY | TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE;
2848
2849 /* get a random SHA1 hash for the auth data */
2850 if ((rc = token_specific_rng(tokdata, authHash, SHA1_HASH_SIZE))) {
2851 TRACE_DEVEL("token_rng failed. rc=%lx\n", rc);
2852 return CKR_FUNCTION_FAILED;
2853 }
2854
2855 authData = authHash;
2856 hParentKey = hPrivateRootKey;
2857 } else {
2858 /* logged in SO session */
2859 initFlags |=
2860 TSS_KEY_TYPE_LEGACY | TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE;
2861
2862 /* get a random SHA1 hash for the auth data */
2863 rc = token_specific_rng(tokdata, authHash, SHA1_HASH_SIZE);
2864 if (rc != CKR_OK) {
2865 TRACE_DEVEL("token_rng failed. rc=0x%lx\n", rc);
2866 return CKR_FUNCTION_FAILED;
2867 }
2868
2869 authData = authHash;
2870 hParentKey = hPublicRootKey;
2871 }
2872
2873 result = tss_generate_key(initFlags, authData, hParentKey, &hKey);
2874 if (result) {
2875 TRACE_ERROR("tss_generate_key returned 0x%x\n", result);
2876 return result;
2877 }
2878
2879 result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
2880 TSS_TSPATTRIB_KEYBLOB_BLOB,
2881 &ulBlobLen, &rgbBlob);
2882 if (result) {
2883 TRACE_ERROR("Tspi_GetAttribData failed with rc: 0x%x\n", result);
2884 return CKR_FUNCTION_FAILED;
2885 }
2886
2887 rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, &attr);
2888 if (rc != CKR_OK) {
2889 TRACE_DEVEL("build_attribute(CKA_IBM_OPAQUE) failed.\n");
2890 Tspi_Context_FreeMemory(tspContext, rgbBlob);
2891 return rc;
2892 }
2893 template_update_attribute(priv_tmpl, attr);
2894
2895 rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, &attr);
2896 if (rc != CKR_OK) {
2897 TRACE_DEVEL("build_attribute(CKA_IBM_OPAQUE) failed.\n");
2898 Tspi_Context_FreeMemory(tspContext, rgbBlob);
2899 return rc;
2900 }
2901 template_update_attribute(publ_tmpl, attr);
2902
2903 Tspi_Context_FreeMemory(tspContext, rgbBlob);
2904
2905 /* grab the public key to put into the public key object */
2906 result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
2907 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS,
2908 &ulBlobLen, &rgbBlob);
2909 if (result) {
2910 TRACE_ERROR("Tspi_GetAttribData failed with rc: 0x%x\n", result);
2911 return result;
2912 }
2913
2914 /* add the public key blob to the object template */
2915 rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr);
2916 if (rc != CKR_OK) {
2917 TRACE_DEVEL("build_attribute(CKA_MODULUS) failed.\n");
2918 Tspi_Context_FreeMemory(tspContext, rgbBlob);
2919 return rc;
2920 }
2921 template_update_attribute(publ_tmpl, attr);
2922
2923 /* add the public key blob to the object template */
2924 rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr);
2925 if (rc != CKR_OK) {
2926 TRACE_DEVEL("build_attribute(CKA_MODULUS) failed.\n");
2927 Tspi_Context_FreeMemory(tspContext, rgbBlob);
2928 return rc;
2929 }
2930 template_update_attribute(priv_tmpl, attr);
2931 Tspi_Context_FreeMemory(tspContext, rgbBlob);
2932
2933 /* put the public exponent into the private key object */
2934 rc = build_attribute(CKA_PUBLIC_EXPONENT,
2935 tpm_pubexp, sizeof(tpm_pubexp), &attr);
2936 if (rc != CKR_OK) {
2937 TRACE_DEVEL("build_attribute(CKA_PUBLIC_EXPONENT) failed.\n");
2938 return rc;
2939 }
2940 template_update_attribute(priv_tmpl, attr);
2941
2942 /* wrap the authdata and put it into an object */
2943 if (authData != NULL) {
2944 rc = token_wrap_auth_data(authData, publ_tmpl, priv_tmpl);
2945 if (rc != CKR_OK) {
2946 TRACE_DEVEL("token_wrap_auth_data failed with rc: 0x%lx\n", rc);
2947 }
2948 }
2949
2950 return rc;
2951 }
2952
token_rsa_load_key(STDLL_TokData_t * tokdata,OBJECT * key_obj,TSS_HKEY * phKey)2953 CK_RV token_rsa_load_key(STDLL_TokData_t * tokdata, OBJECT * key_obj,
2954 TSS_HKEY * phKey)
2955 {
2956 TSS_RESULT result;
2957 TSS_HPOLICY hPolicy = NULL_HPOLICY;
2958 TSS_HKEY hParentKey;
2959 BYTE *authData = NULL;
2960 CK_ATTRIBUTE *attr;
2961 CK_RV rc;
2962 CK_OBJECT_HANDLE handle;
2963
2964 if (hPrivateLeafKey != NULL_HKEY) {
2965 hParentKey = hPrivateRootKey;
2966 } else {
2967 result = token_load_public_root_key(tokdata);
2968 if (result) {
2969 TRACE_DEVEL("token_load_public_root_key failed. "
2970 "rc=%x\n", result);
2971 return CKR_FUNCTION_FAILED;
2972 }
2973
2974 hParentKey = hPublicRootKey;
2975 }
2976
2977
2978 rc = template_attribute_find(key_obj->template, CKA_IBM_OPAQUE, &attr);
2979 if (rc == FALSE) {
2980 /* if the key blob wasn't found, then try to wrap the key */
2981 rc = object_mgr_find_in_map2(tokdata, key_obj, &handle);
2982 if (rc != CKR_OK)
2983 return CKR_FUNCTION_FAILED;
2984
2985 rc = token_load_key(tokdata, handle, hParentKey, NULL, phKey);
2986 if (rc != CKR_OK) {
2987 TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
2988 return rc;
2989 }
2990 /* try again to get the CKA_IBM_OPAQUE attr */
2991 rc = template_attribute_find(key_obj->template, CKA_IBM_OPAQUE, &attr);
2992 if (rc == FALSE) {
2993 TRACE_ERROR("Could not find key blob\n");
2994 return rc;
2995 }
2996 }
2997
2998 result = Tspi_Context_LoadKeyByBlob(tspContext, hParentKey,
2999 attr->ulValueLen, attr->pValue, phKey);
3000 if (result) {
3001 TRACE_ERROR("Tspi_Context_LoadKeyByBlob failed. rc=0x%x\n", result);
3002 return CKR_FUNCTION_FAILED;
3003 }
3004
3005 /* auth data may be required */
3006 if (template_attribute_find(key_obj->template, CKA_ENC_AUTHDATA, &attr) ==
3007 TRUE && attr) {
3008 if ((hPrivateLeafKey == NULL_HKEY) && (hPublicLeafKey == NULL_HKEY)) {
3009 TRACE_ERROR("Shouldn't be in a public session here\n");
3010 return CKR_FUNCTION_FAILED;
3011 } else if (hPublicLeafKey != NULL_HKEY) {
3012 hParentKey = hPublicLeafKey;
3013 } else {
3014 hParentKey = hPrivateLeafKey;
3015 }
3016
3017 result = token_unwrap_auth_data(attr->pValue, attr->ulValueLen,
3018 hParentKey, &authData);
3019 if (result) {
3020 TRACE_DEVEL("token_unwrap_auth_data: 0x%x\n", result);
3021 return CKR_FUNCTION_FAILED;
3022 }
3023
3024 result = Tspi_GetPolicyObject(*phKey, TSS_POLICY_USAGE, &hPolicy);
3025 if (result) {
3026 TRACE_ERROR("Tspi_GetPolicyObject: 0x%x\n", result);
3027 return CKR_FUNCTION_FAILED;
3028 }
3029
3030 /* If the policy handle returned is the same as the context's default
3031 * policy, then a new policy must be created and assigned to the key.
3032 * Otherwise, just set the secret in the policy */
3033 if (hPolicy == hDefaultPolicy) {
3034 result = Tspi_Context_CreateObject(tspContext,
3035 TSS_OBJECT_TYPE_POLICY,
3036 TSS_POLICY_USAGE, &hPolicy);
3037 if (result) {
3038 TRACE_ERROR("Tspi_Context_CreateObject: 0x%x\n", result);
3039 return CKR_FUNCTION_FAILED;
3040 }
3041
3042 result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
3043 SHA1_HASH_SIZE, authData);
3044 if (result) {
3045 TRACE_ERROR("Tspi_Policy_SetSecret failed. "
3046 "rc=0x%x\n", result);
3047 return CKR_FUNCTION_FAILED;
3048 }
3049
3050 result = Tspi_Policy_AssignToObject(hPolicy, *phKey);
3051 if (result) {
3052 TRACE_ERROR("Tspi_Policy_AssignToObject failed."
3053 " rc=0x%x\n", result);
3054 return CKR_FUNCTION_FAILED;
3055 }
3056 } else {
3057 result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
3058 SHA1_HASH_SIZE, authData);
3059 if (result) {
3060 TRACE_ERROR("Tspi_Policy_SetSecret failed. rc=0x%x\n", result);
3061 return CKR_FUNCTION_FAILED;
3062 }
3063 }
3064
3065 Tspi_Context_FreeMemory(tspContext, authData);
3066 }
3067
3068 return CKR_OK;
3069 }
3070
token_specific_rsa_decrypt(STDLL_TokData_t * tokdata,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)3071 CK_RV token_specific_rsa_decrypt(STDLL_TokData_t * tokdata,
3072 CK_BYTE * in_data,
3073 CK_ULONG in_data_len,
3074 CK_BYTE * out_data,
3075 CK_ULONG * out_data_len, OBJECT * key_obj)
3076 {
3077 CK_RV rc;
3078 TSS_RESULT result;
3079 TSS_HKEY hKey;
3080 TSS_HENCDATA hEncData = NULL_HENCDATA;
3081 UINT32 buf_size = 0;
3082 BYTE *buf = NULL;
3083
3084 rc = token_rsa_load_key(tokdata, key_obj, &hKey);
3085 if (rc != CKR_OK) {
3086 TRACE_DEVEL("token_rsa_load_key failed. rc=0x%lx\n", rc);
3087 return rc;
3088 }
3089
3090 /* push the data into the encrypted data object */
3091 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_ENCDATA,
3092 TSS_ENCDATA_BIND, &hEncData);
3093 if (result) {
3094 TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
3095 return CKR_FUNCTION_FAILED;
3096 }
3097
3098 result = Tspi_SetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
3099 TSS_TSPATTRIB_ENCDATABLOB_BLOB,
3100 in_data_len, in_data);
3101 if (result) {
3102 TRACE_ERROR("Tspi_SetAttribData failed. rc=0x%x\n", result);
3103 return CKR_FUNCTION_FAILED;
3104 }
3105
3106 /* unbind the data, receiving the plaintext back */
3107 TRACE_DEVEL("unbinding data with size: %ld\n", in_data_len);
3108
3109 result = Tspi_Data_Unbind(hEncData, hKey, &buf_size, &buf);
3110 if (result) {
3111 TRACE_ERROR("Tspi_Data_Unbind failed: 0x%x\n", result);
3112 return CKR_FUNCTION_FAILED;
3113 }
3114
3115 if (*out_data_len < buf_size) {
3116 TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
3117 Tspi_Context_FreeMemory(tspContext, buf);
3118 return CKR_BUFFER_TOO_SMALL;
3119 }
3120
3121 memcpy(out_data, buf, buf_size);
3122 *out_data_len = buf_size;
3123
3124 Tspi_Context_FreeMemory(tspContext, buf);
3125
3126 return CKR_OK;
3127 }
3128
token_specific_rsa_verify(STDLL_TokData_t * tokdata,SESSION * sess,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * sig,CK_ULONG sig_len,OBJECT * key_obj)3129 CK_RV token_specific_rsa_verify(STDLL_TokData_t * tokdata,
3130 SESSION * sess,
3131 CK_BYTE * in_data,
3132 CK_ULONG in_data_len,
3133 CK_BYTE * sig,
3134 CK_ULONG sig_len, OBJECT * key_obj)
3135 {
3136 TSS_RESULT result;
3137 TSS_HHASH hHash;
3138 TSS_HKEY hKey;
3139 CK_RV rc;
3140
3141 UNUSED(sess);
3142
3143 rc = token_rsa_load_key(tokdata, key_obj, &hKey);
3144 if (rc != CKR_OK) {
3145 TRACE_DEVEL("token_rsa_load_key failed. rc=0x%lx\n", rc);
3146 return rc;
3147 }
3148
3149 /* Create the hash object we'll use to sign */
3150 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_HASH,
3151 TSS_HASH_OTHER, &hHash);
3152 if (result) {
3153 TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
3154 return CKR_FUNCTION_FAILED;
3155 }
3156
3157 /* Insert the data into the hash object */
3158 result = Tspi_Hash_SetHashValue(hHash, in_data_len, in_data);
3159 if (result) {
3160 TRACE_ERROR("Tspi_Hash_SetHashValue failed. rc=0x%x\n", result);
3161 return CKR_FUNCTION_FAILED;
3162 }
3163
3164 /* Verify */
3165 result = Tspi_Hash_VerifySignature(hHash, hKey, sig_len, sig);
3166 if (result != TSS_SUCCESS && TPMTOK_TSS_ERROR_CODE(result) != TSS_E_FAIL) {
3167 TRACE_ERROR("Tspi_Hash_VerifySignature failed. rc=0x%x\n", result);
3168 }
3169
3170 if (TPMTOK_TSS_ERROR_CODE(result) == TSS_E_FAIL) {
3171 rc = CKR_SIGNATURE_INVALID;
3172 } else {
3173 rc = CKR_OK;
3174 }
3175
3176 return rc;
3177 }
3178
token_specific_rsa_sign(STDLL_TokData_t * tokdata,SESSION * sess,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)3179 CK_RV token_specific_rsa_sign(STDLL_TokData_t * tokdata,
3180 SESSION * sess,
3181 CK_BYTE * in_data,
3182 CK_ULONG in_data_len,
3183 CK_BYTE * out_data,
3184 CK_ULONG * out_data_len, OBJECT * key_obj)
3185 {
3186 TSS_RESULT result;
3187 TSS_HHASH hHash;
3188 BYTE *sig;
3189 UINT32 sig_len;
3190 TSS_HKEY hKey;
3191 CK_RV rc;
3192
3193 UNUSED(sess);
3194
3195 rc = token_rsa_load_key(tokdata, key_obj, &hKey);
3196 if (rc != CKR_OK) {
3197 TRACE_DEVEL("token_rsa_load_key failed. rc=0x%lx\n", rc);
3198 return rc;
3199 }
3200
3201 /* Create the hash object we'll use to sign */
3202 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_HASH,
3203 TSS_HASH_OTHER, &hHash);
3204 if (result) {
3205 TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
3206 return CKR_FUNCTION_FAILED;
3207 }
3208
3209 /* Insert the data into the hash object */
3210 result = Tspi_Hash_SetHashValue(hHash, in_data_len, in_data);
3211 if (result) {
3212 TRACE_ERROR("Tspi_Hash_SetHashValue failed. rc=0x%x\n", result);
3213 return CKR_FUNCTION_FAILED;
3214 }
3215
3216 /* Sign */
3217 result = Tspi_Hash_Sign(hHash, hKey, &sig_len, &sig);
3218 if (result) {
3219 TRACE_ERROR("Tspi_Hash_Sign failed. rc=0x%x\n", result);
3220 return CKR_FUNCTION_FAILED;
3221 }
3222
3223 if (sig_len > *out_data_len) {
3224 TRACE_ERROR("Buffer too small to hold result.\n");
3225 Tspi_Context_FreeMemory(tspContext, sig);
3226 return CKR_BUFFER_TOO_SMALL;
3227 }
3228
3229 memcpy(out_data, sig, sig_len);
3230 *out_data_len = sig_len;
3231 Tspi_Context_FreeMemory(tspContext, sig);
3232
3233 return CKR_OK;
3234 }
3235
3236
token_specific_rsa_encrypt(STDLL_TokData_t * tokdata,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)3237 CK_RV token_specific_rsa_encrypt(STDLL_TokData_t * tokdata,
3238 CK_BYTE * in_data,
3239 CK_ULONG in_data_len,
3240 CK_BYTE * out_data,
3241 CK_ULONG * out_data_len, OBJECT * key_obj)
3242 {
3243 TSS_RESULT result;
3244 TSS_HENCDATA hEncData;
3245 BYTE *dataBlob;
3246 UINT32 dataBlobSize;
3247 TSS_HKEY hKey;
3248 CK_RV rc;
3249
3250 rc = token_rsa_load_key(tokdata, key_obj, &hKey);
3251 if (rc != CKR_OK) {
3252 TRACE_DEVEL("token_rsa_load_key failed. rc=0x%lx\n", rc);
3253 return rc;
3254 }
3255
3256 result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_ENCDATA,
3257 TSS_ENCDATA_BIND, &hEncData);
3258 if (result) {
3259 TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
3260 return CKR_FUNCTION_FAILED;
3261 }
3262
3263 result = Tspi_Data_Bind(hEncData, hKey, in_data_len, in_data);
3264 if (result) {
3265 TRACE_ERROR("Tspi_Data_Bind failed. rc=0x%x\n", result);
3266 return CKR_FUNCTION_FAILED;
3267 }
3268
3269 result = Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
3270 TSS_TSPATTRIB_ENCDATABLOB_BLOB,
3271 &dataBlobSize, &dataBlob);
3272 if (result) {
3273 TRACE_ERROR("Tspi_SetAttribData failed. rc=0x%x\n", result);
3274 return CKR_FUNCTION_FAILED;
3275 }
3276
3277 if (dataBlobSize > *out_data_len) {
3278 TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
3279 Tspi_Context_FreeMemory(tspContext, dataBlob);
3280 return CKR_DATA_LEN_RANGE;
3281 }
3282
3283 memcpy(out_data, dataBlob, dataBlobSize);
3284 *out_data_len = dataBlobSize;
3285 Tspi_Context_FreeMemory(tspContext, dataBlob);
3286
3287 return CKR_OK;
3288 }
3289
token_specific_rsa_verify_recover(STDLL_TokData_t * tokdata,CK_BYTE * signature,CK_ULONG sig_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)3290 CK_RV token_specific_rsa_verify_recover(STDLL_TokData_t * tokdata,
3291 CK_BYTE * signature, CK_ULONG sig_len,
3292 CK_BYTE * out_data,
3293 CK_ULONG * out_data_len,
3294 OBJECT * key_obj)
3295 {
3296 CK_RV rc;
3297
3298 rc = token_specific_rsa_encrypt(tokdata, signature, sig_len, out_data,
3299 out_data_len, key_obj);
3300
3301 if (rc != CKR_OK)
3302 TRACE_DEVEL("token specific rsa_encrypt failed.\n");
3303
3304 return rc;
3305 }
3306
token_specific_aes_key_gen(STDLL_TokData_t * tokdata,CK_BYTE * key,CK_ULONG len,CK_ULONG keysize)3307 CK_RV token_specific_aes_key_gen(STDLL_TokData_t * tokdata, CK_BYTE * key,
3308 CK_ULONG len, CK_ULONG keysize)
3309 {
3310 UNUSED(keysize);
3311
3312 return token_specific_rng(tokdata, key, len);
3313 }
3314
token_specific_aes_ecb(STDLL_TokData_t * tokdata,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key,CK_BYTE encrypt)3315 CK_RV token_specific_aes_ecb(STDLL_TokData_t * tokdata,
3316 CK_BYTE * in_data,
3317 CK_ULONG in_data_len,
3318 CK_BYTE * out_data,
3319 CK_ULONG * out_data_len,
3320 OBJECT * key, CK_BYTE encrypt)
3321 {
3322 CK_ATTRIBUTE *attr = NULL;
3323 AES_KEY ssl_aes_key;
3324 unsigned int i;
3325 /* There's a previous check that in_data_len % AES_BLOCK_SIZE == 0,
3326 * so this is fine */
3327 CK_ULONG loops = (CK_ULONG) (in_data_len / AES_BLOCK_SIZE);
3328
3329 UNUSED(tokdata);
3330
3331 // get the key value
3332 if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
3333 TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
3334 return CKR_FUNCTION_FAILED;
3335 }
3336
3337 memset(&ssl_aes_key, 0, sizeof(AES_KEY));
3338
3339 // AES_ecb_encrypt encrypts only a single block, so we have to break up the
3340 // input data here
3341 if (encrypt) {
3342 AES_set_encrypt_key((unsigned char *) attr->pValue,
3343 (attr->ulValueLen * 8), &ssl_aes_key);
3344 for (i = 0; i < loops; i++) {
3345 AES_ecb_encrypt((unsigned char *) in_data + (i * AES_BLOCK_SIZE),
3346 (unsigned char *) out_data + (i * AES_BLOCK_SIZE),
3347 &ssl_aes_key, AES_ENCRYPT);
3348 }
3349 } else {
3350 AES_set_decrypt_key((unsigned char *) attr->pValue,
3351 (attr->ulValueLen * 8), &ssl_aes_key);
3352 for (i = 0; i < loops; i++) {
3353 AES_ecb_encrypt((unsigned char *) in_data + (i * AES_BLOCK_SIZE),
3354 (unsigned char *) out_data + (i * AES_BLOCK_SIZE),
3355 &ssl_aes_key, AES_DECRYPT);
3356 }
3357 }
3358 *out_data_len = in_data_len;
3359
3360 return CKR_OK;
3361 }
3362
token_specific_aes_cbc(STDLL_TokData_t * tokdata,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key,CK_BYTE * init_v,CK_BYTE encrypt)3363 CK_RV token_specific_aes_cbc(STDLL_TokData_t * tokdata,
3364 CK_BYTE * in_data,
3365 CK_ULONG in_data_len,
3366 CK_BYTE * out_data,
3367 CK_ULONG * out_data_len,
3368 OBJECT * key, CK_BYTE * init_v, CK_BYTE encrypt)
3369 {
3370 AES_KEY ssl_aes_key;
3371 CK_ATTRIBUTE *attr = NULL;
3372
3373 UNUSED(tokdata);
3374
3375 // get the key value
3376 if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
3377 TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
3378 return CKR_FUNCTION_FAILED;
3379 }
3380
3381 memset(&ssl_aes_key, 0, sizeof(AES_KEY));
3382
3383 // AES_cbc_encrypt chunks the data into AES_BLOCK_SIZE blocks, unlike
3384 // AES_ecb_encrypt, so no looping required.
3385 if (encrypt) {
3386 AES_set_encrypt_key((unsigned char *) attr->pValue,
3387 (attr->ulValueLen * 8), &ssl_aes_key);
3388 AES_cbc_encrypt((unsigned char *) in_data, (unsigned char *) out_data,
3389 in_data_len, &ssl_aes_key, init_v, AES_ENCRYPT);
3390 } else {
3391 AES_set_decrypt_key((unsigned char *) attr->pValue,
3392 (attr->ulValueLen * 8), &ssl_aes_key);
3393 AES_cbc_encrypt((unsigned char *) in_data, (unsigned char *) out_data,
3394 in_data_len, &ssl_aes_key, init_v, AES_DECRYPT);
3395 }
3396 *out_data_len = in_data_len;
3397
3398 return CKR_OK;
3399 }
3400
token_specific_get_mechanism_list(STDLL_TokData_t * tokdata,CK_MECHANISM_TYPE_PTR pMechanismList,CK_ULONG_PTR pulCount)3401 CK_RV token_specific_get_mechanism_list(STDLL_TokData_t * tokdata,
3402 CK_MECHANISM_TYPE_PTR pMechanismList,
3403 CK_ULONG_PTR pulCount)
3404 {
3405 int rc;
3406
3407 UNUSED(tokdata);
3408
3409 /* common/mech_list.c */
3410 rc = ock_generic_get_mechanism_list(pMechanismList, pulCount);
3411
3412 return rc;
3413 }
3414
token_specific_get_mechanism_info(STDLL_TokData_t * tokdata,CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo)3415 CK_RV token_specific_get_mechanism_info(STDLL_TokData_t * tokdata,
3416 CK_MECHANISM_TYPE type,
3417 CK_MECHANISM_INFO_PTR pInfo)
3418 {
3419 int rc;
3420
3421 UNUSED(tokdata);
3422
3423 /* common/mech_list.c */
3424 rc = ock_generic_get_mechanism_info(type, pInfo);
3425
3426 return rc;
3427 }
3428
token_specific_creatlock(void)3429 int token_specific_creatlock(void)
3430 {
3431 char lockfile[PATH_MAX + (sizeof(LOCKDIR_PATH) - 1)
3432 + 2 * (sizeof(SUB_DIR) - 1)
3433 + (sizeof("///LCK..") - 1) + 1];
3434 char lockdir[(sizeof(LOCKDIR_PATH) - 1) + (sizeof(SUB_DIR) - 1)
3435 + (sizeof("/") - 1) + 1];
3436 struct passwd *pw = NULL;
3437 struct stat statbuf;
3438 mode_t mode = (S_IRUSR | S_IWUSR | S_IXUSR);
3439 int lockfd = -1;;
3440 int ret = -1;
3441 struct group *grp = NULL;
3442
3443 /* get userid */
3444 pw = getpwuid(getuid());
3445 if (pw == NULL) {
3446 OCK_SYSLOG(LOG_ERR, "getpwuid(): %s\n", strerror(errno));
3447 return -1;
3448 }
3449 if (strlen(pw->pw_name) > PATH_MAX) {
3450 OCK_SYSLOG(LOG_ERR, "Username(%s) too long\n", pw->pw_name);
3451 return -1;
3452 }
3453
3454 /** create lock subdir for each token if it doesn't exist.
3455 * The root /var/lock/opencryptoki directory should be created in slotmgr
3456 * daemon **/
3457 sprintf(lockdir, "%s/%s", LOCKDIR_PATH, SUB_DIR);
3458
3459 ret = stat(lockdir, &statbuf);
3460 if (ret != 0 && errno == ENOENT) {
3461 /* dir does not exist, try to create it */
3462 ret = mkdir(lockdir, S_IRWXU | S_IRWXG);
3463 if (ret != 0) {
3464 OCK_SYSLOG(LOG_ERR,
3465 "Directory(%s) missing: %s\n", lockdir, strerror(errno));
3466 goto err;
3467 }
3468 grp = getgrnam("pkcs11");
3469 if (grp == NULL) {
3470 fprintf(stderr, "getgrname(pkcs11): %s", strerror(errno));
3471 goto err;
3472 }
3473 /* set ownership to euid, and pkcs11 group */
3474 if (chown(lockdir, geteuid(), grp->gr_gid) != 0) {
3475 fprintf(stderr, "Failed to set owner:group \
3476 ownership\
3477 on %s directory", lockdir);
3478 goto err;
3479 }
3480 /* mkdir does not set group permission right, so
3481 ** trying explictly here again */
3482 if (chmod(lockdir, S_IRWXU | S_IRWXG) != 0) {
3483 fprintf(stderr, "Failed to change \
3484 permissions\
3485 on %s directory", lockdir);
3486 goto err;
3487 }
3488 }
3489
3490 /* create user-specific directory */
3491 sprintf(lockfile, "%s/%s/%s", LOCKDIR_PATH, SUB_DIR, pw->pw_name);
3492
3493 /* see if it exists, otherwise mkdir will fail */
3494 if (stat(lockfile, &statbuf) < 0) {
3495 if (mkdir(lockfile, mode) == -1) {
3496 OCK_SYSLOG(LOG_ERR, "mkdir(%s): %s\n", lockfile, strerror(errno));
3497 return -1;
3498 }
3499
3500 /* ensure correct perms on user dir */
3501 if (chmod(lockfile, mode) == -1) {
3502 OCK_SYSLOG(LOG_ERR, "chmod(%s): %s\n", lockfile, strerror(errno));
3503 return -1;
3504 }
3505 }
3506
3507 /* create user lock file */
3508 memset(lockfile, 0, sizeof(lockfile));
3509 sprintf(lockfile, "%s/%s/%s/LCK..%s", LOCKDIR_PATH, SUB_DIR, pw->pw_name,
3510 SUB_DIR);
3511
3512 lockfd = open(lockfile, O_CREAT | O_RDWR, mode);
3513 if (lockfd == -1) {
3514 OCK_SYSLOG(LOG_ERR, "open(%s): %s\n", lockfile, strerror(errno));
3515 return -1;
3516 } else {
3517 /* umask may prevent correct mode, so set it. */
3518 if (fchmod(lockfd, mode) == -1) {
3519 OCK_SYSLOG(LOG_ERR, "fchmod(%s): %s\n", lockfile, strerror(errno));
3520 goto err;
3521 }
3522 }
3523
3524 return lockfd;
3525 err:
3526 if (lockfd != -1)
3527 close(lockfd);
3528
3529 return -1;
3530 }
3531
token_specific_init_token_data(STDLL_TokData_t * tokdata,CK_SLOT_ID slot_id)3532 CK_RV token_specific_init_token_data(STDLL_TokData_t * tokdata,
3533 CK_SLOT_ID slot_id)
3534 {
3535 UNUSED(tokdata);
3536 UNUSED(slot_id);
3537
3538 /* do nothing. */
3539 return CKR_OK;
3540 }
3541