Aaben Kryptografi Limited DES Programming Reference Version 1 27 March 2001 DES Programming Reference Page 2 Table of Contents 1. 1.1. 1.2. 1.3. 1.4. 1.5. 1.6. The Data Encryption Standard Introduction Key Parity Security of DES Triple DES Modes of DES Final Short Block Page 3 Page 3 Page 3 Page 3 Page 4 Page 4 Page 4 2. 2.1. 2.2. 2.3. Key Types and Key Tokens Key Types Key Distribution Key Tokens Page 5 Page 5 Page 5 Page 6 3, 3.1. 3.2. Using the DES APIs The Header File and the DLL The DES APIs Page 7 Page 7 Page 7 4. 4.1. 4.2. Setting and Erasing the Local Master Key Setting the LMK Erasing the LMK Page 8 Page 8 Page 8 5. 6. 7. 8. Generating a Key Setting a Working Key Encrypting and Decrypting Data Generating a Message Authentication Code Page 9 Page 10 Page 11 Page 12 9. 9.1. 9.2. Importing and Exporting Keys Importing Exporting Page 13 Page 13 Page 13 10. 11. 12. 13. 14. Creating a KEK or KTK from Clear Components Computing a Key Check Value Re-Enciphering a Key Under a New LMK Hexadecimal and Binary Conversions Converting Error Codes to Text Page 14 Page 15 Page 16 Page 17 Page 18 © 2001 Aaben Kryptografi Limited Page 2 DES Programming Reference Page 3 1. The Data Encryption Standard (DES) 1.1. Introduction The Data Encryption Standard (DES) has been a worldwide standard for more than 20 years, and is probably the most commonly used of all the symmetric key algorithms. DES uses a 56-bit key to encipher or decipher a 64-bit data block. Both key and data are presented as 8-byte fields, but in the case of the key, the low order bit in each byte is ignored by the algorithm. The Aaben Kryptografi DES toolkit provides the software developer with a comprehensive set of APIs (Application Program Interfaces) to implement application level cryptographic security. The toolkit is supplied as a DLL (dynamic link library) together with a demonstration program which illustrates all the features of the toolkit. 1.2. Key Parity Although the low order bit in each byte of a DES key is ignored, it is traditional to set it so that there is an odd number of bits in each byte. This is known as odd parity adjustment. For example, a key with all its bytes zero (00h) would be adjusted so that each byte contains 01h. 1.3. Security of DES Ever since its invention there has been controversy about whether the key length of 56 bits is long enough. The argument revolves around whether a machine could be built which could crack DES by exhaustive key search. That is, given a plain-text block of data and its corresponding cipher-text, is it possible to determine the key by trying all possible keys in turn? A celebrated article by Diffie and Hellman postulated that if a million machines could each test a million DES keys per second, then it would take about 24 hours to try all the keys, so on average one might expect to determine just one key in about 12 hours. Some say this is to much of a risk, but for all practical purposes it indicates that DES even with a short 56-bit key is very secure. To overcome arguments about key length, you can have double or triple length keys (112 bits and 168 bits respectively) which remove any possibility of exhaustive search. The penalty for this added security is that encryption and decryption take three times as long as if you had used a 56-bit key. © 2001 Aaben Kryptografi Limited Page 3 DES Programming Reference 1.4. Page 4 Triple DES If you consider a triple-length key as the concatenation of three single length keys Key_1, Key_2 and Key_3, then encryption is performed by: Encrypt with Key_1 Decrypt with Key_2 Encrypt with Key_3 Decryption is then: Decrypt with Key_3 Encrypt with Key_2 Decrypt with Key_1 In the case of a double-length key, the processes are precisely the same, but Key_3 is replaced by Key_1. 1.5. Modes of DES You can use DES in a variety of modes, the two most common being ECB (Electronic Code Book) and CBC (Cipher Block Chaining). In ECB mode, the data is split up into 8-byte blocks, and each block is enciphered independently. The trouble with this is that patterns in the plain-text may give rise to corresponding patterns in the cipher-text, and this could give a cryptanalyst a hint as to the content of the original text. To overcome this, use CBC mode. As before, the data is split into 8-byte blocks, but each block is exclusive-OR’d with the previous block before being enciphered. Thus, each encipherment incorporates the encipherment of the previous block. Obviously, you need something to exclusive-OR with the first block, so you use an initial 8-byte block specifically for this purpose. This block is known as the ICV (Initial Chaining Value). 1.6. Final Short Block If the data is not an exact multiple of 8 bytes long, how do we deal with the final short block? There are several standards available to deal with this problem, but none of them are totally satisfactory. The method used by the Aaben Kryptografi toolkit is the one used by IBM in their PCF and CUSP products (and which has been continued in their later ICSF product). The last complete block is re-enciphered and the result is exclusive-OR’d with the short block. This ensures that there is no change in data length. Most techniques result in the cipher-text being longer than the plain-text. © 2001 Aaben Kryptografi Limited Page 4 DES Programming Reference Page 5 2. Key Usage and Key Tokens 2.1. Key Types It is a principle of good cryptographic security that a key should only be used for a single purpose. For example, if you set up a key for encryption then it should not be possible to use it for data authentication. Also, it is usual to implement a key hierarchy such that data keys (keys used for processing data) are encrypted by higher level keys known as key encrypting keys, which are in turn encrypted by key transport keys (also known as zone master keys or zone control master keys). At the top of the hierarchy is the LMK (Local Master Key), which can encrypt any locally held key. The LMK is unique in that it is never transported outside its own environment. If you ever see local master keys being distributed to users, then there is something wrong with the security. Key encrypting keys are never used for processing data, and data keys are never used for encrypting keys. 2.2. Key Distribution Typically, data keys are enciphered under key encrypting keys (KEKs) which are shared by users. For example, if Alice wants to send an encrypted message to Bob, she generates a random data key, encrypts the message with it and sends the cipher-text to Bob, and also the random key encrypted using a KEK previously shared with Bob. Notice that it is good practice to use a different data key for each session between users. How did the KEK get shared between Alice and Bob? The recommended method is to send it encrypted under a KTK (key transport key). The KTK has to be shared manually, and the traditional way to do this is to construct it from a number of components input into both systems by several operators so that no one person knows the entire key. Once a KTK has been securely established, KEKs and data keys may be distributed electronically. The policy should be to change a KTK rarely, a KEK on a regular basis (say every 6 months) and data keys frequently. It is a good principle to ensure that key length is commensurate with the importance of the key. Thus a KTK should not be shorter than a KEK which in turn should not be shorter than a data key. © 2001 Aaben Kryptografi Limited Page 5 DES Programming Reference 2.3. Page 6 Key Tokens Because a key has at least three properties, namely its length (8, 16 or 24 bytes), its type (data, KEK or KTK) and its value, it is convenient to present keys to the various APIs in a structure known as a key token. This greatly simplifies usage of the APIs and allows greater control over security than would be the case if each property were specified separately. A key token is a 32-byte array of unsigned characters, and is always presented to the APIs enciphered under the LMK. The only exception to this is when clear keys are used, in which case the programmer must construct his own (un-enciphered) token. The format of a key token is as follows: Byte 1 Key length (8, 16 or 24) Byte 2 Key type (0 to 255) Bytes 3-8 Reserved (set to zero if constructing a clear key token) Bytes 9-32 The key value Note that a DES key token is always 32 bytes long. Do not be tempted to think that if your key is only 8 bytes long you can reduce the token length accordingly. © 2001 Aaben Kryptografi Limited Page 6 DES Programming Reference Page 7 3. Using the DES APIs 3.1 The Header File and the DLL The DES function prototypes are defined in the header file DES_DLL.H. To link your application to the DLL you need to specify the library DES_DLL.LIB and the DLL itself is DES_DLL.DLL. The header file defines the DES class cAK_DES so to use the APIs in your program you need to declare an instance of this: cAK_DES DES; You can then access all the DES APIs. 3.2. The DES APIs RC = DES.Set_LMK(Seed); RC = DES.ZAP_LMK( ); RC = DES.Generate_Key(Key_Length, Key_Type, Key_Token); RC = DES.Set_Working_Key(Key_Token); RC = DES.Encrypt (Data_Length, Icv, Data); RC = DES.Decrypt(Data_Length,ICV,Data); RC = DES.Encode(Data_Length,Clear_Key_Token,Data); RC = DES.Decode(Data_Length,Clear_Key_Token,Data); RC = DES.Generate_MAC(Data_Length, Segment, MAC, Data); RC = DES.Import_Key(Key_u_KEK, KEK_u_LMK, Key_u_LMK); RC = DES.Export_Key(Key_u_LMK, KEK_u_LMK, Key_u_KEK); RC = DES.Initialise_Key_Encrypting_Key(KeyLen, NComps, Type, Token ); RC = DES.Generate_Clear_Component(KeyLen, Component); RC = DES.Add_Clear_Component(Component, KeyToken); RC = DES.Key_Check_Value(Token,KCV,KeyType,KeyLen,Option ); RC = DES.Translate_Key( Key_Token, New_LMK_Seed); RC = DES.Bin_To_Hex( Length, Binary, Hexadecimal); RC = DES.Hex_To_Bin( Length, Hexadecimal, Binary); RC = DES.Message( RC, Message_Text ); RC is the return code, and indicates the success or failure of the operation. If the return code is set to zero, then the operation was successful. This is the kind of thing you may wish to code: if ( RC != 0 ) { DES.Message( RC, Text ); MessageBox( Text ); Return; © 2001 Aaben Kryptografi Limited Page 7 DES Programming Reference Page 8 } 4. Setting and Erasing the Local Master Key 4.1. Setting the LMK Many of the APIs require the LMK to have been installed. For example, the LMK must be available to the Generate_Key function. RC = DES.Set_LMK( LMK_Seed ); unsigned char LMK_Seed[128]; short int RC; A 128-byte data area is hashed and then converted to a DES key that is then installed into the DLL and used to protect all other keys. The 128-byte seed you choose must be unique to you, and kept secret at all times. 4.2. Erasing the LMK When all cryptographic processing is finished, you can get rid of the installed LMK by: RC = DES.ZAP_LMK( ); short int RC; © 2001 Aaben Kryptografi Limited Page 8 DES Programming Reference 5. Page 9 Generating a Key You can generate a key of any valid type and length. The usual result is a key token enciphered under the LMK. However, if you specify a clear key (type = 00) then the key token remains in clear and you may use it with Encode/Decode or to derive keys using the special option of Import/Export. The key value generated depends in part on the value in the Key Token on entry, so you might consider seeding the process with a random value at the beginning of your program. RC = DES.Generate_Key( KeyLength, KeyType, Key_Token ); short int RC, KeyLength, KeyTYpe; unsigned char Key_Token[32]; The valid key lengths are 08, 16 or 24. The following are the valid key types: 00 01 02 03 04 05 06 07 16 17 18 19 32 33 34 35 Clear data key (no usage defined) Encrypt Decrypt Encrypt and decrypt Generate MAC Encrypt and generate MAC Decrypt and generate MAC Encrypt, decrypt and generate MAC Key encrypting key (no usage defined) Key encrypting key (Exporter) Key encrypting key (Importer) Key encrypting key (Exporter and Importer) Key transport key (no usage defined) Key transport key (Exporter) Key transport key (Importer) Key transport key (Exporter and Importer) Adding 8 to any of the above type codes allows you to export the key token using an RSA public or private key. The key token is returned enciphered under the LMK. Do not be tempted to shorten the key token if your key length is less than 24: there are internal checks to ensure that key tokens are always 32 bytes long. © 2001 Aaben Kryptografi Limited Page 9 DES Programming Reference 6. Page 10 Setting a Working Key In order to encrypt/decrypt data or to generate MACs (Message Authentication Codes), a working key needs to be installed. The idea of this is that the key can be prepared for use just once and then used many times. RC = DES.Set_Working_Key(Key_Token); unsigned char Key_Token[32]; short int RC; Note that you cannot set a KEK or a KTK as a working key, since these can only be used to protect other keys and may not be used to encrypt data. © 2001 Aaben Kryptografi Limited Page 10 DES Programming Reference 7. Page 11 Encrypting and Decrypting Data Four APIs are available, namely Encrypt/Decrypt and Encode/Decode. Encrypt and Decrypt use DES in CBC mode (Cipher Block Chaining) and require a working key to be installed and an ICV (Initial Chaining Value) to be specified. Encode and Decode use DES in ECB mode (Electronic Cod Book) and require a clear key to be specified. Encode/Decode should not normally be used for data encryption, and are provided to support any unusual functionality that may be required in the future. RC = DES.Encrypt( Data_Length,ICV,Data); RC = DES.Decrypt(Data_Length,ICV,Data); RC = DES.Encode(Data_Length,Clear_Key_Token,Data); RC = DES.Decode(Data_Length,Clear_Key_Token,Data); long Data_Length; unsigned char ICV[8], Data[ ], Clear_Key_Token[32]; short int RC; For Encrypt and Decrypt the ICV is updated according to IBM’s rules for CUSP/PCF. That is, the final complete cipher block is re-enciphered and set to the new value of the ICV. If there is a final short block (less than 8 bytes) it is enciphered by exclusive-OR with the updated ICV (again, this is an IBM standard). For Encode and Decode the data length must be a multiple of 8 bytes. © 2001 Aaben Kryptografi Limited Page 11 DES Programming Reference 8. Page 12 Generating a Message Authentication Code A Message Authentication Code (MAC) is a cryptographic check sum appended to a message so that the recipient can check that the data has not been changed in transit. Both sender and receiver share a common DES key used to create/verify the MAC. Note that this technique is fine when used to protect against a third party, but it does not provide non-repudiation (for that you need digital signatures, which are supported by RSA but not by DES). This API provides an 8-byte binary MAC. It is usual to convert some or all of this to hexadecimal form before sending it with the message (ANSI X9.9 specifies a MAC of 8 hex characters). You can either create a MAC for an entire message, or you can process the message in segments (this is convenient if you are MACing an entire file). RC = DES.Generate_MAC( Data_Length, Segment, MAC, Data); long Data_Length; short int RC, Segment; unsigned char MAC[8], Data[ ]; The Segment code can be 0 (entire message), 1 (first segment), 2 (middle segment) or 3 (last segment). There can be as many middle segments as necessary. If Segment is 1 or 2 then the data length must be a multiple of 8. When processing a multi-segment message, be careful not to change MAC between calls to the API. © 2001 Aaben Kryptografi Limited Page 12 DES Programming Reference Page 13 9. Importing and Exporting Keys 9.1. Import A key token enciphered under a KEK or a KTK is re-enciphered under the LMK. Optionally you can derive a new working key (key type < 16) by specifying a clear key token, in which case, the key value is deciphered under the KEK or KTK and adjusted to odd parity. The entire key token is then enciphered under the LMK. Apart from supporting certain industry standards, key derivation can be used to create several keys of different types, but having the same value. For example, you may want to set up a data encrypting key for your own use, but distribute copies of it that can only be used for decryption. There is a better way to do this if you have the RSA export function. RC = DES.Import_Key( KEY_under_KEK, KEK_under_LMK, KEY_under_LMK ); unsigned char KEY_under_KEK[32], KEK_under_LMK[32], KEY_under_LMK[32]; short int RC; 9.2. Export A key token enciphered under the LMK is re-enciphered under a KEK or a KTK. Optionally you can derive a new working key (key type < 16) by specifying a clear key token, in which case, the key value is enciphered under the KEK or KTK and adjusted to odd parity. The entire key token is then enciphered under the KEK or KTK. Apart from supporting certain industry standards, key derivation can be used to create several keys of different types, but having the same value. For example, you may want to create an encryption key for your own use, but distribute copies of it that can only be used for decryption. There is a better way to do this if you have the RSA export function. RC = DES.Export_Key( KEY_under_LMK, KEK_under_LMK, KEY_under_KEK ); unsigned char KEY_under_LMK[32], KEK_under_LMK[32], KEY_under_KEK[32]; short int RC; © 2001 Aaben Kryptografi Limited Page 13 DES Programming Reference 10. Page 14 Creating a KEK or KTK from Clear Components At least one high level key needs to be set up manually. Thereafter, other keys can be distributed encrypted under this high level key. Normally this is a KTK and is often referred to as a ZMK or ZCMK (Zone Master Key or Zone Control Master Key). At least one ZMK should be shared between a pair of cryptographic zones. ZMKs are constructed from clear components by means of the exclusive-OR operation. Three APIs are provided to support this: RC = DES.Initialise_Key_Encrypting_Key(KeyLength,NumComps,Type,KeyToken); RC = DES.Generate_Clear_Component(KeyLength, Component); RC = DES.Add_Clear_Component(Component, KeyToken); short int RC, KeyLength, NumComps, Type; unsigned char KeyToken[32], Component[24]; The key token is first initialised with the key length, the key type and the number of components required. You can then add components to the token until the key is complete. At every stage the token under construction is enciphered under the LMK. © 2001 Aaben Kryptografi Limited Page 14 DES Programming Reference 11. Page 15 Computing a Key Check Value A key check value is derived by enciphering a zero data block (64-bits all set to zero). A key token enciphered under the LMK is presented as input, and a 64-bit KCV is returned. It is usual for the key check value to be converted to hexadecimal form. In the case of a single length key only the first few hexadecimal digits (usually 6) should be published, to avoid the possibility of the key being determined by exhaustive search. You can also check the parity of the key or force it to have odd parity. The options available are: Option = 0: Option = 1: Option = 2: No parity check required An error condition is raised if parity is not odd Force odd parity In addition to computing the KCV, this API also returns the key length and the key type. RC = DES.Key_Check_Value(Token, Key_Check, &KeyType, &KeyLen, Option); unsigned char Token[32], Key_Check[8]; short int RC, KeyType, KeyLen, Option; © 2001 Aaben Kryptografi Limited Page 15 DES Programming Reference 12. Page 16 Re-enciphering a Key under a New LMK This API allows you to re-encipher all your key tokens before you change to a new LMK. Note that the LMK itself is not changed until you re-set it with Set_LMK. RC = DES.Translate_Key( Key_Token, New_LMK_Seed); unsigned char Key_Token[32], New_LMK_Seed[128]; short int RC; © 2001 Aaben Kryptografi Limited Page 16 DES Programming Reference 13. Page 17 Hexadecimal and Binary Conversions You need to be able to convert data from printable hexadecimal form to binary before you can process it, and conversely you need to convert from binary to hexadecimal so that you can display your results. RC = DES.Bin_To_Hex( Length, Binary, Hexadecimal); RC = DES.Hex_To_Bin( Length, Hexadecimal, Binary); int Length; unsigned char Binary[ ]; char Hexadecimal[ ]; short int RC; The integer Length specifies the number of bytes to be converted. Conversion from binary to hexadecimal doubles the number of characters, and the result is null terminated. Be sure that the length of the hexadecimal text is at least twice that of the binary field plus 1. Conversion from hexadecimal to binary halves the number of bytes. This process performs validation on the hexadecimal input and can fail in the following ways: Invalid hexadecimal digit (must be 0-9, A-F or a-f) Odd number of hexadecimal digits © 2001 Aaben Kryptografi Limited Page 17 DES Programming Reference 14. Page 18 Converting Error Codes to Message Text When the return code from any of the APIs is non-zero, you may wish to display a suitable error message. This API converts a return code into a 64-byte message. The DES error codes are all in the range 100 to 199. RC = DES.Message( Return_Code, Message_Text ); short int RC, Return_Code; char Message_Text[64]; The RSA toolkit has an equivalent function RSA.Message but the error codes for RSA are in the range 200 to 299. When using both RSA and DES toolkits be careful to call the correct function when creating message text. If there is any doubt you should code something such as this: if (RC >= 100 && RC < 200) DES.Message( RC, Text); else if (RC >= 200 && RC < 300) RSA.Message( RC, Text); © 2001 Aaben Kryptografi Limited Page 18