summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/include/ipxe/drbg.h
blob: 6374e7787128d373375dfa8ff67f32218ccb3355 (plain)
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#ifndef _IPXE_DRBG_H
#define _IPXE_DRBG_H

/** @file
 *
 * DRBG mechanism
 *
 */

FILE_LICENCE ( GPL2_OR_LATER );

#include <stdint.h>
#include <ipxe/sha256.h>
#include <ipxe/hmac_drbg.h>

/** Choose HMAC_DRBG using SHA-256
 *
 * HMAC_DRBG using SHA-256 is an Approved algorithm in ANS X9.82.
 */
#define HMAC_DRBG_ALGORITHM HMAC_DRBG_SHA256

/** Maximum security strength */
#define DRBG_MAX_SECURITY_STRENGTH \
	HMAC_DRBG_MAX_SECURITY_STRENGTH ( HMAC_DRBG_ALGORITHM )

/** Security strength
 *
 * We choose to operate at a strength of 128 bits.
 */
#define DRBG_SECURITY_STRENGTH 128

/** Minimum entropy input length */
#define DRBG_MIN_ENTROPY_LEN_BYTES \
	HMAC_DRBG_MIN_ENTROPY_LEN_BYTES ( DRBG_SECURITY_STRENGTH )

/** Maximum entropy input length */
#define DRBG_MAX_ENTROPY_LEN_BYTES HMAC_DRBG_MAX_ENTROPY_LEN_BYTES

/** Maximum personalisation string length */
#define DRBG_MAX_PERSONAL_LEN_BYTES HMAC_DRBG_MAX_PERSONAL_LEN_BYTES

/** Maximum additional input length */
#define DRBG_MAX_ADDITIONAL_LEN_BYTES HMAC_DRBG_MAX_ADDITIONAL_LEN_BYTES

/** Maximum length of generated pseudorandom data per request */
#define DRBG_MAX_GENERATED_LEN_BYTES HMAC_DRBG_MAX_GENERATED_LEN_BYTES

/** A Deterministic Random Bit Generator */
struct drbg_state {
	/** Algorithm internal state */
	struct hmac_drbg_state internal;
	/** Reseed required flag */
	int reseed_required;
	/** State is valid */
	int valid;
};

/**
 * Instantiate DRBG algorithm
 *
 * @v state		Algorithm state
 * @v entropy		Entropy input
 * @v entropy_len	Length of entropy input
 * @v personal		Personalisation string
 * @v personal_len	Length of personalisation string
 *
 * This is the Instantiate_algorithm function defined in ANS X9.82
 * Part 3-2007 Section 9.2 (NIST SP 800-90 Section 9.1).
 */
static inline void drbg_instantiate_algorithm ( struct drbg_state *state,
						const void *entropy,
						size_t entropy_len,
						const void *personal,
						size_t personal_len ) {
	hmac_drbg_instantiate ( HMAC_DRBG_HASH ( HMAC_DRBG_ALGORITHM ),
				&state->internal, entropy, entropy_len,
				personal, personal_len );
}

/**
 * Reseed DRBG algorithm
 *
 * @v state		Algorithm state
 * @v entropy		Entropy input
 * @v entropy_len	Length of entropy input
 * @v additional	Additional input
 * @v additional_len	Length of additional input
 *
 * This is the Reseed_algorithm function defined in ANS X9.82
 * Part 3-2007 Section 9.3 (NIST SP 800-90 Section 9.2).
 */
static inline void drbg_reseed_algorithm ( struct drbg_state *state,
					   const void *entropy,
					   size_t entropy_len,
					   const void *additional,
					   size_t additional_len ) {
	hmac_drbg_reseed ( HMAC_DRBG_HASH ( HMAC_DRBG_ALGORITHM ),
			   &state->internal, entropy, entropy_len,
			   additional, additional_len );
}

/**
 * Generate pseudorandom bits using DRBG algorithm
 *
 * @v state		Algorithm state
 * @v additional	Additional input
 * @v additional_len	Length of additional input
 * @v data		Output buffer
 * @v len		Length of output buffer
 * @ret rc		Return status code
 *
 * This is the Generate_algorithm function defined in ANS X9.82
 * Part 3-2007 Section 9.4 (NIST SP 800-90 Section 9.3).
 *
 * Note that the only permitted error is "reseed required".
 */
static inline int drbg_generate_algorithm ( struct drbg_state *state,
					    const void *additional,
					    size_t additional_len,
					    void *data, size_t len ) {
	return hmac_drbg_generate ( HMAC_DRBG_HASH ( HMAC_DRBG_ALGORITHM ),
				    &state->internal, additional,
				    additional_len, data, len );
}

extern int drbg_instantiate ( struct drbg_state *state, const void *personal,
			      size_t personal_len );
extern int drbg_reseed ( struct drbg_state *state, const void *additional,
			 size_t additional_len );
extern int drbg_generate ( struct drbg_state *state, const void *additional,
			   size_t additional_len, int prediction_resist,
			   void *data, size_t len );
extern void drbg_uninstantiate ( struct drbg_state *state );

#endif /* _IPXE_DRBG_H */