mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-24 07:06:42 +00:00
WiP: NK3 with p256 ECC algo supported for in-memory keygen and key-to-card op. With this commit, one can provision NK3 with thumb drive backup which enables authenticated recovery shell and USB boot.
Signed-off-by: Thierry Laurion <insurgo@riseup.net>
This commit is contained in:
parent
2b21623bc6
commit
56b602974b
@ -45,6 +45,7 @@ Bootstrapping a working system
|
|||||||
* `sudo mount /dev/loop0p2 /media/fd_heads_gpg` to mount the second partition (public) or if only one partition, /dev/loop0p1
|
* `sudo mount /dev/loop0p2 /media/fd_heads_gpg` to mount the second partition (public) or if only one partition, /dev/loop0p1
|
||||||
* Look in `/media/fd_heads_gpg` and copy the most recent public key
|
* Look in `/media/fd_heads_gpg` and copy the most recent public key
|
||||||
* `sudo umount /media/fd_heads_gpg`
|
* `sudo umount /media/fd_heads_gpg`
|
||||||
|
* `sudo losetup --detach /dev/loop0`
|
||||||
6. Inject the GPG key into the Heads image and run again
|
6. Inject the GPG key into the Heads image and run again
|
||||||
* `make BOARD=qemu-coreboot-fbwhiptail-tpm1-hotp PUBKEY_ASC=<path_to_key.asc> inject_gpg`
|
* `make BOARD=qemu-coreboot-fbwhiptail-tpm1-hotp PUBKEY_ASC=<path_to_key.asc> inject_gpg`
|
||||||
* `make BOARD=qemu-coreboot-fbwhiptail-tpm1-hotp USB_TOKEN=LibremKey PUBKEY_ASC=<path_to_key.asc> run`
|
* `make BOARD=qemu-coreboot-fbwhiptail-tpm1-hotp USB_TOKEN=LibremKey PUBKEY_ASC=<path_to_key.asc> run`
|
||||||
|
@ -12,7 +12,7 @@ export CONFIG_LINUX_VERSION=5.10.5
|
|||||||
|
|
||||||
#Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing))
|
#Enable HAVE_GPG_KEY_BACKUP to test GPG key backup drive (we cannot inject config under QEMU (no internal flashing))
|
||||||
#TODO: comment following line prior of pushing final version
|
#TODO: comment following line prior of pushing final version
|
||||||
export CONFIG_HAVE_GPG_KEY_BACKUP=y
|
#export CONFIG_HAVE_GPG_KEY_BACKUP=y
|
||||||
|
|
||||||
#Enable DEBUG output
|
#Enable DEBUG output
|
||||||
export CONFIG_DEBUG_OUTPUT=y
|
export CONFIG_DEBUG_OUTPUT=y
|
||||||
|
@ -35,6 +35,8 @@ MAX_HOTP_GPG_PIN_LENGTH=25
|
|||||||
# What are the Security components affected by custom passwords
|
# What are the Security components affected by custom passwords
|
||||||
CUSTOM_PASS_AFFECTED_COMPONENTS=""
|
CUSTOM_PASS_AFFECTED_COMPONENTS=""
|
||||||
|
|
||||||
|
# Default GPG Algorithm is RSA
|
||||||
|
GPG_ALGO="RSA"
|
||||||
# Default RSA key length
|
# Default RSA key length
|
||||||
#TODO change it back to 3076. Canokey cannot be tested easily and Nitrokey prov1 I have doesn't key-attr to 3076
|
#TODO change it back to 3076. Canokey cannot be tested easily and Nitrokey prov1 I have doesn't key-attr to 3076
|
||||||
RSA_KEY_LENGTH=2048
|
RSA_KEY_LENGTH=2048
|
||||||
@ -70,7 +72,7 @@ whiptail_error_die() {
|
|||||||
die
|
die
|
||||||
}
|
}
|
||||||
|
|
||||||
#Generate a gpg master key: passwordless, no expiration date, RSA 4096 bits
|
#Generate a gpg master key: no expiration date, RSA 4096 bits
|
||||||
#This key will be used to sign 3 subkeys: encryption, authentication and signing
|
#This key will be used to sign 3 subkeys: encryption, authentication and signing
|
||||||
#The master key will be stored on the disk, and the subkeys on the smartcard
|
#The master key will be stored on the disk, and the subkeys on the smartcard
|
||||||
generate_inmemory_RSA_master_and_subkeys() {
|
generate_inmemory_RSA_master_and_subkeys() {
|
||||||
@ -169,6 +171,63 @@ generate_inmemory_RSA_master_and_subkeys() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Generate a gpg master key: no expiration date, p256 key (ECC)
|
||||||
|
#This key will be used to sign 3 subkeys: encryption, authentication and signing
|
||||||
|
#The master key will be stored on the disk, and the subkeys on the smartcard
|
||||||
|
generate_inmemory_p256_master_and_subkeys() {
|
||||||
|
DEBUG "Generating GPG key material in memory:"
|
||||||
|
gpg --expert --batch --pinentry-mode=loopback --passphrase ${ADMIN_PIN} --quick-generate-key "${GPG_USER_NAME} (${GPG_USER_COMMENT}) <${GPG_USER_MAIL}>" nistp256 cert 0
|
||||||
|
|
||||||
|
DEBUG "Getting master key fingerprint..."
|
||||||
|
MASTER_KEY_FP=$(gpg --list-secret-keys --with-colons | grep fpr | cut -d: -f10)
|
||||||
|
|
||||||
|
DEBUG "MASTER_KEY_FP=${MASTER_KEY_FP}"
|
||||||
|
|
||||||
|
DEBUG "Adding GPG nistp256 signing subkey to master key..."
|
||||||
|
{
|
||||||
|
echo addkey
|
||||||
|
echo 11 # ECC own set capability
|
||||||
|
echo Q # sign already present
|
||||||
|
echo 3 # P-256
|
||||||
|
echo 0 # no expiration
|
||||||
|
echo save # save the key
|
||||||
|
} | gpg --command-fd=0 --passphrase ${ADMIN_PIN} --pinentry-mode=loopback --expert --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
ERROR_MSG=$(cat /tmp/gpg_card_edit_output)
|
||||||
|
whiptail_error_die "Failed to add ECC nistp256 signing key to master key\n\n${ERROR_MSG}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
DEBUG "Adding GPG nistp256 encryption subkey to master key..."
|
||||||
|
{
|
||||||
|
echo addkey
|
||||||
|
echo 12# ECC encrypt only
|
||||||
|
echo E # encrypt already present
|
||||||
|
echo 3 # P-256
|
||||||
|
echo 0 # no expiration
|
||||||
|
echo save # save the key
|
||||||
|
} | gpg --command-fd=0 --passphrase ${ADMIN_PIN} --pinentry-mode=loopback --expert --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
ERROR_MSG=$(cat /tmp/gpg_card_edit_output)
|
||||||
|
whiptail_error_die "Failed to add ECC nistp256 encryption key to master key\n\n${ERROR_MSG}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
DEBUG "Adding GPG nistp256 authentication subkey to master key..."
|
||||||
|
{
|
||||||
|
echo addkey
|
||||||
|
echo 11 # ECC own set capability
|
||||||
|
echo S # deactivate sign
|
||||||
|
echo A # activate auth
|
||||||
|
echo Q # Quit
|
||||||
|
echo 3 # P-256
|
||||||
|
echo 0 # no expiration
|
||||||
|
echo save # save the key
|
||||||
|
} | gpg --command-fd=0 --passphrase ${ADMIN_PIN} --pinentry-mode=loopback --expert --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
ERROR_MSG=$(cat /tmp/gpg_card_edit_output)
|
||||||
|
whiptail_error_die "Failed to add ECC nistp256 authentication key to master key\n\n${ERROR_MSG}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
#Function to move current gpg keyring subkeys to card (keytocard)
|
#Function to move current gpg keyring subkeys to card (keytocard)
|
||||||
# This is aimed to be used after having generated master key and subkeys in memory and having backuped them to a LUKS container
|
# This is aimed to be used after having generated master key and subkeys in memory and having backuped them to a LUKS container
|
||||||
# This function will keytocard the subkeys from the master key in the keyring
|
# This function will keytocard the subkeys from the master key in the keyring
|
||||||
@ -435,23 +494,27 @@ gpg_key_factory_reset() {
|
|||||||
generate_OEM_gpg_keys() {
|
generate_OEM_gpg_keys() {
|
||||||
# Generate OEM GPG keys
|
# Generate OEM GPG keys
|
||||||
TRACE "Under oem-factory-reset:generate_OEM_gpg_keys"
|
TRACE "Under oem-factory-reset:generate_OEM_gpg_keys"
|
||||||
DEBUG "Generating GPG keys to RSA ${RSA_KEY_LENGTH} bits in smartcard..."
|
|
||||||
{
|
#TODO: finish refactoring to adapt to GPG_ALGO != RSA
|
||||||
echo admin
|
if [ "$GPG_ALGO" = "RSA" ]; then
|
||||||
echo generate
|
DEBUG "Generating GPG keys to RSA ${RSA_KEY_LENGTH} bits in smartcard..."
|
||||||
echo n
|
{
|
||||||
echo ${ADMIN_PIN_DEF}
|
echo admin
|
||||||
echo ${USER_PIN_DEF}
|
echo generate
|
||||||
echo 0
|
echo n
|
||||||
echo ${GPG_USER_NAME}
|
echo ${ADMIN_PIN_DEF}
|
||||||
echo ${GPG_USER_MAIL}
|
echo ${USER_PIN_DEF}
|
||||||
echo ${GPG_USER_COMMENT}
|
echo 0
|
||||||
echo ${USER_PIN_DEF}
|
echo ${GPG_USER_NAME}
|
||||||
} | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \
|
echo ${GPG_USER_MAIL}
|
||||||
>/tmp/gpg_card_edit_output 2>&1
|
echo ${GPG_USER_COMMENT}
|
||||||
if [ $? -ne 0 ]; then
|
echo ${USER_PIN_DEF}
|
||||||
ERROR=$(cat /tmp/gpg_card_edit_output)
|
} | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \
|
||||||
whiptail_error_die "GPG Key automatic keygen failed!\n\n$ERROR"
|
>/tmp/gpg_card_edit_output 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
ERROR=$(cat /tmp/gpg_card_edit_output)
|
||||||
|
whiptail_error_die "GPG Key automatic keygen failed!\n\n$ERROR"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -680,11 +743,10 @@ usb_security_token_capabilities_check() {
|
|||||||
DEBUG "Setting GPG_ALGO to (board-)configured: $CONFIG_GPG_ALGO"
|
DEBUG "Setting GPG_ALGO to (board-)configured: $CONFIG_GPG_ALGO"
|
||||||
fi
|
fi
|
||||||
# ... overwrite with usb-token capability
|
# ... overwrite with usb-token capability
|
||||||
#TODO: revert. Testing test firmware for Nitrokey 3 which is supposed to support RSA 3076 now
|
if lsusb | grep -q "20a0:42b2"; then
|
||||||
#if lsusb | grep -q "20a0:42b2"; then
|
GPG_ALGO="p256"
|
||||||
# GPG_ALGO="p256"
|
DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO"
|
||||||
# DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO"
|
fi
|
||||||
#fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
## main script start
|
## main script start
|
||||||
@ -722,7 +784,8 @@ $TPM_STR
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# We show current integrity measurements status and time
|
# We show current integrity measurements status and time
|
||||||
report_integrity_measurements
|
#TODO: Reactivate this prior of PR review
|
||||||
|
#report_integrity_measurements
|
||||||
|
|
||||||
# Determine gpg algorithm to be used, based on available usb-token
|
# Determine gpg algorithm to be used, based on available usb-token
|
||||||
usb_security_token_capabilities_check
|
usb_security_token_capabilities_check
|
||||||
@ -947,7 +1010,6 @@ assert_signable
|
|||||||
# clear local keyring
|
# clear local keyring
|
||||||
rm /.gnupg/* | true
|
rm /.gnupg/* | true
|
||||||
|
|
||||||
|
|
||||||
# detect and set /boot device
|
# detect and set /boot device
|
||||||
echo -e "\nDetecting and setting boot device...\n"
|
echo -e "\nDetecting and setting boot device...\n"
|
||||||
if ! detect_boot_device; then
|
if ! detect_boot_device; then
|
||||||
@ -962,7 +1024,6 @@ if [[ "$SKIP_BOOT" == "n" ]]; then
|
|||||||
combine_configs
|
combine_configs
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ -n "$luks_new_Disk_Recovery_Key_desired" -a -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then
|
if [ -n "$luks_new_Disk_Recovery_Key_desired" -a -n "$luks_new_Disk_Recovery_Key_passphrase_desired" ]; then
|
||||||
#Reencryption of disk, disk recovery key and Disk Recovery Key passphrase change is requested
|
#Reencryption of disk, disk recovery key and Disk Recovery Key passphrase change is requested
|
||||||
luks_reencrypt
|
luks_reencrypt
|
||||||
@ -992,14 +1053,27 @@ gpg --list-keys >/dev/null 2>&1
|
|||||||
|
|
||||||
#Generate key in memory and copy to smartcard
|
#Generate key in memory and copy to smartcard
|
||||||
if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then
|
if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then
|
||||||
# Generate GPG master key
|
# TODO: Refactoring in progress for RSA and p256 support. Now just GPG_ALGO RSA
|
||||||
generate_inmemory_RSA_master_and_subkeys
|
if [ "$GPG_ALGO" == "RSA" ]; then
|
||||||
#TODO seperate wiping and thumb drive functions with proper validation
|
# Generate GPG master key
|
||||||
wipe_thumb_drive_and_copy_gpg_key_material
|
generate_inmemory_RSA_master_and_subkeys
|
||||||
#TODO seperate setting config
|
#TODO seperate wiping and thumb drive functions with proper validation
|
||||||
set_user_config CONFIG_HAVE_GPG_KEY_BACKUP y
|
wipe_thumb_drive_and_copy_gpg_key_material
|
||||||
gpg_key_factory_reset
|
#TODO seperate setting config
|
||||||
keytocard_subkeys_to_smartcard
|
set_user_config CONFIG_HAVE_GPG_KEY_BACKUP y
|
||||||
|
gpg_key_factory_reset #TODO: do we currently double reset? I think so
|
||||||
|
keytocard_subkeys_to_smartcard
|
||||||
|
elif [ "$GPG_ALGO" == "p256" ]; then
|
||||||
|
generate_inmemory_p256_master_and_subkeys
|
||||||
|
#TODO seperate wiping and thumb drive functions with proper validation
|
||||||
|
wipe_thumb_drive_and_copy_gpg_key_material
|
||||||
|
#TODO seperate setting config
|
||||||
|
set_user_config CONFIG_HAVE_GPG_KEY_BACKUP y
|
||||||
|
gpg_key_factory_reset #TODO: do we currently double reset? I think so
|
||||||
|
keytocard_subkeys_to_smartcard
|
||||||
|
else
|
||||||
|
die "Unsupported GPG_ALGO: $GPG_ALGO"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
#Generate GPG key and subkeys on smartcard
|
#Generate GPG key and subkeys on smartcard
|
||||||
## reset the GPG Key
|
## reset the GPG Key
|
||||||
@ -1022,7 +1096,6 @@ if ! gpg --export --armor "$GPG_GEN_KEY" >"${PUBKEY}" 2>/tmp/error; then
|
|||||||
whiptail_error_die "GPG Key gpg export to file failed!\n\n$ERROR"
|
whiptail_error_die "GPG Key gpg export to file failed!\n\n$ERROR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
#Applying custom GPG PINs if keys were not generated in memory
|
#Applying custom GPG PINs if keys were not generated in memory
|
||||||
if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then
|
if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then
|
||||||
if [ "$USER_PIN" != "" -o "$ADMIN_PIN" != "" ]; then
|
if [ "$USER_PIN" != "" -o "$ADMIN_PIN" != "" ]; then
|
||||||
|
Loading…
Reference in New Issue
Block a user