mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-19 21:17:55 +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
|
||||
* Look in `/media/fd_heads_gpg` and copy the most recent public key
|
||||
* `sudo umount /media/fd_heads_gpg`
|
||||
* `sudo losetup --detach /dev/loop0`
|
||||
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 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))
|
||||
#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
|
||||
export CONFIG_DEBUG_OUTPUT=y
|
||||
|
@ -35,6 +35,8 @@ MAX_HOTP_GPG_PIN_LENGTH=25
|
||||
# What are the Security components affected by custom passwords
|
||||
CUSTOM_PASS_AFFECTED_COMPONENTS=""
|
||||
|
||||
# Default GPG Algorithm is RSA
|
||||
GPG_ALGO="RSA"
|
||||
# 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
|
||||
RSA_KEY_LENGTH=2048
|
||||
@ -70,7 +72,7 @@ whiptail_error_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
|
||||
#The master key will be stored on the disk, and the subkeys on the smartcard
|
||||
generate_inmemory_RSA_master_and_subkeys() {
|
||||
@ -169,6 +171,63 @@ generate_inmemory_RSA_master_and_subkeys() {
|
||||
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)
|
||||
# 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
|
||||
@ -435,23 +494,27 @@ gpg_key_factory_reset() {
|
||||
generate_OEM_gpg_keys() {
|
||||
# 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..."
|
||||
{
|
||||
echo admin
|
||||
echo generate
|
||||
echo n
|
||||
echo ${ADMIN_PIN_DEF}
|
||||
echo ${USER_PIN_DEF}
|
||||
echo 0
|
||||
echo ${GPG_USER_NAME}
|
||||
echo ${GPG_USER_MAIL}
|
||||
echo ${GPG_USER_COMMENT}
|
||||
echo ${USER_PIN_DEF}
|
||||
} | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \
|
||||
>/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"
|
||||
|
||||
#TODO: finish refactoring to adapt to GPG_ALGO != RSA
|
||||
if [ "$GPG_ALGO" = "RSA" ]; then
|
||||
DEBUG "Generating GPG keys to RSA ${RSA_KEY_LENGTH} bits in smartcard..."
|
||||
{
|
||||
echo admin
|
||||
echo generate
|
||||
echo n
|
||||
echo ${ADMIN_PIN_DEF}
|
||||
echo ${USER_PIN_DEF}
|
||||
echo 0
|
||||
echo ${GPG_USER_NAME}
|
||||
echo ${GPG_USER_MAIL}
|
||||
echo ${GPG_USER_COMMENT}
|
||||
echo ${USER_PIN_DEF}
|
||||
} | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \
|
||||
>/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
|
||||
}
|
||||
|
||||
@ -680,11 +743,10 @@ usb_security_token_capabilities_check() {
|
||||
DEBUG "Setting GPG_ALGO to (board-)configured: $CONFIG_GPG_ALGO"
|
||||
fi
|
||||
# ... 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
|
||||
# GPG_ALGO="p256"
|
||||
# DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO"
|
||||
#fi
|
||||
if lsusb | grep -q "20a0:42b2"; then
|
||||
GPG_ALGO="p256"
|
||||
DEBUG "Nitrokey 3 detected: Setting GPG_ALGO to: $GPG_ALGO"
|
||||
fi
|
||||
}
|
||||
|
||||
## main script start
|
||||
@ -722,7 +784,8 @@ $TPM_STR
|
||||
fi
|
||||
|
||||
# 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
|
||||
usb_security_token_capabilities_check
|
||||
@ -947,7 +1010,6 @@ assert_signable
|
||||
# clear local keyring
|
||||
rm /.gnupg/* | true
|
||||
|
||||
|
||||
# detect and set /boot device
|
||||
echo -e "\nDetecting and setting boot device...\n"
|
||||
if ! detect_boot_device; then
|
||||
@ -962,7 +1024,6 @@ if [[ "$SKIP_BOOT" == "n" ]]; then
|
||||
combine_configs
|
||||
fi
|
||||
|
||||
|
||||
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
|
||||
luks_reencrypt
|
||||
@ -992,14 +1053,27 @@ gpg --list-keys >/dev/null 2>&1
|
||||
|
||||
#Generate key in memory and copy to smartcard
|
||||
if [ "$GPG_GEN_KEY_IN_MEMORY" == "1" ]; then
|
||||
# Generate GPG master key
|
||||
generate_inmemory_RSA_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
|
||||
keytocard_subkeys_to_smartcard
|
||||
# TODO: Refactoring in progress for RSA and p256 support. Now just GPG_ALGO RSA
|
||||
if [ "$GPG_ALGO" == "RSA" ]; then
|
||||
# Generate GPG master key
|
||||
generate_inmemory_RSA_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
|
||||
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
|
||||
#Generate GPG key and subkeys on smartcard
|
||||
## 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"
|
||||
fi
|
||||
|
||||
|
||||
#Applying custom GPG PINs if keys were not generated in memory
|
||||
if [ "$GPG_GEN_KEY_IN_MEMORY" == "0" ]; then
|
||||
if [ "$USER_PIN" != "" -o "$ADMIN_PIN" != "" ]; then
|
||||
|
Loading…
Reference in New Issue
Block a user