Nitrokey / nitrokey-pro-firmware

Firmware for the Nitrokey Pro device
GNU General Public License v3.0
117 stars 21 forks source link

build_aes_key reports WrongPassword after factory reset #57

Open d-e-s-o opened 5 years ago

d-e-s-o commented 5 years ago

(this issue is somewhat similar to https://github.com/Nitrokey/nitrokey-storage-firmware/issues/80 but the symptoms are different and it only occurs on Pro devices)

When running build_aes_key after factory_reset on a Nitrokey Pro, I see a WrongPassword error being emitted (you may have to reset the card using gpg first).

int main()
{
    NK_set_debug(true);
    assert(NK_login_auto() == 1);
    assert(NK_factory_reset("12345678") == 0);
    sleep(10); // issue #80
    assert(NK_build_aes_key("12345678") == 0);
    return 0;
}
[Sun Jan 20 09:30:42 2019][DEBUG_L1]    Connection success: 1 ()
[Sun Jan 20 09:30:42 2019][DEBUG_L1]    Connection success: 0 ()
[Sun Jan 20 09:30:42 2019][DEBUG_L1]    Disconnection: handle already freed: 1 ()
[Sun Jan 20 09:30:42 2019][DEBUG]       -------------------
[Sun Jan 20 09:30:42 2019][DEBUG]       Outgoing HID packet:
[Sun Jan 20 09:30:42 2019][DEBUG]       Contents:
Command ID:     FACTORY_RESET
CRC:    ccd3b413
Payload:
 admin_password:        ***********

[Sun Jan 20 09:30:42 2019][DEBUG_L1]    => FACTORY_RESET
..........
[Sun Jan 20 09:30:43 2019][DEBUG]       Status busy, decreasing receiving_retry_counter counter: 4, current delay:200
[Sun Jan 20 09:30:43 2019][DEBUG_L1]    Busy retry: status 0, 200ms, counter 4, progress: 0
...........
[Sun Jan 20 09:30:46 2019][DEBUG]       Status busy, decreasing receiving_retry_counter counter: 3, current delay:300
[Sun Jan 20 09:30:46 2019][DEBUG_L1]    Busy retry: status 0, 300ms, counter 3, progress: 0
..
[Sun Jan 20 09:30:46 2019][DEBUG_L1]    <= FACTORY_RESET 0 0
[Sun Jan 20 09:30:46 2019][DEBUG]       Incoming HID packet:
[Sun Jan 20 09:30:46 2019][DEBUG]       Device status:  0 OK
Command ID:     FACTORY_RESET hex: 13
Last command CRC:       ccd3b413
Last command status:    0 STICK10::COMMAND_STATUS::OK
CRC:    32405835
Payload:
Empty Payload.
[Sun Jan 20 09:30:46 2019][DEBUG_L1]    Packet received with receiving_retry_counter count: 2
[Sun Jan 20 09:30:49 2019][DEBUG]       -------------------
[Sun Jan 20 09:30:49 2019][DEBUG]       Outgoing HID packet:
[Sun Jan 20 09:30:49 2019][DEBUG]       Contents:
Command ID:     NEW_AES_KEY
CRC:    52a99af0
Payload:
 admin_password:        ***********

[Sun Jan 20 09:30:49 2019][DEBUG_L1]    => NEW_AES_KEY
..........
[Sun Jan 20 09:30:50 2019][DEBUG]       Status busy, decreasing receiving_retry_counter counter: 4, current delay:200
[Sun Jan 20 09:30:50 2019][DEBUG_L1]    Busy retry: status 0, 200ms, counter 4, progress: 0
.....
[Sun Jan 20 09:30:51 2019][DEBUG_L1]    <= NEW_AES_KEY 0 0
[Sun Jan 20 09:30:51 2019][DEBUG]       Incoming HID packet:
[Sun Jan 20 09:30:51 2019][DEBUG]       Device status:  0 OK
Command ID:     NEW_AES_KEY hex: 6b
Last command CRC:       52a99af0
Last command status:    4 STICK10::COMMAND_STATUS::WRONG_PASSWORD
CRC:    2b5d073e
Payload:
Empty Payload.
[Sun Jan 20 09:30:51 2019][DEBUG_L1]    Throw: CommandFailedException 4
[Sun Jan 20 09:30:51 2019][DEBUG]       CommandFailedException, status: 4
test: test.cpp:11: int main(): Assertion `NK_build_aes_key("12345678") == 0' failed.
Aborted

The problem can seemingly be mitigated by inserting certain commands before the build_aes_key step. E.g.,

int main()
{
    NK_set_debug(true);
    assert(NK_login_auto() == 1);
    assert(NK_factory_reset("12345678") == 0);
    sleep(10);
    assert(NK_get_user_retry_count() == 3);
    assert(NK_build_aes_key("12345678") == 0);
    return 0;
}
szszszsz commented 5 years ago

Hi! Sorry for delay. I believe smart card synchronization code is indeed at fault here. I can add a workaround to libnitrokey to avoid this case. Is it still blocking the development for nitrocli?

Related: https://github.com/Nitrokey/nitrokey-pro-firmware/issues/37

d-e-s-o commented 5 years ago

No worries. We went ahead and merged the code for now (with the proposed addition of NK_get_user_retry_count as a work around). I won't release it until the root cause is understood, so it would be great if that could be investigated. My peeking at the firmware code was unfortunately not very successful in that respect, but I am not familiar with it so that was a long shot.

robinkrahl commented 3 years ago

Apparently, this is not only triggered by a factory reset, but also after writing to a PWS slot, see: https://github.com/d-e-s-o/nitrocli/pull/149