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