1 /* 2 * The Initial Developer of the Original Code is International 3 * Business Machines Corporation. Portions created by IBM 4 * Corporation are Copyright (C) 2005 International Business 5 * Machines Corporation. All Rights Reserved. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the Common Public License as published by 9 * IBM Corporation; either version 1 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * Common Public License for more details. 16 * 17 * You should have received a copy of the Common Public License 18 * along with this program; if not, a copy can be viewed at 19 * http://www.opensource.org/licenses/cpl1.0.php. 20 */ 21 22 #include <limits.h> 23 24 #include "tpm_tspi.h" 25 #include "tpm_utils.h" 26 #include "tpm_nvcommon.h" 27 28 static unsigned int nvindex; 29 static BOOL nvindex_set; 30 static unsigned int nvperm; 31 static unsigned int nvsize; 32 static const char *ownerpass; 33 static BOOL ownerWellKnown; 34 static BOOL askOwnerPass; 35 static const char *datapass; 36 static BOOL dataWellKnown; 37 static BOOL askDataPass; 38 static int end; 39 40 TSS_HCONTEXT hContext = 0; 41 42 43 static int parse(const int aOpt, const char *aArg) 44 { 45 switch (aOpt) { 46 case 'i': 47 if (parseHexOrDecimal(aArg, &nvindex, 0, UINT_MAX, 48 "NVRAM index") != 0) 49 return -1; 50 nvindex_set = TRUE; 51 break; 52 53 case 'p': 54 if (!strcmp(aArg, "?")) { 55 displayStringsAndValues(permvalues, ""); 56 end = 1; 57 return 0; 58 } 59 if (parseStringWithValues(aArg, permvalues, &nvperm, UINT_MAX, 60 "NVRAM permission") != 0) 61 return -1; 62 break; 63 64 case 's': 65 if (parseHexOrDecimal(aArg, &nvsize, 0, UINT_MAX, 66 "NVRAM index size") != 0) 67 return -1; 68 break; 69 70 case 'o': 71 ownerpass = aArg; 72 if (!ownerpass) 73 askOwnerPass = TRUE; 74 else 75 askOwnerPass = FALSE; 76 ownerWellKnown = FALSE; 77 break; 78 79 case 'y': 80 ownerWellKnown = TRUE; 81 ownerpass = NULL; 82 askOwnerPass = FALSE; 83 break; 84 85 case 'a': 86 datapass = aArg; 87 if (!datapass) 88 askDataPass = TRUE; 89 else 90 askDataPass = FALSE; 91 dataWellKnown = FALSE; 92 break; 93 94 case 'z': 95 dataWellKnown = TRUE; 96 datapass = NULL; 97 askDataPass = FALSE; 98 break; 99 100 case 'u': 101 useUnicode = TRUE; 102 break; 103 104 default: 105 return -1; 106 } 107 return 0; 108 } 109 110 static void help(const char* aCmd) 111 { 112 logCmdHelp(aCmd); 113 logUnicodeCmdOption(); 114 logCmdOption("-y, --owner-well-known", 115 _("Use 20 bytes of zeros (TSS_WELL_KNOWN_SECRET) as the " 116 "TPM owner secret")); 117 logCmdOption("-z, --data-well-known", 118 _("Use 20 bytes of zeros (TSS_WELL_KNOWN_SECRET) as the " 119 "NVRAM area's secret")); 120 logOwnerPassCmdOption(); 121 logCmdOption("-a, --pwda", 122 _("NVRAM area password")); 123 logNVIndexCmdOption(); 124 logCmdOption("-s, --size", 125 _("Size of the NVRAM area")); 126 logCmdOption("-p, --permissions", 127 _("Permissions of the NVRAM area")); 128 129 displayStringsAndValues(permvalues, " "); 130 } 131 132 int main(int argc, char **argv) 133 { 134 TSS_HTPM hTpm; 135 TSS_HNVSTORE nvObject; 136 TSS_FLAG fNvAttrs; 137 TSS_HPOLICY hTpmPolicy, hDataPolicy; 138 int iRc = -1; 139 BYTE well_known_secret[] = TSS_WELL_KNOWN_SECRET; 140 int opswd_len = -1; 141 int dpswd_len = -1; 142 struct option hOpts[] = { 143 {"index" , required_argument, NULL, 'i'}, 144 {"size" , required_argument, NULL, 's'}, 145 {"permissions" , required_argument, NULL, 'p'}, 146 {"pwdo" , optional_argument, NULL, 'o'}, 147 {"pwda" , optional_argument, NULL, 'a'}, 148 {"use-unicode" , no_argument, NULL, 'u'}, 149 {"data-well-known" , no_argument, NULL, 'z'}, 150 {"owner-well-known", no_argument, NULL, 'y'}, 151 {NULL , no_argument, NULL, 0}, 152 }; 153 154 initIntlSys(); 155 156 if (genericOptHandler 157 (argc, argv, "i:s:p:o:a:yzu", hOpts, 158 sizeof(hOpts) / sizeof(struct option), parse, help) != 0) 159 goto out; 160 161 if (end) { 162 iRc = 0; 163 goto out; 164 } 165 166 if (!nvindex_set) { 167 logError(_("You must provide an index for the NVRAM area.\n")); 168 goto out; 169 } 170 171 if (nvperm == 0 && 172 (UINT32)nvindex != TPM_NV_INDEX_LOCK && 173 (UINT32)nvindex != TPM_NV_INDEX0) { 174 logError(_("You must provide permission bits for the NVRAM area.\n")); 175 goto out; 176 } 177 178 logDebug("permissions = 0x%08x\n", nvperm); 179 180 if (contextCreate(&hContext) != TSS_SUCCESS) 181 goto out; 182 183 if (contextConnect(hContext) != TSS_SUCCESS) 184 goto out_close; 185 186 if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) 187 goto out_close; 188 189 fNvAttrs = 0; 190 191 if (contextCreateObject(hContext, 192 TSS_OBJECT_TYPE_NV, 193 fNvAttrs, 194 &nvObject) != TSS_SUCCESS) 195 goto out_close; 196 197 if (askOwnerPass) { 198 ownerpass = _GETPASSWD(_("Enter owner password: "), &opswd_len, 199 FALSE, useUnicode ); 200 if (!ownerpass) { 201 logError(_("Failed to get owner password\n")); 202 goto out_close; 203 } 204 } 205 206 if (ownerpass || ownerWellKnown) { 207 if (policyGet(hTpm, &hTpmPolicy) != TSS_SUCCESS) 208 goto out_close; 209 if (ownerpass) { 210 if (opswd_len < 0) 211 opswd_len = strlen(ownerpass); 212 if (policySetSecret(hTpmPolicy, opswd_len, 213 (BYTE *)ownerpass) != TSS_SUCCESS) 214 goto out_close; 215 } else { 216 if (policySetSecret(hTpmPolicy, TCPA_SHA1_160_HASH_LEN, 217 (BYTE *)well_known_secret) != TSS_SUCCESS) 218 goto out_close; 219 } 220 } 221 222 if (askDataPass) { 223 datapass = _GETPASSWD(_("Enter NVRAM data password: "), &dpswd_len, 224 TRUE, useUnicode ); 225 if (!datapass) { 226 logError(_("Failed to get NVRAM data password\n")); 227 goto out_close; 228 } 229 } 230 231 if (datapass || dataWellKnown) { 232 if (contextCreateObject 233 (hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, 234 &hDataPolicy) != TSS_SUCCESS) 235 goto out_close; 236 237 if (datapass) { 238 if (dpswd_len < 0) 239 dpswd_len = strlen(datapass); 240 if (policySetSecret(hDataPolicy, dpswd_len, 241 (BYTE *)datapass) != TSS_SUCCESS) 242 goto out_close; 243 } else { 244 if (policySetSecret(hDataPolicy, TCPA_SHA1_160_HASH_LEN, 245 (BYTE *)well_known_secret) != TSS_SUCCESS) 246 goto out_close; 247 } 248 249 if (Tspi_Policy_AssignToObject(hDataPolicy, nvObject) != 250 TSS_SUCCESS) 251 goto out_close; 252 } 253 254 if (Tspi_SetAttribUint32(nvObject, 255 TSS_TSPATTRIB_NV_INDEX, 256 0, 257 nvindex) != TSS_SUCCESS) 258 goto out_close_obj; 259 260 if (Tspi_SetAttribUint32(nvObject, 261 TSS_TSPATTRIB_NV_PERMISSIONS, 262 0, 263 nvperm) != TSS_SUCCESS) 264 goto out_close_obj; 265 266 if (Tspi_SetAttribUint32(nvObject, 267 TSS_TSPATTRIB_NV_DATASIZE, 268 0, 269 nvsize) != TSS_SUCCESS) 270 goto out_close_obj; 271 272 if (NVDefineSpace(nvObject, (TSS_HPCRS)0, (TSS_HPCRS)0) != 273 TSS_SUCCESS) 274 goto out_close; 275 276 logMsg(_("Successfully created NVRAM area at index 0x%x (%u).\n"), 277 nvindex, nvindex); 278 279 iRc = 0; 280 281 goto out_close; 282 283 out_close_obj: 284 contextCloseObject(hContext, nvObject); 285 286 out_close: 287 contextClose(hContext); 288 289 out: 290 return iRc; 291 } 292