1*47e946e7SWyllys Ingersoll /* 2*47e946e7SWyllys Ingersoll * The Initial Developer of the Original Code is International 3*47e946e7SWyllys Ingersoll * Business Machines Corporation. Portions created by IBM 4*47e946e7SWyllys Ingersoll * Corporation are Copyright (C) 2005 International Business 5*47e946e7SWyllys Ingersoll * Machines Corporation. All Rights Reserved. 6*47e946e7SWyllys Ingersoll * 7*47e946e7SWyllys Ingersoll * This program is free software; you can redistribute it and/or modify 8*47e946e7SWyllys Ingersoll * it under the terms of the Common Public License as published by 9*47e946e7SWyllys Ingersoll * IBM Corporation; either version 1 of the License, or (at your option) 10*47e946e7SWyllys Ingersoll * any later version. 11*47e946e7SWyllys Ingersoll * 12*47e946e7SWyllys Ingersoll * This program is distributed in the hope that it will be useful, 13*47e946e7SWyllys Ingersoll * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*47e946e7SWyllys Ingersoll * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*47e946e7SWyllys Ingersoll * Common Public License for more details. 16*47e946e7SWyllys Ingersoll * 17*47e946e7SWyllys Ingersoll * You should have received a copy of the Common Public License 18*47e946e7SWyllys Ingersoll * along with this program; if not, a copy can be viewed at 19*47e946e7SWyllys Ingersoll * http://www.opensource.org/licenses/cpl1.0.php. 20*47e946e7SWyllys Ingersoll */ 21*47e946e7SWyllys Ingersoll /* 22*47e946e7SWyllys Ingersoll * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*47e946e7SWyllys Ingersoll * Use is subject to license terms. 24*47e946e7SWyllys Ingersoll */ 25*47e946e7SWyllys Ingersoll 26*47e946e7SWyllys Ingersoll #include <pthread.h> 27*47e946e7SWyllys Ingersoll #include <string.h> 28*47e946e7SWyllys Ingersoll 29*47e946e7SWyllys Ingersoll #include <sys/types.h> 30*47e946e7SWyllys Ingersoll #include <sys/stat.h> 31*47e946e7SWyllys Ingersoll #include <uuid/uuid.h> 32*47e946e7SWyllys Ingersoll #include <fcntl.h> 33*47e946e7SWyllys Ingersoll #include <errno.h> 34*47e946e7SWyllys Ingersoll #include <pwd.h> 35*47e946e7SWyllys Ingersoll #include <syslog.h> 36*47e946e7SWyllys Ingersoll 37*47e946e7SWyllys Ingersoll #include <tss/platform.h> 38*47e946e7SWyllys Ingersoll #include <tss/tss_defines.h> 39*47e946e7SWyllys Ingersoll #include <tss/tss_typedef.h> 40*47e946e7SWyllys Ingersoll #include <tss/tss_structs.h> 41*47e946e7SWyllys Ingersoll #include <tss/tss_error.h> 42*47e946e7SWyllys Ingersoll #include <tss/tcs_error.h> 43*47e946e7SWyllys Ingersoll #include <tss/tspi.h> 44*47e946e7SWyllys Ingersoll #include <trousers/trousers.h> 45*47e946e7SWyllys Ingersoll 46*47e946e7SWyllys Ingersoll #include "tpmtok_int.h" 47*47e946e7SWyllys Ingersoll #include "tpmtok_defs.h" 48*47e946e7SWyllys Ingersoll 49*47e946e7SWyllys Ingersoll extern void stlogit(char *fmt, ...); 50*47e946e7SWyllys Ingersoll 51*47e946e7SWyllys Ingersoll CK_RV token_rng(TSS_HCONTEXT, CK_BYTE *, CK_ULONG); 52*47e946e7SWyllys Ingersoll int tok_slot2local(CK_SLOT_ID); 53*47e946e7SWyllys Ingersoll CK_RV token_specific_session(CK_SLOT_ID); 54*47e946e7SWyllys Ingersoll CK_RV token_specific_final(void); 55*47e946e7SWyllys Ingersoll 56*47e946e7SWyllys Ingersoll CK_RV 57*47e946e7SWyllys Ingersoll token_specific_rsa_decrypt( 58*47e946e7SWyllys Ingersoll TSS_HCONTEXT, 59*47e946e7SWyllys Ingersoll CK_BYTE *, 60*47e946e7SWyllys Ingersoll CK_ULONG, 61*47e946e7SWyllys Ingersoll CK_BYTE *, 62*47e946e7SWyllys Ingersoll CK_ULONG *, 63*47e946e7SWyllys Ingersoll OBJECT *); 64*47e946e7SWyllys Ingersoll 65*47e946e7SWyllys Ingersoll CK_RV 66*47e946e7SWyllys Ingersoll token_specific_rsa_encrypt( 67*47e946e7SWyllys Ingersoll TSS_HCONTEXT, 68*47e946e7SWyllys Ingersoll CK_BYTE *, 69*47e946e7SWyllys Ingersoll CK_ULONG, 70*47e946e7SWyllys Ingersoll CK_BYTE *, 71*47e946e7SWyllys Ingersoll CK_ULONG *, 72*47e946e7SWyllys Ingersoll OBJECT *); 73*47e946e7SWyllys Ingersoll 74*47e946e7SWyllys Ingersoll CK_RV 75*47e946e7SWyllys Ingersoll token_specific_rsa_sign( 76*47e946e7SWyllys Ingersoll TSS_HCONTEXT, 77*47e946e7SWyllys Ingersoll CK_BYTE *, 78*47e946e7SWyllys Ingersoll CK_ULONG, 79*47e946e7SWyllys Ingersoll CK_BYTE *, 80*47e946e7SWyllys Ingersoll CK_ULONG *, 81*47e946e7SWyllys Ingersoll OBJECT *); 82*47e946e7SWyllys Ingersoll 83*47e946e7SWyllys Ingersoll CK_RV 84*47e946e7SWyllys Ingersoll token_specific_rsa_verify(TSS_HCONTEXT, CK_BYTE *, 85*47e946e7SWyllys Ingersoll CK_ULONG, CK_BYTE *, CK_ULONG, OBJECT *); 86*47e946e7SWyllys Ingersoll 87*47e946e7SWyllys Ingersoll CK_RV 88*47e946e7SWyllys Ingersoll token_specific_rsa_generate_keypair(TSS_HCONTEXT, 89*47e946e7SWyllys Ingersoll TEMPLATE *, 90*47e946e7SWyllys Ingersoll TEMPLATE *); 91*47e946e7SWyllys Ingersoll 92*47e946e7SWyllys Ingersoll CK_RV 93*47e946e7SWyllys Ingersoll token_specific_sha_init(DIGEST_CONTEXT *); 94*47e946e7SWyllys Ingersoll 95*47e946e7SWyllys Ingersoll CK_RV 96*47e946e7SWyllys Ingersoll token_specific_sha_update(DIGEST_CONTEXT *, 97*47e946e7SWyllys Ingersoll CK_BYTE *, 98*47e946e7SWyllys Ingersoll CK_ULONG); 99*47e946e7SWyllys Ingersoll 100*47e946e7SWyllys Ingersoll CK_RV 101*47e946e7SWyllys Ingersoll token_specific_sha_final(DIGEST_CONTEXT *, 102*47e946e7SWyllys Ingersoll CK_BYTE *, 103*47e946e7SWyllys Ingersoll CK_ULONG *); 104*47e946e7SWyllys Ingersoll 105*47e946e7SWyllys Ingersoll CK_RV token_specific_login(TSS_HCONTEXT, CK_USER_TYPE, CK_CHAR_PTR, CK_ULONG); 106*47e946e7SWyllys Ingersoll CK_RV token_specific_logout(TSS_HCONTEXT); 107*47e946e7SWyllys Ingersoll CK_RV token_specific_init_pin(TSS_HCONTEXT, CK_CHAR_PTR, CK_ULONG); 108*47e946e7SWyllys Ingersoll CK_RV token_specific_set_pin(ST_SESSION_HANDLE, CK_CHAR_PTR, 109*47e946e7SWyllys Ingersoll CK_ULONG, CK_CHAR_PTR, CK_ULONG); 110*47e946e7SWyllys Ingersoll CK_RV token_specific_verify_so_pin(TSS_HCONTEXT, CK_CHAR_PTR, CK_ULONG); 111*47e946e7SWyllys Ingersoll 112*47e946e7SWyllys Ingersoll static CK_RV 113*47e946e7SWyllys Ingersoll token_specific_init(char *, CK_SLOT_ID, TSS_HCONTEXT *); 114*47e946e7SWyllys Ingersoll 115*47e946e7SWyllys Ingersoll struct token_specific_struct token_specific = { 116*47e946e7SWyllys Ingersoll "TPM_Debug", 117*47e946e7SWyllys Ingersoll &token_specific_init, 118*47e946e7SWyllys Ingersoll NULL, 119*47e946e7SWyllys Ingersoll &token_rng, 120*47e946e7SWyllys Ingersoll &token_specific_session, 121*47e946e7SWyllys Ingersoll &token_specific_final, 122*47e946e7SWyllys Ingersoll &token_specific_rsa_decrypt, 123*47e946e7SWyllys Ingersoll &token_specific_rsa_encrypt, 124*47e946e7SWyllys Ingersoll &token_specific_rsa_sign, 125*47e946e7SWyllys Ingersoll &token_specific_rsa_verify, 126*47e946e7SWyllys Ingersoll &token_specific_rsa_generate_keypair, 127*47e946e7SWyllys Ingersoll NULL, 128*47e946e7SWyllys Ingersoll NULL, 129*47e946e7SWyllys Ingersoll NULL, 130*47e946e7SWyllys Ingersoll &token_specific_login, 131*47e946e7SWyllys Ingersoll &token_specific_logout, 132*47e946e7SWyllys Ingersoll &token_specific_init_pin, 133*47e946e7SWyllys Ingersoll &token_specific_set_pin, 134*47e946e7SWyllys Ingersoll &token_specific_verify_so_pin 135*47e946e7SWyllys Ingersoll }; 136*47e946e7SWyllys Ingersoll 137*47e946e7SWyllys Ingersoll /* The context we'll use globally to connect to the TSP */ 138*47e946e7SWyllys Ingersoll 139*47e946e7SWyllys Ingersoll /* TSP key handles */ 140*47e946e7SWyllys Ingersoll TSS_HKEY hPublicRootKey = NULL_HKEY; 141*47e946e7SWyllys Ingersoll TSS_HKEY hPublicLeafKey = NULL_HKEY; 142*47e946e7SWyllys Ingersoll TSS_HKEY hPrivateRootKey = NULL_HKEY; 143*47e946e7SWyllys Ingersoll TSS_HKEY hPrivateLeafKey = NULL_HKEY; 144*47e946e7SWyllys Ingersoll 145*47e946e7SWyllys Ingersoll TSS_UUID publicRootKeyUUID; 146*47e946e7SWyllys Ingersoll TSS_UUID publicLeafKeyUUID; 147*47e946e7SWyllys Ingersoll TSS_UUID privateRootKeyUUID; 148*47e946e7SWyllys Ingersoll TSS_UUID privateLeafKeyUUID; 149*47e946e7SWyllys Ingersoll 150*47e946e7SWyllys Ingersoll /* TSP policy handles */ 151*47e946e7SWyllys Ingersoll TSS_HPOLICY hDefaultPolicy = NULL_HPOLICY; 152*47e946e7SWyllys Ingersoll 153*47e946e7SWyllys Ingersoll /* PKCS#11 key handles */ 154*47e946e7SWyllys Ingersoll CK_OBJECT_HANDLE ckPublicRootKey = 0; 155*47e946e7SWyllys Ingersoll CK_OBJECT_HANDLE ckPublicLeafKey = 0; 156*47e946e7SWyllys Ingersoll CK_OBJECT_HANDLE ckPrivateRootKey = 0; 157*47e946e7SWyllys Ingersoll CK_OBJECT_HANDLE ckPrivateLeafKey = 0; 158*47e946e7SWyllys Ingersoll 159*47e946e7SWyllys Ingersoll int not_initialized = 0; 160*47e946e7SWyllys Ingersoll 161*47e946e7SWyllys Ingersoll CK_BYTE current_user_pin_sha[SHA1_DIGEST_LENGTH]; 162*47e946e7SWyllys Ingersoll CK_BYTE current_so_pin_sha[SHA1_DIGEST_LENGTH]; 163*47e946e7SWyllys Ingersoll 164*47e946e7SWyllys Ingersoll static TPM_CAP_VERSION_INFO tpmvinfo; 165*47e946e7SWyllys Ingersoll 166*47e946e7SWyllys Ingersoll static CK_RV 167*47e946e7SWyllys Ingersoll verify_user_pin(TSS_HCONTEXT, CK_BYTE *); 168*47e946e7SWyllys Ingersoll 169*47e946e7SWyllys Ingersoll static void 170*47e946e7SWyllys Ingersoll local_uuid_clear(TSS_UUID *uuid) 171*47e946e7SWyllys Ingersoll { 172*47e946e7SWyllys Ingersoll if (uuid == NULL) 173*47e946e7SWyllys Ingersoll return; 174*47e946e7SWyllys Ingersoll (void) memset(uuid, 0, sizeof (TSS_UUID)); 175*47e946e7SWyllys Ingersoll } 176*47e946e7SWyllys Ingersoll 177*47e946e7SWyllys Ingersoll 178*47e946e7SWyllys Ingersoll /* convert from TSS_UUID to uuid_t */ 179*47e946e7SWyllys Ingersoll static void 180*47e946e7SWyllys Ingersoll tss_uuid_convert_from(TSS_UUID *uu, uuid_t ptr) 181*47e946e7SWyllys Ingersoll { 182*47e946e7SWyllys Ingersoll uint_t tmp; 183*47e946e7SWyllys Ingersoll uchar_t *out = ptr; 184*47e946e7SWyllys Ingersoll 185*47e946e7SWyllys Ingersoll tmp = ntohl(uu->ulTimeLow); 186*47e946e7SWyllys Ingersoll out[3] = (uchar_t)tmp; 187*47e946e7SWyllys Ingersoll tmp >>= 8; 188*47e946e7SWyllys Ingersoll out[2] = (uchar_t)tmp; 189*47e946e7SWyllys Ingersoll tmp >>= 8; 190*47e946e7SWyllys Ingersoll out[1] = (uchar_t)tmp; 191*47e946e7SWyllys Ingersoll tmp >>= 8; 192*47e946e7SWyllys Ingersoll out[0] = (uchar_t)tmp; 193*47e946e7SWyllys Ingersoll 194*47e946e7SWyllys Ingersoll tmp = ntohs(uu->usTimeMid); 195*47e946e7SWyllys Ingersoll out[5] = (uchar_t)tmp; 196*47e946e7SWyllys Ingersoll tmp >>= 8; 197*47e946e7SWyllys Ingersoll out[4] = (uchar_t)tmp; 198*47e946e7SWyllys Ingersoll 199*47e946e7SWyllys Ingersoll tmp = ntohs(uu->usTimeHigh); 200*47e946e7SWyllys Ingersoll out[7] = (uchar_t)tmp; 201*47e946e7SWyllys Ingersoll tmp >>= 8; 202*47e946e7SWyllys Ingersoll out[6] = (uchar_t)tmp; 203*47e946e7SWyllys Ingersoll 204*47e946e7SWyllys Ingersoll tmp = uu->bClockSeqHigh; 205*47e946e7SWyllys Ingersoll out[8] = (uchar_t)tmp; 206*47e946e7SWyllys Ingersoll tmp = uu->bClockSeqLow; 207*47e946e7SWyllys Ingersoll out[9] = (uchar_t)tmp; 208*47e946e7SWyllys Ingersoll 209*47e946e7SWyllys Ingersoll (void) memcpy(out+10, uu->rgbNode, 6); 210*47e946e7SWyllys Ingersoll } 211*47e946e7SWyllys Ingersoll 212*47e946e7SWyllys Ingersoll /* convert from uuid_t to TSS_UUID */ 213*47e946e7SWyllys Ingersoll static void 214*47e946e7SWyllys Ingersoll tss_uuid_convert_to(TSS_UUID *uuid, uuid_t in) 215*47e946e7SWyllys Ingersoll { 216*47e946e7SWyllys Ingersoll uchar_t *ptr; 217*47e946e7SWyllys Ingersoll uint32_t ltmp; 218*47e946e7SWyllys Ingersoll uint16_t stmp; 219*47e946e7SWyllys Ingersoll 220*47e946e7SWyllys Ingersoll ptr = in; 221*47e946e7SWyllys Ingersoll 222*47e946e7SWyllys Ingersoll ltmp = *ptr++; 223*47e946e7SWyllys Ingersoll ltmp = (ltmp << 8) | *ptr++; 224*47e946e7SWyllys Ingersoll ltmp = (ltmp << 8) | *ptr++; 225*47e946e7SWyllys Ingersoll ltmp = (ltmp << 8) | *ptr++; 226*47e946e7SWyllys Ingersoll uuid->ulTimeLow = ntohl(ltmp); 227*47e946e7SWyllys Ingersoll 228*47e946e7SWyllys Ingersoll stmp = *ptr++; 229*47e946e7SWyllys Ingersoll stmp = (stmp << 8) | *ptr++; 230*47e946e7SWyllys Ingersoll uuid->usTimeMid = ntohs(stmp); 231*47e946e7SWyllys Ingersoll 232*47e946e7SWyllys Ingersoll stmp = *ptr++; 233*47e946e7SWyllys Ingersoll stmp = (stmp << 8) | *ptr++; 234*47e946e7SWyllys Ingersoll uuid->usTimeHigh = ntohs(stmp); 235*47e946e7SWyllys Ingersoll 236*47e946e7SWyllys Ingersoll uuid->bClockSeqHigh = *ptr++; 237*47e946e7SWyllys Ingersoll 238*47e946e7SWyllys Ingersoll uuid->bClockSeqLow = *ptr++; 239*47e946e7SWyllys Ingersoll 240*47e946e7SWyllys Ingersoll (void) memcpy(uuid->rgbNode, ptr, 6); 241*47e946e7SWyllys Ingersoll } 242*47e946e7SWyllys Ingersoll 243*47e946e7SWyllys Ingersoll static void 244*47e946e7SWyllys Ingersoll local_uuid_copy(TSS_UUID *dst, TSS_UUID *src) 245*47e946e7SWyllys Ingersoll { 246*47e946e7SWyllys Ingersoll uuid_t udst, usrc; 247*47e946e7SWyllys Ingersoll 248*47e946e7SWyllys Ingersoll tss_uuid_convert_from(dst, udst); 249*47e946e7SWyllys Ingersoll tss_uuid_convert_from(src, usrc); 250*47e946e7SWyllys Ingersoll 251*47e946e7SWyllys Ingersoll uuid_copy(udst, usrc); 252*47e946e7SWyllys Ingersoll 253*47e946e7SWyllys Ingersoll tss_uuid_convert_to(dst, udst); 254*47e946e7SWyllys Ingersoll } 255*47e946e7SWyllys Ingersoll 256*47e946e7SWyllys Ingersoll static void 257*47e946e7SWyllys Ingersoll local_uuid_generate(TSS_UUID *uu) 258*47e946e7SWyllys Ingersoll { 259*47e946e7SWyllys Ingersoll uuid_t newuuid; 260*47e946e7SWyllys Ingersoll 261*47e946e7SWyllys Ingersoll uuid_generate(newuuid); 262*47e946e7SWyllys Ingersoll 263*47e946e7SWyllys Ingersoll tss_uuid_convert_to(uu, newuuid); 264*47e946e7SWyllys Ingersoll } 265*47e946e7SWyllys Ingersoll 266*47e946e7SWyllys Ingersoll static int 267*47e946e7SWyllys Ingersoll local_copy_file(char *dst, char *src) 268*47e946e7SWyllys Ingersoll { 269*47e946e7SWyllys Ingersoll FILE *fdest, *fsrc; 270*47e946e7SWyllys Ingersoll char line[BUFSIZ]; 271*47e946e7SWyllys Ingersoll 272*47e946e7SWyllys Ingersoll fdest = fopen(dst, "w"); 273*47e946e7SWyllys Ingersoll if (fdest == NULL) 274*47e946e7SWyllys Ingersoll return (-1); 275*47e946e7SWyllys Ingersoll 276*47e946e7SWyllys Ingersoll fsrc = fopen(src, "r"); 277*47e946e7SWyllys Ingersoll if (fsrc == NULL) { 278*47e946e7SWyllys Ingersoll (void) fclose(fdest); 279*47e946e7SWyllys Ingersoll return (-1); 280*47e946e7SWyllys Ingersoll } 281*47e946e7SWyllys Ingersoll 282*47e946e7SWyllys Ingersoll while (fread(line, sizeof (line), 1, fsrc)) 283*47e946e7SWyllys Ingersoll (void) fprintf(fdest, "%s\n", line); 284*47e946e7SWyllys Ingersoll (void) fclose(fsrc); 285*47e946e7SWyllys Ingersoll (void) fclose(fdest); 286*47e946e7SWyllys Ingersoll return (0); 287*47e946e7SWyllys Ingersoll } 288*47e946e7SWyllys Ingersoll 289*47e946e7SWyllys Ingersoll static int 290*47e946e7SWyllys Ingersoll remove_uuid(char *keyname) 291*47e946e7SWyllys Ingersoll { 292*47e946e7SWyllys Ingersoll int ret = 0; 293*47e946e7SWyllys Ingersoll FILE *fp, *newfp; 294*47e946e7SWyllys Ingersoll char fname[MAXPATHLEN]; 295*47e946e7SWyllys Ingersoll char line[BUFSIZ], key[BUFSIZ], idstr[BUFSIZ]; 296*47e946e7SWyllys Ingersoll char *tmpfname; 297*47e946e7SWyllys Ingersoll char *p = get_tpm_keystore_path(); 298*47e946e7SWyllys Ingersoll 299*47e946e7SWyllys Ingersoll if (p == NULL) 300*47e946e7SWyllys Ingersoll return (-1); 301*47e946e7SWyllys Ingersoll 302*47e946e7SWyllys Ingersoll (void) snprintf(fname, sizeof (fname), 303*47e946e7SWyllys Ingersoll "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME); 304*47e946e7SWyllys Ingersoll 305*47e946e7SWyllys Ingersoll fp = fopen(fname, "r"); 306*47e946e7SWyllys Ingersoll if (fp == NULL) { 307*47e946e7SWyllys Ingersoll return (-1); 308*47e946e7SWyllys Ingersoll } 309*47e946e7SWyllys Ingersoll 310*47e946e7SWyllys Ingersoll tmpfname = tempnam("/tmp", "tpmtok"); 311*47e946e7SWyllys Ingersoll newfp = fopen(tmpfname, "w+"); 312*47e946e7SWyllys Ingersoll if (newfp == NULL) { 313*47e946e7SWyllys Ingersoll free(tmpfname); 314*47e946e7SWyllys Ingersoll (void) fclose(fp); 315*47e946e7SWyllys Ingersoll return (-1); 316*47e946e7SWyllys Ingersoll } 317*47e946e7SWyllys Ingersoll 318*47e946e7SWyllys Ingersoll while (!feof(fp)) { 319*47e946e7SWyllys Ingersoll (void) fgets(line, sizeof (line), fp); 320*47e946e7SWyllys Ingersoll if (sscanf(line, "%1024s %1024s", key, idstr) == 2) { 321*47e946e7SWyllys Ingersoll if (strcmp(key, keyname)) 322*47e946e7SWyllys Ingersoll (void) fprintf(newfp, "%s\n", line); 323*47e946e7SWyllys Ingersoll } 324*47e946e7SWyllys Ingersoll } 325*47e946e7SWyllys Ingersoll 326*47e946e7SWyllys Ingersoll (void) fclose(fp); 327*47e946e7SWyllys Ingersoll (void) fclose(newfp); 328*47e946e7SWyllys Ingersoll if (local_copy_file(fname, tmpfname) == 0) 329*47e946e7SWyllys Ingersoll (void) unlink(tmpfname); 330*47e946e7SWyllys Ingersoll 331*47e946e7SWyllys Ingersoll free(tmpfname); 332*47e946e7SWyllys Ingersoll 333*47e946e7SWyllys Ingersoll return (ret); 334*47e946e7SWyllys Ingersoll } 335*47e946e7SWyllys Ingersoll 336*47e946e7SWyllys Ingersoll static int 337*47e946e7SWyllys Ingersoll find_uuid(char *keyname, TSS_UUID *uu) 338*47e946e7SWyllys Ingersoll { 339*47e946e7SWyllys Ingersoll int ret = 0, found = 0; 340*47e946e7SWyllys Ingersoll FILE *fp = NULL; 341*47e946e7SWyllys Ingersoll char fname[MAXPATHLEN]; 342*47e946e7SWyllys Ingersoll char line[BUFSIZ], key[BUFSIZ], idstr[BUFSIZ]; 343*47e946e7SWyllys Ingersoll uuid_t uuid; 344*47e946e7SWyllys Ingersoll char *p = get_tpm_keystore_path(); 345*47e946e7SWyllys Ingersoll 346*47e946e7SWyllys Ingersoll if (p == NULL) 347*47e946e7SWyllys Ingersoll return (-1); 348*47e946e7SWyllys Ingersoll 349*47e946e7SWyllys Ingersoll tss_uuid_convert_from(uu, uuid); 350*47e946e7SWyllys Ingersoll 351*47e946e7SWyllys Ingersoll (void) snprintf(fname, sizeof (fname), 352*47e946e7SWyllys Ingersoll "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME); 353*47e946e7SWyllys Ingersoll 354*47e946e7SWyllys Ingersoll /* Open UUID Index file */ 355*47e946e7SWyllys Ingersoll fp = fopen(fname, "r"); 356*47e946e7SWyllys Ingersoll if (fp == NULL) { 357*47e946e7SWyllys Ingersoll if (errno == ENOENT) { 358*47e946e7SWyllys Ingersoll /* initialize the file */ 359*47e946e7SWyllys Ingersoll fp = fopen(fname, "w"); 360*47e946e7SWyllys Ingersoll if (fp != NULL) 361*47e946e7SWyllys Ingersoll (void) fclose(fp); 362*47e946e7SWyllys Ingersoll } 363*47e946e7SWyllys Ingersoll return (-1); 364*47e946e7SWyllys Ingersoll } 365*47e946e7SWyllys Ingersoll 366*47e946e7SWyllys Ingersoll while (!feof(fp)) { 367*47e946e7SWyllys Ingersoll (void) fgets(line, sizeof (line), fp); 368*47e946e7SWyllys Ingersoll if (sscanf(line, "%1024s %1024s", key, idstr) == 2) { 369*47e946e7SWyllys Ingersoll if (strcmp(key, keyname) == 0) { 370*47e946e7SWyllys Ingersoll ret = uuid_parse(idstr, uuid); 371*47e946e7SWyllys Ingersoll if (ret == 0) { 372*47e946e7SWyllys Ingersoll found = 1; 373*47e946e7SWyllys Ingersoll tss_uuid_convert_to(uu, 374*47e946e7SWyllys Ingersoll uuid); 375*47e946e7SWyllys Ingersoll } 376*47e946e7SWyllys Ingersoll break; 377*47e946e7SWyllys Ingersoll } 378*47e946e7SWyllys Ingersoll } 379*47e946e7SWyllys Ingersoll } 380*47e946e7SWyllys Ingersoll (void) fclose(fp); 381*47e946e7SWyllys Ingersoll 382*47e946e7SWyllys Ingersoll if (!found) 383*47e946e7SWyllys Ingersoll ret = -1; 384*47e946e7SWyllys Ingersoll return (ret); 385*47e946e7SWyllys Ingersoll } 386*47e946e7SWyllys Ingersoll 387*47e946e7SWyllys Ingersoll static int 388*47e946e7SWyllys Ingersoll local_uuid_is_null(TSS_UUID *uu) 389*47e946e7SWyllys Ingersoll { 390*47e946e7SWyllys Ingersoll uuid_t uuid; 391*47e946e7SWyllys Ingersoll int nulluuid; 392*47e946e7SWyllys Ingersoll 393*47e946e7SWyllys Ingersoll tss_uuid_convert_from(uu, uuid); 394*47e946e7SWyllys Ingersoll 395*47e946e7SWyllys Ingersoll nulluuid = uuid_is_null(uuid); 396*47e946e7SWyllys Ingersoll return (nulluuid); 397*47e946e7SWyllys Ingersoll } 398*47e946e7SWyllys Ingersoll 399*47e946e7SWyllys Ingersoll static int 400*47e946e7SWyllys Ingersoll add_uuid(char *keyname, TSS_UUID *uu) 401*47e946e7SWyllys Ingersoll { 402*47e946e7SWyllys Ingersoll FILE *fp = NULL; 403*47e946e7SWyllys Ingersoll char fname[MAXPATHLEN]; 404*47e946e7SWyllys Ingersoll char idstr[BUFSIZ]; 405*47e946e7SWyllys Ingersoll uuid_t uuid; 406*47e946e7SWyllys Ingersoll char *p = get_tpm_keystore_path(); 407*47e946e7SWyllys Ingersoll 408*47e946e7SWyllys Ingersoll if (p == NULL) 409*47e946e7SWyllys Ingersoll return (-1); 410*47e946e7SWyllys Ingersoll 411*47e946e7SWyllys Ingersoll tss_uuid_convert_from(uu, uuid); 412*47e946e7SWyllys Ingersoll 413*47e946e7SWyllys Ingersoll if (uuid_is_null(uuid)) 414*47e946e7SWyllys Ingersoll return (-1); 415*47e946e7SWyllys Ingersoll 416*47e946e7SWyllys Ingersoll uuid_unparse(uuid, idstr); 417*47e946e7SWyllys Ingersoll 418*47e946e7SWyllys Ingersoll (void) snprintf(fname, sizeof (fname), 419*47e946e7SWyllys Ingersoll "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME); 420*47e946e7SWyllys Ingersoll 421*47e946e7SWyllys Ingersoll fp = fopen(fname, "a"); 422*47e946e7SWyllys Ingersoll if (fp == NULL) 423*47e946e7SWyllys Ingersoll return (-1); 424*47e946e7SWyllys Ingersoll 425*47e946e7SWyllys Ingersoll (void) fprintf(fp, "%s %s\n", keyname, idstr); 426*47e946e7SWyllys Ingersoll (void) fclose(fp); 427*47e946e7SWyllys Ingersoll 428*47e946e7SWyllys Ingersoll return (0); 429*47e946e7SWyllys Ingersoll } 430*47e946e7SWyllys Ingersoll 431*47e946e7SWyllys Ingersoll 432*47e946e7SWyllys Ingersoll static UINT32 433*47e946e7SWyllys Ingersoll util_get_keysize_flag(CK_ULONG size) 434*47e946e7SWyllys Ingersoll { 435*47e946e7SWyllys Ingersoll switch (size) { 436*47e946e7SWyllys Ingersoll case 512: 437*47e946e7SWyllys Ingersoll return (TSS_KEY_SIZE_512); 438*47e946e7SWyllys Ingersoll break; 439*47e946e7SWyllys Ingersoll case 1024: 440*47e946e7SWyllys Ingersoll return (TSS_KEY_SIZE_1024); 441*47e946e7SWyllys Ingersoll break; 442*47e946e7SWyllys Ingersoll case 2048: 443*47e946e7SWyllys Ingersoll return (TSS_KEY_SIZE_2048); 444*47e946e7SWyllys Ingersoll break; 445*47e946e7SWyllys Ingersoll default: 446*47e946e7SWyllys Ingersoll break; 447*47e946e7SWyllys Ingersoll } 448*47e946e7SWyllys Ingersoll 449*47e946e7SWyllys Ingersoll return (0); 450*47e946e7SWyllys Ingersoll } 451*47e946e7SWyllys Ingersoll 452*47e946e7SWyllys Ingersoll /* make sure the public exponent attribute is 65537 */ 453*47e946e7SWyllys Ingersoll static CK_ULONG 454*47e946e7SWyllys Ingersoll util_check_public_exponent(TEMPLATE *tmpl) 455*47e946e7SWyllys Ingersoll { 456*47e946e7SWyllys Ingersoll CK_BBOOL flag; 457*47e946e7SWyllys Ingersoll CK_ATTRIBUTE *publ_exp_attr; 458*47e946e7SWyllys Ingersoll CK_BYTE pubexp_bytes[] = { 1, 0, 1 }; 459*47e946e7SWyllys Ingersoll CK_ULONG publ_exp, rc = 1; 460*47e946e7SWyllys Ingersoll 461*47e946e7SWyllys Ingersoll flag = template_attribute_find(tmpl, CKA_PUBLIC_EXPONENT, 462*47e946e7SWyllys Ingersoll &publ_exp_attr); 463*47e946e7SWyllys Ingersoll if (!flag) { 464*47e946e7SWyllys Ingersoll LogError1("Couldn't find public exponent attribute"); 465*47e946e7SWyllys Ingersoll return (CKR_TEMPLATE_INCOMPLETE); 466*47e946e7SWyllys Ingersoll } 467*47e946e7SWyllys Ingersoll 468*47e946e7SWyllys Ingersoll switch (publ_exp_attr->ulValueLen) { 469*47e946e7SWyllys Ingersoll case 3: 470*47e946e7SWyllys Ingersoll rc = memcmp(pubexp_bytes, publ_exp_attr->pValue, 3); 471*47e946e7SWyllys Ingersoll break; 472*47e946e7SWyllys Ingersoll case sizeof (CK_ULONG): 473*47e946e7SWyllys Ingersoll publ_exp = *((CK_ULONG *)publ_exp_attr->pValue); 474*47e946e7SWyllys Ingersoll if (publ_exp == 65537) 475*47e946e7SWyllys Ingersoll rc = 0; 476*47e946e7SWyllys Ingersoll break; 477*47e946e7SWyllys Ingersoll default: 478*47e946e7SWyllys Ingersoll break; 479*47e946e7SWyllys Ingersoll } 480*47e946e7SWyllys Ingersoll 481*47e946e7SWyllys Ingersoll return (rc); 482*47e946e7SWyllys Ingersoll } 483*47e946e7SWyllys Ingersoll 484*47e946e7SWyllys Ingersoll TSS_RESULT 485*47e946e7SWyllys Ingersoll set_public_modulus(TSS_HCONTEXT hContext, TSS_HKEY hKey, 486*47e946e7SWyllys Ingersoll unsigned long size_n, unsigned char *n) 487*47e946e7SWyllys Ingersoll { 488*47e946e7SWyllys Ingersoll UINT64 offset; 489*47e946e7SWyllys Ingersoll UINT32 blob_size; 490*47e946e7SWyllys Ingersoll BYTE *blob, pub_blob[1024]; 491*47e946e7SWyllys Ingersoll TCPA_PUBKEY pub_key; 492*47e946e7SWyllys Ingersoll TSS_RESULT result; 493*47e946e7SWyllys Ingersoll 494*47e946e7SWyllys Ingersoll /* Get the TCPA_PUBKEY blob from the key object. */ 495*47e946e7SWyllys Ingersoll result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, 496*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, &blob_size, &blob); 497*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS) { 498*47e946e7SWyllys Ingersoll stlogit("Tspi_GetAttribData failed: rc=0x%0x - %s\n", 499*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 500*47e946e7SWyllys Ingersoll return (result); 501*47e946e7SWyllys Ingersoll } 502*47e946e7SWyllys Ingersoll 503*47e946e7SWyllys Ingersoll offset = 0; 504*47e946e7SWyllys Ingersoll result = Trspi_UnloadBlob_PUBKEY(&offset, blob, &pub_key); 505*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS) { 506*47e946e7SWyllys Ingersoll stlogit("Trspi_UnloadBlob_PUBKEY failed: rc=0x%0x - %s\n", 507*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 508*47e946e7SWyllys Ingersoll return (result); 509*47e946e7SWyllys Ingersoll } 510*47e946e7SWyllys Ingersoll 511*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, blob); 512*47e946e7SWyllys Ingersoll /* Free the first dangling reference, putting 'n' in its place */ 513*47e946e7SWyllys Ingersoll free(pub_key.pubKey.key); 514*47e946e7SWyllys Ingersoll pub_key.pubKey.keyLength = size_n; 515*47e946e7SWyllys Ingersoll pub_key.pubKey.key = n; 516*47e946e7SWyllys Ingersoll 517*47e946e7SWyllys Ingersoll offset = 0; 518*47e946e7SWyllys Ingersoll Trspi_LoadBlob_PUBKEY(&offset, pub_blob, &pub_key); 519*47e946e7SWyllys Ingersoll 520*47e946e7SWyllys Ingersoll /* Free the second dangling reference */ 521*47e946e7SWyllys Ingersoll free(pub_key.algorithmParms.parms); 522*47e946e7SWyllys Ingersoll 523*47e946e7SWyllys Ingersoll /* set the public key data in the TSS object */ 524*47e946e7SWyllys Ingersoll result = Tspi_SetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, 525*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, (UINT32)offset, pub_blob); 526*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS) { 527*47e946e7SWyllys Ingersoll stlogit("Tspi_SetAttribData failed: rc=0x%0x - %s\n", 528*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 529*47e946e7SWyllys Ingersoll return (result); 530*47e946e7SWyllys Ingersoll } 531*47e946e7SWyllys Ingersoll 532*47e946e7SWyllys Ingersoll return (result); 533*47e946e7SWyllys Ingersoll } 534*47e946e7SWyllys Ingersoll 535*47e946e7SWyllys Ingersoll /* 536*47e946e7SWyllys Ingersoll * Get details about the TPM to put into the token_info structure. 537*47e946e7SWyllys Ingersoll */ 538*47e946e7SWyllys Ingersoll CK_RV 539*47e946e7SWyllys Ingersoll token_get_tpm_info(TSS_HCONTEXT hContext, TOKEN_DATA *td) 540*47e946e7SWyllys Ingersoll { 541*47e946e7SWyllys Ingersoll TSS_RESULT result; 542*47e946e7SWyllys Ingersoll TPM_CAPABILITY_AREA capArea = TSS_TPMCAP_VERSION_VAL; 543*47e946e7SWyllys Ingersoll UINT32 datalen; 544*47e946e7SWyllys Ingersoll BYTE *data; 545*47e946e7SWyllys Ingersoll TSS_HTPM hTPM; 546*47e946e7SWyllys Ingersoll 547*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_GetTpmObject(hContext, &hTPM))) { 548*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_GetTpmObject: 0x%0x - %s", 549*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 550*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 551*47e946e7SWyllys Ingersoll } 552*47e946e7SWyllys Ingersoll if ((result = Tspi_TPM_GetCapability(hTPM, 553*47e946e7SWyllys Ingersoll capArea, 0, NULL, &datalen, &data)) != 0 || datalen == 0 || 554*47e946e7SWyllys Ingersoll data == NULL) { 555*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_GetCapability: 0x%0x - %s", 556*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 557*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 558*47e946e7SWyllys Ingersoll } 559*47e946e7SWyllys Ingersoll if (datalen > sizeof (tpmvinfo)) { 560*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, data); 561*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 562*47e946e7SWyllys Ingersoll } 563*47e946e7SWyllys Ingersoll 564*47e946e7SWyllys Ingersoll (void) memcpy(&tpmvinfo, (void *)data, sizeof (tpmvinfo)); 565*47e946e7SWyllys Ingersoll 566*47e946e7SWyllys Ingersoll bzero(td->token_info.manufacturerID, 567*47e946e7SWyllys Ingersoll sizeof (td->token_info.manufacturerID)); 568*47e946e7SWyllys Ingersoll 569*47e946e7SWyllys Ingersoll (void) memset(td->token_info.manufacturerID, ' ', 570*47e946e7SWyllys Ingersoll sizeof (td->token_info.manufacturerID) - 1); 571*47e946e7SWyllys Ingersoll (void) memcpy(td->token_info.manufacturerID, 572*47e946e7SWyllys Ingersoll tpmvinfo.tpmVendorID, sizeof (tpmvinfo.tpmVendorID)); 573*47e946e7SWyllys Ingersoll 574*47e946e7SWyllys Ingersoll (void) memset(td->token_info.label, ' ', 575*47e946e7SWyllys Ingersoll sizeof (td->token_info.label) - 1); 576*47e946e7SWyllys Ingersoll (void) memcpy(td->token_info.label, "TPM", 6); 577*47e946e7SWyllys Ingersoll 578*47e946e7SWyllys Ingersoll td->token_info.hardwareVersion.major = tpmvinfo.version.major; 579*47e946e7SWyllys Ingersoll td->token_info.hardwareVersion.minor = tpmvinfo.version.minor; 580*47e946e7SWyllys Ingersoll td->token_info.firmwareVersion.major = tpmvinfo.version.revMajor; 581*47e946e7SWyllys Ingersoll td->token_info.firmwareVersion.minor = tpmvinfo.version.revMinor; 582*47e946e7SWyllys Ingersoll 583*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, data); 584*47e946e7SWyllys Ingersoll return (CKR_OK); 585*47e946e7SWyllys Ingersoll } 586*47e946e7SWyllys Ingersoll 587*47e946e7SWyllys Ingersoll /*ARGSUSED*/ 588*47e946e7SWyllys Ingersoll CK_RV 589*47e946e7SWyllys Ingersoll token_specific_session(CK_SLOT_ID slotid) 590*47e946e7SWyllys Ingersoll { 591*47e946e7SWyllys Ingersoll return (CKR_OK); 592*47e946e7SWyllys Ingersoll } 593*47e946e7SWyllys Ingersoll 594*47e946e7SWyllys Ingersoll CK_RV 595*47e946e7SWyllys Ingersoll token_rng(TSS_HCONTEXT hContext, CK_BYTE *output, CK_ULONG bytes) 596*47e946e7SWyllys Ingersoll { 597*47e946e7SWyllys Ingersoll TSS_RESULT rc; 598*47e946e7SWyllys Ingersoll TSS_HTPM hTPM; 599*47e946e7SWyllys Ingersoll BYTE *random_bytes = NULL; 600*47e946e7SWyllys Ingersoll 601*47e946e7SWyllys Ingersoll if ((rc = Tspi_Context_GetTpmObject(hContext, &hTPM))) { 602*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_GetTpmObject: 0x%0x - %s", 603*47e946e7SWyllys Ingersoll rc, Trspi_Error_String(rc)); 604*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 605*47e946e7SWyllys Ingersoll } 606*47e946e7SWyllys Ingersoll 607*47e946e7SWyllys Ingersoll if ((rc = Tspi_TPM_GetRandom(hTPM, bytes, &random_bytes))) { 608*47e946e7SWyllys Ingersoll stlogit("Tspi_TPM_GetRandom: 0x%0x - %s", 609*47e946e7SWyllys Ingersoll rc, Trspi_Error_String(rc)); 610*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 611*47e946e7SWyllys Ingersoll } 612*47e946e7SWyllys Ingersoll 613*47e946e7SWyllys Ingersoll (void) memcpy(output, random_bytes, bytes); 614*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, random_bytes); 615*47e946e7SWyllys Ingersoll 616*47e946e7SWyllys Ingersoll return (CKR_OK); 617*47e946e7SWyllys Ingersoll } 618*47e946e7SWyllys Ingersoll 619*47e946e7SWyllys Ingersoll TSS_RESULT 620*47e946e7SWyllys Ingersoll open_tss_context(TSS_HCONTEXT *pContext) 621*47e946e7SWyllys Ingersoll { 622*47e946e7SWyllys Ingersoll TSS_RESULT result; 623*47e946e7SWyllys Ingersoll 624*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_Create(pContext))) { 625*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_Create: 0x%0x - %s", 626*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 627*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 628*47e946e7SWyllys Ingersoll } 629*47e946e7SWyllys Ingersoll 630*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_Connect(*pContext, NULL))) { 631*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_Connect: 0x%0x - %s", 632*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 633*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 634*47e946e7SWyllys Ingersoll } 635*47e946e7SWyllys Ingersoll return (result); 636*47e946e7SWyllys Ingersoll } 637*47e946e7SWyllys Ingersoll 638*47e946e7SWyllys Ingersoll /*ARGSUSED*/ 639*47e946e7SWyllys Ingersoll static CK_RV 640*47e946e7SWyllys Ingersoll token_specific_init(char *Correlator, CK_SLOT_ID SlotNumber, 641*47e946e7SWyllys Ingersoll TSS_HCONTEXT *hContext) 642*47e946e7SWyllys Ingersoll { 643*47e946e7SWyllys Ingersoll TSS_RESULT result; 644*47e946e7SWyllys Ingersoll 645*47e946e7SWyllys Ingersoll result = open_tss_context(hContext); 646*47e946e7SWyllys Ingersoll if (result) 647*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 648*47e946e7SWyllys Ingersoll 649*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_GetDefaultPolicy(*hContext, 650*47e946e7SWyllys Ingersoll &hDefaultPolicy))) { 651*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_GetDefaultPolicy: 0x%0x - %s", 652*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 653*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 654*47e946e7SWyllys Ingersoll } 655*47e946e7SWyllys Ingersoll 656*47e946e7SWyllys Ingersoll local_uuid_clear(&publicRootKeyUUID); 657*47e946e7SWyllys Ingersoll local_uuid_clear(&privateRootKeyUUID); 658*47e946e7SWyllys Ingersoll local_uuid_clear(&publicLeafKeyUUID); 659*47e946e7SWyllys Ingersoll local_uuid_clear(&privateLeafKeyUUID); 660*47e946e7SWyllys Ingersoll 661*47e946e7SWyllys Ingersoll result = token_get_tpm_info(*hContext, nv_token_data); 662*47e946e7SWyllys Ingersoll return (result); 663*47e946e7SWyllys Ingersoll } 664*47e946e7SWyllys Ingersoll 665*47e946e7SWyllys Ingersoll /* 666*47e946e7SWyllys Ingersoll * Try to find the opaque key blob data for a token object. 667*47e946e7SWyllys Ingersoll */ 668*47e946e7SWyllys Ingersoll static CK_RV 669*47e946e7SWyllys Ingersoll token_get_key_blob(CK_OBJECT_HANDLE ckKey, CK_ULONG *blob_size, 670*47e946e7SWyllys Ingersoll CK_BYTE **ret_blob) 671*47e946e7SWyllys Ingersoll { 672*47e946e7SWyllys Ingersoll CK_RV rc = CKR_OK; 673*47e946e7SWyllys Ingersoll CK_BYTE_PTR blob = NULL; 674*47e946e7SWyllys Ingersoll CK_ATTRIBUTE tmpl[] = { 675*47e946e7SWyllys Ingersoll {CKA_IBM_OPAQUE, NULL_PTR, 0} 676*47e946e7SWyllys Ingersoll }; 677*47e946e7SWyllys Ingersoll SESSION dummy_sess; 678*47e946e7SWyllys Ingersoll 679*47e946e7SWyllys Ingersoll /* set up dummy session */ 680*47e946e7SWyllys Ingersoll (void) memset(&dummy_sess, 0, sizeof (SESSION)); 681*47e946e7SWyllys Ingersoll dummy_sess.session_info.state = CKS_RO_USER_FUNCTIONS; 682*47e946e7SWyllys Ingersoll 683*47e946e7SWyllys Ingersoll /* find object the first time to return the size of the buffer needed */ 684*47e946e7SWyllys Ingersoll if ((rc = object_mgr_get_attribute_values(&dummy_sess, ckKey, 685*47e946e7SWyllys Ingersoll tmpl, 1))) { 686*47e946e7SWyllys Ingersoll return (rc); 687*47e946e7SWyllys Ingersoll } 688*47e946e7SWyllys Ingersoll 689*47e946e7SWyllys Ingersoll blob = malloc(tmpl[0].ulValueLen); 690*47e946e7SWyllys Ingersoll if (blob == NULL) { 691*47e946e7SWyllys Ingersoll rc = CKR_HOST_MEMORY; 692*47e946e7SWyllys Ingersoll return (rc); 693*47e946e7SWyllys Ingersoll } 694*47e946e7SWyllys Ingersoll 695*47e946e7SWyllys Ingersoll tmpl[0].pValue = blob; 696*47e946e7SWyllys Ingersoll /* find object the 2nd time to fill the buffer with data */ 697*47e946e7SWyllys Ingersoll if ((rc = object_mgr_get_attribute_values(&dummy_sess, ckKey, 698*47e946e7SWyllys Ingersoll tmpl, 1))) { 699*47e946e7SWyllys Ingersoll return (rc); 700*47e946e7SWyllys Ingersoll } 701*47e946e7SWyllys Ingersoll 702*47e946e7SWyllys Ingersoll *ret_blob = blob; 703*47e946e7SWyllys Ingersoll *blob_size = tmpl[0].ulValueLen; 704*47e946e7SWyllys Ingersoll done: 705*47e946e7SWyllys Ingersoll return (rc); 706*47e946e7SWyllys Ingersoll } 707*47e946e7SWyllys Ingersoll 708*47e946e7SWyllys Ingersoll /* 709*47e946e7SWyllys Ingersoll * Given a modulus and prime from an RSA key, create a TSS_HKEY object by 710*47e946e7SWyllys Ingersoll * wrapping the RSA key with a key from the TPM (SRK or other previously stored 711*47e946e7SWyllys Ingersoll * key). 712*47e946e7SWyllys Ingersoll */ 713*47e946e7SWyllys Ingersoll static CK_RV 714*47e946e7SWyllys Ingersoll token_wrap_sw_key( 715*47e946e7SWyllys Ingersoll TSS_HCONTEXT hContext, 716*47e946e7SWyllys Ingersoll int size_n, 717*47e946e7SWyllys Ingersoll unsigned char *n, 718*47e946e7SWyllys Ingersoll int size_p, 719*47e946e7SWyllys Ingersoll unsigned char *p, 720*47e946e7SWyllys Ingersoll TSS_HKEY hParentKey, 721*47e946e7SWyllys Ingersoll TSS_FLAG initFlags, 722*47e946e7SWyllys Ingersoll TSS_HKEY *phKey) 723*47e946e7SWyllys Ingersoll { 724*47e946e7SWyllys Ingersoll TSS_RESULT result; 725*47e946e7SWyllys Ingersoll TSS_HPOLICY hPolicy; 726*47e946e7SWyllys Ingersoll UINT32 key_size; 727*47e946e7SWyllys Ingersoll 728*47e946e7SWyllys Ingersoll key_size = util_get_keysize_flag(size_n * 8); 729*47e946e7SWyllys Ingersoll if (initFlags == 0) { 730*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 731*47e946e7SWyllys Ingersoll } 732*47e946e7SWyllys Ingersoll 733*47e946e7SWyllys Ingersoll /* create the TSS key object */ 734*47e946e7SWyllys Ingersoll result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY, 735*47e946e7SWyllys Ingersoll TSS_KEY_MIGRATABLE | initFlags | key_size, phKey); 736*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS) { 737*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 738*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 739*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 740*47e946e7SWyllys Ingersoll } 741*47e946e7SWyllys Ingersoll 742*47e946e7SWyllys Ingersoll result = set_public_modulus(hContext, *phKey, size_n, n); 743*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS) { 744*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 745*47e946e7SWyllys Ingersoll *phKey = NULL_HKEY; 746*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 747*47e946e7SWyllys Ingersoll } 748*47e946e7SWyllys Ingersoll 749*47e946e7SWyllys Ingersoll /* set the private key data in the TSS object */ 750*47e946e7SWyllys Ingersoll result = Tspi_SetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB, 751*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY, size_p, p); 752*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS) { 753*47e946e7SWyllys Ingersoll stlogit("Tspi_SetAttribData: 0x%x - %s", 754*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 755*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 756*47e946e7SWyllys Ingersoll *phKey = NULL_HKEY; 757*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 758*47e946e7SWyllys Ingersoll } 759*47e946e7SWyllys Ingersoll 760*47e946e7SWyllys Ingersoll result = Tspi_Context_CreateObject(hContext, 761*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_POLICY, TSS_POLICY_MIGRATION, &hPolicy); 762*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS) { 763*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 764*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 765*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 766*47e946e7SWyllys Ingersoll *phKey = NULL_HKEY; 767*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 768*47e946e7SWyllys Ingersoll } 769*47e946e7SWyllys Ingersoll 770*47e946e7SWyllys Ingersoll result = Tspi_Policy_AssignToObject(hPolicy, *phKey); 771*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS) { 772*47e946e7SWyllys Ingersoll stlogit("Tspi_Policy_AssignToObject: 0x%0x - %s\n", 773*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 774*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 775*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hPolicy); 776*47e946e7SWyllys Ingersoll *phKey = NULL_HKEY; 777*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 778*47e946e7SWyllys Ingersoll } 779*47e946e7SWyllys Ingersoll 780*47e946e7SWyllys Ingersoll result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE, 0, NULL); 781*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS) { 782*47e946e7SWyllys Ingersoll stlogit("Tspi_Policy_SetSecret: 0x%0x - %s\n", 783*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 784*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 785*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hPolicy); 786*47e946e7SWyllys Ingersoll *phKey = NULL_HKEY; 787*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 788*47e946e7SWyllys Ingersoll } 789*47e946e7SWyllys Ingersoll 790*47e946e7SWyllys Ingersoll if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) { 791*47e946e7SWyllys Ingersoll if ((result = Tspi_SetAttribUint32(*phKey, 792*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_ENCSCHEME, 793*47e946e7SWyllys Ingersoll TSS_ES_RSAESPKCSV15))) { 794*47e946e7SWyllys Ingersoll stlogit("Tspi_SetAttribUint32: 0x%0x - %s\n", 795*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 796*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 797*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hPolicy); 798*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 799*47e946e7SWyllys Ingersoll } 800*47e946e7SWyllys Ingersoll 801*47e946e7SWyllys Ingersoll if ((result = Tspi_SetAttribUint32(*phKey, 802*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_SIGSCHEME, 803*47e946e7SWyllys Ingersoll TSS_SS_RSASSAPKCS1V15_DER))) { 804*47e946e7SWyllys Ingersoll stlogit("Tspi_SetAttribUint32: 0x%0x - %s\n", 805*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 806*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 807*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hPolicy); 808*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 809*47e946e7SWyllys Ingersoll } 810*47e946e7SWyllys Ingersoll } 811*47e946e7SWyllys Ingersoll 812*47e946e7SWyllys Ingersoll result = Tspi_Key_WrapKey(*phKey, hParentKey, NULL_HPCRS); 813*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS) { 814*47e946e7SWyllys Ingersoll stlogit("Tspi_Key_WrapKey: 0x%0x - %s", 815*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 816*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 817*47e946e7SWyllys Ingersoll *phKey = NULL_HKEY; 818*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 819*47e946e7SWyllys Ingersoll } 820*47e946e7SWyllys Ingersoll 821*47e946e7SWyllys Ingersoll return (CKR_OK); 822*47e946e7SWyllys Ingersoll } 823*47e946e7SWyllys Ingersoll 824*47e946e7SWyllys Ingersoll /* 825*47e946e7SWyllys Ingersoll * Create a TPM key blob for an imported key. This function is only called when 826*47e946e7SWyllys Ingersoll * a key is in active use, so any failure should trickle through. 827*47e946e7SWyllys Ingersoll */ 828*47e946e7SWyllys Ingersoll static CK_RV 829*47e946e7SWyllys Ingersoll token_wrap_key_object(TSS_HCONTEXT hContext, 830*47e946e7SWyllys Ingersoll CK_OBJECT_HANDLE ckObject, 831*47e946e7SWyllys Ingersoll TSS_HKEY hParentKey, TSS_HKEY *phKey) 832*47e946e7SWyllys Ingersoll { 833*47e946e7SWyllys Ingersoll CK_RV rc = CKR_OK; 834*47e946e7SWyllys Ingersoll CK_ATTRIBUTE *attr = NULL, *new_attr, *prime_attr; 835*47e946e7SWyllys Ingersoll CK_ULONG class, key_type; 836*47e946e7SWyllys Ingersoll OBJECT *obj; 837*47e946e7SWyllys Ingersoll 838*47e946e7SWyllys Ingersoll TSS_RESULT result; 839*47e946e7SWyllys Ingersoll TSS_FLAG initFlags = 0; 840*47e946e7SWyllys Ingersoll BYTE *rgbBlob; 841*47e946e7SWyllys Ingersoll UINT32 ulBlobLen; 842*47e946e7SWyllys Ingersoll 843*47e946e7SWyllys Ingersoll if ((rc = object_mgr_find_in_map1(hContext, ckObject, &obj))) { 844*47e946e7SWyllys Ingersoll return (rc); 845*47e946e7SWyllys Ingersoll } 846*47e946e7SWyllys Ingersoll 847*47e946e7SWyllys Ingersoll /* if the object isn't a key, fail */ 848*47e946e7SWyllys Ingersoll if (template_attribute_find(obj->template, CKA_KEY_TYPE, 849*47e946e7SWyllys Ingersoll &attr) == FALSE) { 850*47e946e7SWyllys Ingersoll return (CKR_TEMPLATE_INCOMPLETE); 851*47e946e7SWyllys Ingersoll } 852*47e946e7SWyllys Ingersoll 853*47e946e7SWyllys Ingersoll key_type = *((CK_ULONG *)attr->pValue); 854*47e946e7SWyllys Ingersoll 855*47e946e7SWyllys Ingersoll if (key_type != CKK_RSA) { 856*47e946e7SWyllys Ingersoll return (CKR_TEMPLATE_INCONSISTENT); 857*47e946e7SWyllys Ingersoll } 858*47e946e7SWyllys Ingersoll 859*47e946e7SWyllys Ingersoll if (template_attribute_find(obj->template, CKA_CLASS, 860*47e946e7SWyllys Ingersoll &attr) == FALSE) { 861*47e946e7SWyllys Ingersoll return (CKR_TEMPLATE_INCOMPLETE); 862*47e946e7SWyllys Ingersoll } 863*47e946e7SWyllys Ingersoll 864*47e946e7SWyllys Ingersoll class = *((CK_ULONG *)attr->pValue); 865*47e946e7SWyllys Ingersoll 866*47e946e7SWyllys Ingersoll if (class == CKO_PRIVATE_KEY) { 867*47e946e7SWyllys Ingersoll /* 868*47e946e7SWyllys Ingersoll * In order to create a full TSS key blob using a PKCS#11 869*47e946e7SWyllys Ingersoll * private key object, we need one of the two primes, the 870*47e946e7SWyllys Ingersoll * modulus and the private exponent and we need the public 871*47e946e7SWyllys Ingersoll * exponent to be correct. 872*47e946e7SWyllys Ingersoll */ 873*47e946e7SWyllys Ingersoll 874*47e946e7SWyllys Ingersoll /* 875*47e946e7SWyllys Ingersoll * Check the least likely attribute to exist first, the 876*47e946e7SWyllys Ingersoll * primes. 877*47e946e7SWyllys Ingersoll */ 878*47e946e7SWyllys Ingersoll if (template_attribute_find(obj->template, CKA_PRIME_1, 879*47e946e7SWyllys Ingersoll &prime_attr) == FALSE) { 880*47e946e7SWyllys Ingersoll if (template_attribute_find(obj->template, 881*47e946e7SWyllys Ingersoll CKA_PRIME_2, &prime_attr) == FALSE) { 882*47e946e7SWyllys Ingersoll return (CKR_TEMPLATE_INCOMPLETE); 883*47e946e7SWyllys Ingersoll } 884*47e946e7SWyllys Ingersoll } 885*47e946e7SWyllys Ingersoll 886*47e946e7SWyllys Ingersoll /* Make sure the public exponent is usable */ 887*47e946e7SWyllys Ingersoll if ((rc = util_check_public_exponent(obj->template))) { 888*47e946e7SWyllys Ingersoll return (CKR_TEMPLATE_INCONSISTENT); 889*47e946e7SWyllys Ingersoll } 890*47e946e7SWyllys Ingersoll 891*47e946e7SWyllys Ingersoll /* get the modulus */ 892*47e946e7SWyllys Ingersoll if (template_attribute_find(obj->template, CKA_MODULUS, 893*47e946e7SWyllys Ingersoll &attr) == FALSE) { 894*47e946e7SWyllys Ingersoll return (CKR_TEMPLATE_INCOMPLETE); 895*47e946e7SWyllys Ingersoll } 896*47e946e7SWyllys Ingersoll 897*47e946e7SWyllys Ingersoll /* make sure the key size is usable */ 898*47e946e7SWyllys Ingersoll initFlags = util_get_keysize_flag(attr->ulValueLen * 8); 899*47e946e7SWyllys Ingersoll if (initFlags == 0) { 900*47e946e7SWyllys Ingersoll return (CKR_TEMPLATE_INCONSISTENT); 901*47e946e7SWyllys Ingersoll } 902*47e946e7SWyllys Ingersoll 903*47e946e7SWyllys Ingersoll /* generate the software based key */ 904*47e946e7SWyllys Ingersoll if ((rc = token_wrap_sw_key(hContext, 905*47e946e7SWyllys Ingersoll (int)attr->ulValueLen, attr->pValue, 906*47e946e7SWyllys Ingersoll (int)prime_attr->ulValueLen, prime_attr->pValue, 907*47e946e7SWyllys Ingersoll hParentKey, TSS_KEY_TYPE_LEGACY | TSS_KEY_NO_AUTHORIZATION, 908*47e946e7SWyllys Ingersoll phKey))) { 909*47e946e7SWyllys Ingersoll return (rc); 910*47e946e7SWyllys Ingersoll } 911*47e946e7SWyllys Ingersoll } else if (class == CKO_PUBLIC_KEY) { 912*47e946e7SWyllys Ingersoll /* Make sure the public exponent is usable */ 913*47e946e7SWyllys Ingersoll if ((util_check_public_exponent(obj->template))) { 914*47e946e7SWyllys Ingersoll return (CKR_TEMPLATE_INCONSISTENT); 915*47e946e7SWyllys Ingersoll } 916*47e946e7SWyllys Ingersoll 917*47e946e7SWyllys Ingersoll /* grab the modulus to put into the TSS key object */ 918*47e946e7SWyllys Ingersoll if (template_attribute_find(obj->template, 919*47e946e7SWyllys Ingersoll CKA_MODULUS, &attr) == FALSE) { 920*47e946e7SWyllys Ingersoll return (CKR_TEMPLATE_INCONSISTENT); 921*47e946e7SWyllys Ingersoll } 922*47e946e7SWyllys Ingersoll 923*47e946e7SWyllys Ingersoll /* make sure the key size is usable */ 924*47e946e7SWyllys Ingersoll initFlags = util_get_keysize_flag(attr->ulValueLen * 8); 925*47e946e7SWyllys Ingersoll if (initFlags == 0) { 926*47e946e7SWyllys Ingersoll return (CKR_TEMPLATE_INCONSISTENT); 927*47e946e7SWyllys Ingersoll } 928*47e946e7SWyllys Ingersoll 929*47e946e7SWyllys Ingersoll initFlags |= TSS_KEY_TYPE_LEGACY | TSS_KEY_MIGRATABLE | 930*47e946e7SWyllys Ingersoll TSS_KEY_NO_AUTHORIZATION; 931*47e946e7SWyllys Ingersoll 932*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_CreateObject(hContext, 933*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_RSAKEY, initFlags, phKey))) { 934*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 935*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 936*47e946e7SWyllys Ingersoll return (result); 937*47e946e7SWyllys Ingersoll } 938*47e946e7SWyllys Ingersoll 939*47e946e7SWyllys Ingersoll if ((result = set_public_modulus(hContext, *phKey, 940*47e946e7SWyllys Ingersoll attr->ulValueLen, attr->pValue))) { 941*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 942*47e946e7SWyllys Ingersoll *phKey = NULL_HKEY; 943*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 944*47e946e7SWyllys Ingersoll } 945*47e946e7SWyllys Ingersoll } else { 946*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 947*47e946e7SWyllys Ingersoll } 948*47e946e7SWyllys Ingersoll 949*47e946e7SWyllys Ingersoll /* grab the entire key blob to put into the PKCS#11 object */ 950*47e946e7SWyllys Ingersoll if ((result = Tspi_GetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB, 951*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob))) { 952*47e946e7SWyllys Ingersoll stlogit("Tspi_GetAttribData: 0x%0x - %s", 953*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 954*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 955*47e946e7SWyllys Ingersoll } 956*47e946e7SWyllys Ingersoll 957*47e946e7SWyllys Ingersoll /* insert the key blob into the object */ 958*47e946e7SWyllys Ingersoll if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, 959*47e946e7SWyllys Ingersoll &new_attr))) { 960*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, rgbBlob); 961*47e946e7SWyllys Ingersoll return (rc); 962*47e946e7SWyllys Ingersoll } 963*47e946e7SWyllys Ingersoll (void) template_update_attribute(obj->template, new_attr); 964*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, rgbBlob); 965*47e946e7SWyllys Ingersoll 966*47e946e7SWyllys Ingersoll /* 967*47e946e7SWyllys Ingersoll * If this is a token object, save it with the new attribute 968*47e946e7SWyllys Ingersoll * so that we don't have to go down this path again. 969*47e946e7SWyllys Ingersoll */ 970*47e946e7SWyllys Ingersoll if (!object_is_session_object(obj)) { 971*47e946e7SWyllys Ingersoll rc = save_token_object(hContext, obj); 972*47e946e7SWyllys Ingersoll } 973*47e946e7SWyllys Ingersoll 974*47e946e7SWyllys Ingersoll return (rc); 975*47e946e7SWyllys Ingersoll } 976*47e946e7SWyllys Ingersoll 977*47e946e7SWyllys Ingersoll static TSS_RESULT 978*47e946e7SWyllys Ingersoll tss_assign_secret_key_policy(TSS_HCONTEXT hContext, TSS_HKEY hKey, 979*47e946e7SWyllys Ingersoll CK_CHAR *passHash) 980*47e946e7SWyllys Ingersoll { 981*47e946e7SWyllys Ingersoll TSS_RESULT result; 982*47e946e7SWyllys Ingersoll TSS_HPOLICY hPolicy; 983*47e946e7SWyllys Ingersoll 984*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_CreateObject(hContext, 985*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy))) { 986*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 987*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 988*47e946e7SWyllys Ingersoll return (result); 989*47e946e7SWyllys Ingersoll } 990*47e946e7SWyllys Ingersoll if ((result = Tspi_Policy_AssignToObject(hPolicy, hKey))) { 991*47e946e7SWyllys Ingersoll stlogit("Tspi_Policy_AssignToObject: 0x%0x - %s", 992*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 993*47e946e7SWyllys Ingersoll goto done; 994*47e946e7SWyllys Ingersoll } 995*47e946e7SWyllys Ingersoll if (passHash == NULL) { 996*47e946e7SWyllys Ingersoll result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE, 997*47e946e7SWyllys Ingersoll 0, NULL); 998*47e946e7SWyllys Ingersoll } else { 999*47e946e7SWyllys Ingersoll result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, 1000*47e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH, passHash); 1001*47e946e7SWyllys Ingersoll } 1002*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS) { 1003*47e946e7SWyllys Ingersoll stlogit("Tspi_Policy_SetSecret: 0x%0x - %s", 1004*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1005*47e946e7SWyllys Ingersoll goto done; 1006*47e946e7SWyllys Ingersoll } 1007*47e946e7SWyllys Ingersoll done: 1008*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS) 1009*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hPolicy); 1010*47e946e7SWyllys Ingersoll return (result); 1011*47e946e7SWyllys Ingersoll } 1012*47e946e7SWyllys Ingersoll 1013*47e946e7SWyllys Ingersoll /* 1014*47e946e7SWyllys Ingersoll * Take a key from the TSS store (on-disk) and load it into the TPM, wrapped 1015*47e946e7SWyllys Ingersoll * by an already TPM-resident key and protected with a PIN (optional). 1016*47e946e7SWyllys Ingersoll */ 1017*47e946e7SWyllys Ingersoll static CK_RV 1018*47e946e7SWyllys Ingersoll token_load_key( 1019*47e946e7SWyllys Ingersoll TSS_HCONTEXT hContext, 1020*47e946e7SWyllys Ingersoll CK_OBJECT_HANDLE ckKey, 1021*47e946e7SWyllys Ingersoll TSS_HKEY hParentKey, 1022*47e946e7SWyllys Ingersoll CK_CHAR_PTR passHash, 1023*47e946e7SWyllys Ingersoll TSS_HKEY *phKey) 1024*47e946e7SWyllys Ingersoll { 1025*47e946e7SWyllys Ingersoll TSS_RESULT result; 1026*47e946e7SWyllys Ingersoll CK_BYTE *blob = NULL; 1027*47e946e7SWyllys Ingersoll CK_ULONG ulBlobSize = 0; 1028*47e946e7SWyllys Ingersoll CK_RV rc; 1029*47e946e7SWyllys Ingersoll 1030*47e946e7SWyllys Ingersoll if ((rc = token_get_key_blob(ckKey, &ulBlobSize, &blob))) { 1031*47e946e7SWyllys Ingersoll if (rc != CKR_ATTRIBUTE_TYPE_INVALID) { 1032*47e946e7SWyllys Ingersoll return (rc); 1033*47e946e7SWyllys Ingersoll } 1034*47e946e7SWyllys Ingersoll /* 1035*47e946e7SWyllys Ingersoll * The key blob wasn't found, load the parts of the key 1036*47e946e7SWyllys Ingersoll * from the object DB and create a new key object that 1037*47e946e7SWyllys Ingersoll * gets loaded into the TPM, wrapped with the parent key. 1038*47e946e7SWyllys Ingersoll */ 1039*47e946e7SWyllys Ingersoll if ((rc = token_wrap_key_object(hContext, ckKey, 1040*47e946e7SWyllys Ingersoll hParentKey, phKey))) { 1041*47e946e7SWyllys Ingersoll return (rc); 1042*47e946e7SWyllys Ingersoll } 1043*47e946e7SWyllys Ingersoll } 1044*47e946e7SWyllys Ingersoll 1045*47e946e7SWyllys Ingersoll if (blob != NULL) { 1046*47e946e7SWyllys Ingersoll /* load the key into the TPM, wrapped with parent key */ 1047*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_LoadKeyByBlob(hContext, 1048*47e946e7SWyllys Ingersoll hParentKey, ulBlobSize, blob, phKey))) { 1049*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_LoadKeyByBlob: 0x%x - %s", 1050*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1051*47e946e7SWyllys Ingersoll goto done; 1052*47e946e7SWyllys Ingersoll } 1053*47e946e7SWyllys Ingersoll } 1054*47e946e7SWyllys Ingersoll /* 1055*47e946e7SWyllys Ingersoll * Assign the PIN hash (optional) to the newly loaded key object, 1056*47e946e7SWyllys Ingersoll * if this PIN is incorrect, the TPM will not be able to decrypt 1057*47e946e7SWyllys Ingersoll * the private key and use it. 1058*47e946e7SWyllys Ingersoll */ 1059*47e946e7SWyllys Ingersoll result = tss_assign_secret_key_policy(hContext, *phKey, passHash); 1060*47e946e7SWyllys Ingersoll done: 1061*47e946e7SWyllys Ingersoll free(blob); 1062*47e946e7SWyllys Ingersoll return (result); 1063*47e946e7SWyllys Ingersoll } 1064*47e946e7SWyllys Ingersoll 1065*47e946e7SWyllys Ingersoll /* 1066*47e946e7SWyllys Ingersoll * Load the SRK into the TPM by referencing its well-known UUID and using the 1067*47e946e7SWyllys Ingersoll * default SRK PIN (20 bytes of 0x00). 1068*47e946e7SWyllys Ingersoll * 1069*47e946e7SWyllys Ingersoll * NOTE - if the SRK PIN is changed by an administrative tool, this code will 1070*47e946e7SWyllys Ingersoll * fail because it assumes that the well-known PIN is still being used. 1071*47e946e7SWyllys Ingersoll */ 1072*47e946e7SWyllys Ingersoll static TSS_RESULT 1073*47e946e7SWyllys Ingersoll token_load_srk(TSS_HCONTEXT hContext, TSS_HKEY *hSRK) 1074*47e946e7SWyllys Ingersoll { 1075*47e946e7SWyllys Ingersoll TSS_HPOLICY hPolicy; 1076*47e946e7SWyllys Ingersoll TSS_RESULT result; 1077*47e946e7SWyllys Ingersoll TSS_UUID SRK_UUID = TSS_UUID_SRK; 1078*47e946e7SWyllys Ingersoll BYTE wellKnown[] = TSS_WELL_KNOWN_SECRET; 1079*47e946e7SWyllys Ingersoll TSS_HTPM hTPM; 1080*47e946e7SWyllys Ingersoll 1081*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_GetTpmObject(hContext, &hTPM))) { 1082*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_GetTpmObject: 0x%0x - %s", 1083*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1084*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1085*47e946e7SWyllys Ingersoll } 1086*47e946e7SWyllys Ingersoll 1087*47e946e7SWyllys Ingersoll /* load the SRK */ 1088*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_LoadKeyByUUID(hContext, 1089*47e946e7SWyllys Ingersoll TSS_PS_TYPE_SYSTEM, SRK_UUID, hSRK))) { 1090*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_LoadKeyByUUID: 0x%0x - %s", 1091*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1092*47e946e7SWyllys Ingersoll goto done; 1093*47e946e7SWyllys Ingersoll } 1094*47e946e7SWyllys Ingersoll if ((result = Tspi_GetPolicyObject(*hSRK, TSS_POLICY_USAGE, 1095*47e946e7SWyllys Ingersoll &hPolicy))) { 1096*47e946e7SWyllys Ingersoll stlogit("Tspi_GetPolicyObject: 0x%0x - %s", 1097*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1098*47e946e7SWyllys Ingersoll goto done; 1099*47e946e7SWyllys Ingersoll } 1100*47e946e7SWyllys Ingersoll if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, 1101*47e946e7SWyllys Ingersoll sizeof (wellKnown), wellKnown))) { 1102*47e946e7SWyllys Ingersoll stlogit("Tspi_Policy_SetSecret: 0x%0x - %s", 1103*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1104*47e946e7SWyllys Ingersoll goto done; 1105*47e946e7SWyllys Ingersoll } 1106*47e946e7SWyllys Ingersoll 1107*47e946e7SWyllys Ingersoll done: 1108*47e946e7SWyllys Ingersoll return (result); 1109*47e946e7SWyllys Ingersoll } 1110*47e946e7SWyllys Ingersoll 1111*47e946e7SWyllys Ingersoll static TSS_RESULT 1112*47e946e7SWyllys Ingersoll tss_find_and_load_key(TSS_HCONTEXT hContext, 1113*47e946e7SWyllys Ingersoll char *keyid, TSS_UUID *uuid, TSS_HKEY hParent, 1114*47e946e7SWyllys Ingersoll BYTE *hash, TSS_HKEY *hKey) 1115*47e946e7SWyllys Ingersoll { 1116*47e946e7SWyllys Ingersoll TSS_RESULT result; 1117*47e946e7SWyllys Ingersoll 1118*47e946e7SWyllys Ingersoll if (local_uuid_is_null(uuid) && 1119*47e946e7SWyllys Ingersoll find_uuid(keyid, uuid)) { 1120*47e946e7SWyllys Ingersoll /* The UUID was not created or saved yet */ 1121*47e946e7SWyllys Ingersoll return (1); 1122*47e946e7SWyllys Ingersoll } 1123*47e946e7SWyllys Ingersoll result = Tspi_Context_GetKeyByUUID(hContext, 1124*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, *uuid, hKey); 1125*47e946e7SWyllys Ingersoll if (result) { 1126*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_GetKeyByUUID: 0x%0x - %s", 1127*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1128*47e946e7SWyllys Ingersoll return (result); 1129*47e946e7SWyllys Ingersoll } 1130*47e946e7SWyllys Ingersoll 1131*47e946e7SWyllys Ingersoll if (hash != NULL) { 1132*47e946e7SWyllys Ingersoll result = tss_assign_secret_key_policy(hContext, *hKey, 1133*47e946e7SWyllys Ingersoll (CK_BYTE *)hash); 1134*47e946e7SWyllys Ingersoll if (result) 1135*47e946e7SWyllys Ingersoll return (result); 1136*47e946e7SWyllys Ingersoll } 1137*47e946e7SWyllys Ingersoll 1138*47e946e7SWyllys Ingersoll result = Tspi_Key_LoadKey(*hKey, hParent); 1139*47e946e7SWyllys Ingersoll if (result) 1140*47e946e7SWyllys Ingersoll stlogit("Tspi_Key_LoadKey: 0x%0x - %s", 1141*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1142*47e946e7SWyllys Ingersoll 1143*47e946e7SWyllys Ingersoll return (result); 1144*47e946e7SWyllys Ingersoll } 1145*47e946e7SWyllys Ingersoll 1146*47e946e7SWyllys Ingersoll static TSS_RESULT 1147*47e946e7SWyllys Ingersoll token_load_public_root_key(TSS_HCONTEXT hContext) 1148*47e946e7SWyllys Ingersoll { 1149*47e946e7SWyllys Ingersoll TSS_RESULT result; 1150*47e946e7SWyllys Ingersoll TSS_HKEY hSRK; 1151*47e946e7SWyllys Ingersoll 1152*47e946e7SWyllys Ingersoll if (hPublicRootKey != NULL_HKEY) 1153*47e946e7SWyllys Ingersoll return (TSS_SUCCESS); 1154*47e946e7SWyllys Ingersoll 1155*47e946e7SWyllys Ingersoll if ((result = token_load_srk(hContext, &hSRK))) { 1156*47e946e7SWyllys Ingersoll return (result); 1157*47e946e7SWyllys Ingersoll } 1158*47e946e7SWyllys Ingersoll 1159*47e946e7SWyllys Ingersoll result = tss_find_and_load_key(hContext, 1160*47e946e7SWyllys Ingersoll TPMTOK_PUBLIC_ROOT_KEY_ID, 1161*47e946e7SWyllys Ingersoll &publicRootKeyUUID, hSRK, NULL, &hPublicRootKey); 1162*47e946e7SWyllys Ingersoll if (result) 1163*47e946e7SWyllys Ingersoll return (result); 1164*47e946e7SWyllys Ingersoll 1165*47e946e7SWyllys Ingersoll return (result); 1166*47e946e7SWyllys Ingersoll } 1167*47e946e7SWyllys Ingersoll 1168*47e946e7SWyllys Ingersoll static TSS_RESULT 1169*47e946e7SWyllys Ingersoll tss_generate_key(TSS_HCONTEXT hContext, TSS_FLAG initFlags, BYTE *passHash, 1170*47e946e7SWyllys Ingersoll TSS_HKEY hParentKey, TSS_HKEY *phKey) 1171*47e946e7SWyllys Ingersoll { 1172*47e946e7SWyllys Ingersoll TSS_RESULT result; 1173*47e946e7SWyllys Ingersoll TSS_HPOLICY hMigPolicy; 1174*47e946e7SWyllys Ingersoll 1175*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_CreateObject(hContext, 1176*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_RSAKEY, initFlags, phKey))) { 1177*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 1178*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1179*47e946e7SWyllys Ingersoll return (result); 1180*47e946e7SWyllys Ingersoll } 1181*47e946e7SWyllys Ingersoll result = tss_assign_secret_key_policy(hContext, *phKey, passHash); 1182*47e946e7SWyllys Ingersoll 1183*47e946e7SWyllys Ingersoll if (result) { 1184*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 1185*47e946e7SWyllys Ingersoll return (result); 1186*47e946e7SWyllys Ingersoll } 1187*47e946e7SWyllys Ingersoll 1188*47e946e7SWyllys Ingersoll if (TPMTOK_TSS_KEY_MIG_TYPE(initFlags) == TSS_KEY_MIGRATABLE) { 1189*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_CreateObject(hContext, 1190*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_POLICY, TSS_POLICY_MIGRATION, 1191*47e946e7SWyllys Ingersoll &hMigPolicy))) { 1192*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 1193*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1194*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 1195*47e946e7SWyllys Ingersoll return (result); 1196*47e946e7SWyllys Ingersoll } 1197*47e946e7SWyllys Ingersoll 1198*47e946e7SWyllys Ingersoll if (passHash == NULL) { 1199*47e946e7SWyllys Ingersoll result = Tspi_Policy_SetSecret(hMigPolicy, 1200*47e946e7SWyllys Ingersoll TSS_SECRET_MODE_NONE, 0, NULL); 1201*47e946e7SWyllys Ingersoll } else { 1202*47e946e7SWyllys Ingersoll result = Tspi_Policy_SetSecret(hMigPolicy, 1203*47e946e7SWyllys Ingersoll TSS_SECRET_MODE_SHA1, 20, passHash); 1204*47e946e7SWyllys Ingersoll } 1205*47e946e7SWyllys Ingersoll 1206*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS) { 1207*47e946e7SWyllys Ingersoll stlogit("Tspi_Policy_SetSecret: 0x%0x - %s", 1208*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1209*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 1210*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hMigPolicy); 1211*47e946e7SWyllys Ingersoll return (result); 1212*47e946e7SWyllys Ingersoll } 1213*47e946e7SWyllys Ingersoll 1214*47e946e7SWyllys Ingersoll if ((result = Tspi_Policy_AssignToObject(hMigPolicy, *phKey))) { 1215*47e946e7SWyllys Ingersoll stlogit("Tspi_Policy_AssignToObject: 0x%0x - %s", 1216*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1217*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 1218*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hMigPolicy); 1219*47e946e7SWyllys Ingersoll return (result); 1220*47e946e7SWyllys Ingersoll } 1221*47e946e7SWyllys Ingersoll } 1222*47e946e7SWyllys Ingersoll 1223*47e946e7SWyllys Ingersoll if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) { 1224*47e946e7SWyllys Ingersoll if ((result = Tspi_SetAttribUint32(*phKey, 1225*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEY_INFO, 1226*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEYINFO_ENCSCHEME, 1227*47e946e7SWyllys Ingersoll TSS_ES_RSAESPKCSV15))) { 1228*47e946e7SWyllys Ingersoll stlogit("Tspi_SetAttribUint32: 0x%0x - %s", 1229*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1230*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 1231*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hMigPolicy); 1232*47e946e7SWyllys Ingersoll return (result); 1233*47e946e7SWyllys Ingersoll } 1234*47e946e7SWyllys Ingersoll 1235*47e946e7SWyllys Ingersoll if ((result = Tspi_SetAttribUint32(*phKey, 1236*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEY_INFO, 1237*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEYINFO_SIGSCHEME, 1238*47e946e7SWyllys Ingersoll TSS_SS_RSASSAPKCS1V15_DER))) { 1239*47e946e7SWyllys Ingersoll stlogit("Tspi_SetAttribUint32: 0x%0x - %s", 1240*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1241*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 1242*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hMigPolicy); 1243*47e946e7SWyllys Ingersoll return (result); 1244*47e946e7SWyllys Ingersoll } 1245*47e946e7SWyllys Ingersoll } 1246*47e946e7SWyllys Ingersoll 1247*47e946e7SWyllys Ingersoll if ((result = Tspi_Key_CreateKey(*phKey, hParentKey, 0))) { 1248*47e946e7SWyllys Ingersoll stlogit("Tspi_Key_CreateKey: 0x%0x - %s", 1249*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1250*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, *phKey); 1251*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hMigPolicy); 1252*47e946e7SWyllys Ingersoll } 1253*47e946e7SWyllys Ingersoll 1254*47e946e7SWyllys Ingersoll return (result); 1255*47e946e7SWyllys Ingersoll } 1256*47e946e7SWyllys Ingersoll 1257*47e946e7SWyllys Ingersoll static TSS_RESULT 1258*47e946e7SWyllys Ingersoll tss_change_auth( 1259*47e946e7SWyllys Ingersoll TSS_HCONTEXT hContext, 1260*47e946e7SWyllys Ingersoll TSS_HKEY hObjectToChange, TSS_HKEY hParentObject, 1261*47e946e7SWyllys Ingersoll TSS_UUID objUUID, TSS_UUID parentUUID, 1262*47e946e7SWyllys Ingersoll CK_CHAR *passHash) 1263*47e946e7SWyllys Ingersoll { 1264*47e946e7SWyllys Ingersoll TSS_RESULT result; 1265*47e946e7SWyllys Ingersoll TSS_HPOLICY hPolicy; 1266*47e946e7SWyllys Ingersoll TSS_HKEY oldkey; 1267*47e946e7SWyllys Ingersoll 1268*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_CreateObject(hContext, 1269*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy))) { 1270*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 1271*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1272*47e946e7SWyllys Ingersoll return (result); 1273*47e946e7SWyllys Ingersoll } 1274*47e946e7SWyllys Ingersoll 1275*47e946e7SWyllys Ingersoll if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, 1276*47e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH, passHash))) { 1277*47e946e7SWyllys Ingersoll stlogit("Tspi_Policy_SetSecret: 0x%0x - %s", 1278*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1279*47e946e7SWyllys Ingersoll return (result); 1280*47e946e7SWyllys Ingersoll } 1281*47e946e7SWyllys Ingersoll 1282*47e946e7SWyllys Ingersoll if ((result = Tspi_ChangeAuth(hObjectToChange, hParentObject, 1283*47e946e7SWyllys Ingersoll hPolicy))) { 1284*47e946e7SWyllys Ingersoll stlogit("Tspi_ChangeAuth: 0x%0x - %s", 1285*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1286*47e946e7SWyllys Ingersoll } 1287*47e946e7SWyllys Ingersoll /* 1288*47e946e7SWyllys Ingersoll * Update the PS key by unregistering the key UUID and then 1289*47e946e7SWyllys Ingersoll * re-registering with the same UUID. This forces the updated 1290*47e946e7SWyllys Ingersoll * auth data associated with the key to be stored in PS so 1291*47e946e7SWyllys Ingersoll * the new PIN can be used next time. 1292*47e946e7SWyllys Ingersoll */ 1293*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_UnregisterKey(hContext, 1294*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, objUUID, &oldkey))) 1295*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_UnregisterKey: 0x%0x - %s", 1296*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1297*47e946e7SWyllys Ingersoll 1298*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_RegisterKey(hContext, hObjectToChange, 1299*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, objUUID, TSS_PS_TYPE_USER, parentUUID))) 1300*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_RegisterKey: 0x%0x - %s", 1301*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1302*47e946e7SWyllys Ingersoll 1303*47e946e7SWyllys Ingersoll return (result); 1304*47e946e7SWyllys Ingersoll } 1305*47e946e7SWyllys Ingersoll 1306*47e946e7SWyllys Ingersoll static CK_RV 1307*47e946e7SWyllys Ingersoll token_generate_leaf_key(TSS_HCONTEXT hContext, 1308*47e946e7SWyllys Ingersoll int key_type, CK_CHAR_PTR passHash, TSS_HKEY *phKey) 1309*47e946e7SWyllys Ingersoll { 1310*47e946e7SWyllys Ingersoll CK_RV rc = CKR_FUNCTION_FAILED; 1311*47e946e7SWyllys Ingersoll TSS_RESULT result; 1312*47e946e7SWyllys Ingersoll TSS_HKEY hParentKey; 1313*47e946e7SWyllys Ingersoll TSS_UUID newuuid, parentUUID; 1314*47e946e7SWyllys Ingersoll char *keyid; 1315*47e946e7SWyllys Ingersoll TSS_FLAG initFlags = TSS_KEY_MIGRATABLE | 1316*47e946e7SWyllys Ingersoll TSS_KEY_TYPE_BIND | TSS_KEY_SIZE_2048 | TSS_KEY_AUTHORIZATION; 1317*47e946e7SWyllys Ingersoll 1318*47e946e7SWyllys Ingersoll switch (key_type) { 1319*47e946e7SWyllys Ingersoll case TPMTOK_PUBLIC_LEAF_KEY: 1320*47e946e7SWyllys Ingersoll hParentKey = hPublicRootKey; 1321*47e946e7SWyllys Ingersoll keyid = TPMTOK_PUBLIC_LEAF_KEY_ID; 1322*47e946e7SWyllys Ingersoll local_uuid_copy(&parentUUID, &publicRootKeyUUID); 1323*47e946e7SWyllys Ingersoll break; 1324*47e946e7SWyllys Ingersoll case TPMTOK_PRIVATE_LEAF_KEY: 1325*47e946e7SWyllys Ingersoll hParentKey = hPrivateRootKey; 1326*47e946e7SWyllys Ingersoll keyid = TPMTOK_PRIVATE_LEAF_KEY_ID; 1327*47e946e7SWyllys Ingersoll local_uuid_copy(&parentUUID, &privateRootKeyUUID); 1328*47e946e7SWyllys Ingersoll break; 1329*47e946e7SWyllys Ingersoll default: 1330*47e946e7SWyllys Ingersoll stlogit("Unknown key type 0x%0x", key_type); 1331*47e946e7SWyllys Ingersoll goto done; 1332*47e946e7SWyllys Ingersoll break; 1333*47e946e7SWyllys Ingersoll } 1334*47e946e7SWyllys Ingersoll 1335*47e946e7SWyllys Ingersoll if (result = tss_generate_key(hContext, initFlags, passHash, 1336*47e946e7SWyllys Ingersoll hParentKey, phKey)) { 1337*47e946e7SWyllys Ingersoll return (rc); 1338*47e946e7SWyllys Ingersoll } 1339*47e946e7SWyllys Ingersoll 1340*47e946e7SWyllys Ingersoll /* 1341*47e946e7SWyllys Ingersoll * - generate newUUID 1342*47e946e7SWyllys Ingersoll * - Tspi_Context_RegisterKey(hContext, hPrivateRootKey, 1343*47e946e7SWyllys Ingersoll * USER, newUUID, USER, parentUUID); 1344*47e946e7SWyllys Ingersoll * - store newUUID 1345*47e946e7SWyllys Ingersoll */ 1346*47e946e7SWyllys Ingersoll (void) local_uuid_generate(&newuuid); 1347*47e946e7SWyllys Ingersoll 1348*47e946e7SWyllys Ingersoll result = Tspi_Context_RegisterKey(hContext, *phKey, 1349*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, newuuid, 1350*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, parentUUID); 1351*47e946e7SWyllys Ingersoll if (result == TSS_SUCCESS) { 1352*47e946e7SWyllys Ingersoll int ret; 1353*47e946e7SWyllys Ingersoll /* 1354*47e946e7SWyllys Ingersoll * Add the UUID to the token UUID index. 1355*47e946e7SWyllys Ingersoll */ 1356*47e946e7SWyllys Ingersoll ret = add_uuid(keyid, &newuuid); 1357*47e946e7SWyllys Ingersoll 1358*47e946e7SWyllys Ingersoll if (ret) 1359*47e946e7SWyllys Ingersoll result = Tspi_Context_UnregisterKey(hContext, 1360*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, newuuid, phKey); 1361*47e946e7SWyllys Ingersoll else 1362*47e946e7SWyllys Ingersoll rc = CKR_OK; 1363*47e946e7SWyllys Ingersoll } 1364*47e946e7SWyllys Ingersoll 1365*47e946e7SWyllys Ingersoll done: 1366*47e946e7SWyllys Ingersoll return (rc); 1367*47e946e7SWyllys Ingersoll } 1368*47e946e7SWyllys Ingersoll 1369*47e946e7SWyllys Ingersoll /* 1370*47e946e7SWyllys Ingersoll * PINs are verified by attempting to bind/unbind random data using a 1371*47e946e7SWyllys Ingersoll * TPM resident key that has the PIN being tested assigned as its "secret". 1372*47e946e7SWyllys Ingersoll * If the PIN is incorrect, the unbind operation will fail. 1373*47e946e7SWyllys Ingersoll */ 1374*47e946e7SWyllys Ingersoll static CK_RV 1375*47e946e7SWyllys Ingersoll token_verify_pin(TSS_HCONTEXT hContext, TSS_HKEY hKey) 1376*47e946e7SWyllys Ingersoll { 1377*47e946e7SWyllys Ingersoll TSS_HENCDATA hEncData; 1378*47e946e7SWyllys Ingersoll UINT32 ulUnboundDataLen; 1379*47e946e7SWyllys Ingersoll BYTE *rgbUnboundData = NULL; 1380*47e946e7SWyllys Ingersoll BYTE rgbData[16]; 1381*47e946e7SWyllys Ingersoll TSS_RESULT result; 1382*47e946e7SWyllys Ingersoll CK_RV rc = CKR_FUNCTION_FAILED; 1383*47e946e7SWyllys Ingersoll 1384*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_CreateObject(hContext, 1385*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 1386*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 1387*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1388*47e946e7SWyllys Ingersoll goto done; 1389*47e946e7SWyllys Ingersoll } 1390*47e946e7SWyllys Ingersoll 1391*47e946e7SWyllys Ingersoll /* Use some random data */ 1392*47e946e7SWyllys Ingersoll rc = token_rng(hContext, rgbData, sizeof (rgbData)); 1393*47e946e7SWyllys Ingersoll if (rc) 1394*47e946e7SWyllys Ingersoll goto done; 1395*47e946e7SWyllys Ingersoll 1396*47e946e7SWyllys Ingersoll if ((result = Tspi_Data_Bind(hEncData, hKey, 1397*47e946e7SWyllys Ingersoll sizeof (rgbData), rgbData))) { 1398*47e946e7SWyllys Ingersoll stlogit("Tspi_Data_Bind: 0x%0x - %s", 1399*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1400*47e946e7SWyllys Ingersoll goto done; 1401*47e946e7SWyllys Ingersoll } 1402*47e946e7SWyllys Ingersoll 1403*47e946e7SWyllys Ingersoll /* unbind the junk data to test the key's auth data */ 1404*47e946e7SWyllys Ingersoll result = Tspi_Data_Unbind(hEncData, hKey, &ulUnboundDataLen, 1405*47e946e7SWyllys Ingersoll &rgbUnboundData); 1406*47e946e7SWyllys Ingersoll if (result == TSS_E_TSP_AUTHFAIL) { 1407*47e946e7SWyllys Ingersoll rc = CKR_PIN_INCORRECT; 1408*47e946e7SWyllys Ingersoll stlogit("Tspi_Data_Unbind: 0x%0x - %s", 1409*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1410*47e946e7SWyllys Ingersoll goto done; 1411*47e946e7SWyllys Ingersoll } else if (result != TSS_SUCCESS) { 1412*47e946e7SWyllys Ingersoll stlogit("Tspi_Data_Unbind: 0x%0x - %s", 1413*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1414*47e946e7SWyllys Ingersoll rc = CKR_FUNCTION_FAILED; 1415*47e946e7SWyllys Ingersoll goto done; 1416*47e946e7SWyllys Ingersoll } 1417*47e946e7SWyllys Ingersoll 1418*47e946e7SWyllys Ingersoll if (memcmp(rgbUnboundData, rgbData, ulUnboundDataLen)) 1419*47e946e7SWyllys Ingersoll rc = CKR_PIN_INCORRECT; 1420*47e946e7SWyllys Ingersoll else 1421*47e946e7SWyllys Ingersoll rc = CKR_OK; 1422*47e946e7SWyllys Ingersoll 1423*47e946e7SWyllys Ingersoll done: 1424*47e946e7SWyllys Ingersoll if (rgbUnboundData != NULL) 1425*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, rgbUnboundData); 1426*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hEncData); 1427*47e946e7SWyllys Ingersoll return (rc); 1428*47e946e7SWyllys Ingersoll } 1429*47e946e7SWyllys Ingersoll 1430*47e946e7SWyllys Ingersoll static CK_RV 1431*47e946e7SWyllys Ingersoll token_create_private_tree(TSS_HCONTEXT hContext, CK_BYTE *pinHash) 1432*47e946e7SWyllys Ingersoll { 1433*47e946e7SWyllys Ingersoll CK_RV rc; 1434*47e946e7SWyllys Ingersoll TSS_RESULT result; 1435*47e946e7SWyllys Ingersoll int ret; 1436*47e946e7SWyllys Ingersoll TSS_FLAG initFlags = TSS_KEY_SIZE_2048 | 1437*47e946e7SWyllys Ingersoll TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE; 1438*47e946e7SWyllys Ingersoll TSS_UUID SRK_UUID = TSS_UUID_SRK; 1439*47e946e7SWyllys Ingersoll TSS_HKEY hSRK; 1440*47e946e7SWyllys Ingersoll 1441*47e946e7SWyllys Ingersoll if (token_load_srk(hContext, &hSRK)) 1442*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1443*47e946e7SWyllys Ingersoll 1444*47e946e7SWyllys Ingersoll /* 1445*47e946e7SWyllys Ingersoll * - create UUID privateRootKeyUUID 1446*47e946e7SWyllys Ingersoll * - Tspi_Context_RegisterKey(hContext, hPrivateRootKey, 1447*47e946e7SWyllys Ingersoll * USER, privateRootKeyUUID, system, UUID_SRK); 1448*47e946e7SWyllys Ingersoll * - store privateRootKeyUUID in users private token space. 1449*47e946e7SWyllys Ingersoll */ 1450*47e946e7SWyllys Ingersoll if ((result = tss_generate_key(hContext, initFlags, NULL, hSRK, 1451*47e946e7SWyllys Ingersoll &hPrivateRootKey))) { 1452*47e946e7SWyllys Ingersoll return (result); 1453*47e946e7SWyllys Ingersoll } 1454*47e946e7SWyllys Ingersoll if (local_uuid_is_null(&privateRootKeyUUID)) 1455*47e946e7SWyllys Ingersoll local_uuid_generate(&privateRootKeyUUID); 1456*47e946e7SWyllys Ingersoll 1457*47e946e7SWyllys Ingersoll result = Tspi_Context_RegisterKey(hContext, hPrivateRootKey, 1458*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, privateRootKeyUUID, 1459*47e946e7SWyllys Ingersoll TSS_PS_TYPE_SYSTEM, SRK_UUID); 1460*47e946e7SWyllys Ingersoll 1461*47e946e7SWyllys Ingersoll if (result) { 1462*47e946e7SWyllys Ingersoll local_uuid_clear(&privateRootKeyUUID); 1463*47e946e7SWyllys Ingersoll return (result); 1464*47e946e7SWyllys Ingersoll } 1465*47e946e7SWyllys Ingersoll 1466*47e946e7SWyllys Ingersoll ret = add_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID, &privateRootKeyUUID); 1467*47e946e7SWyllys Ingersoll if (ret) { 1468*47e946e7SWyllys Ingersoll result = Tspi_Context_UnregisterKey(hContext, 1469*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, privateRootKeyUUID, 1470*47e946e7SWyllys Ingersoll &hPrivateRootKey); 1471*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1472*47e946e7SWyllys Ingersoll } 1473*47e946e7SWyllys Ingersoll 1474*47e946e7SWyllys Ingersoll if ((result = Tspi_Key_LoadKey(hPrivateRootKey, hSRK))) { 1475*47e946e7SWyllys Ingersoll stlogit("Tspi_Key_LoadKey: 0x%0x - %s", 1476*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1477*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hPrivateRootKey); 1478*47e946e7SWyllys Ingersoll 1479*47e946e7SWyllys Ingersoll (void) remove_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID); 1480*47e946e7SWyllys Ingersoll local_uuid_clear(&privateRootKeyUUID); 1481*47e946e7SWyllys Ingersoll 1482*47e946e7SWyllys Ingersoll hPrivateRootKey = NULL_HKEY; 1483*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1484*47e946e7SWyllys Ingersoll } 1485*47e946e7SWyllys Ingersoll 1486*47e946e7SWyllys Ingersoll 1487*47e946e7SWyllys Ingersoll /* generate the private leaf key */ 1488*47e946e7SWyllys Ingersoll if ((rc = token_generate_leaf_key(hContext, 1489*47e946e7SWyllys Ingersoll TPMTOK_PRIVATE_LEAF_KEY, 1490*47e946e7SWyllys Ingersoll pinHash, &hPrivateLeafKey))) { 1491*47e946e7SWyllys Ingersoll return (rc); 1492*47e946e7SWyllys Ingersoll } 1493*47e946e7SWyllys Ingersoll 1494*47e946e7SWyllys Ingersoll if ((result = Tspi_Key_LoadKey(hPrivateLeafKey, hPrivateRootKey))) { 1495*47e946e7SWyllys Ingersoll stlogit("Tspi_Key_LoadKey: 0x%0x - %s", 1496*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1497*47e946e7SWyllys Ingersoll 1498*47e946e7SWyllys Ingersoll (void) Tspi_Context_UnregisterKey(hContext, 1499*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, privateLeafKeyUUID, 1500*47e946e7SWyllys Ingersoll &hPrivateLeafKey); 1501*47e946e7SWyllys Ingersoll (void) remove_uuid(TPMTOK_PRIVATE_LEAF_KEY_ID); 1502*47e946e7SWyllys Ingersoll local_uuid_clear(&privateLeafKeyUUID); 1503*47e946e7SWyllys Ingersoll 1504*47e946e7SWyllys Ingersoll (void) Tspi_Context_UnregisterKey(hContext, 1505*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, privateRootKeyUUID, 1506*47e946e7SWyllys Ingersoll &hPrivateRootKey); 1507*47e946e7SWyllys Ingersoll (void) remove_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID); 1508*47e946e7SWyllys Ingersoll local_uuid_clear(&privateRootKeyUUID); 1509*47e946e7SWyllys Ingersoll 1510*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hPrivateRootKey); 1511*47e946e7SWyllys Ingersoll hPrivateRootKey = NULL_HKEY; 1512*47e946e7SWyllys Ingersoll 1513*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hPrivateLeafKey); 1514*47e946e7SWyllys Ingersoll hPrivateRootKey = NULL_HKEY; 1515*47e946e7SWyllys Ingersoll 1516*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1517*47e946e7SWyllys Ingersoll } 1518*47e946e7SWyllys Ingersoll return (rc); 1519*47e946e7SWyllys Ingersoll } 1520*47e946e7SWyllys Ingersoll 1521*47e946e7SWyllys Ingersoll static CK_RV 1522*47e946e7SWyllys Ingersoll token_create_public_tree(TSS_HCONTEXT hContext, CK_BYTE *pinHash) 1523*47e946e7SWyllys Ingersoll { 1524*47e946e7SWyllys Ingersoll CK_RV rc; 1525*47e946e7SWyllys Ingersoll TSS_RESULT result; 1526*47e946e7SWyllys Ingersoll int ret; 1527*47e946e7SWyllys Ingersoll TSS_FLAG initFlags = TSS_KEY_SIZE_2048 | 1528*47e946e7SWyllys Ingersoll TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE; 1529*47e946e7SWyllys Ingersoll TSS_UUID srk_uuid = TSS_UUID_SRK; 1530*47e946e7SWyllys Ingersoll TSS_HKEY hSRK; 1531*47e946e7SWyllys Ingersoll 1532*47e946e7SWyllys Ingersoll if (token_load_srk(hContext, &hSRK)) 1533*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1534*47e946e7SWyllys Ingersoll 1535*47e946e7SWyllys Ingersoll /* 1536*47e946e7SWyllys Ingersoll * - create publicRootKeyUUID 1537*47e946e7SWyllys Ingersoll * - Tspi_Context_RegisterKey(hContext, hPublicRootKey, 1538*47e946e7SWyllys Ingersoll * USER, publicRootKeyUUID, system, UUID_SRK); 1539*47e946e7SWyllys Ingersoll * - store publicRootKeyUUID in users private token space. 1540*47e946e7SWyllys Ingersoll */ 1541*47e946e7SWyllys Ingersoll if ((result = tss_generate_key(hContext, initFlags, NULL, hSRK, 1542*47e946e7SWyllys Ingersoll &hPublicRootKey))) { 1543*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1544*47e946e7SWyllys Ingersoll } 1545*47e946e7SWyllys Ingersoll if (local_uuid_is_null(&publicRootKeyUUID)) 1546*47e946e7SWyllys Ingersoll local_uuid_generate(&publicRootKeyUUID); 1547*47e946e7SWyllys Ingersoll 1548*47e946e7SWyllys Ingersoll result = Tspi_Context_RegisterKey(hContext, hPublicRootKey, 1549*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, publicRootKeyUUID, 1550*47e946e7SWyllys Ingersoll TSS_PS_TYPE_SYSTEM, srk_uuid); 1551*47e946e7SWyllys Ingersoll 1552*47e946e7SWyllys Ingersoll if (result) { 1553*47e946e7SWyllys Ingersoll local_uuid_clear(&publicRootKeyUUID); 1554*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1555*47e946e7SWyllys Ingersoll } 1556*47e946e7SWyllys Ingersoll 1557*47e946e7SWyllys Ingersoll ret = add_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID, &publicRootKeyUUID); 1558*47e946e7SWyllys Ingersoll if (ret) { 1559*47e946e7SWyllys Ingersoll result = Tspi_Context_UnregisterKey(hContext, 1560*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, publicRootKeyUUID, 1561*47e946e7SWyllys Ingersoll &hPublicRootKey); 1562*47e946e7SWyllys Ingersoll /* does result matter here? */ 1563*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1564*47e946e7SWyllys Ingersoll } 1565*47e946e7SWyllys Ingersoll 1566*47e946e7SWyllys Ingersoll /* Load the newly created publicRootKey into the TPM using the SRK */ 1567*47e946e7SWyllys Ingersoll if ((result = Tspi_Key_LoadKey(hPublicRootKey, hSRK))) { 1568*47e946e7SWyllys Ingersoll stlogit("Tspi_Key_LoadKey: 0x%x - %s", result, 1569*47e946e7SWyllys Ingersoll Trspi_Error_String(result)); 1570*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hPublicRootKey); 1571*47e946e7SWyllys Ingersoll hPublicRootKey = NULL_HKEY; 1572*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1573*47e946e7SWyllys Ingersoll } 1574*47e946e7SWyllys Ingersoll 1575*47e946e7SWyllys Ingersoll /* create the SO's leaf key */ 1576*47e946e7SWyllys Ingersoll if ((rc = token_generate_leaf_key(hContext, TPMTOK_PUBLIC_LEAF_KEY, 1577*47e946e7SWyllys Ingersoll pinHash, &hPublicLeafKey))) { 1578*47e946e7SWyllys Ingersoll return (rc); 1579*47e946e7SWyllys Ingersoll } 1580*47e946e7SWyllys Ingersoll 1581*47e946e7SWyllys Ingersoll if ((result = Tspi_Key_LoadKey(hPublicLeafKey, hPublicRootKey))) { 1582*47e946e7SWyllys Ingersoll stlogit("Tspi_Key_LoadKey: 0x%0x - %s", 1583*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 1584*47e946e7SWyllys Ingersoll 1585*47e946e7SWyllys Ingersoll /* Unregister keys and clear UUIDs */ 1586*47e946e7SWyllys Ingersoll (void) Tspi_Context_UnregisterKey(hContext, 1587*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, publicLeafKeyUUID, 1588*47e946e7SWyllys Ingersoll &hPublicLeafKey); 1589*47e946e7SWyllys Ingersoll (void) remove_uuid(TPMTOK_PUBLIC_LEAF_KEY_ID); 1590*47e946e7SWyllys Ingersoll 1591*47e946e7SWyllys Ingersoll (void) Tspi_Context_UnregisterKey(hContext, 1592*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, publicRootKeyUUID, 1593*47e946e7SWyllys Ingersoll &hPublicRootKey); 1594*47e946e7SWyllys Ingersoll (void) remove_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID); 1595*47e946e7SWyllys Ingersoll 1596*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hPublicRootKey); 1597*47e946e7SWyllys Ingersoll hPublicRootKey = NULL_HKEY; 1598*47e946e7SWyllys Ingersoll 1599*47e946e7SWyllys Ingersoll Tspi_Context_CloseObject(hContext, hPublicLeafKey); 1600*47e946e7SWyllys Ingersoll hPublicLeafKey = NULL_HKEY; 1601*47e946e7SWyllys Ingersoll 1602*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1603*47e946e7SWyllys Ingersoll } 1604*47e946e7SWyllys Ingersoll 1605*47e946e7SWyllys Ingersoll return (rc); 1606*47e946e7SWyllys Ingersoll } 1607*47e946e7SWyllys Ingersoll 1608*47e946e7SWyllys Ingersoll CK_RV 1609*47e946e7SWyllys Ingersoll token_specific_login( 1610*47e946e7SWyllys Ingersoll TSS_HCONTEXT hContext, 1611*47e946e7SWyllys Ingersoll CK_USER_TYPE userType, 1612*47e946e7SWyllys Ingersoll CK_CHAR_PTR pPin, 1613*47e946e7SWyllys Ingersoll CK_ULONG ulPinLen) 1614*47e946e7SWyllys Ingersoll { 1615*47e946e7SWyllys Ingersoll CK_RV rc; 1616*47e946e7SWyllys Ingersoll CK_BYTE hash_sha[SHA1_DIGEST_LENGTH]; 1617*47e946e7SWyllys Ingersoll TSS_RESULT result; 1618*47e946e7SWyllys Ingersoll TSS_HKEY hSRK; 1619*47e946e7SWyllys Ingersoll 1620*47e946e7SWyllys Ingersoll /* Make sure the SRK is loaded into the TPM */ 1621*47e946e7SWyllys Ingersoll if ((result = token_load_srk(hContext, &hSRK))) { 1622*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1623*47e946e7SWyllys Ingersoll } 1624*47e946e7SWyllys Ingersoll 1625*47e946e7SWyllys Ingersoll if ((rc = compute_sha(pPin, ulPinLen, hash_sha))) { 1626*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1627*47e946e7SWyllys Ingersoll } 1628*47e946e7SWyllys Ingersoll 1629*47e946e7SWyllys Ingersoll if (userType == CKU_USER) { 1630*47e946e7SWyllys Ingersoll /* 1631*47e946e7SWyllys Ingersoll * If the public root key doesn't exist yet, 1632*47e946e7SWyllys Ingersoll * the SO hasn't init'd the token. 1633*47e946e7SWyllys Ingersoll */ 1634*47e946e7SWyllys Ingersoll if ((result = token_load_public_root_key(hContext))) { 1635*47e946e7SWyllys Ingersoll if (result == TPM_E_DECRYPT_ERROR) { 1636*47e946e7SWyllys Ingersoll return (CKR_USER_PIN_NOT_INITIALIZED); 1637*47e946e7SWyllys Ingersoll } 1638*47e946e7SWyllys Ingersoll } 1639*47e946e7SWyllys Ingersoll 1640*47e946e7SWyllys Ingersoll /* 1641*47e946e7SWyllys Ingersoll * - find privateRootKeyUUID 1642*47e946e7SWyllys Ingersoll * - load by UUID (SRK parent) 1643*47e946e7SWyllys Ingersoll */ 1644*47e946e7SWyllys Ingersoll if (local_uuid_is_null(&privateRootKeyUUID) && 1645*47e946e7SWyllys Ingersoll find_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID, 1646*47e946e7SWyllys Ingersoll &privateRootKeyUUID)) { 1647*47e946e7SWyllys Ingersoll if (memcmp(hash_sha, 1648*47e946e7SWyllys Ingersoll default_user_pin_sha, 1649*47e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH)) 1650*47e946e7SWyllys Ingersoll return (CKR_PIN_INCORRECT); 1651*47e946e7SWyllys Ingersoll 1652*47e946e7SWyllys Ingersoll not_initialized = 1; 1653*47e946e7SWyllys Ingersoll return (CKR_OK); 1654*47e946e7SWyllys Ingersoll } 1655*47e946e7SWyllys Ingersoll 1656*47e946e7SWyllys Ingersoll if ((rc = verify_user_pin(hContext, hash_sha))) { 1657*47e946e7SWyllys Ingersoll return (rc); 1658*47e946e7SWyllys Ingersoll } 1659*47e946e7SWyllys Ingersoll 1660*47e946e7SWyllys Ingersoll (void) memcpy(current_user_pin_sha, hash_sha, 1661*47e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH); 1662*47e946e7SWyllys Ingersoll 1663*47e946e7SWyllys Ingersoll rc = load_private_token_objects(hContext); 1664*47e946e7SWyllys Ingersoll if (rc == CKR_OK) { 1665*47e946e7SWyllys Ingersoll (void) XProcLock(xproclock); 1666*47e946e7SWyllys Ingersoll global_shm->priv_loaded = TRUE; 1667*47e946e7SWyllys Ingersoll (void) XProcUnLock(xproclock); 1668*47e946e7SWyllys Ingersoll } 1669*47e946e7SWyllys Ingersoll } else { 1670*47e946e7SWyllys Ingersoll /* 1671*47e946e7SWyllys Ingersoll * SO login logic: 1672*47e946e7SWyllys Ingersoll * 1673*47e946e7SWyllys Ingersoll * - find publicRootKey UUID 1674*47e946e7SWyllys Ingersoll * - load by UUID wrap with hSRK from above 1675*47e946e7SWyllys Ingersoll */ 1676*47e946e7SWyllys Ingersoll if (local_uuid_is_null(&publicRootKeyUUID) && 1677*47e946e7SWyllys Ingersoll find_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID, 1678*47e946e7SWyllys Ingersoll &publicRootKeyUUID)) { 1679*47e946e7SWyllys Ingersoll if (memcmp(hash_sha, 1680*47e946e7SWyllys Ingersoll default_so_pin_sha, 1681*47e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH)) 1682*47e946e7SWyllys Ingersoll return (CKR_PIN_INCORRECT); 1683*47e946e7SWyllys Ingersoll 1684*47e946e7SWyllys Ingersoll not_initialized = 1; 1685*47e946e7SWyllys Ingersoll return (CKR_OK); 1686*47e946e7SWyllys Ingersoll 1687*47e946e7SWyllys Ingersoll } 1688*47e946e7SWyllys Ingersoll if (hPublicRootKey == NULL_HKEY) { 1689*47e946e7SWyllys Ingersoll result = tss_find_and_load_key( 1690*47e946e7SWyllys Ingersoll hContext, 1691*47e946e7SWyllys Ingersoll TPMTOK_PUBLIC_ROOT_KEY_ID, 1692*47e946e7SWyllys Ingersoll &publicRootKeyUUID, hSRK, NULL, 1693*47e946e7SWyllys Ingersoll &hPublicRootKey); 1694*47e946e7SWyllys Ingersoll 1695*47e946e7SWyllys Ingersoll if (result) 1696*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1697*47e946e7SWyllys Ingersoll } 1698*47e946e7SWyllys Ingersoll 1699*47e946e7SWyllys Ingersoll /* find, load the public leaf key */ 1700*47e946e7SWyllys Ingersoll if (hPublicLeafKey == NULL_HKEY) { 1701*47e946e7SWyllys Ingersoll result = tss_find_and_load_key( 1702*47e946e7SWyllys Ingersoll hContext, 1703*47e946e7SWyllys Ingersoll TPMTOK_PUBLIC_LEAF_KEY_ID, 1704*47e946e7SWyllys Ingersoll &publicLeafKeyUUID, hPublicRootKey, hash_sha, 1705*47e946e7SWyllys Ingersoll &hPublicLeafKey); 1706*47e946e7SWyllys Ingersoll if (result) 1707*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1708*47e946e7SWyllys Ingersoll } 1709*47e946e7SWyllys Ingersoll 1710*47e946e7SWyllys Ingersoll if ((rc = token_verify_pin(hContext, hPublicLeafKey))) { 1711*47e946e7SWyllys Ingersoll return (rc); 1712*47e946e7SWyllys Ingersoll } 1713*47e946e7SWyllys Ingersoll 1714*47e946e7SWyllys Ingersoll (void) memcpy(current_so_pin_sha, hash_sha, SHA1_DIGEST_LENGTH); 1715*47e946e7SWyllys Ingersoll } 1716*47e946e7SWyllys Ingersoll 1717*47e946e7SWyllys Ingersoll return (rc); 1718*47e946e7SWyllys Ingersoll } 1719*47e946e7SWyllys Ingersoll 1720*47e946e7SWyllys Ingersoll CK_RV 1721*47e946e7SWyllys Ingersoll token_specific_logout(TSS_HCONTEXT hContext) 1722*47e946e7SWyllys Ingersoll { 1723*47e946e7SWyllys Ingersoll if (hPrivateLeafKey != NULL_HKEY) { 1724*47e946e7SWyllys Ingersoll Tspi_Key_UnloadKey(hPrivateLeafKey); 1725*47e946e7SWyllys Ingersoll hPrivateLeafKey = NULL_HKEY; 1726*47e946e7SWyllys Ingersoll } else if (hPublicLeafKey != NULL_HKEY) { 1727*47e946e7SWyllys Ingersoll Tspi_Key_UnloadKey(hPublicLeafKey); 1728*47e946e7SWyllys Ingersoll hPublicLeafKey = NULL_HKEY; 1729*47e946e7SWyllys Ingersoll } 1730*47e946e7SWyllys Ingersoll 1731*47e946e7SWyllys Ingersoll local_uuid_clear(&publicRootKeyUUID); 1732*47e946e7SWyllys Ingersoll local_uuid_clear(&publicLeafKeyUUID); 1733*47e946e7SWyllys Ingersoll local_uuid_clear(&privateRootKeyUUID); 1734*47e946e7SWyllys Ingersoll local_uuid_clear(&privateLeafKeyUUID); 1735*47e946e7SWyllys Ingersoll 1736*47e946e7SWyllys Ingersoll (void) memset(current_so_pin_sha, 0, SHA1_DIGEST_LENGTH); 1737*47e946e7SWyllys Ingersoll (void) memset(current_user_pin_sha, 0, SHA1_DIGEST_LENGTH); 1738*47e946e7SWyllys Ingersoll 1739*47e946e7SWyllys Ingersoll (void) object_mgr_purge_private_token_objects(hContext); 1740*47e946e7SWyllys Ingersoll 1741*47e946e7SWyllys Ingersoll return (CKR_OK); 1742*47e946e7SWyllys Ingersoll } 1743*47e946e7SWyllys Ingersoll 1744*47e946e7SWyllys Ingersoll /*ARGSUSED*/ 1745*47e946e7SWyllys Ingersoll CK_RV 1746*47e946e7SWyllys Ingersoll token_specific_init_pin(TSS_HCONTEXT hContext, 1747*47e946e7SWyllys Ingersoll CK_CHAR_PTR pPin, CK_ULONG ulPinLen) 1748*47e946e7SWyllys Ingersoll { 1749*47e946e7SWyllys Ingersoll /* 1750*47e946e7SWyllys Ingersoll * Since the SO must log in before calling C_InitPIN, we will 1751*47e946e7SWyllys Ingersoll * be able to return (CKR_OK) automatically here. 1752*47e946e7SWyllys Ingersoll * This is because the USER key structure is created at the 1753*47e946e7SWyllys Ingersoll * time of her first login, not at C_InitPIN time. 1754*47e946e7SWyllys Ingersoll */ 1755*47e946e7SWyllys Ingersoll return (CKR_OK); 1756*47e946e7SWyllys Ingersoll } 1757*47e946e7SWyllys Ingersoll 1758*47e946e7SWyllys Ingersoll static CK_RV 1759*47e946e7SWyllys Ingersoll check_pin_properties(CK_USER_TYPE userType, CK_BYTE *pinHash, 1760*47e946e7SWyllys Ingersoll CK_ULONG ulPinLen) 1761*47e946e7SWyllys Ingersoll { 1762*47e946e7SWyllys Ingersoll /* make sure the new PIN is different */ 1763*47e946e7SWyllys Ingersoll if (userType == CKU_USER) { 1764*47e946e7SWyllys Ingersoll if (!memcmp(pinHash, default_user_pin_sha, 1765*47e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH)) { 1766*47e946e7SWyllys Ingersoll LogError1("new PIN must not be the default"); 1767*47e946e7SWyllys Ingersoll return (CKR_PIN_INVALID); 1768*47e946e7SWyllys Ingersoll } 1769*47e946e7SWyllys Ingersoll } else { 1770*47e946e7SWyllys Ingersoll if (!memcmp(pinHash, default_so_pin_sha, 1771*47e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH)) { 1772*47e946e7SWyllys Ingersoll LogError1("new PIN must not be the default"); 1773*47e946e7SWyllys Ingersoll return (CKR_PIN_INVALID); 1774*47e946e7SWyllys Ingersoll } 1775*47e946e7SWyllys Ingersoll } 1776*47e946e7SWyllys Ingersoll 1777*47e946e7SWyllys Ingersoll if (ulPinLen > MAX_PIN_LEN || ulPinLen < MIN_PIN_LEN) { 1778*47e946e7SWyllys Ingersoll LogError1("New PIN is out of size range"); 1779*47e946e7SWyllys Ingersoll return (CKR_PIN_LEN_RANGE); 1780*47e946e7SWyllys Ingersoll } 1781*47e946e7SWyllys Ingersoll 1782*47e946e7SWyllys Ingersoll return (CKR_OK); 1783*47e946e7SWyllys Ingersoll } 1784*47e946e7SWyllys Ingersoll 1785*47e946e7SWyllys Ingersoll /* 1786*47e946e7SWyllys Ingersoll * This function is called from set_pin only, where a non-logged-in public 1787*47e946e7SWyllys Ingersoll * session can provide the user pin which must be verified. This function 1788*47e946e7SWyllys Ingersoll * assumes that the pin has already been set once, so there's no migration 1789*47e946e7SWyllys Ingersoll * path option or checking of the default user pin. 1790*47e946e7SWyllys Ingersoll */ 1791*47e946e7SWyllys Ingersoll static CK_RV 1792*47e946e7SWyllys Ingersoll verify_user_pin(TSS_HCONTEXT hContext, CK_BYTE *hash_sha) 1793*47e946e7SWyllys Ingersoll { 1794*47e946e7SWyllys Ingersoll CK_RV rc; 1795*47e946e7SWyllys Ingersoll TSS_RESULT result; 1796*47e946e7SWyllys Ingersoll TSS_HKEY hSRK; 1797*47e946e7SWyllys Ingersoll 1798*47e946e7SWyllys Ingersoll if (token_load_srk(hContext, &hSRK)) 1799*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1800*47e946e7SWyllys Ingersoll 1801*47e946e7SWyllys Ingersoll /* 1802*47e946e7SWyllys Ingersoll * Verify the user by loading the privateLeafKey 1803*47e946e7SWyllys Ingersoll * into the TPM (if it's not already) and then 1804*47e946e7SWyllys Ingersoll * call the verify_pin operation. 1805*47e946e7SWyllys Ingersoll * 1806*47e946e7SWyllys Ingersoll * The hashed PIN is assigned to the private leaf key. 1807*47e946e7SWyllys Ingersoll * If it is incorrect (not the same as the one originally 1808*47e946e7SWyllys Ingersoll * used when the key was created), the verify operation 1809*47e946e7SWyllys Ingersoll * will fail. 1810*47e946e7SWyllys Ingersoll */ 1811*47e946e7SWyllys Ingersoll if (hPrivateRootKey == NULL_HKEY) { 1812*47e946e7SWyllys Ingersoll result = tss_find_and_load_key( 1813*47e946e7SWyllys Ingersoll hContext, 1814*47e946e7SWyllys Ingersoll TPMTOK_PRIVATE_ROOT_KEY_ID, 1815*47e946e7SWyllys Ingersoll &privateRootKeyUUID, hSRK, NULL, &hPrivateRootKey); 1816*47e946e7SWyllys Ingersoll if (result) 1817*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1818*47e946e7SWyllys Ingersoll } 1819*47e946e7SWyllys Ingersoll 1820*47e946e7SWyllys Ingersoll if (hPrivateLeafKey == NULL_HKEY) { 1821*47e946e7SWyllys Ingersoll result = tss_find_and_load_key( 1822*47e946e7SWyllys Ingersoll hContext, 1823*47e946e7SWyllys Ingersoll TPMTOK_PRIVATE_LEAF_KEY_ID, 1824*47e946e7SWyllys Ingersoll &privateLeafKeyUUID, hPrivateRootKey, hash_sha, 1825*47e946e7SWyllys Ingersoll &hPrivateLeafKey); 1826*47e946e7SWyllys Ingersoll 1827*47e946e7SWyllys Ingersoll if (result) 1828*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1829*47e946e7SWyllys Ingersoll } 1830*47e946e7SWyllys Ingersoll 1831*47e946e7SWyllys Ingersoll /* 1832*47e946e7SWyllys Ingersoll * Verify that the PIN is correct by attempting to wrap/unwrap some 1833*47e946e7SWyllys Ingersoll * random data. 1834*47e946e7SWyllys Ingersoll */ 1835*47e946e7SWyllys Ingersoll if ((rc = token_verify_pin(hContext, hPrivateLeafKey))) { 1836*47e946e7SWyllys Ingersoll return (rc); 1837*47e946e7SWyllys Ingersoll } 1838*47e946e7SWyllys Ingersoll 1839*47e946e7SWyllys Ingersoll return (CKR_OK); 1840*47e946e7SWyllys Ingersoll } 1841*47e946e7SWyllys Ingersoll 1842*47e946e7SWyllys Ingersoll CK_RV 1843*47e946e7SWyllys Ingersoll token_specific_set_pin(ST_SESSION_HANDLE session, 1844*47e946e7SWyllys Ingersoll CK_CHAR_PTR pOldPin, CK_ULONG ulOldPinLen, 1845*47e946e7SWyllys Ingersoll CK_CHAR_PTR pNewPin, CK_ULONG ulNewPinLen) 1846*47e946e7SWyllys Ingersoll { 1847*47e946e7SWyllys Ingersoll SESSION *sess = session_mgr_find(session.sessionh); 1848*47e946e7SWyllys Ingersoll CK_BYTE oldpin_hash[SHA1_DIGEST_LENGTH]; 1849*47e946e7SWyllys Ingersoll CK_BYTE newpin_hash[SHA1_DIGEST_LENGTH]; 1850*47e946e7SWyllys Ingersoll CK_RV rc; 1851*47e946e7SWyllys Ingersoll TSS_HKEY hSRK; 1852*47e946e7SWyllys Ingersoll 1853*47e946e7SWyllys Ingersoll if (!sess) { 1854*47e946e7SWyllys Ingersoll return (CKR_SESSION_HANDLE_INVALID); 1855*47e946e7SWyllys Ingersoll } 1856*47e946e7SWyllys Ingersoll 1857*47e946e7SWyllys Ingersoll if ((rc = compute_sha(pOldPin, ulOldPinLen, oldpin_hash))) { 1858*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1859*47e946e7SWyllys Ingersoll } 1860*47e946e7SWyllys Ingersoll if ((rc = compute_sha(pNewPin, ulNewPinLen, newpin_hash))) { 1861*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1862*47e946e7SWyllys Ingersoll } 1863*47e946e7SWyllys Ingersoll 1864*47e946e7SWyllys Ingersoll if (token_load_srk(sess->hContext, &hSRK)) { 1865*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1866*47e946e7SWyllys Ingersoll } 1867*47e946e7SWyllys Ingersoll 1868*47e946e7SWyllys Ingersoll /* 1869*47e946e7SWyllys Ingersoll * From the PKCS#11 2.20 spec: "C_SetPIN modifies the PIN of 1870*47e946e7SWyllys Ingersoll * the user that is currently logged in, or the CKU_USER PIN 1871*47e946e7SWyllys Ingersoll * if the session is not logged in." 1872*47e946e7SWyllys Ingersoll * A non R/W session fails with CKR_SESSION_READ_ONLY. 1873*47e946e7SWyllys Ingersoll */ 1874*47e946e7SWyllys Ingersoll if (sess->session_info.state == CKS_RW_USER_FUNCTIONS || 1875*47e946e7SWyllys Ingersoll sess->session_info.state == CKS_RW_PUBLIC_SESSION) { 1876*47e946e7SWyllys Ingersoll if (not_initialized) { 1877*47e946e7SWyllys Ingersoll if (memcmp(oldpin_hash, default_user_pin_sha, 1878*47e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH)) { 1879*47e946e7SWyllys Ingersoll return (CKR_PIN_INCORRECT); 1880*47e946e7SWyllys Ingersoll } 1881*47e946e7SWyllys Ingersoll 1882*47e946e7SWyllys Ingersoll if ((rc = check_pin_properties(CKU_USER, newpin_hash, 1883*47e946e7SWyllys Ingersoll ulNewPinLen))) { 1884*47e946e7SWyllys Ingersoll return (rc); 1885*47e946e7SWyllys Ingersoll } 1886*47e946e7SWyllys Ingersoll 1887*47e946e7SWyllys Ingersoll if ((rc = token_create_private_tree(sess->hContext, 1888*47e946e7SWyllys Ingersoll newpin_hash))) { 1889*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1890*47e946e7SWyllys Ingersoll } 1891*47e946e7SWyllys Ingersoll 1892*47e946e7SWyllys Ingersoll nv_token_data->token_info.flags &= 1893*47e946e7SWyllys Ingersoll ~(CKF_USER_PIN_TO_BE_CHANGED); 1894*47e946e7SWyllys Ingersoll nv_token_data->token_info.flags |= 1895*47e946e7SWyllys Ingersoll CKF_USER_PIN_INITIALIZED; 1896*47e946e7SWyllys Ingersoll 1897*47e946e7SWyllys Ingersoll nv_token_data->token_info.flags &= 1898*47e946e7SWyllys Ingersoll ~(CKF_USER_PIN_TO_BE_CHANGED); 1899*47e946e7SWyllys Ingersoll nv_token_data->token_info.flags |= 1900*47e946e7SWyllys Ingersoll CKF_USER_PIN_INITIALIZED; 1901*47e946e7SWyllys Ingersoll 1902*47e946e7SWyllys Ingersoll return (save_token_data(nv_token_data)); 1903*47e946e7SWyllys Ingersoll } 1904*47e946e7SWyllys Ingersoll 1905*47e946e7SWyllys Ingersoll if (sess->session_info.state == CKS_RW_USER_FUNCTIONS) { 1906*47e946e7SWyllys Ingersoll /* if we're already logged in, just verify the hash */ 1907*47e946e7SWyllys Ingersoll if (memcmp(current_user_pin_sha, oldpin_hash, 1908*47e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH)) { 1909*47e946e7SWyllys Ingersoll return (CKR_PIN_INCORRECT); 1910*47e946e7SWyllys Ingersoll } 1911*47e946e7SWyllys Ingersoll } else { 1912*47e946e7SWyllys Ingersoll if ((rc = verify_user_pin(sess->hContext, 1913*47e946e7SWyllys Ingersoll oldpin_hash))) { 1914*47e946e7SWyllys Ingersoll return (rc); 1915*47e946e7SWyllys Ingersoll } 1916*47e946e7SWyllys Ingersoll } 1917*47e946e7SWyllys Ingersoll 1918*47e946e7SWyllys Ingersoll if ((rc = check_pin_properties(CKU_USER, newpin_hash, 1919*47e946e7SWyllys Ingersoll ulNewPinLen))) 1920*47e946e7SWyllys Ingersoll return (rc); 1921*47e946e7SWyllys Ingersoll 1922*47e946e7SWyllys Ingersoll /* change the auth on the TSS object */ 1923*47e946e7SWyllys Ingersoll if (tss_change_auth(sess->hContext, 1924*47e946e7SWyllys Ingersoll hPrivateLeafKey, hPrivateRootKey, 1925*47e946e7SWyllys Ingersoll privateLeafKeyUUID, privateRootKeyUUID, 1926*47e946e7SWyllys Ingersoll newpin_hash)) 1927*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1928*47e946e7SWyllys Ingersoll 1929*47e946e7SWyllys Ingersoll } else if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) { 1930*47e946e7SWyllys Ingersoll if (not_initialized) { 1931*47e946e7SWyllys Ingersoll if (memcmp(default_so_pin_sha, oldpin_hash, 1932*47e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH)) 1933*47e946e7SWyllys Ingersoll return (CKR_PIN_INCORRECT); 1934*47e946e7SWyllys Ingersoll 1935*47e946e7SWyllys Ingersoll if ((rc = check_pin_properties(CKU_SO, 1936*47e946e7SWyllys Ingersoll newpin_hash, ulNewPinLen))) 1937*47e946e7SWyllys Ingersoll return (rc); 1938*47e946e7SWyllys Ingersoll 1939*47e946e7SWyllys Ingersoll if ((rc = token_create_public_tree(sess->hContext, 1940*47e946e7SWyllys Ingersoll newpin_hash))) 1941*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1942*47e946e7SWyllys Ingersoll 1943*47e946e7SWyllys Ingersoll nv_token_data->token_info.flags &= 1944*47e946e7SWyllys Ingersoll ~(CKF_SO_PIN_TO_BE_CHANGED); 1945*47e946e7SWyllys Ingersoll 1946*47e946e7SWyllys Ingersoll return (save_token_data(nv_token_data)); 1947*47e946e7SWyllys Ingersoll } 1948*47e946e7SWyllys Ingersoll 1949*47e946e7SWyllys Ingersoll if (memcmp(current_so_pin_sha, oldpin_hash, 1950*47e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH)) 1951*47e946e7SWyllys Ingersoll return (CKR_PIN_INCORRECT); 1952*47e946e7SWyllys Ingersoll 1953*47e946e7SWyllys Ingersoll if ((rc = check_pin_properties(CKU_SO, newpin_hash, 1954*47e946e7SWyllys Ingersoll ulNewPinLen))) 1955*47e946e7SWyllys Ingersoll return (rc); 1956*47e946e7SWyllys Ingersoll 1957*47e946e7SWyllys Ingersoll /* change auth on the SO's leaf key */ 1958*47e946e7SWyllys Ingersoll if (tss_change_auth(sess->hContext, 1959*47e946e7SWyllys Ingersoll hPublicLeafKey, hPublicRootKey, 1960*47e946e7SWyllys Ingersoll publicLeafKeyUUID, publicRootKeyUUID, 1961*47e946e7SWyllys Ingersoll newpin_hash)) 1962*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1963*47e946e7SWyllys Ingersoll 1964*47e946e7SWyllys Ingersoll } else { 1965*47e946e7SWyllys Ingersoll rc = CKR_SESSION_READ_ONLY; 1966*47e946e7SWyllys Ingersoll } 1967*47e946e7SWyllys Ingersoll 1968*47e946e7SWyllys Ingersoll return (rc); 1969*47e946e7SWyllys Ingersoll } 1970*47e946e7SWyllys Ingersoll 1971*47e946e7SWyllys Ingersoll /* only called at token init time */ 1972*47e946e7SWyllys Ingersoll CK_RV 1973*47e946e7SWyllys Ingersoll token_specific_verify_so_pin(TSS_HCONTEXT hContext, CK_CHAR_PTR pPin, 1974*47e946e7SWyllys Ingersoll CK_ULONG ulPinLen) 1975*47e946e7SWyllys Ingersoll { 1976*47e946e7SWyllys Ingersoll CK_BYTE hash_sha[SHA1_DIGEST_LENGTH]; 1977*47e946e7SWyllys Ingersoll CK_RV rc; 1978*47e946e7SWyllys Ingersoll TSS_RESULT result; 1979*47e946e7SWyllys Ingersoll TSS_HKEY hSRK; 1980*47e946e7SWyllys Ingersoll 1981*47e946e7SWyllys Ingersoll if ((rc = compute_sha(pPin, ulPinLen, hash_sha))) { 1982*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1983*47e946e7SWyllys Ingersoll } 1984*47e946e7SWyllys Ingersoll if ((rc = token_load_srk(hContext, &hSRK))) { 1985*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 1986*47e946e7SWyllys Ingersoll } 1987*47e946e7SWyllys Ingersoll 1988*47e946e7SWyllys Ingersoll /* 1989*47e946e7SWyllys Ingersoll * TRYME INSTEAD: 1990*47e946e7SWyllys Ingersoll * - find publicRootKeyUUID 1991*47e946e7SWyllys Ingersoll * - Load publicRootKey by UUID (SRK parent) 1992*47e946e7SWyllys Ingersoll * - find publicLeafKeyUUID 1993*47e946e7SWyllys Ingersoll * - Load publicLeafKey by UUID (publicRootKey parent) 1994*47e946e7SWyllys Ingersoll * - set password policy on publicLeafKey 1995*47e946e7SWyllys Ingersoll */ 1996*47e946e7SWyllys Ingersoll if (local_uuid_is_null(&publicRootKeyUUID) && 1997*47e946e7SWyllys Ingersoll find_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID, &publicRootKeyUUID)) { 1998*47e946e7SWyllys Ingersoll /* 1999*47e946e7SWyllys Ingersoll * The SO hasn't set her PIN yet, compare the 2000*47e946e7SWyllys Ingersoll * login pin with the hard-coded value. 2001*47e946e7SWyllys Ingersoll */ 2002*47e946e7SWyllys Ingersoll if (memcmp(default_so_pin_sha, hash_sha, 2003*47e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH)) { 2004*47e946e7SWyllys Ingersoll return (CKR_PIN_INCORRECT); 2005*47e946e7SWyllys Ingersoll } 2006*47e946e7SWyllys Ingersoll return (CKR_OK); 2007*47e946e7SWyllys Ingersoll } 2008*47e946e7SWyllys Ingersoll 2009*47e946e7SWyllys Ingersoll result = Tspi_Context_GetKeyByUUID(hContext, 2010*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, publicRootKeyUUID, &hPublicRootKey); 2011*47e946e7SWyllys Ingersoll 2012*47e946e7SWyllys Ingersoll if (result) 2013*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2014*47e946e7SWyllys Ingersoll 2015*47e946e7SWyllys Ingersoll result = Tspi_Key_LoadKey(hPublicRootKey, hSRK); 2016*47e946e7SWyllys Ingersoll if (result) 2017*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2018*47e946e7SWyllys Ingersoll 2019*47e946e7SWyllys Ingersoll if (local_uuid_is_null(&publicLeafKeyUUID) && 2020*47e946e7SWyllys Ingersoll find_uuid(TPMTOK_PUBLIC_LEAF_KEY_ID, &publicLeafKeyUUID)) 2021*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2022*47e946e7SWyllys Ingersoll 2023*47e946e7SWyllys Ingersoll result = Tspi_Context_GetKeyByUUID(hContext, 2024*47e946e7SWyllys Ingersoll TSS_PS_TYPE_USER, publicLeafKeyUUID, &hPublicLeafKey); 2025*47e946e7SWyllys Ingersoll if (result) 2026*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2027*47e946e7SWyllys Ingersoll 2028*47e946e7SWyllys Ingersoll result = tss_assign_secret_key_policy(hContext, hPublicLeafKey, 2029*47e946e7SWyllys Ingersoll hash_sha); 2030*47e946e7SWyllys Ingersoll if (result) 2031*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2032*47e946e7SWyllys Ingersoll 2033*47e946e7SWyllys Ingersoll result = Tspi_Key_LoadKey(hPublicLeafKey, hPublicRootKey); 2034*47e946e7SWyllys Ingersoll if (result) 2035*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2036*47e946e7SWyllys Ingersoll 2037*47e946e7SWyllys Ingersoll /* If the hash given is wrong, the verify will fail */ 2038*47e946e7SWyllys Ingersoll if ((rc = token_verify_pin(hContext, hPublicLeafKey))) { 2039*47e946e7SWyllys Ingersoll return (rc); 2040*47e946e7SWyllys Ingersoll } 2041*47e946e7SWyllys Ingersoll 2042*47e946e7SWyllys Ingersoll return (CKR_OK); 2043*47e946e7SWyllys Ingersoll } 2044*47e946e7SWyllys Ingersoll 2045*47e946e7SWyllys Ingersoll CK_RV 2046*47e946e7SWyllys Ingersoll token_specific_final() 2047*47e946e7SWyllys Ingersoll { 2048*47e946e7SWyllys Ingersoll return (CKR_OK); 2049*47e946e7SWyllys Ingersoll } 2050*47e946e7SWyllys Ingersoll 2051*47e946e7SWyllys Ingersoll /* 2052*47e946e7SWyllys Ingersoll * Wrap the 20 bytes of auth data and store in an attribute of the two 2053*47e946e7SWyllys Ingersoll * keys. 2054*47e946e7SWyllys Ingersoll */ 2055*47e946e7SWyllys Ingersoll static CK_RV 2056*47e946e7SWyllys Ingersoll token_wrap_auth_data(TSS_HCONTEXT hContext, 2057*47e946e7SWyllys Ingersoll CK_BYTE *authData, TEMPLATE *publ_tmpl, 2058*47e946e7SWyllys Ingersoll TEMPLATE *priv_tmpl) 2059*47e946e7SWyllys Ingersoll { 2060*47e946e7SWyllys Ingersoll CK_RV rc; 2061*47e946e7SWyllys Ingersoll CK_ATTRIBUTE *new_attr; 2062*47e946e7SWyllys Ingersoll 2063*47e946e7SWyllys Ingersoll TSS_RESULT ret; 2064*47e946e7SWyllys Ingersoll TSS_HKEY hParentKey; 2065*47e946e7SWyllys Ingersoll TSS_HENCDATA hEncData; 2066*47e946e7SWyllys Ingersoll BYTE *blob; 2067*47e946e7SWyllys Ingersoll UINT32 blob_size; 2068*47e946e7SWyllys Ingersoll 2069*47e946e7SWyllys Ingersoll if ((hPrivateLeafKey == NULL_HKEY) && (hPublicLeafKey == NULL_HKEY)) { 2070*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2071*47e946e7SWyllys Ingersoll } else if (hPublicLeafKey != NULL_HKEY) { 2072*47e946e7SWyllys Ingersoll hParentKey = hPublicLeafKey; 2073*47e946e7SWyllys Ingersoll } else { 2074*47e946e7SWyllys Ingersoll hParentKey = hPrivateLeafKey; 2075*47e946e7SWyllys Ingersoll } 2076*47e946e7SWyllys Ingersoll 2077*47e946e7SWyllys Ingersoll /* create the encrypted data object */ 2078*47e946e7SWyllys Ingersoll if ((ret = Tspi_Context_CreateObject(hContext, 2079*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 2080*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2081*47e946e7SWyllys Ingersoll ret, Trspi_Error_String(ret)); 2082*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2083*47e946e7SWyllys Ingersoll } 2084*47e946e7SWyllys Ingersoll 2085*47e946e7SWyllys Ingersoll if ((ret = Tspi_Data_Bind(hEncData, hParentKey, SHA1_DIGEST_LENGTH, 2086*47e946e7SWyllys Ingersoll authData))) { 2087*47e946e7SWyllys Ingersoll stlogit("Tspi_Data_Bind: 0x%0x - %s", 2088*47e946e7SWyllys Ingersoll ret, Trspi_Error_String(ret)); 2089*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2090*47e946e7SWyllys Ingersoll } 2091*47e946e7SWyllys Ingersoll 2092*47e946e7SWyllys Ingersoll /* pull the encrypted data out of the encrypted data object */ 2093*47e946e7SWyllys Ingersoll if ((ret = Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB, 2094*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_ENCDATABLOB_BLOB, &blob_size, &blob))) { 2095*47e946e7SWyllys Ingersoll stlogit("Tspi_SetAttribData: 0x%0x - %s", 2096*47e946e7SWyllys Ingersoll ret, Trspi_Error_String(ret)); 2097*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2098*47e946e7SWyllys Ingersoll } 2099*47e946e7SWyllys Ingersoll 2100*47e946e7SWyllys Ingersoll if ((rc = build_attribute(CKA_ENC_AUTHDATA, blob, blob_size, 2101*47e946e7SWyllys Ingersoll &new_attr))) { 2102*47e946e7SWyllys Ingersoll return (rc); 2103*47e946e7SWyllys Ingersoll } 2104*47e946e7SWyllys Ingersoll (void) template_update_attribute(publ_tmpl, new_attr); 2105*47e946e7SWyllys Ingersoll 2106*47e946e7SWyllys Ingersoll if ((rc = build_attribute(CKA_ENC_AUTHDATA, blob, 2107*47e946e7SWyllys Ingersoll blob_size, &new_attr))) { 2108*47e946e7SWyllys Ingersoll return (rc); 2109*47e946e7SWyllys Ingersoll } 2110*47e946e7SWyllys Ingersoll (void) template_update_attribute(priv_tmpl, new_attr); 2111*47e946e7SWyllys Ingersoll 2112*47e946e7SWyllys Ingersoll return (rc); 2113*47e946e7SWyllys Ingersoll } 2114*47e946e7SWyllys Ingersoll 2115*47e946e7SWyllys Ingersoll static CK_RV 2116*47e946e7SWyllys Ingersoll token_unwrap_auth_data(TSS_HCONTEXT hContext, CK_BYTE *encAuthData, 2117*47e946e7SWyllys Ingersoll CK_ULONG encAuthDataLen, TSS_HKEY hKey, 2118*47e946e7SWyllys Ingersoll BYTE **authData) 2119*47e946e7SWyllys Ingersoll { 2120*47e946e7SWyllys Ingersoll TSS_RESULT result; 2121*47e946e7SWyllys Ingersoll TSS_HENCDATA hEncData; 2122*47e946e7SWyllys Ingersoll BYTE *buf; 2123*47e946e7SWyllys Ingersoll UINT32 buf_size; 2124*47e946e7SWyllys Ingersoll 2125*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_CreateObject(hContext, 2126*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 2127*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2128*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2129*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2130*47e946e7SWyllys Ingersoll } 2131*47e946e7SWyllys Ingersoll 2132*47e946e7SWyllys Ingersoll if ((result = Tspi_SetAttribData(hEncData, 2133*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB, 2134*47e946e7SWyllys Ingersoll encAuthDataLen, encAuthData))) { 2135*47e946e7SWyllys Ingersoll stlogit("Tspi_SetAttribData: 0x%0x - %s", 2136*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2137*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2138*47e946e7SWyllys Ingersoll } 2139*47e946e7SWyllys Ingersoll 2140*47e946e7SWyllys Ingersoll /* unbind the data, receiving the plaintext back */ 2141*47e946e7SWyllys Ingersoll if ((result = Tspi_Data_Unbind(hEncData, hKey, &buf_size, &buf))) { 2142*47e946e7SWyllys Ingersoll stlogit("Tspi_Data_Unbind: 0x%0x - %s", 2143*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2144*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2145*47e946e7SWyllys Ingersoll } 2146*47e946e7SWyllys Ingersoll 2147*47e946e7SWyllys Ingersoll if (buf_size != SHA1_DIGEST_LENGTH) { 2148*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2149*47e946e7SWyllys Ingersoll } 2150*47e946e7SWyllys Ingersoll 2151*47e946e7SWyllys Ingersoll *authData = buf; 2152*47e946e7SWyllys Ingersoll 2153*47e946e7SWyllys Ingersoll return (CKR_OK); 2154*47e946e7SWyllys Ingersoll } 2155*47e946e7SWyllys Ingersoll 2156*47e946e7SWyllys Ingersoll CK_RV 2157*47e946e7SWyllys Ingersoll token_specific_rsa_generate_keypair( 2158*47e946e7SWyllys Ingersoll TSS_HCONTEXT hContext, 2159*47e946e7SWyllys Ingersoll TEMPLATE *publ_tmpl, 2160*47e946e7SWyllys Ingersoll TEMPLATE *priv_tmpl) 2161*47e946e7SWyllys Ingersoll { 2162*47e946e7SWyllys Ingersoll CK_ATTRIBUTE *attr = NULL; 2163*47e946e7SWyllys Ingersoll CK_ULONG mod_bits = 0; 2164*47e946e7SWyllys Ingersoll CK_BBOOL flag; 2165*47e946e7SWyllys Ingersoll CK_RV rc; 2166*47e946e7SWyllys Ingersoll 2167*47e946e7SWyllys Ingersoll TSS_FLAG initFlags = 0; 2168*47e946e7SWyllys Ingersoll BYTE authHash[SHA1_DIGEST_LENGTH]; 2169*47e946e7SWyllys Ingersoll BYTE *authData = NULL; 2170*47e946e7SWyllys Ingersoll TSS_HKEY hKey = NULL_HKEY; 2171*47e946e7SWyllys Ingersoll TSS_HKEY hParentKey = NULL_HKEY; 2172*47e946e7SWyllys Ingersoll TSS_RESULT result; 2173*47e946e7SWyllys Ingersoll UINT32 ulBlobLen; 2174*47e946e7SWyllys Ingersoll BYTE *rgbBlob; 2175*47e946e7SWyllys Ingersoll 2176*47e946e7SWyllys Ingersoll /* Make sure the public exponent is usable */ 2177*47e946e7SWyllys Ingersoll if ((util_check_public_exponent(publ_tmpl))) { 2178*47e946e7SWyllys Ingersoll return (CKR_TEMPLATE_INCONSISTENT); 2179*47e946e7SWyllys Ingersoll } 2180*47e946e7SWyllys Ingersoll 2181*47e946e7SWyllys Ingersoll flag = template_attribute_find(publ_tmpl, CKA_MODULUS_BITS, &attr); 2182*47e946e7SWyllys Ingersoll if (!flag) { 2183*47e946e7SWyllys Ingersoll return (CKR_TEMPLATE_INCOMPLETE); 2184*47e946e7SWyllys Ingersoll } 2185*47e946e7SWyllys Ingersoll mod_bits = *(CK_ULONG *)attr->pValue; 2186*47e946e7SWyllys Ingersoll 2187*47e946e7SWyllys Ingersoll if ((initFlags = util_get_keysize_flag(mod_bits)) == 0) { 2188*47e946e7SWyllys Ingersoll return (CKR_KEY_SIZE_RANGE); 2189*47e946e7SWyllys Ingersoll } 2190*47e946e7SWyllys Ingersoll 2191*47e946e7SWyllys Ingersoll /* 2192*47e946e7SWyllys Ingersoll * If we're not logged in, hPrivateLeafKey and hPublicLeafKey 2193*47e946e7SWyllys Ingersoll * should be NULL. 2194*47e946e7SWyllys Ingersoll */ 2195*47e946e7SWyllys Ingersoll if ((hPrivateLeafKey == NULL_HKEY) && 2196*47e946e7SWyllys Ingersoll (hPublicLeafKey == NULL_HKEY)) { 2197*47e946e7SWyllys Ingersoll /* public session, wrap key with the PRK */ 2198*47e946e7SWyllys Ingersoll initFlags |= TSS_KEY_TYPE_LEGACY | 2199*47e946e7SWyllys Ingersoll TSS_KEY_NO_AUTHORIZATION | TSS_KEY_MIGRATABLE; 2200*47e946e7SWyllys Ingersoll 2201*47e946e7SWyllys Ingersoll if ((result = token_load_public_root_key(hContext))) { 2202*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2203*47e946e7SWyllys Ingersoll } 2204*47e946e7SWyllys Ingersoll 2205*47e946e7SWyllys Ingersoll hParentKey = hPublicRootKey; 2206*47e946e7SWyllys Ingersoll } else if (hPrivateLeafKey != NULL_HKEY) { 2207*47e946e7SWyllys Ingersoll /* logged in USER session */ 2208*47e946e7SWyllys Ingersoll initFlags |= TSS_KEY_TYPE_LEGACY | 2209*47e946e7SWyllys Ingersoll TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE; 2210*47e946e7SWyllys Ingersoll 2211*47e946e7SWyllys Ingersoll /* get a random SHA1 hash for the auth data */ 2212*47e946e7SWyllys Ingersoll if ((rc = token_rng(hContext, authHash, SHA1_DIGEST_LENGTH))) { 2213*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2214*47e946e7SWyllys Ingersoll } 2215*47e946e7SWyllys Ingersoll 2216*47e946e7SWyllys Ingersoll authData = authHash; 2217*47e946e7SWyllys Ingersoll hParentKey = hPrivateRootKey; 2218*47e946e7SWyllys Ingersoll } else { 2219*47e946e7SWyllys Ingersoll /* logged in SO session */ 2220*47e946e7SWyllys Ingersoll initFlags |= TSS_KEY_TYPE_LEGACY | 2221*47e946e7SWyllys Ingersoll TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE; 2222*47e946e7SWyllys Ingersoll 2223*47e946e7SWyllys Ingersoll /* get a random SHA1 hash for the auth data */ 2224*47e946e7SWyllys Ingersoll if ((rc = token_rng(hContext, authHash, SHA1_DIGEST_LENGTH))) { 2225*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2226*47e946e7SWyllys Ingersoll } 2227*47e946e7SWyllys Ingersoll 2228*47e946e7SWyllys Ingersoll authData = authHash; 2229*47e946e7SWyllys Ingersoll hParentKey = hPublicRootKey; 2230*47e946e7SWyllys Ingersoll } 2231*47e946e7SWyllys Ingersoll 2232*47e946e7SWyllys Ingersoll if ((result = tss_generate_key(hContext, initFlags, authData, 2233*47e946e7SWyllys Ingersoll hParentKey, &hKey))) { 2234*47e946e7SWyllys Ingersoll return (result); 2235*47e946e7SWyllys Ingersoll } 2236*47e946e7SWyllys Ingersoll 2237*47e946e7SWyllys Ingersoll if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, 2238*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob))) { 2239*47e946e7SWyllys Ingersoll stlogit("Tspi_GetAttribData: 0x%0x - %s", 2240*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2241*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2242*47e946e7SWyllys Ingersoll } 2243*47e946e7SWyllys Ingersoll 2244*47e946e7SWyllys Ingersoll if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, 2245*47e946e7SWyllys Ingersoll ulBlobLen, &attr))) { 2246*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, rgbBlob); 2247*47e946e7SWyllys Ingersoll return (rc); 2248*47e946e7SWyllys Ingersoll } 2249*47e946e7SWyllys Ingersoll (void) template_update_attribute(priv_tmpl, attr); 2250*47e946e7SWyllys Ingersoll if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, 2251*47e946e7SWyllys Ingersoll ulBlobLen, &attr))) { 2252*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, rgbBlob); 2253*47e946e7SWyllys Ingersoll return (rc); 2254*47e946e7SWyllys Ingersoll } 2255*47e946e7SWyllys Ingersoll (void) template_update_attribute(publ_tmpl, attr); 2256*47e946e7SWyllys Ingersoll 2257*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, rgbBlob); 2258*47e946e7SWyllys Ingersoll 2259*47e946e7SWyllys Ingersoll /* grab the public key to put into the public key object */ 2260*47e946e7SWyllys Ingersoll if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO, 2261*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &ulBlobLen, &rgbBlob))) { 2262*47e946e7SWyllys Ingersoll stlogit("Tspi_GetAttribData: 0x%0x - %s", 2263*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2264*47e946e7SWyllys Ingersoll return (result); 2265*47e946e7SWyllys Ingersoll } 2266*47e946e7SWyllys Ingersoll 2267*47e946e7SWyllys Ingersoll /* add the public key blob to the object template */ 2268*47e946e7SWyllys Ingersoll if ((rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr))) { 2269*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, rgbBlob); 2270*47e946e7SWyllys Ingersoll return (rc); 2271*47e946e7SWyllys Ingersoll } 2272*47e946e7SWyllys Ingersoll (void) template_update_attribute(publ_tmpl, attr); 2273*47e946e7SWyllys Ingersoll 2274*47e946e7SWyllys Ingersoll /* add the public key blob to the object template */ 2275*47e946e7SWyllys Ingersoll if ((rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr))) { 2276*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, rgbBlob); 2277*47e946e7SWyllys Ingersoll return (rc); 2278*47e946e7SWyllys Ingersoll } 2279*47e946e7SWyllys Ingersoll (void) template_update_attribute(priv_tmpl, attr); 2280*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, rgbBlob); 2281*47e946e7SWyllys Ingersoll 2282*47e946e7SWyllys Ingersoll /* wrap the authdata and put it into an object */ 2283*47e946e7SWyllys Ingersoll if (authData != NULL) { 2284*47e946e7SWyllys Ingersoll rc = token_wrap_auth_data(hContext, authData, publ_tmpl, 2285*47e946e7SWyllys Ingersoll priv_tmpl); 2286*47e946e7SWyllys Ingersoll } 2287*47e946e7SWyllys Ingersoll 2288*47e946e7SWyllys Ingersoll return (rc); 2289*47e946e7SWyllys Ingersoll } 2290*47e946e7SWyllys Ingersoll 2291*47e946e7SWyllys Ingersoll static CK_RV 2292*47e946e7SWyllys Ingersoll token_rsa_load_key( 2293*47e946e7SWyllys Ingersoll TSS_HCONTEXT hContext, 2294*47e946e7SWyllys Ingersoll OBJECT *key_obj, 2295*47e946e7SWyllys Ingersoll TSS_HKEY *phKey) 2296*47e946e7SWyllys Ingersoll { 2297*47e946e7SWyllys Ingersoll TSS_RESULT result; 2298*47e946e7SWyllys Ingersoll TSS_HPOLICY hPolicy = NULL_HPOLICY; 2299*47e946e7SWyllys Ingersoll TSS_HKEY hParentKey; 2300*47e946e7SWyllys Ingersoll BYTE *authData = NULL; 2301*47e946e7SWyllys Ingersoll CK_ATTRIBUTE *attr; 2302*47e946e7SWyllys Ingersoll CK_RV rc; 2303*47e946e7SWyllys Ingersoll CK_OBJECT_HANDLE handle; 2304*47e946e7SWyllys Ingersoll 2305*47e946e7SWyllys Ingersoll if (hPrivateLeafKey != NULL_HKEY) { 2306*47e946e7SWyllys Ingersoll hParentKey = hPrivateRootKey; 2307*47e946e7SWyllys Ingersoll } else { 2308*47e946e7SWyllys Ingersoll if ((result = token_load_public_root_key(hContext))) 2309*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2310*47e946e7SWyllys Ingersoll 2311*47e946e7SWyllys Ingersoll hParentKey = hPublicRootKey; 2312*47e946e7SWyllys Ingersoll } 2313*47e946e7SWyllys Ingersoll 2314*47e946e7SWyllys Ingersoll if ((rc = template_attribute_find(key_obj->template, 2315*47e946e7SWyllys Ingersoll CKA_IBM_OPAQUE, &attr)) == FALSE) { 2316*47e946e7SWyllys Ingersoll /* if the key blob wasn't found, then try to wrap the key */ 2317*47e946e7SWyllys Ingersoll rc = object_mgr_find_in_map2(hContext, key_obj, &handle); 2318*47e946e7SWyllys Ingersoll if (rc != CKR_OK) 2319*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2320*47e946e7SWyllys Ingersoll 2321*47e946e7SWyllys Ingersoll if ((rc = token_load_key(hContext, 2322*47e946e7SWyllys Ingersoll handle, hParentKey, NULL, phKey))) { 2323*47e946e7SWyllys Ingersoll return (rc); 2324*47e946e7SWyllys Ingersoll } 2325*47e946e7SWyllys Ingersoll /* try again to get the CKA_IBM_OPAQUE attr */ 2326*47e946e7SWyllys Ingersoll if ((rc = template_attribute_find(key_obj->template, 2327*47e946e7SWyllys Ingersoll CKA_IBM_OPAQUE, &attr)) == FALSE) { 2328*47e946e7SWyllys Ingersoll return (rc); 2329*47e946e7SWyllys Ingersoll } 2330*47e946e7SWyllys Ingersoll } 2331*47e946e7SWyllys Ingersoll 2332*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_LoadKeyByBlob(hContext, 2333*47e946e7SWyllys Ingersoll hParentKey, attr->ulValueLen, 2334*47e946e7SWyllys Ingersoll attr->pValue, phKey))) { 2335*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_LoadKeyByBlob: 0x%0x - %s", 2336*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2337*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2338*47e946e7SWyllys Ingersoll } 2339*47e946e7SWyllys Ingersoll 2340*47e946e7SWyllys Ingersoll /* auth data may be required */ 2341*47e946e7SWyllys Ingersoll if (template_attribute_find(key_obj->template, CKA_ENC_AUTHDATA, 2342*47e946e7SWyllys Ingersoll &attr) == TRUE && attr) { 2343*47e946e7SWyllys Ingersoll if ((hPrivateLeafKey == NULL_HKEY) && 2344*47e946e7SWyllys Ingersoll (hPublicLeafKey == NULL_HKEY)) { 2345*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2346*47e946e7SWyllys Ingersoll } else if (hPublicLeafKey != NULL_HKEY) { 2347*47e946e7SWyllys Ingersoll hParentKey = hPublicLeafKey; 2348*47e946e7SWyllys Ingersoll } else { 2349*47e946e7SWyllys Ingersoll hParentKey = hPrivateLeafKey; 2350*47e946e7SWyllys Ingersoll } 2351*47e946e7SWyllys Ingersoll 2352*47e946e7SWyllys Ingersoll if ((result = token_unwrap_auth_data(hContext, 2353*47e946e7SWyllys Ingersoll attr->pValue, 2354*47e946e7SWyllys Ingersoll attr->ulValueLen, hParentKey, &authData))) { 2355*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2356*47e946e7SWyllys Ingersoll } 2357*47e946e7SWyllys Ingersoll 2358*47e946e7SWyllys Ingersoll if ((result = Tspi_GetPolicyObject(*phKey, 2359*47e946e7SWyllys Ingersoll TSS_POLICY_USAGE, &hPolicy))) { 2360*47e946e7SWyllys Ingersoll stlogit("Tspi_GetPolicyObject: 0x%0x - %s", 2361*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2362*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2363*47e946e7SWyllys Ingersoll } 2364*47e946e7SWyllys Ingersoll 2365*47e946e7SWyllys Ingersoll /* 2366*47e946e7SWyllys Ingersoll * If the policy handle returned is the same as the 2367*47e946e7SWyllys Ingersoll * context's default policy, then a new policy must 2368*47e946e7SWyllys Ingersoll * be created and assigned to the key. Otherwise, just set the 2369*47e946e7SWyllys Ingersoll * secret in the policy. 2370*47e946e7SWyllys Ingersoll */ 2371*47e946e7SWyllys Ingersoll if (hPolicy == hDefaultPolicy) { 2372*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_CreateObject(hContext, 2373*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, 2374*47e946e7SWyllys Ingersoll &hPolicy))) { 2375*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: " 2376*47e946e7SWyllys Ingersoll "0x%0x - %s", 2377*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2378*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2379*47e946e7SWyllys Ingersoll } 2380*47e946e7SWyllys Ingersoll 2381*47e946e7SWyllys Ingersoll if ((result = Tspi_Policy_SetSecret(hPolicy, 2382*47e946e7SWyllys Ingersoll TSS_SECRET_MODE_SHA1, 2383*47e946e7SWyllys Ingersoll SHA1_DIGEST_LENGTH, authData))) { 2384*47e946e7SWyllys Ingersoll stlogit("Tspi_Policy_SetSecret: " 2385*47e946e7SWyllys Ingersoll "0x%0x - %s", 2386*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2387*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2388*47e946e7SWyllys Ingersoll } 2389*47e946e7SWyllys Ingersoll 2390*47e946e7SWyllys Ingersoll if ((result = Tspi_Policy_AssignToObject(hPolicy, 2391*47e946e7SWyllys Ingersoll *phKey))) { 2392*47e946e7SWyllys Ingersoll stlogit("Tspi_Policy_AssignToObject: " 2393*47e946e7SWyllys Ingersoll "0x%0x - %s", 2394*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2395*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2396*47e946e7SWyllys Ingersoll } 2397*47e946e7SWyllys Ingersoll } else if ((result = Tspi_Policy_SetSecret(hPolicy, 2398*47e946e7SWyllys Ingersoll TSS_SECRET_MODE_SHA1, SHA1_DIGEST_LENGTH, authData))) { 2399*47e946e7SWyllys Ingersoll stlogit("Tspi_Policy_SetSecret: 0x%0x - %s", 2400*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2401*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2402*47e946e7SWyllys Ingersoll } 2403*47e946e7SWyllys Ingersoll 2404*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, authData); 2405*47e946e7SWyllys Ingersoll } 2406*47e946e7SWyllys Ingersoll 2407*47e946e7SWyllys Ingersoll return (CKR_OK); 2408*47e946e7SWyllys Ingersoll } 2409*47e946e7SWyllys Ingersoll 2410*47e946e7SWyllys Ingersoll CK_RV 2411*47e946e7SWyllys Ingersoll tpm_decrypt_data( 2412*47e946e7SWyllys Ingersoll TSS_HCONTEXT hContext, 2413*47e946e7SWyllys Ingersoll TSS_HKEY hKey, 2414*47e946e7SWyllys Ingersoll CK_BYTE * in_data, 2415*47e946e7SWyllys Ingersoll CK_ULONG in_data_len, 2416*47e946e7SWyllys Ingersoll CK_BYTE * out_data, 2417*47e946e7SWyllys Ingersoll CK_ULONG * out_data_len) 2418*47e946e7SWyllys Ingersoll { 2419*47e946e7SWyllys Ingersoll TSS_RESULT result; 2420*47e946e7SWyllys Ingersoll TSS_HENCDATA hEncData = NULL_HENCDATA; 2421*47e946e7SWyllys Ingersoll UINT32 buf_size = 0, modLen; 2422*47e946e7SWyllys Ingersoll BYTE *buf = NULL, *modulus = NULL; 2423*47e946e7SWyllys Ingersoll CK_ULONG chunklen, remain, outlen; 2424*47e946e7SWyllys Ingersoll 2425*47e946e7SWyllys Ingersoll /* push the data into the encrypted data object */ 2426*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_CreateObject(hContext, 2427*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 2428*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2429*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2430*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2431*47e946e7SWyllys Ingersoll } 2432*47e946e7SWyllys Ingersoll 2433*47e946e7SWyllys Ingersoll /* 2434*47e946e7SWyllys Ingersoll * Figure out the modulus size so we can break the data 2435*47e946e7SWyllys Ingersoll * into smaller chunks if necessary. 2436*47e946e7SWyllys Ingersoll */ 2437*47e946e7SWyllys Ingersoll if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO, 2438*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) { 2439*47e946e7SWyllys Ingersoll stlogit("Tspi_GetAttribData: 0x%0x - %s", 2440*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2441*47e946e7SWyllys Ingersoll return (result); 2442*47e946e7SWyllys Ingersoll } 2443*47e946e7SWyllys Ingersoll /* we don't need the actual modulus */ 2444*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, modulus); 2445*47e946e7SWyllys Ingersoll 2446*47e946e7SWyllys Ingersoll chunklen = (in_data_len > modLen ? modLen : in_data_len); 2447*47e946e7SWyllys Ingersoll remain = in_data_len; 2448*47e946e7SWyllys Ingersoll outlen = 0; 2449*47e946e7SWyllys Ingersoll 2450*47e946e7SWyllys Ingersoll while (remain > 0) { 2451*47e946e7SWyllys Ingersoll if ((result = Tspi_SetAttribData(hEncData, 2452*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_ENCDATA_BLOB, 2453*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_ENCDATABLOB_BLOB, 2454*47e946e7SWyllys Ingersoll chunklen, in_data))) { 2455*47e946e7SWyllys Ingersoll stlogit("Tspi_SetAttribData: 0x%0x - %s", 2456*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2457*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2458*47e946e7SWyllys Ingersoll } 2459*47e946e7SWyllys Ingersoll 2460*47e946e7SWyllys Ingersoll /* unbind the data, receiving the plaintext back */ 2461*47e946e7SWyllys Ingersoll if ((result = Tspi_Data_Unbind(hEncData, hKey, 2462*47e946e7SWyllys Ingersoll &buf_size, &buf))) { 2463*47e946e7SWyllys Ingersoll stlogit("Tspi_Data_Unbind: 0x%0x - %s", 2464*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2465*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2466*47e946e7SWyllys Ingersoll } 2467*47e946e7SWyllys Ingersoll 2468*47e946e7SWyllys Ingersoll if (*out_data_len < buf_size + outlen) { 2469*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, buf); 2470*47e946e7SWyllys Ingersoll return (CKR_BUFFER_TOO_SMALL); 2471*47e946e7SWyllys Ingersoll } 2472*47e946e7SWyllys Ingersoll 2473*47e946e7SWyllys Ingersoll (void) memcpy(out_data + outlen, buf, buf_size); 2474*47e946e7SWyllys Ingersoll 2475*47e946e7SWyllys Ingersoll outlen += buf_size; 2476*47e946e7SWyllys Ingersoll in_data += chunklen; 2477*47e946e7SWyllys Ingersoll remain -= chunklen; 2478*47e946e7SWyllys Ingersoll 2479*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, buf); 2480*47e946e7SWyllys Ingersoll if (chunklen > remain) 2481*47e946e7SWyllys Ingersoll chunklen = remain; 2482*47e946e7SWyllys Ingersoll } 2483*47e946e7SWyllys Ingersoll *out_data_len = outlen; 2484*47e946e7SWyllys Ingersoll return (CKR_OK); 2485*47e946e7SWyllys Ingersoll } 2486*47e946e7SWyllys Ingersoll 2487*47e946e7SWyllys Ingersoll CK_RV 2488*47e946e7SWyllys Ingersoll token_specific_rsa_decrypt( 2489*47e946e7SWyllys Ingersoll TSS_HCONTEXT hContext, 2490*47e946e7SWyllys Ingersoll CK_BYTE * in_data, 2491*47e946e7SWyllys Ingersoll CK_ULONG in_data_len, 2492*47e946e7SWyllys Ingersoll CK_BYTE * out_data, 2493*47e946e7SWyllys Ingersoll CK_ULONG * out_data_len, 2494*47e946e7SWyllys Ingersoll OBJECT * key_obj) 2495*47e946e7SWyllys Ingersoll { 2496*47e946e7SWyllys Ingersoll CK_RV rc; 2497*47e946e7SWyllys Ingersoll TSS_HKEY hKey; 2498*47e946e7SWyllys Ingersoll 2499*47e946e7SWyllys Ingersoll if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) { 2500*47e946e7SWyllys Ingersoll return (rc); 2501*47e946e7SWyllys Ingersoll } 2502*47e946e7SWyllys Ingersoll 2503*47e946e7SWyllys Ingersoll rc = tpm_decrypt_data(hContext, hKey, in_data, in_data_len, 2504*47e946e7SWyllys Ingersoll out_data, out_data_len); 2505*47e946e7SWyllys Ingersoll 2506*47e946e7SWyllys Ingersoll return (rc); 2507*47e946e7SWyllys Ingersoll } 2508*47e946e7SWyllys Ingersoll 2509*47e946e7SWyllys Ingersoll CK_RV 2510*47e946e7SWyllys Ingersoll token_specific_rsa_verify( 2511*47e946e7SWyllys Ingersoll TSS_HCONTEXT hContext, 2512*47e946e7SWyllys Ingersoll CK_BYTE * in_data, 2513*47e946e7SWyllys Ingersoll CK_ULONG in_data_len, 2514*47e946e7SWyllys Ingersoll CK_BYTE * sig, 2515*47e946e7SWyllys Ingersoll CK_ULONG sig_len, 2516*47e946e7SWyllys Ingersoll OBJECT * key_obj) 2517*47e946e7SWyllys Ingersoll { 2518*47e946e7SWyllys Ingersoll TSS_RESULT result; 2519*47e946e7SWyllys Ingersoll TSS_HHASH hHash; 2520*47e946e7SWyllys Ingersoll TSS_HKEY hKey; 2521*47e946e7SWyllys Ingersoll CK_RV rc; 2522*47e946e7SWyllys Ingersoll 2523*47e946e7SWyllys Ingersoll if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) { 2524*47e946e7SWyllys Ingersoll return (rc); 2525*47e946e7SWyllys Ingersoll } 2526*47e946e7SWyllys Ingersoll 2527*47e946e7SWyllys Ingersoll /* Create the hash object we'll use to sign */ 2528*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_CreateObject(hContext, 2529*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, &hHash))) { 2530*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2531*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2532*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2533*47e946e7SWyllys Ingersoll } 2534*47e946e7SWyllys Ingersoll 2535*47e946e7SWyllys Ingersoll /* Insert the data into the hash object */ 2536*47e946e7SWyllys Ingersoll if ((result = Tspi_Hash_SetHashValue(hHash, in_data_len, 2537*47e946e7SWyllys Ingersoll in_data))) { 2538*47e946e7SWyllys Ingersoll stlogit("Tspi_Hash_SetHashValue: 0x%0x - %s", 2539*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2540*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2541*47e946e7SWyllys Ingersoll } 2542*47e946e7SWyllys Ingersoll 2543*47e946e7SWyllys Ingersoll /* Verify */ 2544*47e946e7SWyllys Ingersoll result = Tspi_Hash_VerifySignature(hHash, hKey, sig_len, sig); 2545*47e946e7SWyllys Ingersoll if (result != TSS_SUCCESS && 2546*47e946e7SWyllys Ingersoll TPMTOK_TSS_ERROR_CODE(result) != TSS_E_FAIL) { 2547*47e946e7SWyllys Ingersoll stlogit("Tspi_Hash_VerifySignature: 0x%0x - %s", 2548*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2549*47e946e7SWyllys Ingersoll } 2550*47e946e7SWyllys Ingersoll 2551*47e946e7SWyllys Ingersoll if (TPMTOK_TSS_ERROR_CODE(result) == TSS_E_FAIL) { 2552*47e946e7SWyllys Ingersoll rc = CKR_SIGNATURE_INVALID; 2553*47e946e7SWyllys Ingersoll } else { 2554*47e946e7SWyllys Ingersoll rc = CKR_OK; 2555*47e946e7SWyllys Ingersoll } 2556*47e946e7SWyllys Ingersoll 2557*47e946e7SWyllys Ingersoll return (rc); 2558*47e946e7SWyllys Ingersoll } 2559*47e946e7SWyllys Ingersoll 2560*47e946e7SWyllys Ingersoll CK_RV 2561*47e946e7SWyllys Ingersoll token_specific_rsa_sign( 2562*47e946e7SWyllys Ingersoll TSS_HCONTEXT hContext, 2563*47e946e7SWyllys Ingersoll CK_BYTE * in_data, 2564*47e946e7SWyllys Ingersoll CK_ULONG in_data_len, 2565*47e946e7SWyllys Ingersoll CK_BYTE * out_data, 2566*47e946e7SWyllys Ingersoll CK_ULONG * out_data_len, 2567*47e946e7SWyllys Ingersoll OBJECT * key_obj) 2568*47e946e7SWyllys Ingersoll { 2569*47e946e7SWyllys Ingersoll TSS_RESULT result; 2570*47e946e7SWyllys Ingersoll TSS_HHASH hHash; 2571*47e946e7SWyllys Ingersoll BYTE *sig; 2572*47e946e7SWyllys Ingersoll UINT32 sig_len; 2573*47e946e7SWyllys Ingersoll TSS_HKEY hKey; 2574*47e946e7SWyllys Ingersoll CK_RV rc; 2575*47e946e7SWyllys Ingersoll 2576*47e946e7SWyllys Ingersoll if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) { 2577*47e946e7SWyllys Ingersoll return (rc); 2578*47e946e7SWyllys Ingersoll } 2579*47e946e7SWyllys Ingersoll 2580*47e946e7SWyllys Ingersoll /* Create the hash object we'll use to sign */ 2581*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_CreateObject(hContext, 2582*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, &hHash))) { 2583*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2584*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2585*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2586*47e946e7SWyllys Ingersoll } 2587*47e946e7SWyllys Ingersoll 2588*47e946e7SWyllys Ingersoll /* Insert the data into the hash object */ 2589*47e946e7SWyllys Ingersoll if ((result = Tspi_Hash_SetHashValue(hHash, in_data_len, 2590*47e946e7SWyllys Ingersoll in_data))) { 2591*47e946e7SWyllys Ingersoll stlogit("Tspi_Hash_SetHashValue: 0x%0x - %s", 2592*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2593*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2594*47e946e7SWyllys Ingersoll } 2595*47e946e7SWyllys Ingersoll 2596*47e946e7SWyllys Ingersoll /* Sign */ 2597*47e946e7SWyllys Ingersoll if ((result = Tspi_Hash_Sign(hHash, hKey, &sig_len, &sig))) { 2598*47e946e7SWyllys Ingersoll stlogit("Tspi_Hash_Sign: 0x%0x - %s", 2599*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2600*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2601*47e946e7SWyllys Ingersoll } 2602*47e946e7SWyllys Ingersoll 2603*47e946e7SWyllys Ingersoll if (sig_len > *out_data_len) { 2604*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, sig); 2605*47e946e7SWyllys Ingersoll return (CKR_BUFFER_TOO_SMALL); 2606*47e946e7SWyllys Ingersoll } 2607*47e946e7SWyllys Ingersoll 2608*47e946e7SWyllys Ingersoll (void) memcpy(out_data, sig, sig_len); 2609*47e946e7SWyllys Ingersoll *out_data_len = sig_len; 2610*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, sig); 2611*47e946e7SWyllys Ingersoll 2612*47e946e7SWyllys Ingersoll return (CKR_OK); 2613*47e946e7SWyllys Ingersoll } 2614*47e946e7SWyllys Ingersoll 2615*47e946e7SWyllys Ingersoll CK_RV 2616*47e946e7SWyllys Ingersoll tpm_encrypt_data( 2617*47e946e7SWyllys Ingersoll TSS_HCONTEXT hContext, 2618*47e946e7SWyllys Ingersoll TSS_HKEY hKey, 2619*47e946e7SWyllys Ingersoll CK_BYTE *in_data, 2620*47e946e7SWyllys Ingersoll CK_ULONG in_data_len, 2621*47e946e7SWyllys Ingersoll CK_BYTE *out_data, 2622*47e946e7SWyllys Ingersoll CK_ULONG *out_data_len) 2623*47e946e7SWyllys Ingersoll { 2624*47e946e7SWyllys Ingersoll TSS_RESULT result; 2625*47e946e7SWyllys Ingersoll TSS_HENCDATA hEncData; 2626*47e946e7SWyllys Ingersoll BYTE *dataBlob, *modulus; 2627*47e946e7SWyllys Ingersoll UINT32 dataBlobSize, modLen; 2628*47e946e7SWyllys Ingersoll CK_ULONG chunklen, remain; 2629*47e946e7SWyllys Ingersoll CK_ULONG outlen; 2630*47e946e7SWyllys Ingersoll 2631*47e946e7SWyllys Ingersoll if ((result = Tspi_Context_CreateObject(hContext, 2632*47e946e7SWyllys Ingersoll TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 2633*47e946e7SWyllys Ingersoll stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2634*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2635*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2636*47e946e7SWyllys Ingersoll } 2637*47e946e7SWyllys Ingersoll /* 2638*47e946e7SWyllys Ingersoll * Figure out the modulus size so we can break the data 2639*47e946e7SWyllys Ingersoll * into smaller chunks if necessary. 2640*47e946e7SWyllys Ingersoll */ 2641*47e946e7SWyllys Ingersoll if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO, 2642*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) { 2643*47e946e7SWyllys Ingersoll stlogit("Tspi_GetAttribData: 0x%0x - %s", 2644*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2645*47e946e7SWyllys Ingersoll return (result); 2646*47e946e7SWyllys Ingersoll } 2647*47e946e7SWyllys Ingersoll /* we don't need the actual modulus */ 2648*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, modulus); 2649*47e946e7SWyllys Ingersoll 2650*47e946e7SWyllys Ingersoll /* 2651*47e946e7SWyllys Ingersoll * According to TSS spec for Tspi_Data_Bind (4.3.4.21.5), 2652*47e946e7SWyllys Ingersoll * Max input data size is: modLen - (40 - 2 - 4 - 1) 2653*47e946e7SWyllys Ingersoll * (for RSA OAEP SHA1 operations). 2654*47e946e7SWyllys Ingersoll */ 2655*47e946e7SWyllys Ingersoll modLen -= 47; 2656*47e946e7SWyllys Ingersoll 2657*47e946e7SWyllys Ingersoll chunklen = (in_data_len > modLen ? modLen : in_data_len); 2658*47e946e7SWyllys Ingersoll remain = in_data_len; 2659*47e946e7SWyllys Ingersoll outlen = 0; 2660*47e946e7SWyllys Ingersoll while (remain > 0) { 2661*47e946e7SWyllys Ingersoll if ((result = Tspi_Data_Bind(hEncData, hKey, 2662*47e946e7SWyllys Ingersoll chunklen, in_data))) { 2663*47e946e7SWyllys Ingersoll stlogit("Tspi_Data_Bind: 0x%0x - %s", 2664*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2665*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2666*47e946e7SWyllys Ingersoll } 2667*47e946e7SWyllys Ingersoll 2668*47e946e7SWyllys Ingersoll if ((result = Tspi_GetAttribData(hEncData, 2669*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_ENCDATA_BLOB, 2670*47e946e7SWyllys Ingersoll TSS_TSPATTRIB_ENCDATABLOB_BLOB, 2671*47e946e7SWyllys Ingersoll &dataBlobSize, &dataBlob))) { 2672*47e946e7SWyllys Ingersoll stlogit("Tspi_GetAttribData: 0x%0x - %s", 2673*47e946e7SWyllys Ingersoll result, Trspi_Error_String(result)); 2674*47e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED); 2675*47e946e7SWyllys Ingersoll } 2676*47e946e7SWyllys Ingersoll 2677*47e946e7SWyllys Ingersoll if (outlen + dataBlobSize > *out_data_len) { 2678*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, dataBlob); 2679*47e946e7SWyllys Ingersoll return (CKR_DATA_LEN_RANGE); 2680*47e946e7SWyllys Ingersoll } 2681*47e946e7SWyllys Ingersoll 2682*47e946e7SWyllys Ingersoll (void) memcpy(out_data + outlen, 2683*47e946e7SWyllys Ingersoll dataBlob, dataBlobSize); 2684*47e946e7SWyllys Ingersoll 2685*47e946e7SWyllys Ingersoll outlen += dataBlobSize; 2686*47e946e7SWyllys Ingersoll in_data += chunklen; 2687*47e946e7SWyllys Ingersoll remain -= chunklen; 2688*47e946e7SWyllys Ingersoll 2689*47e946e7SWyllys Ingersoll if (chunklen > remain) 2690*47e946e7SWyllys Ingersoll chunklen = remain; 2691*47e946e7SWyllys Ingersoll 2692*47e946e7SWyllys Ingersoll Tspi_Context_FreeMemory(hContext, dataBlob); 2693*47e946e7SWyllys Ingersoll } 2694*47e946e7SWyllys Ingersoll *out_data_len = outlen; 2695*47e946e7SWyllys Ingersoll 2696*47e946e7SWyllys Ingersoll return (CKR_OK); 2697*47e946e7SWyllys Ingersoll } 2698*47e946e7SWyllys Ingersoll 2699*47e946e7SWyllys Ingersoll CK_RV 2700*47e946e7SWyllys Ingersoll token_specific_rsa_encrypt( 2701*47e946e7SWyllys Ingersoll TSS_HCONTEXT hContext, 2702*47e946e7SWyllys Ingersoll CK_BYTE * in_data, 2703*47e946e7SWyllys Ingersoll CK_ULONG in_data_len, 2704*47e946e7SWyllys Ingersoll CK_BYTE * out_data, 2705*47e946e7SWyllys Ingersoll CK_ULONG * out_data_len, 2706*47e946e7SWyllys Ingersoll OBJECT * key_obj) 2707*47e946e7SWyllys Ingersoll { 2708*47e946e7SWyllys Ingersoll TSS_HKEY hKey; 2709*47e946e7SWyllys Ingersoll CK_RV rc; 2710*47e946e7SWyllys Ingersoll 2711*47e946e7SWyllys Ingersoll if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) { 2712*47e946e7SWyllys Ingersoll return (rc); 2713*47e946e7SWyllys Ingersoll } 2714*47e946e7SWyllys Ingersoll 2715*47e946e7SWyllys Ingersoll rc = tpm_encrypt_data(hContext, hKey, in_data, in_data_len, 2716*47e946e7SWyllys Ingersoll out_data, out_data_len); 2717*47e946e7SWyllys Ingersoll 2718*47e946e7SWyllys Ingersoll return (rc); 2719*47e946e7SWyllys Ingersoll } 2720