NK Start: Bad signature using ed25519 keys?

Hello,

I am observing the following strange behavior, that signatures from NK Start when using ed25519 keys are not verifiable.

✔ ~
joh@yksi ⌚ 21:43:40 <0> % ggpg --keyid-format long --list-secret-keys
/home/joh/.gnupg/pubring.kbx
----------------------------
sec#  ed25519/BCAD9887108EFDF4 2019-12-29 [C] [expires: 2024-12-27]
      7F1A07C05AF1A79F11C2CC24BCAD9887108EFDF4
uid                 [ultimate] Johannes Mueller <joh@johannes-mueller.org>
uid                 [ultimate] Johannes Mueller <github@johannes-mueller.org>
uid                 [ultimate] Johannes Mueller <johmue@keybase.io>
uid                 [ultimate] Johannes Mueller <joh@punkto.info>
ssb>  ed25519/E1E57DA4DDCD1ED6 2019-12-29 [SA] [expires: 2020-06-26]
ssb>  cv25519/A4B4D7A80E9D5C86 2019-12-29 [E] [expires: 2020-06-26]


✔ ~
joh@yksi ⌚ 21:44:29 <0> % gpg --card-status
Reader ...........: 20A0:4211:FSIJ-1.2.10-43245419:0
Application ID ...: D276000124010200FFFE432454190000
Application type .: OpenPGP
Version ..........: 2.0
Manufacturer .....: unmanaged S/N range
Serial number ....: 43245419
Name of cardholder: Johannes Mueller
Language prefs ...: [not set]
Salutation .......: 
URL of public key : https://johannes-mueller.org/public_key-2020.asc
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: ed25519 cv25519 ed25519
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
KDF setting ......: off
Signature key ....: A45C 4537 C822 DF43 CBDF  B67E E1E5 7DA4 DDCD 1ED6
      created ....: 2019-12-29 01:42:12
Encryption key....: 6F34 244F 3B48 AB6D 9F10  480D A4B4 D7A8 0E9D 5C86
      created ....: 2019-12-29 01:53:20
Authentication key: A45C 4537 C822 DF43 CBDF  B67E E1E5 7DA4 DDCD 1ED6
      created ....: 2019-12-29 01:42:12
General key info..: sub  ed25519/E1E57DA4DDCD1ED6 2019-12-29 Johannes Mueller <joh@johannes-mueller.org>
sec#  ed25519/BCAD9887108EFDF4  created: 2019-12-29  expires: 2024-12-27
ssb>  ed25519/E1E57DA4DDCD1ED6  created: 2019-12-29  expires: 2020-06-26
                                card-no: FFFE 43245419
ssb>  cv25519/A4B4D7A80E9D5C86  created: 2019-12-29  expires: 2020-06-26
                                card-no: FFFE 43245419

✔ ~
joh@yksi ⌚ 21:44:32 <0> % echo sign this | gpg --sign -u 7F1A07C05AF1A79F11C2CC24BCAD9887108EFDF4 | gpg --verify
gpg: Signature made Fri Feb  7 21:44:33 2020 CET
gpg:                using EDDSA key A45C4537C822DF43CBDFB67EE1E57DA4DDCD1ED6
gpg: BAD signature from "Johannes Mueller <joh@johannes-mueller.org>" [ultimate]

✘ [1] ~
joh@yksi ⌚ 21:44:33 <0> % 

Any idea what’s going on?

The signed not verifiable message:

joh@yksi ⌚ 21:44:33 <0> % echo sign this | gpg --sign -a -u 7F1A07C05AF1A79F11C2CC24BCAD9887108EFDF4               
-----BEGIN PGP MESSAGE-----

owGbwMvMwCH28Gntkrtn5a4xnhZIYoizPdNTnJmep1CSkVnM1VHKwiDGwSArpsiy
JMbV/ITSfefT97fVwXSwMoGUM3BxCsBE7jMz/NM8F+Lw63tvhvp8fh5n85kaWl53
Y99+O131LW99bQin1W9GhpVied3ZWgyc6w+9085+4vg1XPBlcKtrGdPuNUl/JoU/
5AIA
=UemJ
-----END PGP MESSAGE-----

✔ ~
joh@yksi ⌚ 21:46:04 <0> % 

Hello,

Sorry for the delay. Will see, how it behaves on my hardware. I assume you have imported the key to the device, is that right?

Yes, the key is imported to the device. It’s the signing subkey 0xE1E57DA4DDCD1ED6 from

✔ ~
joh@yksi ⌚ 21:01:49 <0> % gpg --list-secret-keys 7F1A07C05AF1A79F11C2CC24BCAD9887108EFDF4
sec#  ed25519/BCAD9887108EFDF4 2019-12-29 [C] [verfällt: 2024-12-27]
      7F1A07C05AF1A79F11C2CC24BCAD9887108EFDF4
uid              [ ultimativ ] Johannes Mueller <joh@johannes-mueller.org>
uid              [ ultimativ ] Johannes Mueller <github@johannes-mueller.org>
uid              [ ultimativ ] Johannes Mueller <johmue@keybase.io>
uid              [ ultimativ ] Johannes Mueller <joh@punkto.info>

here:

ssb>  ed25519/E1E57DA4DDCD1ED6 2019-12-29 [SA] [verfällt: 2020-06-26]
ssb>  cv25519/A4B4D7A80E9D5C86 2019-12-29 [E] [verfällt: 2020-06-26]

It’s shows up on the device:

✔ ~
joh@yksi ⌚ 21:01:58 <0> % gpg --card-status                                              
Reader ...........: 20A0:4211:FSIJ-1.2.10-43245419:0
Application ID ...: D276000124010200FFFE432454190000
Application type .: OpenPGP
Version ..........: 2.0
Manufacturer .....: unmanaged S/N range
Serial number ....: 43245419
Name of cardholder: Johannes Mueller
Language prefs ...: [nicht gesetzt]
Salutation .......: 
URL of public key : https://johannes-mueller.org/public_key-2020.asc
Login data .......: [nicht gesetzt]
Signature PIN ....: zwingend
Key attributes ...: ed25519 cv25519 ed25519
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
KDF setting ......: off

here

Signature key ....: A45C 4537 C822 DF43 CBDF  B67E E1E5 7DA4 DDCD 1ED6
      created ....: 2019-12-29 01:42:12
Encryption key....: 6F34 244F 3B48 AB6D 9F10  480D A4B4 D7A8 0E9D 5C86
      created ....: 2019-12-29 01:53:20
Authentication key: A45C 4537 C822 DF43 CBDF  B67E E1E5 7DA4 DDCD 1ED6
      created ....: 2019-12-29 01:42:12
General key info..: sub  ed25519/E1E57DA4DDCD1ED6 2019-12-29 Johannes Mueller <joh@johannes-mueller.org>
sec#  ed25519/BCAD9887108EFDF4  erzeugt: 2019-12-29  verfällt: 2024-12-27

and here

ssb>  ed25519/E1E57DA4DDCD1ED6  erzeugt: 2019-12-29  verfällt: 2020-06-26
                                Kartennummer:FFFE 43245419
ssb>  cv25519/A4B4D7A80E9D5C86  erzeugt: 2019-12-29  verfällt: 2020-06-26
                                Kartennummer:FFFE 43245419

✔ ~
joh@yksi ⌚ 21:02:13 <0> % 

The problem occurs both of my two NK Start with this key. The key is also properly cross certified. I have a backup of it on a persistent Tails volume. Signatures I create with that one are verified without problems on the same system which fails to verify the signature of the NK.

Any news here?

Can you tell us how you import your keys? For being able to replicate your setup this might help. In the end we do not know yet, what exactly is causing this problem. I guess it was GnuPG v2?

I did the following to reproduce:

  • use firmware 1.2.10
  • create a 25519 curve with gpg2
  • add a subkey with SA key usage
  • keytocard of E subkey to slot 2, keytocard of SA subkey on slot 1 and 3

This is what I got of your pastes. Anything I miss?

Hi @johmue!
Sorry for the long reply time. Your issue still troubles me and I keep this in mind.
In case you have not solved this yet, could you try to do the same in a VM, or another PC?

I had similar case lately, when the decryption was failing due to polluted GnuPG home directory, where I had multiple keys with the same email. The encryption was working with the proper key on the device, but to decrypt the first available one was taken (so no according to the fingerprint/id, but to the email id). I see in your listing you have only one key secret, but perhaps you have public ones with the same email which conflict?

Nitrokey Start firmware is tested on each release with a test suite and by hand against signing and verifying the signatures with GnuPG, so unless this was some edge case we have not tested against I think this could be caused from the host misconfiguration.
I have forgot initially to ask about OS and GnuPG version as well.

PS You could try to run the test suite by yourself to confirm the device is working - please let me know in that case.

Hi szszszsz,

Thanks for coming back to this.

it turns out that it is probably a gpg issue. With the new version 2.2.20, that I have now on my Arch system it works. With the older 2.2.4 on a Ubuntu 18.04 LTS it doesn’t.

An interesting combination is the agent of the 2.2.20 forwarded to a debian server with gpg 2.2.12. Signing works then, but ssh authentication does not. By ssh authentication I mean, that on the remote server there is an ssh client which wants to authenticate itself using a key on the NK device forwarded to by gpg-agent forwarding.

Do you have an idea how I can easily test if authentication works? Like gpg --authenticate $KEYID?

Hi @johmue!

Thank you for the update!
Indeed this case is interesting. I am not aware of any specific incompatible changes between these versions. Does making the signatures with on-disk key makes the same result? If not, maybe scdaemon logs would show the cause?

Unfortunately no. I have looked into the manual and run a brief web search, but nothing has came up besides testing the SSH connection directly (e.g. with ssh -T login@server).
You could try to use --default-key switch to make the signature with the authentication key, though I do not know will this work.

Ok, an update.

I updated my tails system on which I generated the keys. Then I generated new subkeys for signing and authenticating. I exported both an a NK Start.

Signing works with the new signature key on both, Ubuntu Bionic and Arch.

Authentication works … sometimes, maybe 2/3 of the attempts don’t work, the others do. The PIN of the card is only asked on the first attempt.

When it doesn’t work,

2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 <- SERIALNO
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> S SERIALNO D276000124010200FFFE432438310000
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 <- GETINFO card_list
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> S SERIALNO D276000124010200FFFE432438310000
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 <- SERIALNO --demand=D276000124010200FFFE432438310000
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> S SERIALNO D276000124010200FFFE432438310000
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 <- GETATTR $AUTHKEYID
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> S $AUTHKEYID OPENPGP.3
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 <- GETATTR SERIALNO
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> S SERIALNO D276000124010200FFFE432438310000
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 <- READKEY OPENPGP.3
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> [ 44 20 28 31 30 3a 70 75 62 6c 69 63 2d 6b 65 79 ...(83 byte(s) skipped) ]
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 <- GETATTR $DISPSERIALNO
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> S $DISPSERIALNO FFFE43243831
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 <- SERIALNO --demand=D276000124010200FFFE432438310000
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> S SERIALNO D276000124010200FFFE432438310000
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 <- SETDATA 3021300906052B0E03021A05000414000000DF000000650000008D52FC9CB1D1ADA71EA6AC4B54C0B598D15F37B161C9ECA418F3BF630AB435000EE617728D72E2E94F16A16EF6F7D8D1F9F49C00393D72B60AEBA3E555140542B54B958720AEDAB198E2BFA45854B85C87855B50C19D13BB62EAF7A37D7D302FB197F6B4C47BE89119A174696C34399E90CF805A4A94DE1783EEE1B823704BC4D923DB3CBFF58E189E3603561514000000036A6F68000000036A6F68000000047375646F000000092F686F6D652F6A6F680000001200000002000000047375646F000000022D6900000005746F6D7465000000005EB84DBE36000000036A6F680000001270616D5F7373685F6167656E745F61757468000000097075626C69636B6579010000000B7373682D65643235353139000000330000000B7373682D6564323535313900000020162FAC641653FE5EDE60241412FB61763A6D5893503F513504773D9593184CCA
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 <- PKAUTH OPENPGP.3
2020-05-10 20:53:50 scdaemon[23850] operation auth result: Ungültiger Wert
2020-05-10 20:53:50 scdaemon[23850] app_auth failed: Ungültiger Wert
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> ERR 100663351 Ungültiger Wert <SCD>
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 <- RESTART
2020-05-10 20:53:50 scdaemon[23850] DBG: chan_7 -> OK

When it does work:

2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 <- SERIALNO
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> S SERIALNO D276000124010200FFFE432438310000
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 <- GETINFO card_list
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> S SERIALNO D276000124010200FFFE432438310000
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 <- SERIALNO --demand=D276000124010200FFFE432438310000
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> S SERIALNO D276000124010200FFFE432438310000
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 <- GETATTR $AUTHKEYID
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> S $AUTHKEYID OPENPGP.3
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 <- GETATTR SERIALNO
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> S SERIALNO D276000124010200FFFE432438310000
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 <- READKEY OPENPGP.3
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> [ 44 20 28 31 30 3a 70 75 62 6c 69 63 2d 6b 65 79 ...(83 byte(s) skipped) ]
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 <- GETATTR $DISPSERIALNO
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> S $DISPSERIALNO FFFE43243831
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 <- SERIALNO --demand=D276000124010200FFFE432438310000
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> S SERIALNO D276000124010200FFFE432438310000
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 <- SETDATA 3021300906052B0E03021A050004140000007B0000006500000029AF9AB4D2BBEBD5B6DD096173F69BB9C41BCECE8C002841A518BD25465647AD359EC29EF94B840AFE79000000036A6F68000000036A6F68000000047375646F000000092F686F6D652F6A6F680000001200000002000000047375646F000000022D6900000005746F6D7465000000005EB84DC236000000036A6F680000001270616D5F7373685F6167656E745F61757468000000097075626C69636B6579010000000B7373682D65643235353139000000330000000B7373682D6564323535313900000020162FAC641653FE5EDE60241412FB61763A6D5893503F513504773D9593184CCA
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 <- PKAUTH OPENPGP.3
2020-05-10 20:53:54 scdaemon[23850] operation auth result: Erfolg
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> [ 44 20 08 bd 6f 79 6d 6f 2f e2 fc 44 62 1e 5f 50 ...(50 byte(s) skipped) ]
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> OK
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 <- RESTART
2020-05-10 20:53:54 scdaemon[23850] DBG: chan_7 -> OK
1 Like

Thank you for the update! Will take a look into this, with a possible stress test in mind.

Edit: ticket nitrokey-start-firmware/issues/32