xref: /netbsd-src/crypto/external/cpl/tpm-tools/dist/src/tpm_mgmt/tpm_nvdefine.c (revision 212397c69a103ae7e5eafa8731ddfae671d2dee7)
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