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 * 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 * 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 * 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 * 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 * 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 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 * 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 * 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 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 * 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 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 24447e946e7SWyllys Ingersoll DestroyXProcLock(void *xproc) 24547e946e7SWyllys Ingersoll { 24647e946e7SWyllys Ingersoll return (pthread_mutex_destroy((pthread_mutex_t *)xproc)); 24747e946e7SWyllys Ingersoll } 24847e946e7SWyllys Ingersoll 24947e946e7SWyllys Ingersoll int 25047e946e7SWyllys Ingersoll XProcLock(void *xproc) 25147e946e7SWyllys Ingersoll { 25247e946e7SWyllys Ingersoll return (pthread_mutex_lock((pthread_mutex_t *)xproc)); 25347e946e7SWyllys Ingersoll } 25447e946e7SWyllys Ingersoll 25547e946e7SWyllys Ingersoll int 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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