FreeOTFE logo FreeOTFE
Free disk encryption software for PCs and PDAs
(PDA version of WWW site)


Technical Details: Creating a New Hash/Cypher Driver

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.
  1. Create a new directory to contain your new cypher driver
    • Make a copy of the directory containing the Blowfish cypher driver ("CYPHER_BLOWFISH")
    • Rename this directory to reflect the new cypher's name
  2. Modify "my_build_sys.bat"
    • Edit this file using a text editor to change:
      • All instances of "Blowfish" to reflect new cypher's name
      • The files needed
  3. 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 my_build_sys.bat
  4. Modify "src/sources"
    • 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 my_build_sys.bat
  5. In the "src" directory, rename all the "*Blowfish*" files to reflect the new cypher's name
  6. Start VC++ and load the "FreeOTFE.sln" Visual Studio Solution.
  7. Add the "....vcproj" project file you modified above into the solution.
  8. Within VC++, modify the new FreeOTFECypherXXX.rc file to change all instances of "Blowfish" to reflect new cypher's name
  9. Within VC++, modify FreeOTFECypherXXX.h
    • Change:
      • All instances of "Blowfish" to reflect new cypher name
      • Add/remove any "DRIVER_CIPHER_TITLE_XXX" entries as required
      • All of the GUID values (this is important! The FreeOTFE GUI uses these values to differentiate between the different cypher implementations)
      • Set the definition of "CYPHERS_SUPPORTED" to reflect the number of different cyphers the driver will provide (i.e. the number of "DRIVER_CIPHER_TITLE_XXX" definitions you have)
  10. Within VC++, modify FreeOTFECypherXXX.c
    • Change:
      • The cipher descriptions returned
      • The initialization and encrypt/decrypt routines to check for, and use the correct cypher
  11. Modify "clean.bat", in the top level "src" directory to clean up any object, garbage, etc files that are created when your driver is built
  12. You should now be able to build your new cypher driver, which may then be installed as per any other cypher or hash driver.

Hash Length/Blocksize

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 FreeOTFE volumes. (FreeOTFE 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 FreeOTFE volumes. (FreeOTFE 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 FreeOTFE volumes. (FreeOTFE 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 FreeOTFE volumes. (FreeOTFE 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.

Cypher Keysize/Blocksize

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.


Miscellaneous Comments: Cypher Drivers

  • When called upon to encrypt/decrypt data, if the "IVLength" passed in is 0, then "IV" should be ignored (it may be set to NULL)
  • 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)