LibreCrypt: Open-Source disk encryption for Windows
These instructions specify in general terms, the steps in taking an existing cypher driver (Blowfish, in this case), and modifying it to create a new cypher driver. The procedure for creating a new hash driver is practically identical, but one of the existing hash drivers should be used as a base, instead of the Blowfish cypher.
Create a new directory to contain your new cypher driver
Modify "mybuildsys.bat"
All instances of "Blowfish" to reflect new cypher's name
The files needed
Modify "CYPHER_BLOWFISH.vcproj"
Rename this file to reflect the new cypher's name
Edit this file using a text editor to change:
All instances of "Blowfish" to reflect new cypher's name
What files are needed, as per mybuildsys.bat
Modify "src/sources"
In the "src" directory, rename all the "Blowfish" files to reflect the new cypher's name
Start VC++ and load the "FreeOTFE.sln" Visual Studio Solution.
Add the "....vcproj" project file you modified above into the solution.
Within VC++, modify the new FreeOTFECypherXXX.rc file to change all instances of "Blowfish" to reflect new cypher's name
Within VC++, modify FreeOTFECypherXXX.h
All instances of "Blowfish" to reflect new cypher name
All of the GUID values (this is important! The LibreCrypt GUI uses these values to differentiate between the different cypher implementations)* Set the definition of "CYPHERSSUPPORTED" to reflect the number of different cyphers the driver will provide (i.e. the number of "DRIVERCIPHERTITLEXXX" definitions you have)
Within VC++, modify FreeOTFECypherXXX.c
The cipher descriptions returned
The initialization and encrypt/decrypt routines to check for, and use the correct cypher
You should now be able to build your new cypher driver, which may then be installed as per any other cypher or hash driver.
When your hash driver is asked for details of the hash algorithms it provides, the hash length returned for each hash algorithm must be one of the following:
Hash length | Validity | Meaning | Comments |
---|---|---|---|
0 | Valid | Hash values returned are 0 bits long. | Hashes which return zero length hash values cannot be used with LibreCrypt volumes. (LibreCrypt volumes use PKCS#5 PBKDF2 (HMAC), which requires that the length of hash values returned is greater than zero.) |
Less than 0 | Valid | Hash values returned are of variable length (e.g. the "NULL" hash, which returns its input as the generated hash value.) | Hashes which return variable length hash values cannot be used with LibreCrypt volumes. (LibreCrypt volumes use PKCS#5 PBKDF2 (HMAC), which requires that the length of the hash values used is fixed.) |
Greater than 0 | Valid | Hash values returned have a fixed, defined length (e.g. SHA-512's hash length is 512 bits) | Must be a multiple of 8. |
When your hash driver is asked for details of the hash algorithms it provides, the blocksize returned for each hash algorithm must be one of the following:
Hash blocksize | Validity | Meaning | Comments |
---|---|---|---|
0 | Valid | Hash algorithm does not process input data. | Hashes may only have a blocksize of 0 bits if the length of the hash values they output is also 0 bits long, or if they ignore their input. Hashes which use zero length blocksizes cannot be used for LibreCrypt volumes. (LibreCrypt volumes use HMAC, which requires that the blocksize of hashes used is greater than zero.) |
Less than 0 | Valid | Hash algorithm processes input data in variable-length blocks. | Hashes which use variable length blocksizes cannot be used for LibreCrypt volumes. (LibreCrypt volumes use HMAC, which requires that the blocksize of hashes is a fixed size.) |
Greater than 0 | Valid | Hash algorithm processes input data in defined, fixed blocks (e.g. SHA-512's block size is 1024 bits) | Must be a multiple of 8. |
When your hash driver is asked for details of the cyphers it provides, the keysize returned for each cypher must be one of the following:
Cypher keysize | Validity | Meaning | Comments |
---|---|---|---|
0 | Valid | No key is used during encryption (e.g. if the cypher doesn't encrypt data, just returns the plaintext as the cyphertext; or if the cypher uses a hardcoded key) | |
Less than 0 | Valid | The cypher takes variable keylengths (e.g. the "XOR" cypher) | |
Greater than 0 | Valid | The cypher accepts only a specific keysize (e.g. full-strength DES only accepts 64 bit keys) | Must be a multiple of 8. |
When your hash driver is asked for details of the cyphers it provides, the blocksize returned for each cypher must be one of the following:
Cypher blocksize | Validity | Meaning | Comments |
---|---|---|---|
0 | Valid | Cypher does not process input data. (e.g. the "NULL" cypher, which just returns the supplied plaintext as cyphertext) | If the blocksize is 0, then no IVs will be used for encrypting/decrypting. |
Less than 0 | Valid | Cypher processes input data in variable-length blocks. (e.g. XOR processes data in blocks with the same length as the key being used) | If the blocksize isn't fixed, then no IVs will be used for encrypting/decrypting. |
Greater than 0 | Valid | Cypher processes input data in defined, fixed blocks (e.g. AES has a block size is 128 bits) | Must be a multiple of 8. |
When writing a cypher driver, the encrypt/decrypt implementation should *not *write to the input buffer; only the output buffer (i.e. when encrypting, do *not *write to the plaintext buffer passed in; when decrypting, do *not *write to the cyphertext buffer). An optimisation in the driver involves the use of a single buffer for input/output. You may find that you'll need to create a temporary buffer equal to your blocksize when implementing some modes of operation (e.g. CBC)