GNU-divert-to-card S2K format

Peter Lebbing peter at
Tue Feb 24 19:49:48 CET 2015

On 24/02/15 17:52, Werner Koch wrote:
> for everything else you need to look at the code (parse-packet.c)

RFC 4880 specifies that for a string-to-key usage octet of 255, the final two
bytes are a checksum, but it /is/ part of the encrypted data for v4 keys. I was
curious and also had a look at the packets and the source. For the
divert-to-card s2k, RFC 4880 is not very appropriate, and section 5.5.3 should,
I think, be freely interpreted as:

>  The packet contains:
>      - A Public-Key or Public-Subkey packet, as described above.
>      - One octet indicating string-to-key usage conventions.  Zero
>        indicates that the secret-key data is not encrypted.  255 or 254
>        indicates that a string-to-key specifier is being given.  Any
>        other value is a symmetric-key encryption algorithm identifier.

255 for plain checksum s2k

>      - [Optional] If string-to-key usage octet was 255 or 254, a one-
>        octet symmetric encryption algorithm.

cipher algo 0

>      - [Optional] If string-to-key usage octet was 255 or 254, a
>        string-to-key specifier.  The length of the string-to-key
>        specifier is implied by its type, as described above.

specifier 110
hash algo 0
3 bytes prefix GNU
(together 5 bytes)

>      - [Optional] If secret data is encrypted (string-to-key usage octet
>        not zero), an Initial Vector (IV) of the same length as the
>        cipher's block size.

Used to store up to 16 bytes of serial number

>      - Plain or encrypted multiprecision integers comprising the secret
>        key data.  These algorithm-specific fields are as described
>        below.
>      - If the string-to-key usage octet is zero or 255, then a two-octet
>        checksum of the plaintext of the algorithm-specific portion (sum
>        of all octets, mod 65536).  If the string-to-key usage octet was
>        254, then a 20-octet SHA-1 hash of the plaintext of the
>        algorithm-specific portion.  This checksum or hash is encrypted
>        together with the algorithm-specific fields (if string-to-key
>        usage octet is not zero).  Note that for all other values, a
>        two-octet checksum is required.

This whole block is absent! Somehow I expected no MPI's but two bytes where the
checksum should be. This is not the case.

Note that the serial number for OpenPGP cards has the following format:

D2 76 00 01 24
	RID (Registered Application Provider Identifier)[1] for FSFE
	Application identifier for OpenPGP Application
xx xx
	Version number: I've got 01 01 (1.1) and 02 00 (2.0) cards
xx xx
	Manufacturer: I've got
	00 01 PPC Card Systems
        00 05 ZeitControl
	The list is in g10/card-util.c
xx xx xx xx
	Serial number; note the duplicate use of the name; unique for a
	manufacturer (unless manufacturer in range ff 00 to ff fe)
00 00
	Reserved for Future Use

16 bytes in total

Cipher algo and hash algo are written as 0, but don't seem to be used/checked on

I just wrote that up because I think I figured it out and didn't want the effort
to go to waste... It is rather unchecked.




I use the GNU Privacy Guard (GnuPG) in combination with Enigmail.
You can send me encrypted mail if you want some privacy.
My key is available at <>

More information about the Gnupg-users mailing list