Card error trying to decrypt after changing PIN on RP2350 boards (works fine on RP2040) #27

Closed
opened 2025-01-08 04:51:16 +08:00 by 13pgeiser · 2 comments
13pgeiser commented 2025-01-08 04:51:16 +08:00 (Migrated from github.com)

Hello Pol,

Again: thanks a lot for sharing this nice piece of code!

I've discovered a strange behavior.

I tried to:

  • build
  • erase and flash
  • send keys
  • change pin
  • decrypt

On 3 different HWs:

  • Pico
  • Pico2
  • Tiny2350

The operation works perfectly fine on Pico and fails on both Pico2 and Tiny2350.

I called the script below 3 times (github prevents me to attached it sorry...) with 3 different HW connected to my machine:

./bpin.sh pico 2>&1 | tee log_pico.txt
./bpin.sh pico2 2>&1 | tee log_pico2.txt
./bpin.sh pimoroni_tiny2350 2>&1 | tee log_pimoroni_tiny2350.txt

The 3 logs are attached in case.

#!/bin/bash
set -ex
### Board options ###
BOARD="$1"
case "$BOARD" in
"pico")
	BOARD_FOLDER="RPI-RP2"
	;;
"pimoroni_tiny2350" | "pico2")
	BOARD_FOLDER="RP2350"
	;;
*)
	echo "Unsupported board: *$1*. Use either pico, pico2 or pimoroni_tiny2350"
	exit 1
	;;
esac
### Defaults ###
IDENTITY="pico openpgp<pico@openpgp.me>"
CERTIFY_PASS="test"
ADMIN_PASS="12345678"
PIN_PASS="123456"
### Remove pico-* folders, clone and build
function do_build {
	sudo apt install -y cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib opensc gnupg pcsc-tools
	rm -rf ./pico-*
	git clone https://github.com/raspberrypi/pico-sdk.git --branch 2.1.0 --recurse-submodules
	git clone https://github.com/polhenarejos/pico-openpgp.git --branch main --recurse-submodules
	mkdir -p pico-build
	cd pico-build
	cmake -DPICO_BOARD="$BOARD" -DVIDPID="Gnuk" -DPICO_SDK_PATH="../pico-sdk/" ../pico-openpgp
	make -j"$(nproc)"
	cd ..
}
### Wait for the card to reply correctly. ###
function wait_for_card_status {
	while ! gpg --card-status; do
		sleep 1
		echo "retry"
	done
}
### Erase memory first, then copy ###
function do_flash {
	if [ ! -e pico-build/flash_nuke.uf2 ]; then
		curl https://datasheets.raspberrypi.com/soft/flash_nuke.uf2 -o pico-build/flash_nuke.uf2
	fi
	cp pico-build/flash_nuke.uf2 "/media/$USER/$BOARD_FOLDER/"
	sleep 2
	while [ ! -e "/media/$USER/$BOARD_FOLDER/INFO_UF2.TXT" ]; do
		sleep 1
	done
	cp pico-build/pico_openpgp.uf2 "/media/$USER/$BOARD_FOLDER/"
	wait_for_card_status
}
### Create new keys, send them to the card, change pin and try to decrypt.
function do_test {
	# !!! WARNING deletes actual gnupg installation!!!
	rm -rf ~/.gnupg
	echo "$CERTIFY_PASS" | gpg --batch --passphrase-fd 0 --quick-generate-key "$IDENTITY" rsa cert never
	KEYFP=$(gpg -k --with-colons "$IDENTITY" | awk -F: '/^fpr:/ { print $10; exit }')
	echo "$CERTIFY_PASS" | gpg --batch --pinentry-mode=loopback --passphrase-fd 0 --quick-add-key "$KEYFP" rsa sign 1y
	echo "$CERTIFY_PASS" | gpg --batch --pinentry-mode=loopback --passphrase-fd 0 --quick-add-key "$KEYFP" rsa encr 1y
	echo "$CERTIFY_PASS" | gpg --batch --pinentry-mode=loopback --passphrase-fd 0 --quick-add-key "$KEYFP" rsa auth 1y
	gpg -K
	# Put key on card
	KEYID=$(gpg -k --with-colons "$IDENTITY" | awk -F: '/^pub:/ { print $5; exit }')
	wait_for_card_status
	gpg --command-fd=0 --pinentry-mode=loopback --edit-key "$KEYID" <<EOF
key 1
keytocard
1
$CERTIFY_PASS
$ADMIN_PASS
$ADMIN_PASS
key 1
key 2
keytocard
2
$CERTIFY_PASS
$ADMIN_PASS
key 2
key 3
keytocard
3
$CERTIFY_PASS
$ADMIN_PASS
save
EOF
	wait_for_card_status
	gpg -K
	gpg --command-fd=0 --pinentry-mode=loopback --edit-card <<EOF
admin
passwd
1
$PIN_PASS
654321
654321
3
$ADMIN_PASS
87654321
87654321
q
q
EOF
	ADMIN_PASS="87654321"
	PIN_PASS="654321"
	wait_for_card_status
	echo -e "5\ny\n" | gpg --command-fd 0 --expert --edit-key "$KEYFP" trust
	gpg-connect-agent "scd serialno" "learn --force" /bye
	gpg -K
	rm -f ./hello.*
	echo "hello" >hello.txt
	gpg -r pico@openpgp.me -e hello.txt
	rm -f hello.txt
	echo "$PIN_PASS" | gpg --batch --pinentry-mode=loopback --passphrase-fd 0 -d -d hello.txt.gpg
	rm -f hello.txt.gpg
}
do_build
do_flash
do_test

Have you already seen such issue?
Any idea how to debug?
Are you using gpg to change the pin or another tool?

Thanks for your help!

BR,

Pascal.

Hello Pol, Again: thanks a lot for sharing this nice piece of code! I've discovered a strange behavior. I tried to: * build * erase and flash * send keys * change pin * decrypt On 3 different HWs: * Pico * Pico2 * Tiny2350 The operation **works perfectly fine on Pico** and **fails on both Pico2 and Tiny2350**. I called the script below 3 times (github prevents me to attached it sorry...) with 3 different HW connected to my machine: ``` ./bpin.sh pico 2>&1 | tee log_pico.txt ./bpin.sh pico2 2>&1 | tee log_pico2.txt ./bpin.sh pimoroni_tiny2350 2>&1 | tee log_pimoroni_tiny2350.txt ``` The 3 logs are attached in case. * Successful: [log_pico.txt](https://github.com/user-attachments/files/18338301/log_pico.txt) * Failing: [log_pico2.txt](https://github.com/user-attachments/files/18338306/log_pico2.txt) * Failing: [log_pimoroni_tiny2350.txt](https://github.com/user-attachments/files/18338309/log_pimoroni_tiny2350.txt) ```bash #!/bin/bash set -ex ### Board options ### BOARD="$1" case "$BOARD" in "pico") BOARD_FOLDER="RPI-RP2" ;; "pimoroni_tiny2350" | "pico2") BOARD_FOLDER="RP2350" ;; *) echo "Unsupported board: *$1*. Use either pico, pico2 or pimoroni_tiny2350" exit 1 ;; esac ### Defaults ### IDENTITY="pico openpgp<pico@openpgp.me>" CERTIFY_PASS="test" ADMIN_PASS="12345678" PIN_PASS="123456" ### Remove pico-* folders, clone and build function do_build { sudo apt install -y cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib opensc gnupg pcsc-tools rm -rf ./pico-* git clone https://github.com/raspberrypi/pico-sdk.git --branch 2.1.0 --recurse-submodules git clone https://github.com/polhenarejos/pico-openpgp.git --branch main --recurse-submodules mkdir -p pico-build cd pico-build cmake -DPICO_BOARD="$BOARD" -DVIDPID="Gnuk" -DPICO_SDK_PATH="../pico-sdk/" ../pico-openpgp make -j"$(nproc)" cd .. } ### Wait for the card to reply correctly. ### function wait_for_card_status { while ! gpg --card-status; do sleep 1 echo "retry" done } ### Erase memory first, then copy ### function do_flash { if [ ! -e pico-build/flash_nuke.uf2 ]; then curl https://datasheets.raspberrypi.com/soft/flash_nuke.uf2 -o pico-build/flash_nuke.uf2 fi cp pico-build/flash_nuke.uf2 "/media/$USER/$BOARD_FOLDER/" sleep 2 while [ ! -e "/media/$USER/$BOARD_FOLDER/INFO_UF2.TXT" ]; do sleep 1 done cp pico-build/pico_openpgp.uf2 "/media/$USER/$BOARD_FOLDER/" wait_for_card_status } ### Create new keys, send them to the card, change pin and try to decrypt. function do_test { # !!! WARNING deletes actual gnupg installation!!! rm -rf ~/.gnupg echo "$CERTIFY_PASS" | gpg --batch --passphrase-fd 0 --quick-generate-key "$IDENTITY" rsa cert never KEYFP=$(gpg -k --with-colons "$IDENTITY" | awk -F: '/^fpr:/ { print $10; exit }') echo "$CERTIFY_PASS" | gpg --batch --pinentry-mode=loopback --passphrase-fd 0 --quick-add-key "$KEYFP" rsa sign 1y echo "$CERTIFY_PASS" | gpg --batch --pinentry-mode=loopback --passphrase-fd 0 --quick-add-key "$KEYFP" rsa encr 1y echo "$CERTIFY_PASS" | gpg --batch --pinentry-mode=loopback --passphrase-fd 0 --quick-add-key "$KEYFP" rsa auth 1y gpg -K # Put key on card KEYID=$(gpg -k --with-colons "$IDENTITY" | awk -F: '/^pub:/ { print $5; exit }') wait_for_card_status gpg --command-fd=0 --pinentry-mode=loopback --edit-key "$KEYID" <<EOF key 1 keytocard 1 $CERTIFY_PASS $ADMIN_PASS $ADMIN_PASS key 1 key 2 keytocard 2 $CERTIFY_PASS $ADMIN_PASS key 2 key 3 keytocard 3 $CERTIFY_PASS $ADMIN_PASS save EOF wait_for_card_status gpg -K gpg --command-fd=0 --pinentry-mode=loopback --edit-card <<EOF admin passwd 1 $PIN_PASS 654321 654321 3 $ADMIN_PASS 87654321 87654321 q q EOF ADMIN_PASS="87654321" PIN_PASS="654321" wait_for_card_status echo -e "5\ny\n" | gpg --command-fd 0 --expert --edit-key "$KEYFP" trust gpg-connect-agent "scd serialno" "learn --force" /bye gpg -K rm -f ./hello.* echo "hello" >hello.txt gpg -r pico@openpgp.me -e hello.txt rm -f hello.txt echo "$PIN_PASS" | gpg --batch --pinentry-mode=loopback --passphrase-fd 0 -d -d hello.txt.gpg rm -f hello.txt.gpg } do_build do_flash do_test ``` Have you already seen such issue? Any idea how to debug? Are you using gpg to change the pin or another tool? Thanks for your help! BR, Pascal.
polhenarejos commented 2025-01-08 05:08:51 +08:00 (Migrated from github.com)

RP2350 use an OTP key to encrypt the secret keys, while RP2040 doesn't. Perhaps it's something broken for RP2350.

Just for the record, flash_nuke.uf2 from rpi repo is only for Pico board 2M. You can find nuke firmwares for all boards at https://github.com/polhenarejos/pico-nuke/releases

RP2350 use an OTP key to encrypt the secret keys, while RP2040 doesn't. Perhaps it's something broken for RP2350. Just for the record, flash_nuke.uf2 from rpi repo is only for Pico board 2M. You can find nuke firmwares for all boards at [https://github.com/polhenarejos/pico-nuke/releases](https://github.com/polhenarejos/pico-nuke/releases)
13pgeiser commented 2025-01-09 02:27:28 +08:00 (Migrated from github.com)

Wow! That was fast!

Just for the record, flash_nuke.uf2 from rpi repo is only for Pico board 2M. You can find nuke firmwares for all boards at https://github.com/polhenarejos/pico-nuke/releases

Thanks for the hint! This will save me hours of future debugging ;-)

I can confirm that abb4d2326c solves the issue!

./bpin.sh pimoroni_tiny2350 | tee log_pimoroni_tiny2350.txt

log_pimoroni_tiny2350.txt

Many thanks!

Wow! That was fast! > Just for the record, flash_nuke.uf2 from rpi repo is only for Pico board 2M. You can find nuke firmwares for all boards at https://github.com/polhenarejos/pico-nuke/releases Thanks for the hint! This will save me hours of future debugging ;-) I can confirm that https://github.com/polhenarejos/pico-openpgp/commit/abb4d2326ce976a6c42a4354e61c8ae16eeec5ff solves the issue! `./bpin.sh pimoroni_tiny2350 | tee log_pimoroni_tiny2350.txt` [log_pimoroni_tiny2350.txt](https://github.com/user-attachments/files/18351463/log_pimoroni_tiny2350.txt) Many thanks!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dearsky/pico-openpgp#27