Apps     Components     Interfaces     All Files     Source Tree     source: tos.lib.TinySec.CBCModeM.nc

Component: CBCModeM

Implements CBC Mode using Cipher Text Stealing (CBC-CTS) as described in Schneir's Applied Cryptography (195-6) and RFC-2040.
Plain CBC mode is pretty simple; using CTS complicates things. CTS allows the ciphertext to be the same size as the plaintext, even for plaintexts which aren't a multiple of the block size. C_0 == E[IV] C_i == E[ C_{i-1} ^ P_i ] 0 < i < n-2 C_{n-1} == E[ C_{n-2} ^ P_{n-1} ] == E[ C_{n-2} ^ (P_{n-1} || 0/-L) ] == C_{n-1}/+L || C_{n-1}/-L (naming of ciphertext block into left and right pieces) C_n == E[ C_{n-1}/+L ^ P_n || C_{n-1}/-L ] Where 0 = the zero block n = number of blocks. the last block may be length 1..blockSize bytes L = |P_n|, the length of the last block and /+L refers to the first L bytes of a block and /-L refers to the last (blockSize - L) bytes of a block We then output C_0 || ... || C_{n-2} || C_n || C_{n-1}/+L so that the ciphertext is the same size as the input.
Author: Naveen Sastry

Required Interfaces

Provided Interfaces

Variables

Function Index

Function Descriptions

BlockCipherMode.init

command result_t BlockCipherMode.init (CipherModeContext *context, uint8_t keySize, uint8_t *key)

Initialize the Mode. It uses the underlying BlockCipher's preferred block cipher mode, and passes the key and keySize parameters to the underlying BlockCipher.

Parameters:

context - structure to hold the opaque data from this initialization call. It should be passed to future invocations of this module which use this particular key. It also contains the opaque context for the underlying BlockCipher as well.

keySize - key size in bytes

key - pointer to the key

Returns: Whether initialization was successful. The command may be unsuccessful if the key size is not valid for the given cipher implementation. It can also fail if the preferred block size of the cipher does not agree with the preferred size of the mode.

BlockCipherMode.encrypt

async command result_t BlockCipherMode.encrypt (CipherModeContext *context, uint8_t *plainBlocks, uint8_t *cipherBlocks, uint16_t numBytes, uint8_t *IV)

Encrypts numBlocks of plaintext blocks (each of size blockSize) using the key from the init phase. The IV is a pointer to the initialization vector (of size equal to the blockSize) which is used to initialize the encryption. In place encryption should work provided that the plain and and cipher buffer are the same. (they may either be the same or non-overlapping. partial overlaps are not supported).

Parameters:

plainBlocks - a plaintext block numBlocks, where each block is of blockSize bytes

cipherBlocks - an array of numBlocks * blockSize bytes to hold the resulting cyphertext

numBlocks - number of data blocks to encrypt

IV - an array of the initialization vector. It should be of blockSize bytes

Returns: Whether the encryption was successful. Possible failure reasons include not calling init().

BlockCipherMode.decrypt

async command result_t BlockCipherMode.decrypt (CipherModeContext *context, uint8_t *cipherBlock, uint8_t *plainBlock, uint16_t numBytes, uint8_t *IV)

Decrypts numBlocks of ciphertext blocks (each of size blockSize) using the key from the init phase. The IV is a pointer to the initialization vector (of size equal to the blockSize) which is used to initialize the decryption. In place decryption should work provided that the plain and and cipher buffer are the same. (they may either be the same or non-overlapping. partial overlaps are not supported).

Parameters:

cipherBlocks - an array of numBlocks * blockSize bytes that holds the cipher text

plainBlocks - an array of numBlocks * blockSize bytes to hold the resulting plaintext.

numBlocks - number of data blocks to encrypt

IV - an array of the initialization vector. It should be of blockSize bytes

Returns: Whether the decryption was successful. Possible failure reasons include not calling init().

BlockCipherMode.initIncrementalDecrypt

async command result_t BlockCipherMode.initIncrementalDecrypt (CipherModeContext *context, uint8_t *IV, uint16_t length)

Initializes the mode for an incremental decryption operation. This step is necessary for incremental decryption where the incoming data stream is processed a byte at a time and cipher operations are done as soon as possible. This is meant to allow for better overlapping of decryption with a slower process that receives the encrypted stream (say via the network ). This call may induce a block cipher call.

Parameters:

context - holds the module specific opaque data related to the key (perhaps key expansions) and other internal state.

IV - The initialization vector that was used to encrypt this particular data stream. This array must have a length equal to one block size.

The - exact length of the data stream in bytes; this must be at least the underlying block cipher size.

Returns: Whether the initialization was successful. Possible failure reasons include not calling init() or an underlying failure in the block cipher.

BlockCipherMode.incrementalDecrypt

async command result_t BlockCipherMode.incrementalDecrypt (CipherModeContext *context, uint8_t *cipher, uint8_t *plain, uint16_t length, uint16_t *done)

Performs an incremental decryption operation. It executes roughly one block cipher call for every block's worth of ciphertext provided, placing the result into the plaintext buffer. The done out parameter gives an indication of the amount of data that has been successfully been decrypted.

Parameters:

context - holds the module specific opaque data related to the key (perhaps key expansions) and other internal state.

ciphertext - Pointer to the start of the next ciphertext buffer.

plaintext - Pointer to the start of the buffer which is large enough to hold the entire ciphertext. This buffer must be passed in every time to the incrementalDecrypt function. After this call, done bytes of the plaintext buffer will be available for consumption.

length - The number of bytes that is being provided in the ciphertext

done - A pointer to an int which will be filled in after the call completes with the number of bytes of plaintext which is available.

Returns: Whether the call was successful or not. Possible failure reasons include not calling init(), an underlying failure in the block cipher, or providing more ciphertext than is expected.