From 1693246bbcc6381e53a1cbfae1aa5322363d731e Mon Sep 17 00:00:00 2001 From: rasky Date: Wed, 29 Sep 2010 13:38:54 +0000 Subject: [PATCH] SEC: Add symmetric ciphers generic interface. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4346 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/sec/cipher.c | 82 ++++++++++++++++++++++ bertos/sec/cipher.h | 161 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 243 insertions(+) create mode 100644 bertos/sec/cipher.c create mode 100644 bertos/sec/cipher.h diff --git a/bertos/sec/cipher.c b/bertos/sec/cipher.c new file mode 100644 index 00000000..22bebe60 --- /dev/null +++ b/bertos/sec/cipher.c @@ -0,0 +1,82 @@ +/** + * \file + * + * + * \brief Generic interface for symmetric block ciphers. + * \author Giovanni Bajo + * + */ + +#include "cipher.h" +#include + +void cipher_cbc_encrypt(BlockCipher *c, void *block) +{ + xor_block(c->buf, c->buf, block, c->block_len); + c->enc_block(c, c->buf); + memcpy(block, c->buf, c->block_len); +} + +void cipher_cbc_decrypt(BlockCipher *c, void *block) +{ + uint8_t temp[c->block_len]; + memcpy(temp, block, c->block_len); + + c->dec_block(c, block); + xor_block(block, block, c->buf, c->block_len); + + memcpy(c->buf, temp, c->block_len); +} + +static void ctr_increment(void *buf, size_t len) +{ + uint8_t *data = (uint8_t*)buf; + while (len--) + if (LIKELY(++data[len] != 0)) + return; +} + +void cipher_ctr_encrypt(BlockCipher *c, void *block) +{ + uint8_t temp[c->block_len]; + + memcpy(temp, c->buf, c->block_len); + c->enc_block(c, temp); + xor_block(block, block, temp, c->block_len); + + PURGE(temp); + ctr_increment(c->buf, c->block_len); +} + +void cipher_ctr_decrypt(BlockCipher *c, void *block) +{ + cipher_ctr_encrypt(c, block); +} diff --git a/bertos/sec/cipher.h b/bertos/sec/cipher.h new file mode 100644 index 00000000..f7aee505 --- /dev/null +++ b/bertos/sec/cipher.h @@ -0,0 +1,161 @@ +/** + * \file + * + * + * \brief Generic interface for symmetric block ciphers. + * \author Giovanni Bajo + * + */ + +#ifndef SEC_CIPHER_H +#define SEC_CIPHER_H + +#include +#include + +typedef struct BlockCipher +{ + void (*set_key)(struct BlockCipher *c, const void *key); + void (*enc_block)(struct BlockCipher *c, void *block); + void (*dec_block)(struct BlockCipher *c, void *block); + + void *buf; + uint8_t key_len; + uint8_t block_len; +} BlockCipher; + + +/** + * Return the key length (in bytes) + */ +INLINE size_t cipher_key_len(BlockCipher *c) +{ + return c->key_len; +} + +/** + * Return the block length (in bytes) + */ +INLINE size_t cipher_block_len(BlockCipher *c) +{ + return c->block_len; +} + +/** + * Set the current key used by the cipher. + * + * \note the buffer pointed by \a key is not modified and it is + * not needed anymore after this call returns. + */ +INLINE void cipher_set_key(BlockCipher *c, const void *key) +{ + ASSERT(c->set_key); + c->set_key(c, key); +} + +/*********************************************************************************/ +/* ECB mode */ +/*********************************************************************************/ + +/** + * Encrypt a block (in-place) using the current key in ECB mode. + */ +INLINE void cipher_ecb_encrypt(BlockCipher *c, void *block) +{ + ASSERT(c->enc_block); + c->enc_block(c, block); +} + +/** + * Decrypt a block (in-place) using the current key in ECB mode. + */ +INLINE void cipher_ecb_decrypt(BlockCipher *c, void *block) +{ + ASSERT(c->dec_block); + c->dec_block(c, block); +} + + +/*********************************************************************************/ +/* CBC mode */ +/*********************************************************************************/ + +/** + * Initialize CBC by setting the IV. + * + * \note the memory pointed by \a iv will be used and modified by the CBC + * functions. It is caller's responsibility to keep it available until there is + * no more CBC work to do. + */ +INLINE void cipher_cbc_begin(BlockCipher *c, void *iv) +{ + c->buf = ivbuf; +} + +/** + * Encrypt a block (in-place) using the current key in CBC mode. + */ +void cipher_cbc_encrypt(BlockCipher *c, void *block); + +/** + * Decrypt a block (in-place) using the current key in CBC mode. + */ +void cipher_cbc_decrypt(BlockCipher *c, void *block); + + + +/*********************************************************************************/ +/* CTR mode */ +/*********************************************************************************/ + +/** + * Initialize CTR by setting the counter. + * + * \note the memory pointed by \a counter will be used and modified (incremented) + * by the CTR functions. It is caller's responsibility to keep it available until + * there is no more CTR work to do. + */ +INLINE void cipher_ctr_begin(BlockCipher *c, void *counter) +{ + c->buf = counter; +} + +/** + * Encrypt a block (in-place) using the current key in CBC mode. + */ +void cipher_ctr_encrypt(BlockCipher *c, void *block); + +/** + * Decrypt a block (in-place) using the current key in CBC mode. + */ +void cipher_ctr_decrypt(BlockCipher *c, void *block); + +#endif /* SEC_CIPHER_H */ -- 2.25.1