diff --git a/README.md b/README.md index 338e387..d44551a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ performance. Supported platforms: Linux, BSD, macOS, Windows -Files are secured with uses ChaCha20, Curve25519, and SHA-256. +Files are secured with uses ChaCha20, Curve25519, and HMAC-SHA256. ## Usage @@ -90,17 +90,17 @@ The process for encrypting a file: 4. Write the 8-byte IV. 5. Write the 32-byte ephemeral public key. 6. Encrypt the file with ChaCha20 and write the ciphertext. -7. Write `sha256(key + sha256(plaintext))`. +7. Write `HMAC(key, plaintext)`. The process for decrypting a file: 1. Read the 8-byte ChaCha20 IV. -2. Read the 32-byte ephemeral public key +2. Read the 32-byte ephemeral public key. 3. Perform a Curve25519 Diffie-Hellman key exchange with the ephemeral public key. 4. Initialize ChaCha20 with the shared secret as the key. 5. Decrypt the ciphertext using ChaCha20. -6. Verify `sha256(key + sha256(plaintext))`. +7. Write `HMAC(key, plaintext)`. ## Compile-time configuration diff --git a/enchive.c b/enchive.c index 4a00e83..ae6f67e 100644 --- a/enchive.c +++ b/enchive.c @@ -418,11 +418,18 @@ symmetric_encrypt(FILE *in, FILE *out, u8 *key, u8 *iv) { static u8 buffer[2][CHACHA_BLOCKLENGTH * 1024]; u8 msghash[SHA256_BLOCK_SIZE]; + u8 hmac_pad[SHA256_BLOCK_SIZE]; SHA256_CTX hash[1]; chacha_ctx ctx[1]; + int i; + chacha_keysetup(ctx, key, 256); chacha_ivsetup(ctx, iv); + sha256_init(hash); + for (i = 0; i < SHA256_BLOCK_SIZE; i++) + hmac_pad[i] = key[i] ^ 0x36U; + sha256_update(hash, hmac_pad, sizeof(hmac_pad)); for (;;) { size_t z = fread(buffer[0], 1, sizeof(buffer[0]), in); @@ -441,7 +448,9 @@ symmetric_encrypt(FILE *in, FILE *out, u8 *key, u8 *iv) sha256_final(hash, msghash); sha256_init(hash); - sha256_update(hash, key, 32); + for (i = 0; i < SHA256_BLOCK_SIZE; i++) + hmac_pad[i] = key[i] ^ 0x5cU; + sha256_update(hash, hmac_pad, sizeof(hmac_pad)); sha256_update(hash, msghash, sizeof(msghash)); sha256_final(hash, msghash); @@ -459,11 +468,18 @@ symmetric_decrypt(FILE *in, FILE *out, u8 *key, u8 *iv) { static u8 buffer[2][CHACHA_BLOCKLENGTH * 1024 + SHA256_BLOCK_SIZE]; u8 msghash[SHA256_BLOCK_SIZE]; + u8 hmac_pad[SHA256_BLOCK_SIZE]; SHA256_CTX hash[1]; chacha_ctx ctx[1]; + int i; + chacha_keysetup(ctx, key, 256); chacha_ivsetup(ctx, iv); + sha256_init(hash); + for (i = 0; i < SHA256_BLOCK_SIZE; i++) + hmac_pad[i] = key[i] ^ 0x36U; + sha256_update(hash, hmac_pad, sizeof(hmac_pad)); /* Always keep SHA256_BLOCK_SIZE bytes in the buffer. */ if (!(fread(buffer[0], SHA256_BLOCK_SIZE, 1, in))) { @@ -495,7 +511,9 @@ symmetric_decrypt(FILE *in, FILE *out, u8 *key, u8 *iv) sha256_final(hash, msghash); sha256_init(hash); - sha256_update(hash, key, 32); + for (i = 0; i < SHA256_BLOCK_SIZE; i++) + hmac_pad[i] = key[i] ^ 0x5cU; + sha256_update(hash, hmac_pad, sizeof(hmac_pad)); sha256_update(hash, msghash, sizeof(msghash)); sha256_final(hash, msghash);