idCrypt v1.0 - by emoose

===
Info
===
idCrypt is a command-line tool that allows you to decrypt those awful .bfile files into plaintext, and also encrypt plaintext back into those awful .bfiles.

Source code is provided in the idCrypt.c file for anyone interested (at exactly 250 lines of code :D)

Usage:
- idCrypt.exe <file-path> <internal-file-path>

If the input file path ends in .bfile/".bfile;binaryFile" the file will be decrypted to <file-path>.dec
Otherwise the file will be encrypted to <file-path>.bfile.

Example 1, decrypt english.bfile to english.dec:
- idCrypt.exe D:\english.bfile strings/english.lang

Example 2, encrypt english.dec to english.bfile:
- idCrypt.exe D:\english.dec strings/english.lang

Note that you _must_ use the correct internal filename! If it's incorrect idCrypt will fail to decrypt the .bfile, and the game will fail to decrypt your custom .bfile!

If you like this you should also check out my other project LegacyMod for DOOM, which unlocks a bunch of commands/cvars and even adds things like the noclip command:
https://cs.rin.ru/forum/viewtopic.php?p=1519324 (direct link: http://bit.ly/2wKyJXM)

===
Technical description
===
A .bfile is composed of a few different parts (in order):
- 0xC bytes random salt (to make sure each file is encrypted differently)
- 0x10 bytes AES IV (initialization vector)
- n-bytes encrypted cipher-text
- 0x20 bytes HMAC signature

The cipher-text is encrypted with AES128, the key for this is generated by creating a SHA256 hash and updating it with the following (in order):
- 0xC byte salt from the .bfile header
- static string "swapTeam\n" (where \n is a newline character)
- the internal filename of the .bfile (eg. strings/english.lang)

The first 0x10 bytes of the resulting hash is used as the encryption key.
In other terms, enc_key = SHA256(headerSalt, "swapTeam\n", internalFilePath)[:0x10]

The data gets crypted in one go using the BCRYPT_BLOCK_PADDING flag which automatically pads it to a 0x10 byte alignment. As shown above the IV used for this crypto-operation is taken from the 0x10 bytes at offset 0xC in the .bfile.

The HMAC is made with HMAC-SHA256, with the secret/key being the full 0x20 byte encryption key from above. The hash is created by updating with the following (in order):
- 0xC byte salt from the .bfile header
- 0x10 byte IV from the .bfile header
- n-bytes of the encrypted ciphertext
So basically the HMAC hash is made of the whole encrypted .bfile, minus the 0x20 bytes at the end where the HMAC gets stored. The game doesn't hash it all at once though, instead the hash is updated with each part seperately (unsure if this actually makes a difference or not though)

In other words, hmac_hash = HMAC-SHA256(key = enc_key, headerSalt, headerIV, encryptedData)

Source code is also included in idCrypt.c, hopefully it should be readable enough to understand.

===
Version History
===

WolfstoneExtract
- Separated out Win32 API code and ported to Linux crypto API
- Turned core into static library

v1.0
- add support for encrypting files into .bfile
- also release idCrypt.c source code

v0.5
- initial release, supports decrypting only

===
Greets
===
The guys on cs.rin.ru for helping to test when I asked, and everyone out there that's still into DOOM modding!
