Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cli redesign #88

Merged
merged 2 commits into from
Jul 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,30 +60,30 @@ The project includes hooks for [dracut](https://dracut.wiki.kernel.org/),
the TOTP during boot using [Plymouth](https://www.freedesktop.org/wiki/Software/Plymouth/).
They are automatically installed if the corresponding tool is found on the
system (also see [INSTALL](INSTALL.md) regarding necessary configuration
options). To use them, install tpm2-totp and generate a TOTP secret, then enable
options). To use them, install tpm2-totp and initialize a TOTP secret, then enable
the tpm2-totp hook in your initramfs generator and rebuild the initramfs.

# Usage

## Setup
The TOTP secret can be generated with and without password. It is recommended to
The TOTP secret can be initialized with and without password. It is recommended to
set a password `-P`in order to enable recovery options. Also the PCRs and PCR
banks can be selected `-p` and `-b`. Default values are PCRs `0,2,4` and
banks `SHA1, SHA256`.
```
tpm2-totp generate
tpm2-totp -P verysecret generate
tpm2-totp -P verysecret -p 0,1,2,3,4,5,6 generate
tpm2-totp -p 0,1,2,3,4,5,6 -b SHA1,SHA256 generate
tpm2-totp init
tpm2-totp -P verysecret init
tpm2-totp -P verysecret -p 0,1,2,3,4,5,6 init
tpm2-totp -p 0,1,2,3,4,5,6 -b SHA1,SHA256 init
```

## Boot
During boot the TOTP value for the current time, together with the current time
should be shown to the user, e.g. using plymouth from mkinitrd or from dracut.
The command to be executed is:
```
tpm2-totp calculate
tpm2-totp -t calculate
tpm2-totp show
tpm2-totp -t show
```

## Recovery
Expand All @@ -107,8 +107,8 @@ tpm2-totp clean
All command additionally take the `-N` option to specify the NV index to be
used. By default, 0x018094AF is used and recommended.
```
tpm2-totp -N 0x01800001 -P verysecret generate
tpm2-totp -N 0x01800001 calculate
tpm2-totp -N 0x01800001 -P verysecret init
tpm2-totp -N 0x01800001 show
tpm2-totp -N 0x01800001 -P verysecret recover
tpm2-totp -N 0x01800001 -P verysecret reseal
```
Expand All @@ -117,7 +117,7 @@ tpm2-totp -N 0x01800001 -P verysecret reseal
Whilst tpm2-totp provided the added security (in comparison to tpm-totp) that
the key will not leave the TPM during the calculate operation, the time source
is still not trustworthy and thus an attacker might in some situations be able
to generate a set of TOTP values for the future. Depending on the size of the
to calculate a set of TOTP values for the future. Depending on the size of the
possible attack window this can be very large though.

It is not yet possible to specify specific PCR values independent of the
Expand Down
2 changes: 1 addition & 1 deletion dist/dracut/README
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
This dracut module displays a time-based one-time password (TOTP) sealed to a
Trusted Platform Module (TPM) to ensure that the boot process has not been
tampered with. To set this up, a secret needs to be generated first and sealed
to the TPM using 'tpm2-totp generate'.
to the TPM using 'tpm2-totp init'.

This stores the secret in the TPM and displays it to the user so that it can
be recorded on a different device (e.g. a TOTP app). When the hook is run, the
Expand Down
4 changes: 2 additions & 2 deletions dist/dracut/module-setup.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

check() {
if [ -n "$hostonly" ]; then
if tpm2-totp calculate >/dev/null 2>&1; then
if tpm2-totp show >/dev/null 2>&1; then
return 0
else
dinfo "dracut module 'tpm2-totp' will not be installed because no TOTP is configured; run 'tpm2-totp generate'!"
dinfo "dracut module 'tpm2-totp' will not be installed because no TOTP is configured; run 'tpm2-totp init'!"
fi
fi
return 255
Expand Down
2 changes: 1 addition & 1 deletion dist/initcpio/install/plymouth-tpm2-totp.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ to a Trusted Platform Module (TPM) to ensure that the boot process has not been
tampered with. To set this up, a secret needs to be generated first and sealed
to the TPM using

tpm2-totp generate
tpm2-totp init

This stores the secret in the TPM and displays it to the user so that it can
be recorded on a different device (e.g. a TOTP app). When the hook is run, the
Expand Down
2 changes: 1 addition & 1 deletion dist/initcpio/install/sd-plymouth-tpm2-totp.in
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ to a Trusted Platform Module (TPM) to ensure that the boot process has not been
tampered with. To set this up, a secret needs to be generated first and sealed
to the TPM using

tpm2-totp generate
tpm2-totp init

This stores the secret in the TPM and displays it to the user so that it can
be recorded on a different device (e.g. a TOTP app). When the hook is run, the
Expand Down
2 changes: 1 addition & 1 deletion dist/initcpio/install/sd-tpm2-totp.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Platform Module (TPM) to ensure that the boot process has not been tampered
with. To set this up, a secret needs to be generated first and sealed to the
TPM using

tpm2-totp generate
tpm2-totp init

This stores the secret in the TPM and displays it to the user so that it can
be recorded on a different device (e.g. a TOTP app). When the hook is run, the
Expand Down
2 changes: 1 addition & 1 deletion dist/initcpio/install/tpm2-totp.in
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Platform Module (TPM) to ensure that the boot process has not been tampered
with. To set this up, a secret needs to be generated first and sealed to the
TPM using

tpm2-totp generate
tpm2-totp init

This stores the secret in the TPM and displays it to the user so that it can
be recorded on a different device (e.g. a TOTP app). When the hook is run, the
Expand Down
2 changes: 1 addition & 1 deletion dist/show-tpm2-totp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh
while true; do
totp="$(tpm2-totp --time "$@" calculate)" || break
totp="$(tpm2-totp --time "$@" show)" || break
printf '\n%s\n' "$totp"
sleep $(( 30 - $(date +%s) % 30 ))
done
2 changes: 1 addition & 1 deletion dist/tpm2-totp.service.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ DefaultDependencies=no
[Service]
Environment="TPM2TOTP_TCTI=device:/dev/tpm0"
Type=oneshot
ExecStart=/bin/sh -c 'echo "TOTP: $(tpm2-totp --time calculate)"'
ExecStart=/bin/sh -c 'echo "TOTP: $(tpm2-totp --time show)"'
StandardOutput=tty

[Install]
Expand Down
36 changes: 18 additions & 18 deletions man/tpm2-totp.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
% DECEMBER 2018

# NAME
**tpm2-totp**(1) -- generate or calculate TPM based TOTPs
**tpm2-totp**(1) -- initialize or calculate and show TPM based TOTPs

# SYNOPSIS

**tpm2-totp** [*options*] <command>

# DESCRIPTION

**tpm2-totp** creates a key inside a TPM 2.0 that can be used to generate
**tpm2-totp** creates a key inside a TPM 2.0 that can be used to calculate
time-based onetime passwords (TOTPs) to demonstrate to the user that a platform
was not altered during his/her abscense and thus still trustworthy.

Expand All @@ -22,12 +22,12 @@ options.

## COMMANDS

* `generate`:
Generate a new TOTP secret.
* `init`:
Generate and store a new TOTP secret.
Possible options: `-b`, `-l`, `-N`, `-p`, `-P`, `-T`

* `calculate`:
Calculate a TOTP value.
* `show`:
Calculate and show a TOTP value.
Possible options: `-N`, `-t`, `-T`

* `reseal`:
Expand Down Expand Up @@ -60,10 +60,10 @@ options.
Selected PCR registers (default: 0,2,4,6)

* `-P <password>`, `--password <password>`:
Password for the secret (default: none) (commands: generate, recover, reseal)
Password for the secret (default: none) (commands: init, recover, reseal)

* `-t`, `--time`:
Display the date/time of the TOTP calculation (commands: calculate)
Display the date/time of the TOTP calculation (commands: show)

* `-T <tcti-name>[:<tcti-config>]`, `--tcti <tcti-name>[:<tcti-config>]`:
Select the TCTI to use. *tcti-name* is the name of the TCTI library.
Expand All @@ -82,24 +82,24 @@ options.
# EXAMPLES

## Setup
The TOTP secret can be generated with and without password. It is recommended to
The TOTP secret can be initialized with and without password. It is recommended to
set a password `-P`in order to enable recovery options. Also the PCRs and PCR
banks can be selected `-p` and `-b`. Default values are PCRs `0,2,4` and
banks `SHA1, SHA256`.
```
tpm2-totp generate
tpm2-totp -P verysecret generate
tpm2-totp -P verysecret -p 0,1,2,3,4,5,6 generate
tpm2-totp -p 0,1,2,3,4,5,6 -b SHA1,SHA256 generate
tpm2-totp init
tpm2-totp -P verysecret init
tpm2-totp -P verysecret -p 0,1,2,3,4,5,6 init
tpm2-totp -p 0,1,2,3,4,5,6 -b SHA1,SHA256 init
```

## Boot
During boot the TOTP value for the current time, together with the current time
should be shown to the user, e.g. using plymouth from mkinitrd or from dracut.
The command to be executed is:
```
tpm2-totp calculate
tpm2-totp -t calculate
tpm2-totp show
tpm2-totp -t show
```

## Recovery
Expand All @@ -123,8 +123,8 @@ tpm2-totp clean
All command additionally take the `-N` option to specify the NV index to be
used. By default, 0x018094AF is used and recommended.
```
tpm2-totp -N 0x01800001 -P verysecret generate
tpm2-totp -N 0x01800001 calculate
tpm2-totp -N 0x01800001 -P verysecret init
tpm2-totp -N 0x01800001 show
tpm2-totp -N 0x01800001 -P verysecret recover
tpm2-totp -N 0x01800001 -P verysecret reseal
```
Expand All @@ -135,7 +135,7 @@ to specify the TCTI to be used. If the TCTI is not specified explicitly, the
default TCTI configured on the system is used. To e.g. use the TPM simulator
bound to a given port, use
```
tpm2-totp -T mssim:port=2321 generate
tpm2-totp -T mssim:port=2321 init
```

# RETURNS
Expand Down
24 changes: 12 additions & 12 deletions src/tpm2-totp.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#define TPM2TOTP_ENV_TCTI "TPM2TOTP_TCTI"

char *help =
"Usage: [options] {generate|calculate|reseal|recover|clean}\n"
"Usage: [options] {init|show|reseal|recover|clean}\n"
"Options:\n"
" -h, --help print help\n"
" -b, --banks Selected PCR banks (default: SHA1,SHA256)\n"
Expand Down Expand Up @@ -61,7 +61,7 @@ static const struct option long_options[] = {
};

static struct opt {
enum { CMD_NONE, CMD_GENERATE, CMD_CALCULATE, CMD_RESEAL, CMD_RECOVER, CMD_CLEAN } cmd;
enum { CMD_NONE, CMD_INIT, CMD_SHOW, CMD_RESEAL, CMD_RECOVER, CMD_CLEAN } cmd;
int banks;
int nvindex;
char *password;
Expand All @@ -83,10 +83,10 @@ decode_totp_rc(int rc)
return "The TOTP secret has not been stored with a recovery password and thus cannot be retrieved.";
break;
case TPM2_RC_NV_DEFINED:
return "A TOTP secret is already stored, use 'calculate' to calculate the TOTP or 'clean' to delete it.";
return "A TOTP secret is already stored, use 'show' to calculate and show the TOTP or 'clean' to delete it.";
break;
case (TPM2_RC_HANDLE | TPM2_RC_1):
return "No TOTP secret is currently stored, use 'generate' to generate one.";
return "No TOTP secret is currently stored, use 'init' to generate and store one.";
break;
case (TPM2_RC_POLICY_FAIL | TPM2_RC_9):
return "The system state has changed, no TOTP could be calculated.";
Expand Down Expand Up @@ -235,22 +235,22 @@ parse_opts(int argc, char **argv)

/* parse the non-option arguments */
if (optind >= argc) {
ERR("Missing command: generate, calculate, reseal, recover, clean.\n\n");
ERR("Missing command: init, show, reseal, recover, clean.\n\n");
ERR("%s", help);
return -1;
}
if (!strcmp(argv[optind], "generate")) {
opt.cmd = CMD_GENERATE;
} else if (!strcmp(argv[optind], "calculate")) {
opt.cmd = CMD_CALCULATE;
if (!strcmp(argv[optind], "init")) {
opt.cmd = CMD_INIT;
} else if (!strcmp(argv[optind], "show")) {
opt.cmd = CMD_SHOW;
} else if (!strcmp(argv[optind], "reseal")) {
opt.cmd = CMD_RESEAL;
} else if (!strcmp(argv[optind], "recover")) {
opt.cmd = CMD_RECOVER;
} else if (!strcmp(argv[optind], "clean")) {
opt.cmd = CMD_CLEAN;
} else {
ERR("Unknown command: generate, calculate, reseal, recover, clean.\n\n");
ERR("Unknown command: init, show, reseal, recover, clean.\n\n");
ERR("%s", help);
return -1;
}
Expand Down Expand Up @@ -397,7 +397,7 @@ main(int argc, char **argv)
chkrc(rc, goto err);

switch(opt.cmd) {
case CMD_GENERATE:
case CMD_INIT:

rc = tpm2totp_generateKey(opt.pcrs, opt.banks, opt.password, tcti_context,
&secret, &secret_size,
Expand All @@ -412,7 +412,7 @@ main(int argc, char **argv)
goto err;

break;
case CMD_CALCULATE:
case CMD_SHOW:
rc = tpm2totp_loadKey_nv(opt.nvindex, tcti_context, &keyBlob, &keyBlob_size);
chkrc(rc, goto err);

Expand Down
2 changes: 1 addition & 1 deletion test/plymouth-tpm2-totp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ if [ -z "$plymouthd_pid" ]; then
exit 99
fi

tpm2-totp --banks SHA256 --pcrs 0 --nvindex 0x018094AF --password abc generate
tpm2-totp --banks SHA256 --pcrs 0 --nvindex 0x018094AF --password abc init

tpm2_pcrextend 0:sha256=0000000000000000000000000000000000000000000000000000000000000000
exit_status=0
Expand Down
10 changes: 5 additions & 5 deletions test/tpm2-totp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ if [ "$exit_status" -ne 1 ]; then
exit 1
fi

tpm2-totp -P abc -p 0,1,2,3,4,5,6 -b SHA1,SHA256 generate
tpm2-totp -P abc -p 0,1,2,3,4,5,6 -b SHA1,SHA256 init

# Changing an unselected PCR bank should not affect the TOTP calculation
tpm2_pcrextend 0:sha384=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

tpm2-totp -t calculate
tpm2-totp -t show

tpm2_pcrextend 1:sha1=0000000000000000000000000000000000000000

if tpm2-totp -t calculate; then
if tpm2-totp -t show; then
echo "The TOTP was calculated despite a changed PCR state!"
exit 1
fi
Expand All @@ -33,11 +33,11 @@ tpm2-totp -P abc -p 0,1,2,3,4,5,6 -b SHA1,SHA256 reseal
# Changing an unselected PCR bank should not affect the TOTP calculation
tpm2_pcrextend 0:sha384=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

tpm2-totp calculate
tpm2-totp show

tpm2_pcrextend 1:sha1=0000000000000000000000000000000000000000

if tpm2-totp calculate; then
if tpm2-totp show; then
echo "The TOTP was calculated despite a changed PCR state!"
exit 1
fi
Expand Down