1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/sys/include/crypto/ciphers.h
2022-11-22 13:39:35 +01:00

192 lines
6.0 KiB
C

/*
* Copyright (C) 2013 Freie Universität Berlin, Computer Systems & Telematics
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup sys_crypto
* @{
*
* @file
* @brief Headers for the packet encryption class. They are used to encrypt single packets.
*
* @author Freie Universitaet Berlin, Computer Systems & Telematics
* @author Nicolai Schmittberger <nicolai.schmittberger@fu-berlin.de>
* @author Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
* @author Mark Essien <markessien@gmail.com>
*/
#ifndef CRYPTO_CIPHERS_H
#define CRYPTO_CIPHERS_H
#include <stdint.h>
#include "modules.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Shared header file for all cipher algorithms */
/** @brief the length of keys in bytes
*
* As of now AES is the only cipher which supports different key sizes.
* Here we optimize the CIPHERS_MAX_KEY_SIZE to always have the smallest possible
* value based on which AES key sizes are used.
*/
#if IS_USED(MODULE_CRYPTO_AES_256)
#define CIPHERS_MAX_KEY_SIZE 32
#elif IS_USED(MODULE_CRYPTO_AES_192)
#define CIPHERS_MAX_KEY_SIZE 24
#else
#define CIPHERS_MAX_KEY_SIZE 16
#endif
#define CIPHER_MAX_BLOCK_SIZE 16
/**
* Context sizes needed for the different ciphers.
* Always order by number of bytes descending!!! <br><br>
*
* aes needs CIPHERS_MAX_KEY_SIZE bytes <br>
*/
#if IS_USED(MODULE_CRYPTO_AES_256) || IS_USED(MODULE_CRYPTO_AES_192) || \
IS_USED(MODULE_CRYPTO_AES_128)
#define CIPHER_MAX_CONTEXT_SIZE CIPHERS_MAX_KEY_SIZE
#else
/* 0 is not a possibility because 0-sized arrays are not allowed in ISO C */
#define CIPHER_MAX_CONTEXT_SIZE 1
#endif
/* return codes */
#define CIPHER_ERR_INVALID_KEY_SIZE -3
#define CIPHER_ERR_INVALID_LENGTH -4
#define CIPHER_ERR_ENC_FAILED -5
#define CIPHER_ERR_DEC_FAILED -6
/** Is returned by the cipher_init functions, if the corresponding algorithm
* has not been included in the build */
#define CIPHER_ERR_BAD_CONTEXT_SIZE 0
/** Returned by cipher_init upon successful initialization of a cipher. */
#define CIPHER_INIT_SUCCESS 1
/**
* @brief the context for cipher-operations
*/
typedef struct {
uint8_t key_size; /**< key size used */
uint8_t context[CIPHER_MAX_CONTEXT_SIZE]; /**< buffer for cipher operations */
} cipher_context_t;
/**
* @brief BlockCipher-Interface for the Cipher-Algorithms
*/
typedef struct cipher_interface_st {
/** @brief Blocksize of this cipher */
uint8_t block_size;
/**
* @brief the init function.
*
* This function is responsible for checking that the given key_size is
* valid for the chosen cipher.
*/
int (*init)(cipher_context_t *ctx, const uint8_t *key, uint8_t key_size);
/** @brief the encrypt function */
int (*encrypt)(const cipher_context_t *ctx, const uint8_t *plain_block,
uint8_t *cipher_block);
/** @brief the decrypt function */
int (*decrypt)(const cipher_context_t *ctx, const uint8_t *cipher_block,
uint8_t *plain_block);
} cipher_interface_t;
/** Pointer type to BlockCipher-Interface for the Cipher-Algorithms */
typedef const cipher_interface_t *cipher_id_t;
/**
* @brief AES cipher id
*/
extern const cipher_id_t CIPHER_AES;
/**
* @brief basic struct for using block ciphers
* contains the cipher interface and the context
*/
typedef struct {
const cipher_interface_t *interface; /**< BlockCipher-Interface for the
Cipher-Algorithms */
cipher_context_t context; /**< The encryption context (buffer)
for the algorithm */
} cipher_t;
/**
* @brief Initialize new cipher state
*
* @param cipher cipher struct to init (already allocated memory)
* @param cipher_id cipher algorithm id
* @param key encryption key to use
* @param key_size length of the encryption key
*
* @return CIPHER_INIT_SUCCESS if the initialization was successful.
* @return CIPHER_ERR_BAD_CONTEXT_SIZE if CIPHER_MAX_CONTEXT_SIZE has not
* been defined (which means that the cipher has not been included
* in the build)
* @return The command may return CIPHER_ERR_INVALID_KEY_SIZE if the
* key size is not valid.
*/
int cipher_init(cipher_t *cipher, cipher_id_t cipher_id, const uint8_t *key,
uint8_t key_size);
/**
* @brief Encrypt data of BLOCK_SIZE length
* *
*
* @param cipher Already initialized cipher struct
* @param input pointer to input data to encrypt
* @param output pointer to allocated memory for encrypted data. It has to
* be of size BLOCK_SIZE
*
* @return The result of the encrypt operation of the underlying
* cipher, which is always 1 in case of success
* @return A negative value for an error
*/
int cipher_encrypt(const cipher_t *cipher, const uint8_t *input,
uint8_t *output);
/**
* @brief Decrypt data of BLOCK_SIZE length
* *
*
* @param cipher Already initialized cipher struct
* @param input pointer to input data (of size BLOCKS_SIZE) to decrypt
* @param output pointer to allocated memory for decrypted data. It has to
* be of size BLOCK_SIZE
*
* @return The result of the decrypt operation of the underlying
* cipher, which is always 1 in case of success
* @return A negative value for an error
*/
int cipher_decrypt(const cipher_t *cipher, const uint8_t *input,
uint8_t *output);
/**
* @brief Get block size of cipher
* *
*
* @param cipher Already initialized cipher struct
*
* @return The cipher's block size (in bytes)
*/
int cipher_get_block_size(const cipher_t *cipher);
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* CRYPTO_CIPHERS_H */