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.
- 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
- 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
- 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
- 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
- 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
- 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)
- Within VC++, modify FreeOTFECypherXXX.c
- Change:
- The cipher descriptions returned
- The initialization and encrypt/decrypt routines to check for, and use the correct cypher
- 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
- 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)
|