Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/include/crypto/drbg.h
49184 views
1
/*
2
* DRBG based on NIST SP800-90A
3
*
4
* Copyright Stephan Mueller <[email protected]>, 2014
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, and the entire permission notice in its entirety,
11
* including the disclaimer of warranties.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
* 3. The name of the author may not be used to endorse or promote
16
* products derived from this software without specific prior
17
* written permission.
18
*
19
* ALTERNATIVELY, this product may be distributed under the terms of
20
* the GNU General Public License, in which case the provisions of the GPL are
21
* required INSTEAD OF the above restrictions. (This clause is
22
* necessary due to a potential bad interaction between the GPL and
23
* the restrictions contained in a BSD-style copyright.)
24
*
25
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
26
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
28
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
29
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
31
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
32
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
36
* DAMAGE.
37
*/
38
39
#ifndef _DRBG_H
40
#define _DRBG_H
41
42
43
#include <linux/random.h>
44
#include <linux/scatterlist.h>
45
#include <crypto/hash.h>
46
#include <crypto/skcipher.h>
47
#include <linux/module.h>
48
#include <linux/crypto.h>
49
#include <linux/slab.h>
50
#include <crypto/internal/drbg.h>
51
#include <crypto/internal/rng.h>
52
#include <crypto/rng.h>
53
#include <linux/fips.h>
54
#include <linux/mutex.h>
55
#include <linux/list.h>
56
#include <linux/workqueue.h>
57
58
struct drbg_state;
59
typedef uint32_t drbg_flag_t;
60
61
struct drbg_core {
62
drbg_flag_t flags; /* flags for the cipher */
63
__u8 statelen; /* maximum state length */
64
__u8 blocklen_bytes; /* block size of output in bytes */
65
char cra_name[CRYPTO_MAX_ALG_NAME]; /* mapping to kernel crypto API */
66
/* kernel crypto API backend cipher name */
67
char backend_cra_name[CRYPTO_MAX_ALG_NAME];
68
};
69
70
struct drbg_state_ops {
71
int (*update)(struct drbg_state *drbg, struct list_head *seed,
72
int reseed);
73
int (*generate)(struct drbg_state *drbg,
74
unsigned char *buf, unsigned int buflen,
75
struct list_head *addtl);
76
int (*crypto_init)(struct drbg_state *drbg);
77
int (*crypto_fini)(struct drbg_state *drbg);
78
79
};
80
81
struct drbg_test_data {
82
struct drbg_string *testentropy; /* TEST PARAMETER: test entropy */
83
};
84
85
enum drbg_seed_state {
86
DRBG_SEED_STATE_UNSEEDED,
87
DRBG_SEED_STATE_PARTIAL, /* Seeded with !rng_is_initialized() */
88
DRBG_SEED_STATE_FULL,
89
};
90
91
struct drbg_state {
92
struct mutex drbg_mutex; /* lock around DRBG */
93
unsigned char *V; /* internal state 10.1.1.1 1a) */
94
unsigned char *Vbuf;
95
/* hash: static value 10.1.1.1 1b) hmac / ctr: key */
96
unsigned char *C;
97
unsigned char *Cbuf;
98
/* Number of RNG requests since last reseed -- 10.1.1.1 1c) */
99
size_t reseed_ctr;
100
size_t reseed_threshold;
101
/* some memory the DRBG can use for its operation */
102
unsigned char *scratchpad;
103
unsigned char *scratchpadbuf;
104
void *priv_data; /* Cipher handle */
105
106
struct crypto_skcipher *ctr_handle; /* CTR mode cipher handle */
107
struct skcipher_request *ctr_req; /* CTR mode request handle */
108
__u8 *outscratchpadbuf; /* CTR mode output scratchpad */
109
__u8 *outscratchpad; /* CTR mode aligned outbuf */
110
struct crypto_wait ctr_wait; /* CTR mode async wait obj */
111
struct scatterlist sg_in, sg_out; /* CTR mode SGLs */
112
113
enum drbg_seed_state seeded; /* DRBG fully seeded? */
114
unsigned long last_seed_time;
115
bool pr; /* Prediction resistance enabled? */
116
bool fips_primed; /* Continuous test primed? */
117
unsigned char *prev; /* FIPS 140-2 continuous test value */
118
struct crypto_rng *jent;
119
const struct drbg_state_ops *d_ops;
120
const struct drbg_core *core;
121
struct drbg_string test_data;
122
};
123
124
static inline __u8 drbg_statelen(struct drbg_state *drbg)
125
{
126
if (drbg && drbg->core)
127
return drbg->core->statelen;
128
return 0;
129
}
130
131
static inline __u8 drbg_blocklen(struct drbg_state *drbg)
132
{
133
if (drbg && drbg->core)
134
return drbg->core->blocklen_bytes;
135
return 0;
136
}
137
138
static inline __u8 drbg_keylen(struct drbg_state *drbg)
139
{
140
if (drbg && drbg->core)
141
return (drbg->core->statelen - drbg->core->blocklen_bytes);
142
return 0;
143
}
144
145
static inline size_t drbg_max_request_bytes(struct drbg_state *drbg)
146
{
147
/* SP800-90A requires the limit 2**19 bits, but we return bytes */
148
return (1 << 16);
149
}
150
151
static inline size_t drbg_max_addtl(struct drbg_state *drbg)
152
{
153
/* SP800-90A requires 2**35 bytes additional info str / pers str */
154
#if (__BITS_PER_LONG == 32)
155
/*
156
* SP800-90A allows smaller maximum numbers to be returned -- we
157
* return SIZE_MAX - 1 to allow the verification of the enforcement
158
* of this value in drbg_healthcheck_sanity.
159
*/
160
return (SIZE_MAX - 1);
161
#else
162
return (1UL<<35);
163
#endif
164
}
165
166
static inline size_t drbg_max_requests(struct drbg_state *drbg)
167
{
168
/* SP800-90A requires 2**48 maximum requests before reseeding */
169
return (1<<20);
170
}
171
172
/*
173
* This is a wrapper to the kernel crypto API function of
174
* crypto_rng_generate() to allow the caller to provide additional data.
175
*
176
* @drng DRBG handle -- see crypto_rng_get_bytes
177
* @outbuf output buffer -- see crypto_rng_get_bytes
178
* @outlen length of output buffer -- see crypto_rng_get_bytes
179
* @addtl_input additional information string input buffer
180
* @addtllen length of additional information string buffer
181
*
182
* return
183
* see crypto_rng_get_bytes
184
*/
185
static inline int crypto_drbg_get_bytes_addtl(struct crypto_rng *drng,
186
unsigned char *outbuf, unsigned int outlen,
187
struct drbg_string *addtl)
188
{
189
return crypto_rng_generate(drng, addtl->buf, addtl->len,
190
outbuf, outlen);
191
}
192
193
/*
194
* TEST code
195
*
196
* This is a wrapper to the kernel crypto API function of
197
* crypto_rng_generate() to allow the caller to provide additional data and
198
* allow furnishing of test_data
199
*
200
* @drng DRBG handle -- see crypto_rng_get_bytes
201
* @outbuf output buffer -- see crypto_rng_get_bytes
202
* @outlen length of output buffer -- see crypto_rng_get_bytes
203
* @addtl_input additional information string input buffer
204
* @addtllen length of additional information string buffer
205
* @test_data filled test data
206
*
207
* return
208
* see crypto_rng_get_bytes
209
*/
210
static inline int crypto_drbg_get_bytes_addtl_test(struct crypto_rng *drng,
211
unsigned char *outbuf, unsigned int outlen,
212
struct drbg_string *addtl,
213
struct drbg_test_data *test_data)
214
{
215
crypto_rng_set_entropy(drng, test_data->testentropy->buf,
216
test_data->testentropy->len);
217
return crypto_rng_generate(drng, addtl->buf, addtl->len,
218
outbuf, outlen);
219
}
220
221
/*
222
* TEST code
223
*
224
* This is a wrapper to the kernel crypto API function of
225
* crypto_rng_reset() to allow the caller to provide test_data
226
*
227
* @drng DRBG handle -- see crypto_rng_reset
228
* @pers personalization string input buffer
229
* @perslen length of additional information string buffer
230
* @test_data filled test data
231
*
232
* return
233
* see crypto_rng_reset
234
*/
235
static inline int crypto_drbg_reset_test(struct crypto_rng *drng,
236
struct drbg_string *pers,
237
struct drbg_test_data *test_data)
238
{
239
crypto_rng_set_entropy(drng, test_data->testentropy->buf,
240
test_data->testentropy->len);
241
return crypto_rng_reset(drng, pers->buf, pers->len);
242
}
243
244
/* DRBG type flags */
245
#define DRBG_CTR ((drbg_flag_t)1<<0)
246
#define DRBG_HMAC ((drbg_flag_t)1<<1)
247
#define DRBG_HASH ((drbg_flag_t)1<<2)
248
#define DRBG_TYPE_MASK (DRBG_CTR | DRBG_HMAC | DRBG_HASH)
249
/* DRBG strength flags */
250
#define DRBG_STRENGTH128 ((drbg_flag_t)1<<3)
251
#define DRBG_STRENGTH192 ((drbg_flag_t)1<<4)
252
#define DRBG_STRENGTH256 ((drbg_flag_t)1<<5)
253
#define DRBG_STRENGTH_MASK (DRBG_STRENGTH128 | DRBG_STRENGTH192 | \
254
DRBG_STRENGTH256)
255
256
enum drbg_prefixes {
257
DRBG_PREFIX0 = 0x00,
258
DRBG_PREFIX1,
259
DRBG_PREFIX2,
260
DRBG_PREFIX3
261
};
262
263
#endif /* _DRBG_H */
264
265