mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-20 05:28:08 +00:00
Use 160 bits of ROM hash for TPM-less HOTP secret (up from 80)
HOTP/TOTP secrets don't have to be printable. Use binary data to include 160 bits of entropy instead of just 80. The secret is still limited to 20 bytes. Most keys now support up to 40 bytes, but tpmtotp is still limited to 20 bytes. Move the truncation to 20 bytes a bit later, for future improvements to detect the key's actual limit. Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
This commit is contained in:
parent
75cb8a070f
commit
0a35ef912f
@ -38,7 +38,7 @@ if [ "$CONFIG_TPM" = "y" ]; then
|
|||||||
tpmr unseal 4d47 0,1,2,3,4,7 312 "$HOTP_SECRET" \
|
tpmr unseal 4d47 0,1,2,3,4,7 312 "$HOTP_SECRET" \
|
||||||
|| fatal_error "Unable to unseal HOTP secret"
|
|| fatal_error "Unable to unseal HOTP secret"
|
||||||
else
|
else
|
||||||
# without a TPM, use the first 20 characters of the ROM SHA256sum
|
# without a TPM, generate a secret based on the SHA-256 of the ROM
|
||||||
secret_from_rom_hash > "$HOTP_SECRET" || die "Reading ROM failed"
|
secret_from_rom_hash > "$HOTP_SECRET" || die "Reading ROM failed"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -80,6 +80,9 @@ else
|
|||||||
HOTPKEY_BRANDING="HOTP USB Security Dongle"
|
HOTPKEY_BRANDING="HOTP USB Security Dongle"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Truncate the secret if it is longer than the maximum HOTP secret
|
||||||
|
truncate_max_bytes 20 "$HOTP_SECRET"
|
||||||
|
|
||||||
# try using factory default admin PIN
|
# try using factory default admin PIN
|
||||||
admin_pin="12345678"
|
admin_pin="12345678"
|
||||||
hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" >/dev/null 2>&1
|
hotp_initialize "$admin_pin" $HOTP_SECRET $counter_value "$HOTPKEY_BRANDING" >/dev/null 2>&1
|
||||||
|
@ -41,10 +41,13 @@ if [ "$CONFIG_TPM" = "y" ]; then
|
|||||||
DEBUG "Unsealing HOTP secret reuses TOTP sealed secret..."
|
DEBUG "Unsealing HOTP secret reuses TOTP sealed secret..."
|
||||||
tpmr unseal 4d47 0,1,2,3,4,7 312 "$HOTP_SECRET"
|
tpmr unseal 4d47 0,1,2,3,4,7 312 "$HOTP_SECRET"
|
||||||
else
|
else
|
||||||
# without a TPM, use the first 20 characters of the ROM SHA256sum
|
# without a TPM, generate a secret based on the SHA-256 of the ROM
|
||||||
secret_from_rom_hash > "$HOTP_SECRET" || die "Reading ROM failed"
|
secret_from_rom_hash > "$HOTP_SECRET" || die "Reading ROM failed"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Truncate the secret if it is longer than the maximum HOTP secret
|
||||||
|
truncate_max_bytes 20 "$HOTP_SECRET"
|
||||||
|
|
||||||
if ! hotp $counter_value < "$HOTP_SECRET"; then
|
if ! hotp $counter_value < "$HOTP_SECRET"; then
|
||||||
shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null
|
shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null
|
||||||
die 'Unable to compute HOTP hash?'
|
die 'Unable to compute HOTP hash?'
|
||||||
|
@ -349,7 +349,9 @@ load_config_value()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Generate secret value using first 20 chars of ROM SHA256 hash
|
# Generate a secret for TPM-less HOTP by reading the ROM. Output is the
|
||||||
|
# sha256sum of the ROM (binary, not printable), which can be truncated to the
|
||||||
|
# supported secret length.
|
||||||
secret_from_rom_hash() {
|
secret_from_rom_hash() {
|
||||||
local ROM_IMAGE="/tmp/coreboot-notpm.rom"
|
local ROM_IMAGE="/tmp/coreboot-notpm.rom"
|
||||||
|
|
||||||
@ -360,7 +362,7 @@ secret_from_rom_hash() {
|
|||||||
flash.sh -r "${ROM_IMAGE}" >/dev/null 2>&1 || return 1
|
flash.sh -r "${ROM_IMAGE}" >/dev/null 2>&1 || return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sha256sum ${ROM_IMAGE} | cut -f1 -d ' ' | cut -c 1-20 | tr -d '\n'
|
sha256sum "${ROM_IMAGE}" | cut -f1 -d ' ' | fromhex_plain
|
||||||
}
|
}
|
||||||
|
|
||||||
update_checksums()
|
update_checksums()
|
||||||
@ -589,6 +591,32 @@ calc()
|
|||||||
awk "BEGIN { print "$*" }";
|
awk "BEGIN { print "$*" }";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# truncate a file to a size only if it is longer (busybox truncate lacks '<' and
|
||||||
|
# always sets the file size)
|
||||||
|
truncate_max_bytes() {
|
||||||
|
local bytes="$1"
|
||||||
|
local file="$2"
|
||||||
|
if [ "$(stat -c %s "$file")" -gt "$bytes" ]; then
|
||||||
|
truncate -s "$bytes" "$file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Busybox xxd -p pads the last line with spaces to 60 columns, which not only
|
||||||
|
# trips up many scripts, it's very difficult to diagnose by looking at the
|
||||||
|
# output. Delete line breaks and spaces to really get plain hex output.
|
||||||
|
tohex_plain() {
|
||||||
|
xxd -p | tr -d '\n '
|
||||||
|
}
|
||||||
|
|
||||||
|
# Busybox xxd -p -r silently truncates lines longer than 60 hex chars.
|
||||||
|
# Shorter lines are OK, spaces are OK, and even splitting a byte across lines is
|
||||||
|
# allowed, so just fold the text to maximum 60 column lines.
|
||||||
|
# Note that also unlike GNU xxd, non-hex chars in input corrupt the output (GNU
|
||||||
|
# xxd ignores them).
|
||||||
|
fromhex_plain() {
|
||||||
|
fold -w 60 | xxd -p -r
|
||||||
|
}
|
||||||
|
|
||||||
print_battery_health()
|
print_battery_health()
|
||||||
{
|
{
|
||||||
if [ -d /sys/class/power_supply/BAT* ]; then
|
if [ -d /sys/class/power_supply/BAT* ]; then
|
||||||
|
Loading…
Reference in New Issue
Block a user