Commit dc26e913a8d1a62bd4112f41232e0273ee66423d
Committed by
Tom Rini
1 parent
da9c3392e6
Exists in
smarc_8mq_lf_v2020.04
and in
11 other branches
tpm: add TPM2_HierarchyChangeAuth command support
Add support for the TPM2_HierarchyChangeAuth command. Change the command file and the help accordingly. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Tom Rini <trini@konsulko.com>
Showing 3 changed files with 105 additions and 12 deletions Side-by-side Diff
cmd/tpm-v2.c
... | ... | @@ -234,6 +234,36 @@ |
234 | 234 | lockout_recovery)); |
235 | 235 | } |
236 | 236 | |
237 | +static int do_tpm_change_auth(cmd_tbl_t *cmdtp, int flag, int argc, | |
238 | + char *const argv[]) | |
239 | +{ | |
240 | + u32 handle; | |
241 | + const char *newpw = argv[2]; | |
242 | + const char *oldpw = (argc == 3) ? NULL : argv[3]; | |
243 | + const ssize_t newpw_sz = strlen(newpw); | |
244 | + const ssize_t oldpw_sz = oldpw ? strlen(oldpw) : 0; | |
245 | + | |
246 | + if (argc < 3 || argc > 4) | |
247 | + return CMD_RET_USAGE; | |
248 | + | |
249 | + if (newpw_sz > TPM2_DIGEST_LEN || oldpw_sz > TPM2_DIGEST_LEN) | |
250 | + return -EINVAL; | |
251 | + | |
252 | + if (!strcasecmp("TPM2_RH_LOCKOUT", argv[1])) | |
253 | + handle = TPM2_RH_LOCKOUT; | |
254 | + else if (!strcasecmp("TPM2_RH_ENDORSEMENT", argv[1])) | |
255 | + handle = TPM2_RH_ENDORSEMENT; | |
256 | + else if (!strcasecmp("TPM2_RH_OWNER", argv[1])) | |
257 | + handle = TPM2_RH_OWNER; | |
258 | + else if (!strcasecmp("TPM2_RH_PLATFORM", argv[1])) | |
259 | + handle = TPM2_RH_PLATFORM; | |
260 | + else | |
261 | + return CMD_RET_USAGE; | |
262 | + | |
263 | + return report_return_code(tpm2_change_auth(handle, newpw, newpw_sz, | |
264 | + oldpw, oldpw_sz)); | |
265 | +} | |
266 | + | |
237 | 267 | static cmd_tbl_t tpm2_commands[] = { |
238 | 268 | U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""), |
239 | 269 | U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""), |
... | ... | @@ -245,6 +275,7 @@ |
245 | 275 | U_BOOT_CMD_MKENT(get_capability, 0, 1, do_tpm_get_capability, "", ""), |
246 | 276 | U_BOOT_CMD_MKENT(dam_reset, 0, 1, do_tpm_dam_reset, "", ""), |
247 | 277 | U_BOOT_CMD_MKENT(dam_parameters, 0, 1, do_tpm_dam_parameters, "", ""), |
278 | + U_BOOT_CMD_MKENT(change_auth, 0, 1, do_tpm_change_auth, "", ""), | |
248 | 279 | }; |
249 | 280 | |
250 | 281 | cmd_tbl_t *get_tpm_commands(unsigned int *size) |
... | ... | @@ -291,17 +322,21 @@ |
291 | 322 | " <property>: property\n" |
292 | 323 | " <addr>: address to store <count> entries of 4 bytes\n" |
293 | 324 | " <count>: number of entries to retrieve\n" |
294 | -" dam_reset_counter [<password>]\n" | |
295 | -" - If the TPM is not in a LOCKOUT state, reset the internal error\n" | |
296 | -" counter (TPMv2 only)\n" | |
297 | -" dam_set_parameters <maxTries> <recoveryTime> <lockoutRecovery> [<password>]\n" | |
298 | -" - If the TPM is not in a LOCKOUT state, set the dictionary attack\n" | |
299 | -" parameters:\n" | |
300 | -" * maxTries: maximum number of failures before lockout.\n" | |
301 | -" 0 means always locking.\n" | |
302 | -" * recoveryTime: time before decrementation of the error counter,\n" | |
303 | -" 0 means no lockout.\n" | |
304 | -" * lockoutRecovery: time of a lockout (before the next try)\n" | |
305 | -" 0 means a reboot is needed.\n" | |
325 | +"dam_reset [<password>]\n" | |
326 | +" If the TPM is not in a LOCKOUT state, reset the internal error counter.\n" | |
327 | +" <password>: optional password\n" | |
328 | +"dam_parameters <max_tries> <recovery_time> <lockout_recovery> [<password>]\n" | |
329 | +" If the TPM is not in a LOCKOUT state, set the DAM parameters\n" | |
330 | +" <maxTries>: maximum number of failures before lockout,\n" | |
331 | +" 0 means always locking\n" | |
332 | +" <recoveryTime>: time before decrement of the error counter,\n" | |
333 | +" 0 means no lockout\n" | |
334 | +" <lockoutRecovery>: time of a lockout (before the next try),\n" | |
335 | +" 0 means a reboot is needed\n" | |
336 | +" <password>: optional password of the LOCKOUT hierarchy\n" | |
337 | +"change_auth <hierarchy> <new_pw> [<old_pw>]\n" | |
338 | +" <hierarchy>: the hierarchy\n" | |
339 | +" <new_pw>: new password for <hierarchy>\n" | |
340 | +" <old_pw>: optional previous password of <hierarchy>\n" | |
306 | 341 | ); |
include/tpm-v2.h
... | ... | @@ -216,5 +216,19 @@ |
216 | 216 | unsigned int max_tries, unsigned int recovery_time, |
217 | 217 | unsigned int lockout_recovery); |
218 | 218 | |
219 | +/** | |
220 | + * Issue a TPM2_HierarchyChangeAuth command. | |
221 | + * | |
222 | + * @handle Handle | |
223 | + * @newpw New password | |
224 | + * @newpw_sz Length of the new password | |
225 | + * @oldpw Old password | |
226 | + * @oldpw_sz Length of the old password | |
227 | + * | |
228 | + * @return code of the operation | |
229 | + */ | |
230 | +int tpm2_change_auth(u32 handle, const char *newpw, const ssize_t newpw_sz, | |
231 | + const char *oldpw, const ssize_t oldpw_sz); | |
232 | + | |
219 | 233 | #endif /* __TPM_V2_H */ |
lib/tpm-v2.c
... | ... | @@ -273,4 +273,48 @@ |
273 | 273 | |
274 | 274 | return tpm_sendrecv_command(command_v2, NULL, NULL); |
275 | 275 | } |
276 | + | |
277 | +int tpm2_change_auth(u32 handle, const char *newpw, const ssize_t newpw_sz, | |
278 | + const char *oldpw, const ssize_t oldpw_sz) | |
279 | +{ | |
280 | + unsigned int offset = 27; | |
281 | + u8 command_v2[COMMAND_BUFFER_SIZE] = { | |
282 | + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ | |
283 | + tpm_u32(offset + oldpw_sz + 2 + newpw_sz), /* Length */ | |
284 | + tpm_u32(TPM2_CC_HIERCHANGEAUTH), /* Command code */ | |
285 | + | |
286 | + /* HANDLE */ | |
287 | + tpm_u32(handle), /* TPM resource handle */ | |
288 | + | |
289 | + /* AUTH_SESSION */ | |
290 | + tpm_u32(9 + oldpw_sz), /* Authorization size */ | |
291 | + tpm_u32(TPM2_RS_PW), /* Session handle */ | |
292 | + tpm_u16(0), /* Size of <nonce> */ | |
293 | + /* <nonce> (if any) */ | |
294 | + 0, /* Attributes: Cont/Excl/Rst */ | |
295 | + tpm_u16(oldpw_sz) /* Size of <hmac/password> */ | |
296 | + /* STRING(oldpw) <hmac/password> (if any) */ | |
297 | + | |
298 | + /* TPM2B_AUTH (TPM2B_DIGEST) */ | |
299 | + /* tpm_u16(newpw_sz) Digest size, new pw length */ | |
300 | + /* STRING(newpw) Digest buffer, new pw */ | |
301 | + }; | |
302 | + int ret; | |
303 | + | |
304 | + /* | |
305 | + * Fill the command structure starting from the first buffer: | |
306 | + * - the old password (if any) | |
307 | + * - size of the new password | |
308 | + * - new password | |
309 | + */ | |
310 | + ret = pack_byte_string(command_v2, sizeof(command_v2), "sws", | |
311 | + offset, oldpw, oldpw_sz, | |
312 | + offset + oldpw_sz, newpw_sz, | |
313 | + offset + oldpw_sz + 2, newpw, newpw_sz); | |
314 | + offset += oldpw_sz + 2 + newpw_sz; | |
315 | + if (ret) | |
316 | + return TPM_LIB_ERROR; | |
317 | + | |
318 | + return tpm_sendrecv_command(command_v2, NULL, NULL); | |
319 | +} |