diff --git a/doc/blockciphers.rst b/doc/blockciphers.rst new file mode 100644 index 0000000..6668633 --- /dev/null +++ b/doc/blockciphers.rst @@ -0,0 +1,338 @@ + +Block ciphers +============= +A block cipher is a algorithm which turns an input of fixed length into an +output of the same length (enciphering or encrypting). The transformation is +specified by a key which has to be of a fixed length, or a length of a given +set or range. + +Generally there is also an algorithm which turns the output back to the +previous input (deciphering or decrypting) when supplied with the same key. + +List of available block ciphers +------------------------------- +This is a list of the currently supported block ciphers: + +* AES (Advanced Encryption Standard) +* Camellia +* CAST5 +* CAST6 +* CS-Cipher +* DES (Data Encryption Standard) +* Khazad +* Noekeon +* Present +* RC5 +* RC6 +* Seed +* Serpent (AES finalist) +* Shacal1 +* Shacal2 +* Skipjack +* TDES (Tripple DES) +* Threefish +* XTEA + +high frequent parameters +------------------------ +* block size + - 64 bits, 128 bits +* key size + - 64 bits, 80 bits, 128 bits, 192 bits, 256 bits + +(note that some block ciphers use different sizes) + +Parts of a block cipher +----------------------- +* encryption algorithm +* decryption algorithm +* mostly a set of subkeys +* mostly a keyschedule which generates the subkeys from the supplied key. + +As we can see here a block cipher normally has an algorithm besides the +encryption and decryption algorithm, which we call keyschedule. +Mostly the encryption and decryption algorithm consist of multiple rounds, +where each round (and sometimes between rounds) subkeys are needed to modify +the data. This subkeys are generated by the keyschedule and stored in a state +or context variable. + +Note that not all algorithms need a pregenerated context, sometimes it is easy +to generate the subkeys "on the fly" so there is not always the need of a +context variable. In this case instead of a context the actual key is passed +to the encryption and decryption function. + +API of block ciphers +-------------------- +The API is not always consistent due to the fact that we tried to optimize the +code for size (flash, heap and stack) and speed (runtime of the different +components). +Generally the API of the implemented block ciphers consists of: + ++----------+------------------------------------------------------------+ +| Suffix | Description | ++==========+============================================================+ +| \*_init | function, which implements the keyschedule | ++----------+------------------------------------------------------------+ +| \*_enc | function, which implements the encryption algorithm | ++----------+------------------------------------------------------------+ +| \*_dec | function, which implements the decryption algorithm | ++----------+------------------------------------------------------------+ +| \*_free | function, which frees memory allocated for the keyschedule | ++----------+------------------------------------------------------------+ +| \*_ctx_t | context type, which can contain a keyschedule and other | +| | information | ++----------+------------------------------------------------------------+ + +\*_init function +~~~~~~~~~~~~~~~~ +The \*_init function generally takes a pointer to the key as first parameter. +For ciphers where the keysize is not fixed the second parameter gives the +keysize (in bits regularly) and the last parameter points to the context +variable to fill. +For some ciphers there are additional parameters like the number of rounds, +these parameters generally occur before the context pointer. + +\*_enc and \*_dec functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The encryption and decryption function of a specific algorithm normally do not +differ in their parameters. Generally these functions take a pointer to the +block to operate on. Some ciphers allow to specify two blocks, where the first +one will be written to and the second will contain the source block. The two +blocks may overlap or be the same. Most ciphers have only one block pointer. +The block specified by the pointer is encrypted (if the \*_enc function is +called) or decrypted (if the \*_dec function is called). +The last parameter specifies either the key direct (with a pointer to it) or +is a pointer to a context created with the \*_init function. +It is guaranteed that the context is in the same state as before the \*_enc or +\*_dec function call. Most \*_enc and \*_dec functions do not modify the context +at all, but some do for reducing dynamic memory requirements. So here are some +limitations to the reentrant property. + +\*_free function +~~~~~~~~~~~~~~~~ +A \*_free function is only provided where needed (so most ciphers do not have +it). It is used to free memory dynamically allocated by the \*_init function. + +\*_ctx_t type +~~~~~~~~~~~~~ +A variable of the \*_ctx_t type may hold information needed by the \*_enc or +\*_dec function. It is initialized by the \*_init function. If dynamic memory +is allocated by the \*_init function also a \*_free function is provided which +frees the allocated memory. An initialized \*_ctx_t variable may not be copied +as it may contains pointers to itself. + + +Block cipher abstraction layer (BCAL) +===================================== +The BlockCipeherAbstractionLayer (BCAL) is an abstraction layer which allows +usage of all implemented block ciphers in a simple way. It abstracts specific +function details and is suitable for implementations which want to be flexible +in the choosing of specific block ciphers. Another important aspect is that this +abstraction layer enables the implementation of block cipher operating modes +independently from concrete ciphers. It is very simple to use and reassembles +the API used to implement individual ciphers. + +The main component is a block cipher descriptor which contains the details of +the individual ciphers. + +Care should be taken when choosing a specific keysize. It may be the case that +the chosen keysize is not compatible with the chosen block cipher. + +Parts of BCAL +------------- +The BCAL is split up in different parts: +* BCAL declaration for BCAL descriptors +* algorithm specific definitions of BCAL descriptors +* BCAL basic context type +* BCAL basic functions + +BCAL declaration for BCAL descriptors +------------------------------------- +The BCAL descriptor is a structure which is usually placed in FLASH or ROM since +modification is unnecessary. It contains all information required to use the +according block cipher. + +:: + + typedef struct { + uint8_t type; /* 1==block cipher */ + uint8_t flags; + PGM_P name; + uint16_t ctxsize_B; + uint16_t blocksize_b; + bc_init_fpt init; + bc_enc_fpt enc; + bc_dec_fpt dec; + bc_free_fpt free; + PGM_VOID_P valid_keysize_desc; + } bcdesc_t; /* block cipher descriptor type */ + + ++--------------------+---------------------------------------------------------+ +| Element | Description | ++====================+=========================================================+ +| type | should be set to ``1`` to indicate that this descriptor | +| | is for a block cipher. | ++--------------------+---------------------------------------------------------+ +| flags | defines what kind of init function is provided and what | +| | kind of decrypt and encrypt functions are provided. | ++--------------------+---------------------------------------------------------+ +| flags - bit 0 | if clear (``0``) designates an init function with fixed | +| | key length, so the length parameter is omitted | +| | (``init(void* ctx, void* key)``). | +| | | +| | if set (``1``) designates an init function which | +| | requires an explicit keysize argument | +| | (``init(void*ctx, uint16_t length_b, void* key)``). | ++--------------------+---------------------------------------------------------+ +| flags - bit 1 | if clear (``0``) designates that the encryption | +| | function transforms the plaintext block in place to the | +| | ciphertext (``enc(void* block, void* ctx)``). | +| | | +| | if set (``1``) designates that the encryption function | +| | offers a dedicated pointers for input and output. The | +| | two regions may be the same | +| | (``enc(void* out, void* in, void*ctx)``). | ++--------------------+---------------------------------------------------------+ +| flags - bit 2 | if clear (``0``) designates that the decryption | +| | function transforms the ciphertext block in place to | +| | the plaintext (``dec(void* block, void* ctx)``). | +| | | +| | if set (``1``) designates that the decryption function | +| | offers a dedicated pointers for input and output. The | +| | two regions may be the same | +| | (``dec(void* out, void* in, void*ctx)``). | ++--------------------+---------------------------------------------------------+ +| name | is a pointer to a zero terminated ASCII string giving | +| | the name of the implemented primitive. On targets with | +| | Harvard-architecture the string resides in code memory | +| | (FLASH, ROM, ...). | ++--------------------+---------------------------------------------------------+ +| ctxsize_B | is the number of bytes which should be allocated for | +| | the context variable. | ++--------------------+---------------------------------------------------------+ +| blocksize_b | is the number of bits on which the encrypt and decrypt | +| | function work on. | ++--------------------+---------------------------------------------------------+ +| init | is a pointer to the init function (see ``flags`` how | +| | the init function should be called). If there is no | +| | init function this field is NULL. | ++--------------------+---------------------------------------------------------+ +| enc | is a pointer to the encryption function (see ``flags`` | +| | how the encryption function should be called). | ++--------------------+---------------------------------------------------------+ +| dec | is a pointer to the decryption function (see ``flags`` | +| | how the decryption function should be called). | ++--------------------+---------------------------------------------------------+ +| free | is a pointer to the free function or NULL if there is | +| | no free function. | ++--------------------+---------------------------------------------------------+ +| valid_keysize_desc | is a pointer to a keysize descriptor structure which is | +| | used to validate that the chosen keysize is valid | ++--------------------+---------------------------------------------------------+ + +BCAL-Basic context +------------------ +Besides the context types for individual ciphers there is a generic context +type for BCAL. This is the context to use when using BCAL based functions. +The BCAL context has the following structure: + +:: + + typedef struct { + bcdesc_t* desc_ptr; + uint16_t keysize; + void* ctx; + } bcgen_ctx_t; + ++----------+----------------------------------------+ +| desc_ptr | a pointer to the BCAL descriptor | ++----------+----------------------------------------+ +| keysize | the chosen keysize | ++----------+----------------------------------------+ +| ctx | pointer to the cipher specific context | ++----------+----------------------------------------+ + + + +BCAL-Basic +---------- +BCAL-Basic provides the basic features of an block cipher on top of the +BCAL. To use it you simply have to include the algorithms you want to use, +the BCAL descriptor file and of course the BCAL-Basic implementation. + +The following functions are provided: + +bcal_cipher_init +~~~~~~~~~~~~~~~~ +:: + + uint8_t bcal_cipher_init( + const bcdesc_t* cipher_descriptor, + const void* key, + uint16_t keysize_b, + bcgen_ctx_t* ctx) + +this function initializes a BCAL context based on the given BCAL descriptor +pointer (first parameter) with a given key (second parameter) of a given length +(third parameter). The context to initialize is designated by the pointer +passed as fourth parameter. + +If everything works fine ``0`` is returned. In the case something fails +the following codes are returned: + ++---+-------------------------------------------------------------------------+ +| 1 | The specified keysize is not available with this cipher | ++---+-------------------------------------------------------------------------+ +| 2 | It was not possible to allocate enough memory to hold the key. | +| | (This is returned when there is no actual init function and you ran out | +| | of memory) | ++---+-------------------------------------------------------------------------+ +| 3 | It was not possible to allocate enough memory to hold the context | +| | variable for the selected cipher. | ++---+-------------------------------------------------------------------------+ + +bcal_cipher_free +~~~~~~~~~~~~~~~~ +:: + + void bcal_cipher_free(bcgen_ctx_t* ctx) + +this function frees the memory allocated by the init function and should be +called whenever you are finished with BCAL context. It automatically also calls +the free function if necessary. + +bcal_cipher_enc +~~~~~~~~~~~~~~~ +:: + + void bcal_cipher_enc(void* block, const bcgen_ctx_t* ctx) + +this function encrypts a block in-place using a given BCAL contex. + +bcal_cipher_dec +~~~~~~~~~~~~~~~ +:: + + void bcal_cipher_dec(void* block, const bcgen_ctx_t* ctx) + +this function decrypts a block in-place using a given BCAL contex. + +bcal_cipher_getBlocksize_b +~~~~~~~~~~~~~~~~~~~~~~~~~~ +:: + + uint16_t bcal_cipher_getBlocksize_b(const bcdesc_t* desc) + +this function returns the block size of a given cipher by using the BCAL +descriptor (to which a pointer must be passed). + +bcal_cipher_getKeysizeDesc +~~~~~~~~~~~~~~~~~~~~~~~~~~ +:: + + PGM_VOID_P bcal_cipher_getKeysizeDesc(const bcdesc_t* desc) + +this function returns a pointer to the keysize descriptor of a given cipher by +using the BCAL descriptor (to which a pointer must be passed). +