147e946e7SWyllys Ingersoll /*
247e946e7SWyllys Ingersoll * The Initial Developer of the Original Code is International
347e946e7SWyllys Ingersoll * Business Machines Corporation. Portions created by IBM
447e946e7SWyllys Ingersoll * Corporation are Copyright (C) 2005 International Business
547e946e7SWyllys Ingersoll * Machines Corporation. All Rights Reserved.
647e946e7SWyllys Ingersoll *
747e946e7SWyllys Ingersoll * This program is free software; you can redistribute it and/or modify
847e946e7SWyllys Ingersoll * it under the terms of the Common Public License as published by
947e946e7SWyllys Ingersoll * IBM Corporation; either version 1 of the License, or (at your option)
1047e946e7SWyllys Ingersoll * any later version.
1147e946e7SWyllys Ingersoll *
1247e946e7SWyllys Ingersoll * This program is distributed in the hope that it will be useful,
1347e946e7SWyllys Ingersoll * but WITHOUT ANY WARRANTY; without even the implied warranty of
1447e946e7SWyllys Ingersoll * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1547e946e7SWyllys Ingersoll * Common Public License for more details.
1647e946e7SWyllys Ingersoll *
1747e946e7SWyllys Ingersoll * You should have received a copy of the Common Public License
1847e946e7SWyllys Ingersoll * along with this program; if not, a copy can be viewed at
1947e946e7SWyllys Ingersoll * http://www.opensource.org/licenses/cpl1.0.php.
2047e946e7SWyllys Ingersoll */
2147e946e7SWyllys Ingersoll
2247e946e7SWyllys Ingersoll /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */
2347e946e7SWyllys Ingersoll /*
2447e946e7SWyllys Ingersoll * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2547e946e7SWyllys Ingersoll * Use is subject to license terms.
2647e946e7SWyllys Ingersoll */
2747e946e7SWyllys Ingersoll
2847e946e7SWyllys Ingersoll #include "tpmtok_int.h"
2947e946e7SWyllys Ingersoll
3047e946e7SWyllys Ingersoll static CK_SLOT_INFO slot_info;
3147e946e7SWyllys Ingersoll
3247e946e7SWyllys Ingersoll // Function: dlist_add_as_first()
3347e946e7SWyllys Ingersoll //
3447e946e7SWyllys Ingersoll // Adds the specified node to the start of the list
3547e946e7SWyllys Ingersoll //
3647e946e7SWyllys Ingersoll // Returns: pointer to the start of the list
3747e946e7SWyllys Ingersoll //
3847e946e7SWyllys Ingersoll DL_NODE *
dlist_add_as_first(DL_NODE * list,void * data)3947e946e7SWyllys Ingersoll dlist_add_as_first(DL_NODE *list, void *data)
4047e946e7SWyllys Ingersoll {
4147e946e7SWyllys Ingersoll DL_NODE *node = NULL;
4247e946e7SWyllys Ingersoll
4347e946e7SWyllys Ingersoll if (! data)
4447e946e7SWyllys Ingersoll return (list);
4547e946e7SWyllys Ingersoll node = (DL_NODE *)malloc(sizeof (DL_NODE));
4647e946e7SWyllys Ingersoll if (! node)
4747e946e7SWyllys Ingersoll return (NULL);
4847e946e7SWyllys Ingersoll node->data = data;
4947e946e7SWyllys Ingersoll node->prev = NULL;
5047e946e7SWyllys Ingersoll node->next = list;
5147e946e7SWyllys Ingersoll if (list)
5247e946e7SWyllys Ingersoll list->prev = node;
5347e946e7SWyllys Ingersoll
5447e946e7SWyllys Ingersoll return (node);
5547e946e7SWyllys Ingersoll }
5647e946e7SWyllys Ingersoll
5747e946e7SWyllys Ingersoll
5847e946e7SWyllys Ingersoll // Function: dlist_add_as_last()
5947e946e7SWyllys Ingersoll //
6047e946e7SWyllys Ingersoll // Adds the specified node to the end of the list
6147e946e7SWyllys Ingersoll //
6247e946e7SWyllys Ingersoll // Returns: pointer to the start of the list
6347e946e7SWyllys Ingersoll //
6447e946e7SWyllys Ingersoll DL_NODE *
dlist_add_as_last(DL_NODE * list,void * data)6547e946e7SWyllys Ingersoll dlist_add_as_last(DL_NODE *list, void *data) {
6647e946e7SWyllys Ingersoll DL_NODE *node = NULL;
6747e946e7SWyllys Ingersoll
6847e946e7SWyllys Ingersoll if (! data)
6947e946e7SWyllys Ingersoll return (list);
7047e946e7SWyllys Ingersoll node = (DL_NODE *)malloc(sizeof (DL_NODE));
7147e946e7SWyllys Ingersoll if (! node)
7247e946e7SWyllys Ingersoll return (NULL);
7347e946e7SWyllys Ingersoll node->data = data;
7447e946e7SWyllys Ingersoll node->next = NULL;
7547e946e7SWyllys Ingersoll
7647e946e7SWyllys Ingersoll if (! list) {
7747e946e7SWyllys Ingersoll node->prev = NULL;
7847e946e7SWyllys Ingersoll return (node);
7947e946e7SWyllys Ingersoll } else {
8047e946e7SWyllys Ingersoll DL_NODE *temp = dlist_get_last(list);
8147e946e7SWyllys Ingersoll temp->next = node;
8247e946e7SWyllys Ingersoll node->prev = temp;
8347e946e7SWyllys Ingersoll
8447e946e7SWyllys Ingersoll return (list);
8547e946e7SWyllys Ingersoll }
8647e946e7SWyllys Ingersoll }
8747e946e7SWyllys Ingersoll
8847e946e7SWyllys Ingersoll
8947e946e7SWyllys Ingersoll // Function: dlist_find()
9047e946e7SWyllys Ingersoll //
9147e946e7SWyllys Ingersoll DL_NODE *
dlist_find(DL_NODE * list,void * data)9247e946e7SWyllys Ingersoll dlist_find(DL_NODE *list, void *data)
9347e946e7SWyllys Ingersoll {
9447e946e7SWyllys Ingersoll DL_NODE *node = list;
9547e946e7SWyllys Ingersoll
9647e946e7SWyllys Ingersoll while (node && node->data != data)
9747e946e7SWyllys Ingersoll node = node->next;
9847e946e7SWyllys Ingersoll
9947e946e7SWyllys Ingersoll return (node);
10047e946e7SWyllys Ingersoll }
10147e946e7SWyllys Ingersoll
10247e946e7SWyllys Ingersoll
10347e946e7SWyllys Ingersoll // Function: dlist_get_first()
10447e946e7SWyllys Ingersoll //
10547e946e7SWyllys Ingersoll // Returns the last node in the list or NULL if list is empty
10647e946e7SWyllys Ingersoll //
10747e946e7SWyllys Ingersoll DL_NODE *
dlist_get_first(DL_NODE * list)10847e946e7SWyllys Ingersoll dlist_get_first(DL_NODE *list) {
10947e946e7SWyllys Ingersoll DL_NODE *temp = list;
11047e946e7SWyllys Ingersoll
11147e946e7SWyllys Ingersoll if (! list)
11247e946e7SWyllys Ingersoll return (NULL);
11347e946e7SWyllys Ingersoll while (temp->prev != NULL)
11447e946e7SWyllys Ingersoll temp = temp->prev;
11547e946e7SWyllys Ingersoll
11647e946e7SWyllys Ingersoll return (temp);
11747e946e7SWyllys Ingersoll }
11847e946e7SWyllys Ingersoll
11947e946e7SWyllys Ingersoll
12047e946e7SWyllys Ingersoll // Function: dlist_get_last()
12147e946e7SWyllys Ingersoll //
12247e946e7SWyllys Ingersoll // Returns the last node in the list or NULL if list is empty
12347e946e7SWyllys Ingersoll //
12447e946e7SWyllys Ingersoll DL_NODE *
dlist_get_last(DL_NODE * list)12547e946e7SWyllys Ingersoll dlist_get_last(DL_NODE *list) {
12647e946e7SWyllys Ingersoll DL_NODE *temp = list;
12747e946e7SWyllys Ingersoll
12847e946e7SWyllys Ingersoll if (! list)
12947e946e7SWyllys Ingersoll return (NULL);
13047e946e7SWyllys Ingersoll while (temp->next != NULL)
13147e946e7SWyllys Ingersoll temp = temp->next;
13247e946e7SWyllys Ingersoll
13347e946e7SWyllys Ingersoll return (temp);
13447e946e7SWyllys Ingersoll }
13547e946e7SWyllys Ingersoll
13647e946e7SWyllys Ingersoll
13747e946e7SWyllys Ingersoll //
13847e946e7SWyllys Ingersoll //
13947e946e7SWyllys Ingersoll CK_ULONG
dlist_length(DL_NODE * list)14047e946e7SWyllys Ingersoll dlist_length(DL_NODE *list) {
14147e946e7SWyllys Ingersoll DL_NODE *temp = list;
14247e946e7SWyllys Ingersoll CK_ULONG len = 0;
14347e946e7SWyllys Ingersoll
14447e946e7SWyllys Ingersoll while (temp) {
14547e946e7SWyllys Ingersoll len++;
14647e946e7SWyllys Ingersoll temp = temp->next;
14747e946e7SWyllys Ingersoll }
14847e946e7SWyllys Ingersoll
14947e946e7SWyllys Ingersoll return (len);
15047e946e7SWyllys Ingersoll }
15147e946e7SWyllys Ingersoll
15247e946e7SWyllys Ingersoll
15347e946e7SWyllys Ingersoll //
15447e946e7SWyllys Ingersoll //
15547e946e7SWyllys Ingersoll DL_NODE *
dlist_next(DL_NODE * node)15647e946e7SWyllys Ingersoll dlist_next(DL_NODE *node)
15747e946e7SWyllys Ingersoll {
15847e946e7SWyllys Ingersoll if (! node)
15947e946e7SWyllys Ingersoll return (NULL);
16047e946e7SWyllys Ingersoll return (node->next);
16147e946e7SWyllys Ingersoll }
16247e946e7SWyllys Ingersoll
16347e946e7SWyllys Ingersoll
16447e946e7SWyllys Ingersoll //
16547e946e7SWyllys Ingersoll //
16647e946e7SWyllys Ingersoll DL_NODE *
dlist_prev(DL_NODE * node)16747e946e7SWyllys Ingersoll dlist_prev(DL_NODE *node) {
16847e946e7SWyllys Ingersoll if (! node)
16947e946e7SWyllys Ingersoll return (NULL);
17047e946e7SWyllys Ingersoll return (node->prev);
17147e946e7SWyllys Ingersoll }
17247e946e7SWyllys Ingersoll
17347e946e7SWyllys Ingersoll
17447e946e7SWyllys Ingersoll //
17547e946e7SWyllys Ingersoll //
17647e946e7SWyllys Ingersoll void
dlist_purge(DL_NODE * list)17747e946e7SWyllys Ingersoll dlist_purge(DL_NODE *list) {
17847e946e7SWyllys Ingersoll DL_NODE *node;
17947e946e7SWyllys Ingersoll
18047e946e7SWyllys Ingersoll if (! list)
18147e946e7SWyllys Ingersoll return;
18247e946e7SWyllys Ingersoll do {
18347e946e7SWyllys Ingersoll node = list->next;
18447e946e7SWyllys Ingersoll free(list);
18547e946e7SWyllys Ingersoll list = node;
18647e946e7SWyllys Ingersoll } while (list);
18747e946e7SWyllys Ingersoll }
18847e946e7SWyllys Ingersoll
18947e946e7SWyllys Ingersoll // Function: dlist_remove_node()
19047e946e7SWyllys Ingersoll //
19147e946e7SWyllys Ingersoll // Attempts to remove the specified node from the list. The caller is
19247e946e7SWyllys Ingersoll // responsible for freeing the data associated with the node prior to
19347e946e7SWyllys Ingersoll // calling this routine
19447e946e7SWyllys Ingersoll //
19547e946e7SWyllys Ingersoll DL_NODE *
dlist_remove_node(DL_NODE * list,DL_NODE * node)19647e946e7SWyllys Ingersoll dlist_remove_node(DL_NODE *list, DL_NODE *node) {
19747e946e7SWyllys Ingersoll DL_NODE *temp = list;
19847e946e7SWyllys Ingersoll
19947e946e7SWyllys Ingersoll if (! list || ! node)
20047e946e7SWyllys Ingersoll return (NULL);
20147e946e7SWyllys Ingersoll // special case: removing head of the list
20247e946e7SWyllys Ingersoll //
20347e946e7SWyllys Ingersoll if (list == node) {
20447e946e7SWyllys Ingersoll temp = list->next;
20547e946e7SWyllys Ingersoll if (temp)
20647e946e7SWyllys Ingersoll temp->prev = NULL;
20747e946e7SWyllys Ingersoll
20847e946e7SWyllys Ingersoll free(list);
20947e946e7SWyllys Ingersoll return (temp);
21047e946e7SWyllys Ingersoll }
21147e946e7SWyllys Ingersoll
21247e946e7SWyllys Ingersoll // we have no guarantee that the node is in the list
21347e946e7SWyllys Ingersoll // so search through the list to find it
21447e946e7SWyllys Ingersoll //
21547e946e7SWyllys Ingersoll while ((temp != NULL) && (temp->next != node))
21647e946e7SWyllys Ingersoll temp = temp->next;
21747e946e7SWyllys Ingersoll
21847e946e7SWyllys Ingersoll if (temp != NULL) {
21947e946e7SWyllys Ingersoll DL_NODE *next = node->next;
22047e946e7SWyllys Ingersoll
22147e946e7SWyllys Ingersoll temp->next = next;
22247e946e7SWyllys Ingersoll if (next)
22347e946e7SWyllys Ingersoll next->prev = temp;
22447e946e7SWyllys Ingersoll
22547e946e7SWyllys Ingersoll free(node);
22647e946e7SWyllys Ingersoll }
22747e946e7SWyllys Ingersoll
22847e946e7SWyllys Ingersoll return (list);
22947e946e7SWyllys Ingersoll }
23047e946e7SWyllys Ingersoll
23147e946e7SWyllys Ingersoll extern void set_perm(int);
23247e946e7SWyllys Ingersoll
23347e946e7SWyllys Ingersoll void
CreateXProcLock(void * xproc)23447e946e7SWyllys Ingersoll CreateXProcLock(void *xproc)
23547e946e7SWyllys Ingersoll {
23647e946e7SWyllys Ingersoll pthread_mutexattr_t mtxattr;
23747e946e7SWyllys Ingersoll
23847e946e7SWyllys Ingersoll (void) pthread_mutexattr_init(&mtxattr);
23947e946e7SWyllys Ingersoll (void) pthread_mutexattr_setpshared(&mtxattr, PTHREAD_PROCESS_SHARED);
24047e946e7SWyllys Ingersoll (void) pthread_mutex_init((pthread_mutex_t *)xproc, &mtxattr);
24147e946e7SWyllys Ingersoll }
24247e946e7SWyllys Ingersoll
24347e946e7SWyllys Ingersoll int
DestroyXProcLock(void * xproc)24447e946e7SWyllys Ingersoll DestroyXProcLock(void *xproc)
24547e946e7SWyllys Ingersoll {
24647e946e7SWyllys Ingersoll return (pthread_mutex_destroy((pthread_mutex_t *)xproc));
24747e946e7SWyllys Ingersoll }
24847e946e7SWyllys Ingersoll
24947e946e7SWyllys Ingersoll int
XProcLock(void * xproc)25047e946e7SWyllys Ingersoll XProcLock(void *xproc)
25147e946e7SWyllys Ingersoll {
25247e946e7SWyllys Ingersoll return (pthread_mutex_lock((pthread_mutex_t *)xproc));
25347e946e7SWyllys Ingersoll }
25447e946e7SWyllys Ingersoll
25547e946e7SWyllys Ingersoll int
XProcUnLock(void * xproc)25647e946e7SWyllys Ingersoll XProcUnLock(void *xproc)
25747e946e7SWyllys Ingersoll {
25847e946e7SWyllys Ingersoll return (pthread_mutex_unlock((pthread_mutex_t *)xproc));
25947e946e7SWyllys Ingersoll }
26047e946e7SWyllys Ingersoll
26147e946e7SWyllys Ingersoll //
26247e946e7SWyllys Ingersoll //
26347e946e7SWyllys Ingersoll // is_attribute_defined()
26447e946e7SWyllys Ingersoll //
26547e946e7SWyllys Ingersoll // determine whether the specified attribute is defined by Cryptoki
26647e946e7SWyllys Ingersoll //
26747e946e7SWyllys Ingersoll CK_BBOOL
is_attribute_defined(CK_ATTRIBUTE_TYPE type)26847e946e7SWyllys Ingersoll is_attribute_defined(CK_ATTRIBUTE_TYPE type)
26947e946e7SWyllys Ingersoll {
27047e946e7SWyllys Ingersoll if (type >= CKA_VENDOR_DEFINED)
27147e946e7SWyllys Ingersoll return (TRUE);
27247e946e7SWyllys Ingersoll switch (type) {
27347e946e7SWyllys Ingersoll case CKA_CLASS:
27447e946e7SWyllys Ingersoll case CKA_TOKEN:
27547e946e7SWyllys Ingersoll case CKA_PRIVATE:
27647e946e7SWyllys Ingersoll case CKA_LABEL:
27747e946e7SWyllys Ingersoll case CKA_APPLICATION:
27847e946e7SWyllys Ingersoll case CKA_VALUE:
27947e946e7SWyllys Ingersoll case CKA_CERTIFICATE_TYPE:
28047e946e7SWyllys Ingersoll case CKA_ISSUER:
28147e946e7SWyllys Ingersoll case CKA_SERIAL_NUMBER:
28247e946e7SWyllys Ingersoll case CKA_KEY_TYPE:
28347e946e7SWyllys Ingersoll case CKA_SUBJECT:
28447e946e7SWyllys Ingersoll case CKA_ID:
28547e946e7SWyllys Ingersoll case CKA_SENSITIVE:
28647e946e7SWyllys Ingersoll case CKA_ENCRYPT:
28747e946e7SWyllys Ingersoll case CKA_DECRYPT:
28847e946e7SWyllys Ingersoll case CKA_WRAP:
28947e946e7SWyllys Ingersoll case CKA_UNWRAP:
29047e946e7SWyllys Ingersoll case CKA_SIGN:
29147e946e7SWyllys Ingersoll case CKA_SIGN_RECOVER:
29247e946e7SWyllys Ingersoll case CKA_VERIFY:
29347e946e7SWyllys Ingersoll case CKA_VERIFY_RECOVER:
29447e946e7SWyllys Ingersoll case CKA_DERIVE:
29547e946e7SWyllys Ingersoll case CKA_START_DATE:
29647e946e7SWyllys Ingersoll case CKA_END_DATE:
29747e946e7SWyllys Ingersoll case CKA_MODULUS:
29847e946e7SWyllys Ingersoll case CKA_MODULUS_BITS:
29947e946e7SWyllys Ingersoll case CKA_PUBLIC_EXPONENT:
30047e946e7SWyllys Ingersoll case CKA_PRIVATE_EXPONENT:
30147e946e7SWyllys Ingersoll case CKA_PRIME_1:
30247e946e7SWyllys Ingersoll case CKA_PRIME_2:
30347e946e7SWyllys Ingersoll case CKA_EXPONENT_1:
30447e946e7SWyllys Ingersoll case CKA_EXPONENT_2:
30547e946e7SWyllys Ingersoll case CKA_COEFFICIENT:
30647e946e7SWyllys Ingersoll case CKA_PRIME:
30747e946e7SWyllys Ingersoll case CKA_SUBPRIME:
30847e946e7SWyllys Ingersoll case CKA_BASE:
30947e946e7SWyllys Ingersoll case CKA_VALUE_BITS:
31047e946e7SWyllys Ingersoll case CKA_VALUE_LEN:
31147e946e7SWyllys Ingersoll case CKA_EXTRACTABLE:
31247e946e7SWyllys Ingersoll case CKA_LOCAL:
31347e946e7SWyllys Ingersoll case CKA_NEVER_EXTRACTABLE:
31447e946e7SWyllys Ingersoll case CKA_ALWAYS_SENSITIVE:
31547e946e7SWyllys Ingersoll case CKA_MODIFIABLE:
31647e946e7SWyllys Ingersoll case CKA_ECDSA_PARAMS:
31747e946e7SWyllys Ingersoll case CKA_EC_POINT:
31847e946e7SWyllys Ingersoll case CKA_HW_FEATURE_TYPE:
31947e946e7SWyllys Ingersoll case CKA_HAS_RESET:
32047e946e7SWyllys Ingersoll case CKA_RESET_ON_INIT:
32147e946e7SWyllys Ingersoll case CKA_KEY_GEN_MECHANISM:
32247e946e7SWyllys Ingersoll case CKA_PRIME_BITS:
32347e946e7SWyllys Ingersoll case CKA_SUBPRIME_BITS:
32447e946e7SWyllys Ingersoll case CKA_OBJECT_ID:
32547e946e7SWyllys Ingersoll case CKA_AC_ISSUER:
32647e946e7SWyllys Ingersoll case CKA_OWNER:
32747e946e7SWyllys Ingersoll case CKA_ATTR_TYPES:
32847e946e7SWyllys Ingersoll case CKA_TRUSTED:
32947e946e7SWyllys Ingersoll return (TRUE);
33047e946e7SWyllys Ingersoll }
33147e946e7SWyllys Ingersoll
33247e946e7SWyllys Ingersoll return (FALSE);
33347e946e7SWyllys Ingersoll }
33447e946e7SWyllys Ingersoll
33547e946e7SWyllys Ingersoll void
init_slot_info(TOKEN_DATA * td)33647e946e7SWyllys Ingersoll init_slot_info(TOKEN_DATA *td)
33747e946e7SWyllys Ingersoll {
33847e946e7SWyllys Ingersoll /*
33947e946e7SWyllys Ingersoll * Much of the token info is pulled from the TPM itself when
34047e946e7SWyllys Ingersoll * C_Initialize is called.
34147e946e7SWyllys Ingersoll */
34247e946e7SWyllys Ingersoll (void) (void) memset(&slot_info.slotDescription, ' ',
34347e946e7SWyllys Ingersoll sizeof (slot_info.slotDescription) - 1);
34447e946e7SWyllys Ingersoll (void) (void) memset(&slot_info.manufacturerID, ' ',
34547e946e7SWyllys Ingersoll sizeof (slot_info.manufacturerID) - 1);
34647e946e7SWyllys Ingersoll
34747e946e7SWyllys Ingersoll (void) (void) memcpy(&slot_info.slotDescription,
34847e946e7SWyllys Ingersoll "PKCS#11 Interface for TPM",
34947e946e7SWyllys Ingersoll strlen("PKCS#11 Interface for TPM"));
35047e946e7SWyllys Ingersoll
35147e946e7SWyllys Ingersoll (void) (void) memcpy(&slot_info.manufacturerID,
35247e946e7SWyllys Ingersoll td->token_info.manufacturerID,
35347e946e7SWyllys Ingersoll strlen((char *)td->token_info.manufacturerID));
35447e946e7SWyllys Ingersoll
35547e946e7SWyllys Ingersoll slot_info.hardwareVersion = nv_token_data->token_info.hardwareVersion;
35647e946e7SWyllys Ingersoll slot_info.firmwareVersion = nv_token_data->token_info.firmwareVersion;
35747e946e7SWyllys Ingersoll slot_info.flags = CKF_TOKEN_PRESENT | CKF_HW_SLOT;
35847e946e7SWyllys Ingersoll }
35947e946e7SWyllys Ingersoll
36047e946e7SWyllys Ingersoll /*ARGSUSED*/
36147e946e7SWyllys Ingersoll void
copy_slot_info(CK_SLOT_ID slotID,CK_SLOT_INFO_PTR sinfo)36247e946e7SWyllys Ingersoll copy_slot_info(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR sinfo)
36347e946e7SWyllys Ingersoll {
36447e946e7SWyllys Ingersoll if (sinfo != NULL)
36547e946e7SWyllys Ingersoll (void) memcpy(sinfo, &slot_info, sizeof (slot_info));
36647e946e7SWyllys Ingersoll }
36747e946e7SWyllys Ingersoll
36847e946e7SWyllys Ingersoll static void
init_token_info(TOKEN_DATA * td)36947e946e7SWyllys Ingersoll init_token_info(TOKEN_DATA *td)
37047e946e7SWyllys Ingersoll {
37147e946e7SWyllys Ingersoll CK_TOKEN_INFO *token_info = NULL;
37247e946e7SWyllys Ingersoll
37347e946e7SWyllys Ingersoll token_info = &td->token_info;
37447e946e7SWyllys Ingersoll
37547e946e7SWyllys Ingersoll (void) memset(token_info->model, ' ',
37647e946e7SWyllys Ingersoll sizeof (token_info->model));
37747e946e7SWyllys Ingersoll (void) memset(token_info->serialNumber, ' ',
37847e946e7SWyllys Ingersoll sizeof (token_info->serialNumber));
37947e946e7SWyllys Ingersoll
38047e946e7SWyllys Ingersoll //
38147e946e7SWyllys Ingersoll // I don't see any API support for changing the clock so
38247e946e7SWyllys Ingersoll // we will use the system clock for the token's clock.
38347e946e7SWyllys Ingersoll //
38447e946e7SWyllys Ingersoll token_info->flags = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_CLOCK_ON_TOKEN |
38547e946e7SWyllys Ingersoll CKF_SO_PIN_TO_BE_CHANGED;
38647e946e7SWyllys Ingersoll
38747e946e7SWyllys Ingersoll if (memcmp(td->user_pin_sha, "00000000000000000000",
38847e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH) != 0)
38947e946e7SWyllys Ingersoll token_info->flags |= CKF_USER_PIN_INITIALIZED;
39047e946e7SWyllys Ingersoll else
39147e946e7SWyllys Ingersoll token_info->flags |= CKF_USER_PIN_TO_BE_CHANGED;
39247e946e7SWyllys Ingersoll
39347e946e7SWyllys Ingersoll // For the release, we made these
39447e946e7SWyllys Ingersoll // values as CK_UNAVAILABLE_INFORMATION
39547e946e7SWyllys Ingersoll //
39647e946e7SWyllys Ingersoll token_info->ulMaxSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
39747e946e7SWyllys Ingersoll token_info->ulSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
39847e946e7SWyllys Ingersoll token_info->ulMaxRwSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
39947e946e7SWyllys Ingersoll token_info->ulRwSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
40047e946e7SWyllys Ingersoll token_info->ulMaxPinLen = MAX_PIN_LEN;
40147e946e7SWyllys Ingersoll token_info->ulMinPinLen = MIN_PIN_LEN;
40247e946e7SWyllys Ingersoll token_info->ulTotalPublicMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
40347e946e7SWyllys Ingersoll token_info->ulFreePublicMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
40447e946e7SWyllys Ingersoll token_info->ulTotalPrivateMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
40547e946e7SWyllys Ingersoll token_info->ulFreePrivateMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
40647e946e7SWyllys Ingersoll
40747e946e7SWyllys Ingersoll (void) memset(token_info->utcTime, ' ', sizeof (token_info->utcTime));
40847e946e7SWyllys Ingersoll }
40947e946e7SWyllys Ingersoll
41047e946e7SWyllys Ingersoll CK_RV
init_token_data(TSS_HCONTEXT hContext,TOKEN_DATA * td)41147e946e7SWyllys Ingersoll init_token_data(TSS_HCONTEXT hContext, TOKEN_DATA *td) {
41247e946e7SWyllys Ingersoll CK_RV rc;
41347e946e7SWyllys Ingersoll
41447e946e7SWyllys Ingersoll (void) memset((char *)td, 0, sizeof (nv_token_data));
41547e946e7SWyllys Ingersoll //
41647e946e7SWyllys Ingersoll // the normal USER pin is not set when the token is initialized
41747e946e7SWyllys Ingersoll //
41847e946e7SWyllys Ingersoll (void) memcpy(td->user_pin_sha, "00000000000000000000",
41947e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH);
42047e946e7SWyllys Ingersoll (void) memcpy(td->so_pin_sha, default_so_pin_sha,
42147e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH);
42247e946e7SWyllys Ingersoll
42347e946e7SWyllys Ingersoll (void) memset(user_pin_md5, 0x0, MD5_DIGEST_LENGTH);
42447e946e7SWyllys Ingersoll (void) memcpy(so_pin_md5, default_so_pin_md5, MD5_DIGEST_LENGTH);
42547e946e7SWyllys Ingersoll
42647e946e7SWyllys Ingersoll (void) memcpy(td->next_token_object_name, "00000000", 8);
42747e946e7SWyllys Ingersoll
42847e946e7SWyllys Ingersoll td->tweak_vector.allow_key_mods = TRUE;
42947e946e7SWyllys Ingersoll
43047e946e7SWyllys Ingersoll init_token_info(td);
43147e946e7SWyllys Ingersoll
43247e946e7SWyllys Ingersoll rc = token_get_tpm_info(hContext, td);
43347e946e7SWyllys Ingersoll if (rc != CKR_OK)
43447e946e7SWyllys Ingersoll return (rc);
43547e946e7SWyllys Ingersoll
43647e946e7SWyllys Ingersoll rc = save_token_data(td);
43747e946e7SWyllys Ingersoll
43847e946e7SWyllys Ingersoll return (rc);
43947e946e7SWyllys Ingersoll }
44047e946e7SWyllys Ingersoll
44147e946e7SWyllys Ingersoll // Function: compute_next_token_obj_name()
44247e946e7SWyllys Ingersoll //
44347e946e7SWyllys Ingersoll // Given a token object name (8 bytes in the range [0 - 9A - Z])
44447e946e7SWyllys Ingersoll // increment by one adjusting as necessary
44547e946e7SWyllys Ingersoll //
44647e946e7SWyllys Ingersoll // This gives us a namespace of 36^8 = 2, 821, 109, 907, 456
44747e946e7SWyllys Ingersoll // objects before wrapping around.
44847e946e7SWyllys Ingersoll //
44947e946e7SWyllys Ingersoll CK_RV
compute_next_token_obj_name(CK_BYTE * current,CK_BYTE * next)45047e946e7SWyllys Ingersoll compute_next_token_obj_name(CK_BYTE *current, CK_BYTE *next) {
45147e946e7SWyllys Ingersoll int val[8];
45247e946e7SWyllys Ingersoll int i;
45347e946e7SWyllys Ingersoll
45447e946e7SWyllys Ingersoll if (! current || ! next) {
45547e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
45647e946e7SWyllys Ingersoll }
45747e946e7SWyllys Ingersoll // Convert to integral base 36
45847e946e7SWyllys Ingersoll //
45947e946e7SWyllys Ingersoll for (i = 0; i < 8; i++) {
46047e946e7SWyllys Ingersoll if (current[i] >= '0' && current[i] <= '9')
46147e946e7SWyllys Ingersoll val[i] = current[i] - '0';
46247e946e7SWyllys Ingersoll
46347e946e7SWyllys Ingersoll if (current[i] >= 'A' && current[i] <= 'Z')
46447e946e7SWyllys Ingersoll val[i] = current[i] - 'A' + 10;
46547e946e7SWyllys Ingersoll }
46647e946e7SWyllys Ingersoll
46747e946e7SWyllys Ingersoll val[0]++;
46847e946e7SWyllys Ingersoll
46947e946e7SWyllys Ingersoll i = 0;
47047e946e7SWyllys Ingersoll
47147e946e7SWyllys Ingersoll while (val[i] > 35) {
47247e946e7SWyllys Ingersoll val[i] = 0;
47347e946e7SWyllys Ingersoll
47447e946e7SWyllys Ingersoll if (i + 1 < 8) {
47547e946e7SWyllys Ingersoll val[i + 1]++;
47647e946e7SWyllys Ingersoll i++;
47747e946e7SWyllys Ingersoll } else {
47847e946e7SWyllys Ingersoll val[0]++;
47947e946e7SWyllys Ingersoll i = 0; // start pass 2
48047e946e7SWyllys Ingersoll }
48147e946e7SWyllys Ingersoll }
48247e946e7SWyllys Ingersoll
48347e946e7SWyllys Ingersoll // now, convert back to [0 - 9A - Z]
48447e946e7SWyllys Ingersoll //
48547e946e7SWyllys Ingersoll for (i = 0; i < 8; i++) {
48647e946e7SWyllys Ingersoll if (val[i] < 10)
48747e946e7SWyllys Ingersoll next[i] = '0' + val[i];
48847e946e7SWyllys Ingersoll else
48947e946e7SWyllys Ingersoll next[i] = 'A' + val[i] - 10;
49047e946e7SWyllys Ingersoll }
49147e946e7SWyllys Ingersoll
49247e946e7SWyllys Ingersoll return (CKR_OK);
49347e946e7SWyllys Ingersoll }
49447e946e7SWyllys Ingersoll
49547e946e7SWyllys Ingersoll
49647e946e7SWyllys Ingersoll //
49747e946e7SWyllys Ingersoll //
49847e946e7SWyllys Ingersoll CK_RV
build_attribute(CK_ATTRIBUTE_TYPE type,CK_BYTE * data,CK_ULONG data_len,CK_ATTRIBUTE ** attrib)49947e946e7SWyllys Ingersoll build_attribute(CK_ATTRIBUTE_TYPE type,
50047e946e7SWyllys Ingersoll CK_BYTE *data,
50147e946e7SWyllys Ingersoll CK_ULONG data_len,
50247e946e7SWyllys Ingersoll CK_ATTRIBUTE **attrib) {
50347e946e7SWyllys Ingersoll CK_ATTRIBUTE *attr = NULL;
50447e946e7SWyllys Ingersoll
50547e946e7SWyllys Ingersoll attr = (CK_ATTRIBUTE *)malloc(sizeof (CK_ATTRIBUTE) + data_len);
50647e946e7SWyllys Ingersoll if (! attr) {
50747e946e7SWyllys Ingersoll return (CKR_DEVICE_MEMORY);
50847e946e7SWyllys Ingersoll }
50947e946e7SWyllys Ingersoll attr->type = type;
51047e946e7SWyllys Ingersoll attr->ulValueLen = data_len;
51147e946e7SWyllys Ingersoll
51247e946e7SWyllys Ingersoll if (data_len > 0) {
51347e946e7SWyllys Ingersoll attr->pValue = (CK_BYTE *)attr + sizeof (CK_ATTRIBUTE);
51447e946e7SWyllys Ingersoll (void) memcpy(attr->pValue, data, data_len);
51547e946e7SWyllys Ingersoll }
51647e946e7SWyllys Ingersoll else
51747e946e7SWyllys Ingersoll attr->pValue = NULL;
51847e946e7SWyllys Ingersoll
51947e946e7SWyllys Ingersoll *attrib = attr;
52047e946e7SWyllys Ingersoll
52147e946e7SWyllys Ingersoll return (CKR_OK);
52247e946e7SWyllys Ingersoll }
52347e946e7SWyllys Ingersoll
52447e946e7SWyllys Ingersoll CK_RV
add_pkcs_padding(CK_BYTE * ptr,UINT32 block_size,UINT32 data_len,UINT32 total_len)52547e946e7SWyllys Ingersoll add_pkcs_padding(CK_BYTE * ptr,
52633c15889SWyllys Ingersoll UINT32 block_size,
52733c15889SWyllys Ingersoll UINT32 data_len,
52833c15889SWyllys Ingersoll UINT32 total_len)
52947e946e7SWyllys Ingersoll {
53033c15889SWyllys Ingersoll UINT32 i, pad_len;
53147e946e7SWyllys Ingersoll CK_BYTE pad_value;
53247e946e7SWyllys Ingersoll
53347e946e7SWyllys Ingersoll pad_len = block_size - (data_len % block_size);
53447e946e7SWyllys Ingersoll pad_value = (CK_BYTE)pad_len;
53547e946e7SWyllys Ingersoll
53647e946e7SWyllys Ingersoll if (data_len + pad_len > total_len) {
53747e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
53847e946e7SWyllys Ingersoll }
53947e946e7SWyllys Ingersoll for (i = 0; i < pad_len; i++)
54047e946e7SWyllys Ingersoll ptr[i] = pad_value;
54147e946e7SWyllys Ingersoll
54247e946e7SWyllys Ingersoll return (CKR_OK);
54347e946e7SWyllys Ingersoll }
54447e946e7SWyllys Ingersoll
54547e946e7SWyllys Ingersoll CK_RV
strip_pkcs_padding(CK_BYTE * ptr,UINT32 total_len,UINT32 * data_len)54633c15889SWyllys Ingersoll strip_pkcs_padding(
54733c15889SWyllys Ingersoll CK_BYTE *ptr,
54833c15889SWyllys Ingersoll UINT32 total_len,
54933c15889SWyllys Ingersoll UINT32 *data_len)
55033c15889SWyllys Ingersoll {
55147e946e7SWyllys Ingersoll CK_BYTE pad_value;
55247e946e7SWyllys Ingersoll
55347e946e7SWyllys Ingersoll pad_value = ptr[total_len - 1];
55447e946e7SWyllys Ingersoll
55533c15889SWyllys Ingersoll /* We have 'pad_value' bytes of 'pad_value' appended to the end */
55647e946e7SWyllys Ingersoll *data_len = total_len - pad_value;
55747e946e7SWyllys Ingersoll
55847e946e7SWyllys Ingersoll return (CKR_OK);
55947e946e7SWyllys Ingersoll }
56047e946e7SWyllys Ingersoll
56147e946e7SWyllys Ingersoll CK_RV
remove_leading_zeros(CK_ATTRIBUTE * attr)56247e946e7SWyllys Ingersoll remove_leading_zeros(CK_ATTRIBUTE *attr)
56347e946e7SWyllys Ingersoll {
56447e946e7SWyllys Ingersoll CK_BYTE *ptr = NULL;
56547e946e7SWyllys Ingersoll CK_ULONG new_len, i;
56647e946e7SWyllys Ingersoll
56747e946e7SWyllys Ingersoll ptr = attr->pValue;
56847e946e7SWyllys Ingersoll
56947e946e7SWyllys Ingersoll for (i = 0; i < attr->ulValueLen; i++) {
57047e946e7SWyllys Ingersoll if (ptr[i] != 0x0)
57147e946e7SWyllys Ingersoll break;
57247e946e7SWyllys Ingersoll }
57347e946e7SWyllys Ingersoll
57447e946e7SWyllys Ingersoll new_len = attr->ulValueLen - i;
57547e946e7SWyllys Ingersoll
57647e946e7SWyllys Ingersoll (void) memcpy(ptr, ptr + i, new_len);
57747e946e7SWyllys Ingersoll attr->ulValueLen = new_len;
57847e946e7SWyllys Ingersoll
57947e946e7SWyllys Ingersoll return (CKR_OK);
58047e946e7SWyllys Ingersoll }
58147e946e7SWyllys Ingersoll
58247e946e7SWyllys Ingersoll CK_RV
parity_is_odd(CK_BYTE b)58347e946e7SWyllys Ingersoll parity_is_odd(CK_BYTE b) {
58447e946e7SWyllys Ingersoll b = ((b >> 4) ^ b) & 0x0f;
58547e946e7SWyllys Ingersoll b = ((b >> 2) ^ b) & 0x03;
58647e946e7SWyllys Ingersoll b = ((b >> 1) ^ b) & 0x01;
58747e946e7SWyllys Ingersoll
58847e946e7SWyllys Ingersoll if (b == 1)
58947e946e7SWyllys Ingersoll return (TRUE);
59047e946e7SWyllys Ingersoll else
59147e946e7SWyllys Ingersoll return (FALSE);
59247e946e7SWyllys Ingersoll }
59347e946e7SWyllys Ingersoll
59447e946e7SWyllys Ingersoll CK_RV
attach_shm()59547e946e7SWyllys Ingersoll attach_shm() {
59647e946e7SWyllys Ingersoll if (global_shm != NULL)
59747e946e7SWyllys Ingersoll return (CKR_OK);
59847e946e7SWyllys Ingersoll
599*8d26100cSWyllys Ingersoll global_shm = (LW_SHM_TYPE *)calloc(1, sizeof (LW_SHM_TYPE));
60047e946e7SWyllys Ingersoll if (global_shm == NULL) {
60147e946e7SWyllys Ingersoll return (CKR_HOST_MEMORY);
60247e946e7SWyllys Ingersoll }
60347e946e7SWyllys Ingersoll CreateXProcLock(&global_shm->mutex);
60447e946e7SWyllys Ingersoll
60547e946e7SWyllys Ingersoll xproclock = (void *)&global_shm->mutex;
60647e946e7SWyllys Ingersoll
60747e946e7SWyllys Ingersoll return (CKR_OK);
60847e946e7SWyllys Ingersoll }
60947e946e7SWyllys Ingersoll
61047e946e7SWyllys Ingersoll CK_RV
detach_shm()61147e946e7SWyllys Ingersoll detach_shm()
61247e946e7SWyllys Ingersoll {
61347e946e7SWyllys Ingersoll if (global_shm != NULL) {
61447e946e7SWyllys Ingersoll free(global_shm);
61547e946e7SWyllys Ingersoll global_shm = NULL;
61647e946e7SWyllys Ingersoll }
61747e946e7SWyllys Ingersoll
61847e946e7SWyllys Ingersoll return (CKR_OK);
61947e946e7SWyllys Ingersoll }
62047e946e7SWyllys Ingersoll
62147e946e7SWyllys Ingersoll CK_RV
compute_sha(CK_BYTE * data,CK_ULONG_32 len,CK_BYTE * hash)62247e946e7SWyllys Ingersoll compute_sha(CK_BYTE *data,
62333c15889SWyllys Ingersoll CK_ULONG_32 len,
62447e946e7SWyllys Ingersoll CK_BYTE * hash)
62547e946e7SWyllys Ingersoll {
62647e946e7SWyllys Ingersoll SHA1_CTX ctx;
62747e946e7SWyllys Ingersoll
62847e946e7SWyllys Ingersoll SHA1Init(&ctx);
62947e946e7SWyllys Ingersoll
63047e946e7SWyllys Ingersoll SHA1Update(&ctx, data, len);
63147e946e7SWyllys Ingersoll
63247e946e7SWyllys Ingersoll SHA1Final(hash, &ctx);
63347e946e7SWyllys Ingersoll return (CKR_OK);
63447e946e7SWyllys Ingersoll }
635