***************************** ** GECRYPT-0.2 FILE FORMAT ** ***************************** 2007-07-29 Dwayne C. Litzenberger ** DEFINITIONS ** Let AES-CTR(K, N, M) represent the encryption (or decryption, which is equivalent) of M using AES in counter mode using key K and nonce N. Define the constants (represented as 128-bit big-endian integers): FILE_ID = 0x616d1d67ca294e2eb98bc01ff0470100 HEADER_ID = 0x616d1d67ca294e2eb98bc01ff0470101 Let || represent the string concatenation operator. Let S * N represent the string S repeated N times. Let Len(X) represent the length (in octets) of X. Let Int8(N) represent the unsigned 8-bit big-endian representation of N. Let Int16(N) represent the unsigned 16-bit big-endian representation of N. Let Int64(N) represent the unsigned 64-bit big-endian representation of N. ** HOW TO WRITE A GECRYPT-0.2 FILE ** 1. Get from the user: - The arbitrary-length master key K_M - The plaintext message M - The 16-bit iteration count c (must be >= 10. If the master key is a passphrase, c should be at least 1000.) - An optional, 64-bit padding size p. The default is 0 if none is specified. 2. Randomly generate: - 128-bit salt: S - 64-bit nonces: N_H, N_P - 128-, 192-, or 256-bit payload cipher key: K_P 3. Using the password-based key derivation function PBKDF2(P, S, c, dkLen) from RSA PKCS#5 v2.0, compute the session key (using HMAC-SHA256 as the underlying pseudorandom function): K = PBKDF2(K_M, FILE_ID || S, c, 96) 4. Set the authentication key K_A to be the first 512 bits of the session key: K_A = K<0..63> 5. Set the header cipher key K_H to be the last 256 bits of the session key: K_H = K<64..95> 6. Generate the encrypted portion of the header: C_H = AES-CTR(K_H, N_H, HEADER_ID || N_P || Int8(Len(K_P)) || K_P) 7. Generate the header: HEADER = FILE_ID || S || N_H || Int16(c) || C_H 8. Split the plaintext into n chunks M_1, M_2, ... M_n such that the length (in octets) of each chunk falls within the interval [1..2^16-1]. For each chunk M_i: Let L_i = Int16(Len(M_i)) 9. Generate the payload: PAYLOAD = L_1 || M_1 || L_2 || M_2 || ... || L_n || M_n || Int16(0) 10. Generate the padding: PAD = Int8(0) * p ; zero repeated p times PADDING = Int64(p) || PAD 11. Generate the ciphertext: CIPHERTEXT = AES-CTR(K_P, N_P, PAYLOAD || PADDING) 12. Generate the 256-bit MAC: MAC = HMAC-SHA256(K_A, HEADER || CIPHERTEXT) 13. Generate the final message: MESSAGE = HEADER || CIPHERTEXT || MAC 14. Output MESSAGE. ** EOF **