Page MenuHome GnuPG

ecdh/ecdsa private key export, MPI encoding oddity
Closed, ResolvedPublic

Description

In researching GnuPG ECC support, I generated a number of sample ECDH/ECDSA
keypairs and exported them to keyring format in order to analyze the data format
(and confirm that I was reading RFC 6637 correctly).

In doing so, I noticed that ECDH and ECDSA private keys are being encoded in an
unusual way, always indicating a bit count divisible by 8 even when the most
significant bit is zero. Furthermore, when the most significant bit IS set, an
extra 00 byte is being prepended (e.g. "01 08 00 88 a3 a2 ... 4a 0c" rather than
"01 00 88 a3 a2 ... 4a 0c"), analagous to what is done with ASN.1 encoding; in
the case of a NIST P-256 key, the private key's length was reported as 264 bits.

This does not appear to happen in any other places - MPIs in RSA/DSA/ELG
public/private keys, ECDH/ECDSA public keys, and encryption/signature data all
have appropriate bit counts and no leading null bytes.

I'm not certain if this is strictly incorrect (RFC 4880 section 3.2 states that
the length starts "from its most significant non-zero bit", but it does not
stipulate that it MUST be that way). However, it may lead to interoperability
issues as other applications start supporting ECDH/ECDSA keys.

Observed in gpg2 version 2.1.2 - not certain if the latest dev code also has it,
since I'm having trouble building it.

Details

Version
2.1.2

Event Timeline

andy_s set Version to 2.1.2.
andy_s added a subscriber: andy_s.

Well, this sounds more like a question than a bug. Can you please post it to
gnupg-devel?

Posted to the list, though not as a subscriber (so it'll need to be approved).

I apologize if I jumped the gun by posting here first - given that my question
was effectively "is this a bug?" (and that I was expecting the answer to be
"yes"), I was erring on the side of caution.

[Sorry, I didn't found your mail anymore.]

I fixed two bug related to the encoding of MPI created by ECC operations.
ab17f7b gpg: Create all MPIs with RFC-4880 correct length headers.
8bc1deb gpg: Fix broken write of opaque MPI length header.

However your problem was with private keys. Protected private keys or
non-protected? Can you add an example file.

The problem was with protected private keys - I've got my own tool for
decrypting them, and that's how I found the problem in the first place.

I've attached two keypairs which exhibit the issue, both in keyring and in
keybox+key formats (password is "password") - both use NIST P-256, and the
encryption key on Test2 (4e86073a308aa22e) has the extra leading zero byte on
its 'd' value.

Thanks. That was helpful.

Fixed with commit cf83ff0. You should now see no more leading zero bytes and
correct bit lengths after decrypting a protected key. Internally GnuPG may use
a leading zero byte but with an gpg --export it will be removed.

werner claimed this task.
werner removed a project: Restricted Project.