Minimal GnuPG-processable File

Michael Halcrow mike at
Thu Sep 2 19:04:46 CEST 2004

I'm working on an encrypting filesystem that has the option of writing
files that are in OpenPGP format.  I've been looking over RFC 2440 and
the source for GnuPG, and I would like to verify something with
someone who is knowledgeable in this subject, just to make sure that I
am on the right track.  I'm not asking a lot; I just want to know that
I will be debugging code that resembles something sane in the first

I want to start out as simple as possible - basically, a
passphrase-encrypted session key and a packet of encrypted data.  I
need to write out, byte-for-byte, this entire file, and GnuPG needs to
be able to decrypt it with a passphrase.  Here is what I have so far
(basically, I'm writing an ESK packet (tag 3) and a data packet (tag

page_virt = (__user char*)kmalloc( PAGE_CACHE_SIZE, GFP_USER );
i = 0;
page_virt[i++] = 0xc3; /* ctb; tag 3 = ESK */
i++; /* size comes later */

/* - A one-octet version number. The only currently defined
 * version is 4. */
page_virt[i++] = 4;

/* - A one-octet number describing the symmetric algorithm
 *   used. */
page_virt[i++] = 4; /* Blowfish */

/* - A string-to-key (S2K) specifier, length as defined
 * above. */
page_virt[i++] = 0x01; /* salted s2k */
page_virt[i++] = 1; /* md5 */
memcpy( &page_virt[i], "saltsalt", 8 ); /* test value */
i += 8;

/* - Optionally, the encrypted session key itself, which is
 *   decrypted with the string-to-key object. */
cryptfs_md5( session_key_encryption_key, "saltsaltpassword", 16 );

/* The decryption result consists of a one-octet algorithm
 * identifier that specifies the symmetric-key encryption algorithm
 * used to encrypt the following Symmetrically Encrypted Data Packet,
 * followed by the session key octets themselves. */
cipher_and_session_key[0] = 4; /* Blowfish */
memcpy( &cipher_and_session_key[1], crypt_stats->key,
        crypt_stats->key_size_bits/8 );

/* ... crypto initialization code removed for brevity ... */

crypto_cipher_encrypt( tfm, dest_sg, src_sg,
                       (crypt_stats->key_size_bits/8)+1 );
memcpy( &page_virt[i], encrypted_cipher_and_session_key,
        (crypt_stats->key_size_bits/8)+1 );
i += (crypt_stats->key_size_bits/8)+1;
page_virt[1] = i;

So at this point, I've written out an ESK packet (I hope).  Now, can I
just follow it up with a Symmetrically Encrypted Data Packet (Tag 9)
packet, right?  And it is a requirement that I encapsulate a plaintext
packet in the encrypted packet, or can I just write raw data?

I am going to be testing this code next week, and it would really
speed up the debugging process if someone could let me know whether or
not I am even on the right track here, or if there is some glaring
omission (like, I'm missing a required packet or making a silly

                         Michael A. Halcrow                          
       Security Software Engineer, IBM Linux Technology Center       
GnuPG Fingerprint: 05B5 08A8 713A 64C1 D35D  2371 2D3C FDDA 3EB6 601D
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : /pipermail/attachments/20040902/fe9475d8/attachment.bin

More information about the Gnupg-devel mailing list