***************************** ** GECRYPT-0.5 FILE FORMAT ** ***************************** 2008-08-04 Dwayne C. Litzenberger ** DEFINITIONS ** Let || represent the string concatenation operator. Let S * N represent the string S repeated N times. Let length(X) represent the length (in octets) of the string X. Let UInt8(N) represent the unsigned 8-bit representation of N. Let UInt16(N) represent the unsigned 16-bit big-endian representation of N. Let ZPad(N) represent the zero-octet (ASCII NUL) repeated N times. All numbers are represented in network-endian (big-endian) byte order. ** DESCRIPTION ** Every gecrypt-0.5 file starts with a 64-octet cleartext header (FILE_HEADER) that consists of: a 128-bit constant (FILE_ID), a 256-bit nonce (NONCE), a 16-bit iteration count (ITERATIONS), and 14 bytes of zero-padding. The nonce should be randomly-generated, and must be unique for each file generated using the same passphrase. The iteration count must not be zero. FILE_HEADER := FILE_ID || NONCE || UInt16(ITERATIONS) || ZPad(14) ; 16-octet file-type identifier FILE_ID := 61 6d 1d 67 ca 29 4e 2e b9 8b c0 1f f0 47 03 00 Using the header as a salt, we derive three values from the user's secret passphrase using PBKDF2 (see RSA PKCS#5 v2.0) with HMAC-SHA256 as the underlying pseudorandom function: ; Using HMAC-SHA256 as the underlying pseudorandom function, invoke ; PBKDF2 with the following parameters: ; P := PASSPHRASE ; password ; S := FILE_HEADER ; salt ; c := ITERATIONS ; iteration count (between 1 and 65535) ; dkLen := 112 ; number of derived octets needed derived_octets := PBKDF2(PASSPHRASE, FILE_HEADER, ITERATIONS, 112) ; Let MAC_KEY be the first 64 octets of PBKDF2 output MAC_KEY := derived_octets<0..63> ; Let CIPHER_KEY be the next 32 octets of PBKDF2 output CIPHER_KEY := derived_octets<64..95> ; Let CIPHER_IV be the next (and last) 16 octets of PBKDF2 output CIPHER_IV := derived_octets<96..111> The cleartext header is followed by one or more "chunk" ciphertexts, which are each followed by a MAC that authenticates the contents of the (ciphertext) file up to that point. The plaintext for each encrypted chunk consists of a 16-bit length field, the payload data, and any padding necessary to make the chunk a multiple of 16 octets (the AES block size). The length field in each chunk consists of a single "ignore bit" followed by 15 bits that represend the length of the payload data. If the ignore bit is set, then the decoder must ignore the payload data (but only after checking that the MAC of the ciphertext is correct!). If the ignore bit is cleared and the length is zero, then the end of the file is reached. The last chunk in a file must have its length field set to zero, so that a decoder can detect a truncated file. ** TEST VECTORS ** 1. Simple test passphrase = "abc" (3 octets) nonce = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" (32 octets) iteration count = 1 FILE_HEADER = fb8a325ba7934f00ac36248ad91dc089 58585858585858585858585858585858 58585858585858585858585858585858 00010000000000000000000000000000 MAC_KEY = ce9d66e10f01c0415b65669cc01f5d7e 919b104ef0bc60844b08ab41ac25a6da edd113d0e9afbf29b870e23363342f86 a4882b0e80e5acd7c1ddb8d1b7e1dd90 (64 octets) CIPHER_KEY = 99cc90f06762a1f8b0d955f4b121f904 f8e813825ed66777cf29a0af9ebb2149 (32 octets) CIPHER_IV = 9bb46b00b057a2d57cb2efbfd69bab1f (16 octets) input = "hello" (5 octets) chunk[1].len = 0005 (2 octets) chunk[1].payload = "hello" (5 octets) chunk[1].padding = 000000000000000000 (9 octets) chunk[1].ptext = 000568656c6c6f000000000000000000 (16 octets) chunk[1].ctext = 46609c0c999513eeff02417fddb39cd4 (16 octets) chunk[1].mac = 32b46ff1a53cb205f203122c85c07a46 320f37c00a136bd690c865660fde73ea (32 octets) chunk[2].len = 0000 (2 octets) chunk[2].payload = (0 octets) chunk[2].padding = 0000000000000000000000000000 (14 octets) chunk[2].ptext = 00000000000000000000000000000000 (16 octets) chunk[2].ctext = 72b42058ccfcfc39e4ad1b37059b6ad9 (16 octets) chunk[2].mac = 19bba9db26dd7cdc64cfed62e6143eae 93c1f42630573c5c062dd6fb8e9d3e90 (32 octets) output = fb8a325ba7934f00ac36248ad91dc089 58585858585858585858585858585858 58585858585858585858585858585858 00010000000000000000000000000000 46609c0c999513eeff02417fddb39cd4 32b46ff1a53cb205f203122c85c07a46 320f37c00a136bd690c865660fde73ea 72b42058ccfcfc39e4ad1b37059b6ad9 19bba9db26dd7cdc64cfed62e6143eae 93c1f42630573c5c062dd6fb8e9d3e90 (160 octets) ** EOF **