Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade from v6.0 to v6.2 broke pam u2f #91

Open
ByCzech opened this issue Jan 21, 2025 · 12 comments
Open

Upgrade from v6.0 to v6.2 broke pam u2f #91

ByCzech opened this issue Jan 21, 2025 · 12 comments

Comments

@ByCzech
Copy link

ByCzech commented Jan 21, 2025

After upgrade key to v6.2 pam u2f not working if key is unplugged from USB and plugged again. If new configuration is generated via pamu2fcfg, then auth working again, until key is unplugged and plugged to USB.

Debugging pam module says (after USB replug):

"Device for this keyhandle is not present"

@polhenarejos
Copy link
Owner

Can you provide steps to reproduce it and logs?

@ByCzech
Copy link
Author

ByCzech commented Jan 25, 2025

Debian GNU/Linux 12 + backports + backported pam-
u2f 1.3.0

Raspberry Pi Pico Zero RP2040 + Pico Fido.

  1. Added line on top of file /etc/pam.d/common-auth:
    auth sufficient pam_u2f.so cue

  2. Added Pico Key for auth:
    $ pamu2fcfg > ~/.config/Yubico/u2f_keys

  3. After this I can login via Pico Key, unlock screen etc. in Pico Fido 6.0 and 6.2 firmware. But when I unplug key from USB and plug it again, then 6.0 work well, but 6.2 don't. For 6.2 I have to repeat config via pamu2fcfg, to work it again until next unplug/plug Pico Key to USB

pico-fido-6.0-after-unplug.log
pico-fido-6.0-before-unplug.log
pico-fido-6.2-after-unplug.log
pico-fido-6.2-before-unplug.log

PS: I just found out that if a newly programmed Pico Key 6.2 does not have a PIN set (e.g. via fido2-token -S /dev/hidrawN), it works after unplugging it from USB and plugging it in back. After setting the PIN, it behaves as described above and see the logs. Strange.

@ByCzech
Copy link
Author

ByCzech commented Jan 26, 2025

Backported pam-u2f 1.3.2 same issue.

@polhenarejos
Copy link
Owner

Can you test with the last development version? There was an issue with linux, OTP and PCSC interfaces #96.

You can build it yourself or wait til tomorrow and use the nightly development build.

@polhenarejos
Copy link
Owner

TL;DR
The solution is to add pinverification=1 to your /etc/pam.d/ file. Do not forget to pamu2cfg again.

See #54 for an explanation.

@ByCzech
Copy link
Author

ByCzech commented Feb 1, 2025

Forcing pin verification isn't solution, because I don't want to use it. I only want user presence verification (by touching key / pressing button). Original keys from various manufacturers work the same way. (Btw. pinverification is configurable by pamu2cfg, see parameter -N, --pin-verification Require PIN verification during authentication, so every user can configure how he want to be verified with his key, don't need to set it in system PAM config). Firmware 6.0 works well with it too.

@polhenarejos
Copy link
Owner

It's hard to solve. If you don't want PIN verification, then your keys can be dumped really easy. Dumping the flash memory is something straightforward. Thus, I must encrypt the key material with an external key provided by the user, i.e., a PIN.
Firmware 6.0 worked well because this feature was not implemented. Actually, if you run v6.0 anyone can steal your key, dump the flash memory in 1 minute, and return it to you without notice. Then, the dumped content can be reflashed to another device and impersonate you. With v6.2 this is solved, but at expenses of providing a PIN.

IMHO, the purpose of having a FIDO key is to make more robust authentication problems; it's not having a button to log in without any password or PIN, which is a terrible security flaw btw.

@ByCzech
Copy link
Author

ByCzech commented Feb 2, 2025

It's hard to solve. If you don't want PIN verification, then your keys can be dumped really easy. Dumping the flash memory is something straightforward. Thus, I must encrypt the key material with an external key provided by the user, i.e., a PIN. Firmware 6.0 worked well because this feature was not implemented.

I understand. Thanks for clarification.

Actually, if you run v6.0 anyone can steal your key, dump the flash memory in 1 minute, and return it to you without notice.

Anyone is who? User that has physical access to my Pico key? Or application? Dumping has to be runned by somebody. How?

Then, the dumped content can be reflashed to another device and impersonate you. With v6.2 this is solved, but at expenses of providing a PIN.

So why entering PIN is not necessary until unplug key from USB? Does that mean, that dumping keys is possible on 6.2 too?

IMHO, the purpose of having a FIDO key is to make more robust authentication problems; it's not having a button to log in without any password or PIN, which is a terrible security flaw btw.

Other manufacturers of security keys has this problem too or this is problem only for Fido keys?

So best solution will be HW with integrated biometric. Hm...

@polhenarejos
Copy link
Owner

The flash can be dumped putting your board in BOOTSEL mode, like you did to flash the firmware, and with picotool it can be dumped to your disk.
To do so it requires to reboot the board. It must be done physically by pressing the button while reboot.

Other vendors assume the ROM cannot be tampered, relying in the hardware to protect the key material. But if someone finds an exploit (like in the past), then all sold boards are vulnerable by design. RP2350 has a security hardware but it was violated few weeks ago.

Pico Keys are not directly affected due to the encryption of the content. But then it requires a robust user input.

When you enter the PIN, a hash of it is stored in the RAM, which is used to decrypt the content when needed. If you reboot, the session is clreared and thus it must be entered again. The session however is cleared every 10 minutes of inactivity as stated by FIDO specs.

@ByCzech
Copy link
Author

ByCzech commented Feb 2, 2025

It is very difficult to ensure that any security device cannot be misused if you gain physical access to it. This is a generally known principle. But gaining physical access may not be a simple matter. If I gain physical access to a device such as the RP2040, I do not expect that it will not be misused, it must be assumed that it has been or will be misused. In such a case, it is necessary to replace the "lock in the door and thereby invalidate the original keys".
PS: Any data can also be dumped from the RP2350 if physical access is gained, even if is secure boot active. This depends primarily on the security of the hardware used. You may have seen this lecture: https://berlin-ak.ftp.media.ccc.de/congress/2024/h264-hd/38c3-625-eng-deu-Hacking_the_RP2350_hd.mp4

The flash can be dumped putting your board in BOOTSEL mode, like you did to flash the firmware, and with picotool it can be dumped to your disk. To do so it requires to reboot the board. It must be done physically by pressing the button while reboot.

So physical access to my device is needed. There is no possibility without it, right? I treat my keys in a way that no one else can physically access them. It doesn't matter if it's an electronic gadget or a regular door lock key, etc.

Other vendors assume the ROM cannot be tampered, relying in the hardware to protect the key material. But if someone finds an exploit (like in the past), then all sold boards are vulnerable by design. RP2350 has a security hardware but it was violated few weeks ago.

So, security through obscurity. This is not actually secure. Regarding the RP2350, I wrote above.

Pico Keys are not directly affected due to the encryption of the content. But then it requires a robust user input.

When you enter the PIN, a hash of it is stored in the RAM, which is used to decrypt the content when needed. If you reboot, the session is clreared and thus it must be entered again. The session however is cleared every 10 minutes of inactivity as stated by FIDO specs.

So dumping is possible after first PIN input is provided, because information is decrypted and situation is same from this moment like in FW 6.0, but it's in 10 mins window only?

Thanks for your explanation, it is very informative.

@ByCzech
Copy link
Author

ByCzech commented Feb 2, 2025

TL;DR The solution is to add pinverification=1 to your /etc/pam.d/ file. Do not forget to pamu2cfg again.

I tested FW 6.2 now with pinverification=1 forced in pam config, but behavior is same as without PIN verification. After unplug / plug device it stops working until I again run pamu2fcfg, then works again until next unplug / plug Pico Key. And so on and on. So this solution won't help.

Nightly build isn't available still. I can test it when be available or I build own, later.

@polhenarejos
Copy link
Owner

polhenarejos commented Feb 2, 2025

RP2350 is in its early stage and these issues will be solved in next revisions. They will be more robust but I will not leverage new enhancements to transfer security aspects; so I’d rather prefer continue encrypting the flash for a matter of design. If the flash is outside the die anyone can probe the bus between the MCU and the flash. If the communication bus is encrypted, then I could start thinking on new architectures but this is something I will not expect in the mid term.
RP2354 will be released soon, hopefully with the 4 security faults solved, with 4MB of embedded flash. In that case, combined with a fixed OTP, we could bypass the encryption with the PIN and move to an encryption with an OTP key. (Actually the encryption key is sourced by an OTP key in RP2350/ESP32 and the PIN). But I will need to review it first carefully before taking a decision.

“ So dumping is possible after first PIN input is provided, because information is decrypted and situation is same from this moment like in FW 6.0, but it's in 10 mins window only?”

No, this is not how it works. Flash is always encrypted. When a user key has to be retrieved, the portion of the key material is decryptes onto RAM and cleared before the function returns. The key for decryption is taken from a volatile hash of the PIN. This hash is cleared after 10 minutes of inactivity. But in the meantime, the keys can be retrieved by the firmware but nothing else. To dump the flash you must reboot the board, which clears the RAM. An attacker will get an encrypted content without a key.

Edit: I tested pinverification=1 and it does not work. Before asking the PIN, the driver performs something called "silent authentication", which is described in the specs but without an implementation. I followed some discussions and there are some concerns about privacy and traceability, which I guess is not relevant for a login use case. But in any case, it seems that is open to the vendor how to implement it. For instance, Webauthn does not allow silent authentication, but CTAP2 does. So, which to follow?

Here's an interesting paper describing an attack by exploiting consecutive silent authentications:

https://petsymposium.org/popets/2022/popets-2022-0129.pdf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants