mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
147 lines
4.7 KiB
C
147 lines
4.7 KiB
C
/*
|
|
* Copyright (C) 2008 D. J. Bernstein (dedicated to the public domain)
|
|
* Copyright (C) 2015 René Kijewski <rene.kijewski@fu-berlin.de>
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup sys_crypto
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief ChaCha stream cipher
|
|
*
|
|
* @author René Kijewski <rene.kijewski@fu-berlin.de>
|
|
*/
|
|
|
|
#ifndef CRYPTO_CHACHA_H
|
|
#define CRYPTO_CHACHA_H
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @brief A ChaCha cipher stream context.
|
|
* @details Initialize with chacha_init().
|
|
*/
|
|
typedef struct {
|
|
uint32_t state[16]; /**< The current state of the stream. */
|
|
uint8_t rounds; /**< Number of iterations. */
|
|
} chacha_ctx;
|
|
|
|
/**
|
|
* @brief Initialize a ChaCha context
|
|
*
|
|
* @param[out] ctx The context to initialize
|
|
* @param[in] rounds Number of rounds. Recommended: 20. Also in use: 8 and 12.
|
|
* @param[in] key The key to use.
|
|
* @param[in] keylen Length (in bytes) of @p key. Must be 16 or 32.
|
|
* @param[in] nonce IV / nonce to use.
|
|
*
|
|
* @return `== 0` on success.
|
|
* @return `< 0` if an illegal value for @p rounds or @p keylen was supplied.
|
|
*/
|
|
int chacha_init(chacha_ctx *ctx,
|
|
unsigned rounds,
|
|
const uint8_t *key, uint32_t keylen,
|
|
const uint8_t nonce[8]);
|
|
|
|
/**
|
|
* @brief Generate next block in the keystream.
|
|
*
|
|
* @details If you want to seek inside the cipher steam, then you have to
|
|
* update the clock in `ctx->state[13]:ctx->state[12]` manually.
|
|
*
|
|
* @warning You need to re-initialize the context with a new nonce after 2^64
|
|
* encrypted blocks, or the keystream will repeat!
|
|
*
|
|
* @param[in,out] ctx The ChaCha context
|
|
* @param[out] x The block of the keystream (`sizeof(x) == 64`).
|
|
*/
|
|
void chacha_keystream_bytes(chacha_ctx *ctx, void *x);
|
|
|
|
/**
|
|
* @brief Encode or decode a block of data.
|
|
*
|
|
* @details @p m is always the input regardless if it is the plaintext or ciphertext,
|
|
* and @p c vice verse.
|
|
*
|
|
* @warning You need to re-initialize the context with a new nonce after 2^64
|
|
* encrypted blocks, or the keystream will repeat!
|
|
*
|
|
* @param[in,out] ctx The ChaCha context.
|
|
* @param[in] m The input.
|
|
* @param[out] c The output.
|
|
*/
|
|
void chacha_encrypt_bytes(chacha_ctx *ctx, const uint8_t *m, uint8_t *c);
|
|
|
|
/**
|
|
* @copydoc chacha_encrypt_bytes()
|
|
*/
|
|
static inline void chacha_decrypt_bytes(chacha_ctx *ctx, const uint8_t *m,
|
|
uint8_t *c)
|
|
{
|
|
chacha_encrypt_bytes(ctx, m, c);
|
|
}
|
|
|
|
/**
|
|
* @brief Seed the pseudo-random number generator.
|
|
*
|
|
* @details You can seed the random number generator with up to 64 bytes of data.
|
|
* If you feed less than 64 bytes of data, then the privous state gets
|
|
* only partially overwritten.
|
|
*
|
|
* If you want to supply multiple information, then you have to concatenate
|
|
* them manually before invoking the function.
|
|
*
|
|
* The PRNG gets a random seed in the build process.
|
|
* You can set a deterministic value by supplying a comma separated
|
|
* argument to `make` like
|
|
* `RIOT_CHACHA_PRNG_DEFAULT="0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15"`.
|
|
*
|
|
* @param[in] data Some random data.
|
|
* @param[in] bytes Length of @p data in bytes where `0 < bytes <= 64`.
|
|
*/
|
|
void chacha_prng_seed(const void *data, size_t bytes);
|
|
|
|
/**
|
|
* @brief Extract a number from the pseudo-random number generator.
|
|
*
|
|
* @warning After you have read 2^68 numbers you have to re-seed the PRNG.
|
|
* Otherwise the sequence will repeat.
|
|
*
|
|
* @return The random value
|
|
*/
|
|
uint32_t chacha_prng_next(void);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* CRYPTO_CHACHA_H */
|
|
|
|
/**
|
|
* @}
|
|
*/
|