From 486b52f302156cfca70066647804bb6b4c52dedc Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sun, 17 Nov 2024 17:37:30 -0500 Subject: [PATCH] WiP initrd/bin/oem-factory-reset: add qrcode+secet output loop until user press y (end of reownership wizard secret output) Signed-off-by: Thierry Laurion works: - oem and user mode passphrase generation - qrcode missing: - unattended - luks reencryption + passphrase change for OEM mode (only input to be provided) with SINGLE passphrase when in unattended mode - same for user reownership when previously OEM reset unattended Signed-off-by: Thierry Laurion --- initrd/bin/oem-factory-reset | 31 +++++++++++++++++++++---------- initrd/etc/functions | 16 ++++++---------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 135ecbedb..9b5f81422 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -23,12 +23,10 @@ CANCEL="--no-button Cancel" HEIGHT="0" WIDTH="80" +# Default values USER_PIN_DEF=123456 ADMIN_PIN_DEF=12345678 TPM_PASS_DEF=12345678 -USER_PIN="" -ADMIN_PIN="" -TPM_PASS="" GPG_GEN_KEY_IN_MEMORY="n" GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD="n" @@ -50,11 +48,16 @@ handle_mode() { case $mode in oem) DEBUG "OEM mode selected" - # Add OEM mode specific logic here + CUSTOM_SINGLE_PASS=$(generate_passphrase --number_words 2 --max_length $MAX_HOTP_GPG_PIN_LENGTH) + USER_PIN=$CUSTOM_SINGLE_PASS + ADMIN_PIN=$CUSTOM_SINGLE_PASS + TPM_PASS=$CUSTOM_SINGLE_PASS ;; user) DEBUG "User mode selected" - # Add User mode specific logic here + USER_PIN=$(generate_passphrase --number_words 2 --max_length $MAX_HOTP_GPG_PIN_LENGTH) + ADMIN_PIN=$(generate_passphrase --number_words 2 --max_length $MAX_HOTP_GPG_PIN_LENGTH) + TPM_PASS=$ADMIN_PIN ;; *) warn "Unknown mode: $mode" @@ -81,6 +84,9 @@ done # Handle the --mode parameter if provided if [[ -n "$MODE" ]]; then handle_mode "$MODE" +else + # Default to User Re-Ownership mode + handle_mode "user" fi #Override RSA_KEY_LENGTH to 2048 bits for Canokey under qemu testing boards until canokey fixes @@ -719,9 +725,10 @@ generate_checksums() { fi DEBUG "Detach-signing boot files under kexec.sig: ${param_files}" - if sha256sum $param_files 2>/dev/null | DO_WITH_DEBUG gpg \ + + if sha256sum $param_files 2>/dev/null | gpg \ --pinentry-mode loopback \ - --passphrase "${USER_PIN}" \ + --passphrase-file <(echo -n "$USER_PIN") \ --digest-algo SHA256 \ --detach-sign \ -a \ @@ -1371,14 +1378,18 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then passphrases+="GPG key material backup passphrase: ${ADMIN_PIN}\n" fi -# Show qrcode of configured secrets and ask user to confirm scanning of and loop until confirmed with qrenc $passphrases +# Show configured secrets in whiptail and loop until user confirms qr code was scanned while true; do whiptail --msgbox " $(echo -e "$passphrases" | fold -w $((WIDTH - 5)))" \ $HEIGHT $WIDTH --title "Configured secrets" - qrencode "$passphrases" + # strip the initial newline of passphrases + qr_code=$(echo -e "$passphrases" | sed '1s/^\n//') + #Tell user to scan the QR code containing all configured secrets + echo -e "\nScan the QR code below to save the secrets to a secure location" + qrenc "$qr_code" # Prompt user to confirm scanning of qrcode on console prompt not whiptail: y/n - echo -e -n "Please confirm you have scanned the QR code above [y/N]: " + echo -e -n "Please confirm you have scanned the QR code above and/or written down the secrets? [y/N]: " read -n 1 prompt_output echo if [ "$prompt_output" == "y" -o "$prompt_output" == "Y" ]; then diff --git a/initrd/etc/functions b/initrd/etc/functions index 8bca8937d..aa57676d9 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -887,7 +887,7 @@ generate_passphrase() { local dictionary_file="$2" local word="" - word=$(grep "^$rolls" "$dictionary_file" | awk '{print $2}') + word=$(grep "^$rolls" "$dictionary_file" | awk -F ' ' '{print $2}') echo "$word" } @@ -898,17 +898,14 @@ generate_passphrase() { local rolls="" local random_bytes - # Read num_rolls bytes from /dev/urandom in one go - random_bytes=$(dd if=/dev/urandom bs=1 count="$num_rolls" 2>/dev/null | hexdump -e '1/1 "%u\n"') + # Read num_rolls bytes from /dev/random, fed by CPU RRAND in one go + random_bytes=$(dd if=/dev/random bs=1 count="$num_rolls" 2>/dev/null | hexdump -e '1/1 "%u\n"') # Process each byte to generate a dice roll while read -r byte; do roll=$((byte % 6 + 1)) - DEBUG "Randomized dice roll: $roll" rolls+=$roll done <<<"$random_bytes" - - DEBUG "Generated dice rolls: $rolls" echo "$rolls" } @@ -978,15 +975,12 @@ generate_passphrase() { exit 1 fi - digits=${#key} - DEBUG "Number of digits in dice rolls: $digits" + digits=${#key} #Number of digits in dice rolls for ((i = 0; i < num_words; ++i)); do key=$(generate_dice_rolls "$digits") word=$(get_word_from_dictionary "$key" "$dictionary_file") - DEBUG "Retrieved word: $word" if [[ "$lowercase" == "false" ]]; then - DEBUG "Capitalizing the first letter of the word" word=${word^} # Capitalize the first letter fi passphrase+="$word " @@ -997,6 +991,8 @@ generate_passphrase() { fi done + #Remove passphrase trailing space from passphrase+="$word" + passphrase=${passphrase% } echo "$passphrase" return 0 }