-
Notifications
You must be signed in to change notification settings - Fork 1
/
buffered.h
118 lines (104 loc) · 4.19 KB
/
buffered.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#pragma once
#include <inttypes.h>
#include "algorithms.h"
#include "hc-128.h"
#include "rabbit.h"
#include "salsa20.h"
#include "sosemanuk.h"
typedef void (*extract_func_type)(void *state, uint8_t *stream);
typedef struct
{
extract_func_type extract_func;
uint16_t buffered_state_size;
uint16_t buffer_offset;
uint8_t chunk_size;
} cipher_attributes;
typedef struct
{
const cipher_attributes *cipher;
uint8_t available_count;
} buffered_state;
#define CIPHER_SPECIFICS_DECL(name,size) \
typedef struct { \
buffered_state header; \
name##_state state; \
/* Using uint32_t to ensure alignment: */ \
uint32_t buffer[(size)/4]; \
} name##_buffered_state; \
extern const cipher_attributes name##_cipher; \
extern const name##_buffered_state name##_static_initializer;
CIPHER_SPECIFICS_DECL(hc128, 4)
CIPHER_SPECIFICS_DECL(rabbit, 16)
CIPHER_SPECIFICS_DECL(salsa20, 64)
CIPHER_SPECIFICS_DECL(sosemanuk, 16)
#undef CIPHER_SPECIFICS_DECL
typedef enum
{
BUFFERED_EXTRACT,
BUFFERED_ENCDEC
} buffered_ops;
extern const cipher_attributes *cipher_attributes_map[LAST_CIPHER+1];
/** Gets the address of the cipher state contained in the buffered state.
*
* Low lever helper function to help writing generic code that works with
* any cipher.
*
* @returns A value that can be cast to a pointer to one of the
* <cipher>_state types, depending on what cipher this buffered state
* was initialized to use.
*/
void *buffered_get_cipher_state(buffered_state *full_state);
/** Defines the cipher used for the buffered enc/decryption.
*
* The type buffered_state is the header of each of the specific <cipher>_buffered_state.
* Before using the buffered API, this header must be initialized either with this
* function or direct attribution from the static initializer <cipher>_static_initializer, like:
*
* hc128_buffered_state state = hc128_static_initializer;
*
* The header is updated by the buffered operations, so it is needed to reset it in case of
* key or IV change. Use function buffered_reset() for this.
*
* @param state_header The pointer to the buffered state (or its header, their addresses must
* coincide) that must be initialized.
* @param cipher The cipher corresponding to the type of the buffered state.
*/
void buffered_init_header(buffered_state *state_header, cipher_type cipher);
/** Resets an buffered state to its initial state.
*
* Call this upon updating the cipher state with a key or IV change. It will discard any
* buffered bytes generated by the previous key/IV combination. Currently this is as simple
* as setting:
*
* @c state->header->available_count = 0;
*
* @param state_header The pointer to the buffered state (or its header, their addresses must
* coincide).
*/
void buffered_reset(buffered_state *state_header);
/** Performs a buffered encryption, decryption or extraction operation.
*
* This function allows encryption or decryption of buffers of any size, independent of the
* chunk size of the specific algorithm being used.
*
* @param full_state A properly initialized and valid buffered encryption state. One of the
* <cipher>_buffered_state types. The full state (i.e. both the header and the cipher itself)
* must be properly initialized before usage.
* @param stream The buffer to be encrypted or decrypted in place, or to store the
* extraction output.
* @parem len The length of of the stream.
* @param op What operation to perform, i.e. if to encrypt or decrypt (BUFFERED_ENCDEC) or
* to just extract the len sized pseudorandom stream generated by the algorithm
* (BUFFERED_EXTRACT). Notice that, for the kind of stream ciphers implemented, the encryption
* and decryption operations are exactly the same.
*/
void buffered_action(buffered_state *full_state, uint8_t *stream, size_t len, buffered_ops op);
/** Discard an amount of bytes from the stream cipher output.
*
* This function is equivalent to calling buffered_action() with op BUFFERED_EXTRACT,
* and discarding the output stream.
*
* @param full_state The properly initialized and valid buffered encryption state.
* @param len How many bytes to skip from the current state of the buffered cipher.
*/
void buffered_skip(buffered_state *full_state, size_t len);