mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
208 lines
7.4 KiB
C
208 lines
7.4 KiB
C
|
/*
|
||
|
* Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
|
||
|
*
|
||
|
* This source code is licensed under the LGPLv2 license,
|
||
|
* See the file LICENSE for more details.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @ingroup sys_crypto
|
||
|
* @{
|
||
|
*
|
||
|
* @file cbcmode.h
|
||
|
* @brief Headers of the implementation of the CBC Mode of Operation
|
||
|
*
|
||
|
* Implementation of the CBC Mode of Operation with Ciphertext-Stealing for encryption.
|
||
|
*
|
||
|
* @author Freie Universitaet Berlin, Computer Systems & Telematics.
|
||
|
* @author Nicolai Schmittberger <nicolai.schmittberger@fu-berlin.de>
|
||
|
* @author Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdint.h>
|
||
|
|
||
|
#ifndef CBCMODE_H_
|
||
|
#define CBCMODE_H_
|
||
|
|
||
|
#include "crypto/ciphers.h"
|
||
|
|
||
|
#define MIN(a, b) ( ((a) < (b)) ? (a) : (b))
|
||
|
|
||
|
#define DBG_CRYPTO 1
|
||
|
|
||
|
|
||
|
enum {
|
||
|
// we allocate some static buffers on the stack; they have to be less
|
||
|
// than this size
|
||
|
CBCMODE_MAX_BLOCK_SIZE = 8,
|
||
|
CBCMODE_MAX_BLOCK_SIZE_AES = 16
|
||
|
};
|
||
|
|
||
|
/*// We run a simple state machine in the incremental decrypt:
|
||
|
//
|
||
|
// +--> ONE_BLOCK
|
||
|
// |
|
||
|
// ---|
|
||
|
// |
|
||
|
// +--> GENERAL --+---> TWO_LEFT_A ----> TWO_LEFT_B
|
||
|
// ^ |
|
||
|
// | |
|
||
|
// +------+
|
||
|
*/
|
||
|
|
||
|
enum {
|
||
|
ONE_BLOCK,
|
||
|
GENERAL,
|
||
|
TWO_LEFT_A,
|
||
|
TWO_LEFT_B
|
||
|
};
|
||
|
|
||
|
#define FAIL 0
|
||
|
#define SUCCESS 1
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @struct CBCModeContext CBCMode.c "CBCMode.c"
|
||
|
* @brief The context for processing the en-/decryption in the CBC-Mode with
|
||
|
* CTS
|
||
|
*
|
||
|
* @param spill1 test1
|
||
|
*/
|
||
|
typedef struct CBCModeContext {
|
||
|
// Spill-Block 1 for temporary usage
|
||
|
uint8_t spill1 [CBCMODE_MAX_BLOCK_SIZE ];
|
||
|
// Spill-Block 2 for temporary usage
|
||
|
uint8_t spill2 [CBCMODE_MAX_BLOCK_SIZE ];
|
||
|
// the blocksize currently used
|
||
|
uint8_t bsize;
|
||
|
// how many more bytes of ciphertext do we need to recv
|
||
|
uint16_t remaining;
|
||
|
// how many bytes of plaintext we've deciphered.
|
||
|
uint16_t completed;
|
||
|
// TRUE iff spill1 is the accumulator and spill2 holds prev cipher text.
|
||
|
// false o.w.
|
||
|
uint8_t accum;
|
||
|
// into the accumulator
|
||
|
uint8_t offset;
|
||
|
// state enum
|
||
|
uint8_t state;
|
||
|
} /*__attribute__ ((packed)) */ CBCModeContext;
|
||
|
|
||
|
|
||
|
/*
|
||
|
* @brief Initialize the Mode. It uses the underlying BlockCipher's
|
||
|
* preferred block cipher mode, and passes the key and keySize
|
||
|
* parameters to the underlying BlockCipher.
|
||
|
*
|
||
|
* @param 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.
|
||
|
* @param keySize key size in bytes
|
||
|
* @param key pointer to the key
|
||
|
*
|
||
|
* @return 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.
|
||
|
*/
|
||
|
int block_cipher_mode_init(CipherModeContext *context, uint8_t key_size,
|
||
|
uint8_t *key);
|
||
|
|
||
|
/**
|
||
|
* @brief same as BlockCipherMode_init but with the possibility to specify
|
||
|
* the index of the cipher in the archive
|
||
|
*
|
||
|
* @param 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.
|
||
|
* @param keySize key size in bytes.
|
||
|
* @param key pointer to the key.
|
||
|
* @param cipher_index the index of the cipher-algorithm to init in the
|
||
|
* (cipher-)archive
|
||
|
*
|
||
|
* @return 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.
|
||
|
*/
|
||
|
int block_cipher_mode_init0(CipherModeContext *context, uint8_t key_size,
|
||
|
uint8_t *key, uint8_t cipher_index);
|
||
|
|
||
|
/**
|
||
|
* @brief prints the debug-messages passed by ::dumpBuffer
|
||
|
*
|
||
|
* @param mode the mode of the debug-message
|
||
|
* @param format pointer to the message
|
||
|
*/
|
||
|
void dbg(uint8_t mode, const char *format, ...);
|
||
|
|
||
|
/**
|
||
|
* @brief dumps the passed buffer to the console
|
||
|
*
|
||
|
* @param bufName pointer to the name of the buffer
|
||
|
* @param buf pointer to the buffer itself
|
||
|
* @param size the size of the buffer in bytes
|
||
|
*/
|
||
|
void dump_buffer(char *bufName, uint8_t *buf, uint8_t size);
|
||
|
|
||
|
/**
|
||
|
* @brief Encrypts num_bytes 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).
|
||
|
*
|
||
|
* @param plain_blocks a plaintext block numBlocks, where each block is of
|
||
|
* blockSize bytes
|
||
|
* @param cipher_blocks an array of numBlocks * blockSize bytes to hold the
|
||
|
* resulting cyphertext
|
||
|
* @param num_bytes number of data blocks to encrypt
|
||
|
* @param IV an array of the initialization vector. It should be
|
||
|
* of block size bytes
|
||
|
*
|
||
|
* @return Whether the encryption was successful. Possible failure reasons
|
||
|
* include not calling init().
|
||
|
*/
|
||
|
int block_cipher_mode_encrypt(CipherModeContext *context, uint8_t *plain_blocks,
|
||
|
uint8_t *cipher_blocks, uint16_t num_bytes,
|
||
|
uint8_t *IV);
|
||
|
|
||
|
/**
|
||
|
* @brief Decrypts num_bytes 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).
|
||
|
*
|
||
|
* @param cipher_blocks an array of num_bytes * blockSize bytes that holds
|
||
|
* the cipher text
|
||
|
* @param plain_blocks an array of num_bytes * blockSize bytes to hold the
|
||
|
* resulting plaintext.
|
||
|
* @param num_bytes number of data blocks to encrypt
|
||
|
* @param IV an array of the initialization vector. It should be
|
||
|
* of block size bytes
|
||
|
*
|
||
|
* @return Whether the decryption was successful. Possible failure reasons
|
||
|
* include not calling init().
|
||
|
*/
|
||
|
int block_cipher_mode_decrypt(CipherModeContext *context,
|
||
|
uint8_t *cipher_blocks,
|
||
|
uint8_t *plain_blocks,
|
||
|
uint16_t num_bytes,
|
||
|
uint8_t *IV);
|
||
|
|
||
|
/** @} */
|
||
|
#endif /* CBCMODE_H_ */
|