These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / crypto / hmac_drbg.c
1 /*
2  * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 /** @file
27  *
28  * HMAC_DRBG algorithm
29  *
30  * This algorithm is designed to comply with ANS X9.82 Part 3-2007
31  * Section 10.2.2.2.  This standard is not freely available, but most
32  * of the text appears to be shared with NIST SP 800-90, which can be
33  * downloaded from
34  *
35  *     http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
36  *
37  * Where possible, references are given to both documents.  In the
38  * case of any disagreement, ANS X9.82 takes priority over NIST SP
39  * 800-90.  (In particular, note that some algorithms that are
40  * Approved by NIST SP 800-90 are not Approved by ANS X9.82.)
41  */
42
43 #include <stdint.h>
44 #include <string.h>
45 #include <errno.h>
46 #include <assert.h>
47 #include <ipxe/crypto.h>
48 #include <ipxe/hmac.h>
49 #include <ipxe/hmac_drbg.h>
50
51 /**
52  * Update the HMAC_DRBG key
53  *
54  * @v hash              Underlying hash algorithm
55  * @v state             HMAC_DRBG internal state
56  * @v data              Provided data
57  * @v len               Length of provided data
58  * @v single            Single byte used in concatenation
59  *
60  * This function carries out the operation
61  *
62  *     K = HMAC ( K, V || single || provided_data )
63  *
64  * as used by hmac_drbg_update()
65  */
66 static void hmac_drbg_update_key ( struct digest_algorithm *hash,
67                                    struct hmac_drbg_state *state,
68                                    const void *data, size_t len,
69                                    const uint8_t single ) {
70         uint8_t context[ hash->ctxsize ];
71         size_t out_len = hash->digestsize;
72
73         DBGC ( state, "HMAC_DRBG_%s %p provided data :\n", hash->name, state );
74         DBGC_HDA ( state, 0, data, len );
75
76         /* Sanity checks */
77         assert ( hash != NULL );
78         assert ( state != NULL );
79         assert ( ( data != NULL ) || ( len == 0 ) );
80         assert ( ( single == 0x00 ) || ( single == 0x01 ) );
81
82         /* K = HMAC ( K, V || single || provided_data ) */
83         hmac_init ( hash, context, state->key, &out_len );
84         assert ( out_len == hash->digestsize );
85         hmac_update ( hash, context, state->value, out_len );
86         hmac_update ( hash, context, &single, sizeof ( single ) );
87         hmac_update ( hash, context, data, len );
88         hmac_final ( hash, context, state->key, &out_len, state->key );
89         assert ( out_len == hash->digestsize );
90
91         DBGC ( state, "HMAC_DRBG_%s %p K = HMAC ( K, V || %#02x || "
92                "provided_data ) :\n", hash->name, state, single );
93         DBGC_HDA ( state, 0, state->key, out_len );
94 }
95
96 /**
97  * Update the HMAC_DRBG value
98  *
99  * @v hash              Underlying hash algorithm
100  * @v state             HMAC_DRBG internal state
101  * @v data              Provided data
102  * @v len               Length of provided data
103  * @v single            Single byte used in concatenation
104  *
105  * This function carries out the operation
106  *
107  *     V = HMAC ( K, V )
108  *
109  * as used by hmac_drbg_update() and hmac_drbg_generate()
110  */
111 static void hmac_drbg_update_value ( struct digest_algorithm *hash,
112                                      struct hmac_drbg_state *state ) {
113         uint8_t context[ hash->ctxsize ];
114         size_t out_len = hash->digestsize;
115
116         /* Sanity checks */
117         assert ( hash != NULL );
118         assert ( state != NULL );
119
120         /* V = HMAC ( K, V ) */
121         hmac_init ( hash, context, state->key, &out_len );
122         assert ( out_len == hash->digestsize );
123         hmac_update ( hash, context, state->value, out_len );
124         hmac_final ( hash, context, state->key, &out_len, state->value );
125         assert ( out_len == hash->digestsize );
126
127         DBGC ( state, "HMAC_DRBG_%s %p V = HMAC ( K, V ) :\n",
128                hash->name, state );
129         DBGC_HDA ( state, 0, state->value, out_len );
130 }
131
132 /**
133  * Update HMAC_DRBG internal state
134  *
135  * @v hash              Underlying hash algorithm
136  * @v state             HMAC_DRBG internal state
137  * @v data              Provided data
138  * @v len               Length of provided data
139  *
140  * This is the HMAC_DRBG_Update function defined in ANS X9.82 Part
141  * 3-2007 Section 10.2.2.2.2 (NIST SP 800-90 Section 10.1.2.2).
142  *
143  * The key and value are updated in-place within the HMAC_DRBG
144  * internal state.
145  */
146 static void hmac_drbg_update ( struct digest_algorithm *hash,
147                                struct hmac_drbg_state *state,
148                                const void *data, size_t len ) {
149
150         DBGC ( state, "HMAC_DRBG_%s %p update\n", hash->name, state );
151
152         /* Sanity checks */
153         assert ( hash != NULL );
154         assert ( state != NULL );
155         assert ( ( data != NULL ) || ( len == 0 ) );
156
157         /* 1.  K = HMAC ( K, V || 0x00 || provided_data ) */
158         hmac_drbg_update_key ( hash, state, data, len, 0x00 );
159
160         /* 2.  V = HMAC ( K, V ) */
161         hmac_drbg_update_value ( hash, state );
162
163         /* 3.  If ( provided_data = Null ), then return K and V */
164         if ( ! len )
165                 return;
166
167         /* 4.  K = HMAC ( K, V || 0x01 || provided_data ) */
168         hmac_drbg_update_key ( hash, state, data, len, 0x01 );
169
170         /* 5.  V = HMAC ( K, V ) */
171         hmac_drbg_update_value ( hash, state );
172
173         /* 6.  Return K and V */
174 }
175
176 /**
177  * Instantiate HMAC_DRBG
178  *
179  * @v hash              Underlying hash algorithm
180  * @v state             HMAC_DRBG internal state to be initialised
181  * @v entropy           Entropy input
182  * @v entropy_len       Length of entropy input
183  * @v personal          Personalisation string
184  * @v personal_len      Length of personalisation string
185  *
186  * This is the HMAC_DRBG_Instantiate_algorithm function defined in ANS
187  * X9.82 Part 3-2007 Section 10.2.2.2.3 (NIST SP 800-90 Section
188  * 10.1.2.3).
189  *
190  * The nonce must be included within the entropy input (i.e. the
191  * entropy input must contain at least 3/2 * security_strength bits of
192  * entropy, as per ANS X9.82 Part 3-2007 Section 8.4.2 (NIST SP 800-90
193  * Section 8.6.7).
194  *
195  * The key, value and reseed counter are updated in-place within the
196  * HMAC_DRBG internal state.
197  */
198 void hmac_drbg_instantiate ( struct digest_algorithm *hash,
199                              struct hmac_drbg_state *state,
200                              const void *entropy, size_t entropy_len,
201                              const void *personal, size_t personal_len ){
202         size_t out_len = hash->digestsize;
203
204         DBGC ( state, "HMAC_DRBG_%s %p instantiate\n", hash->name, state );
205
206         /* Sanity checks */
207         assert ( hash != NULL );
208         assert ( state != NULL );
209         assert ( entropy != NULL );
210         assert ( ( personal != NULL ) || ( personal_len == 0 ) );
211
212         /* 1.  seed_material = entropy_input || nonce ||
213          *     personalisation_string
214          */
215
216         /* 2.  Key = 0x00 00..00 */
217         memset ( state->key, 0x00, out_len );
218
219         /* 3.  V = 0x01 01...01 */
220         memset ( state->value, 0x01, out_len );
221
222         /* 4.  ( Key, V ) = HMAC_DBRG_Update ( seed_material, Key, V )
223          * 5.  reseed_counter = 1
224          * 6.  Return V, Key and reseed_counter as the
225          *     initial_working_state
226          */
227         hmac_drbg_reseed ( hash, state, entropy, entropy_len,
228                            personal, personal_len );
229 }
230
231 /**
232  * Reseed HMAC_DRBG
233  *
234  * @v hash              Underlying hash algorithm
235  * @v state             HMAC_DRBG internal state
236  * @v entropy           Entropy input
237  * @v entropy_len       Length of entropy input
238  * @v additional        Additional input
239  * @v additional_len    Length of additional input
240  *
241  * This is the HMAC_DRBG_Reseed_algorithm function defined in ANS X9.82
242  * Part 3-2007 Section 10.2.2.2.4 (NIST SP 800-90 Section 10.1.2.4).
243  *
244  * The key, value and reseed counter are updated in-place within the
245  * HMAC_DRBG internal state.
246  */
247 void hmac_drbg_reseed ( struct digest_algorithm *hash,
248                         struct hmac_drbg_state *state,
249                         const void *entropy, size_t entropy_len,
250                         const void *additional, size_t additional_len ) {
251         uint8_t seed_material[ entropy_len + additional_len ];
252
253         DBGC ( state, "HMAC_DRBG_%s %p (re)seed\n", hash->name, state );
254
255         /* Sanity checks */
256         assert ( hash != NULL );
257         assert ( state != NULL );
258         assert ( entropy != NULL );
259         assert ( ( additional != NULL ) || ( additional_len == 0 ) );
260
261         /* 1.  seed_material = entropy_input || additional_input */
262         memcpy ( seed_material, entropy, entropy_len );
263         memcpy ( ( seed_material + entropy_len ), additional, additional_len );
264         DBGC ( state, "HMAC_DRBG_%s %p seed material :\n", hash->name, state );
265         DBGC_HDA ( state, 0, seed_material, sizeof ( seed_material ) );
266
267         /* 2.  ( Key, V ) = HMAC_DBRG_Update ( seed_material, Key, V ) */
268         hmac_drbg_update ( hash, state, seed_material,
269                            sizeof ( seed_material ) );
270
271         /* 3.  reseed_counter = 1 */
272         state->reseed_counter = 1;
273
274         /* 4.  Return V, Key and reseed_counter as the new_working_state */
275 }
276
277 /**
278  * Generate pseudorandom bits using HMAC_DRBG
279  *
280  * @v hash              Underlying hash algorithm
281  * @v state             HMAC_DRBG internal state
282  * @v additional        Additional input
283  * @v additional_len    Length of additional input
284  * @v data              Output buffer
285  * @v len               Length of output buffer
286  * @ret rc              Return status code
287  *
288  * This is the HMAC_DRBG_Generate_algorithm function defined in ANS X9.82
289  * Part 3-2007 Section 10.2.2.2.5 (NIST SP 800-90 Section 10.1.2.5).
290  *
291  * Requests must be for an integral number of bytes.
292  *
293  * The key, value and reseed counter are updated in-place within the
294  * HMAC_DRBG internal state.
295  *
296  * Note that the only permitted error is "reseed required".
297  */
298 int hmac_drbg_generate ( struct digest_algorithm *hash,
299                          struct hmac_drbg_state *state,
300                          const void *additional, size_t additional_len,
301                          void *data, size_t len ) {
302         size_t out_len = hash->digestsize;
303         void *orig_data = data;
304         size_t orig_len = len;
305         size_t frag_len;
306
307         DBGC ( state, "HMAC_DRBG_%s %p generate\n", hash->name, state );
308
309         /* Sanity checks */
310         assert ( hash != NULL );
311         assert ( state != NULL );
312         assert ( data != NULL );
313         assert ( ( additional != NULL ) || ( additional_len == 0 ) );
314
315         /* 1.  If reseed_counter > reseed_interval, then return an
316          *     indication that a reseed is required
317          */
318         if ( state->reseed_counter > HMAC_DRBG_RESEED_INTERVAL ) {
319                 DBGC ( state, "HMAC_DRBG_%s %p reseed interval exceeded\n",
320                        hash->name, state );
321                 return -ESTALE;
322         }
323
324         /* 2.  If additional_input != Null, then
325          *     ( Key, V ) = HMAC_DRBG_Update ( additional_input, Key, V )
326          */
327         if ( additional_len )
328                 hmac_drbg_update ( hash, state, additional, additional_len );
329
330         /* 3.  temp = Null
331          * 4.  While ( len ( temp ) < requested_number_of_bits ) do:
332          */
333         while ( len ) {
334
335                 /* 4.1  V = HMAC ( Key, V ) */
336                 hmac_drbg_update_value ( hash, state );
337
338                 /* 4.2.  temp = temp || V
339                  * 5.    returned_bits = Leftmost requested_number_of_bits
340                  *       of temp
341                  */
342                 frag_len = len;
343                 if ( frag_len > out_len )
344                         frag_len = out_len;
345                 memcpy ( data, state->value, frag_len );
346                 data += frag_len;
347                 len -= frag_len;
348         }
349
350         /* 6.  ( Key, V ) = HMAC_DRBG_Update ( additional_input, Key, V ) */
351         hmac_drbg_update ( hash, state, additional, additional_len );
352
353         /* 7.  reseed_counter = reseed_counter + 1 */
354         state->reseed_counter++;
355
356         DBGC ( state, "HMAC_DRBG_%s %p generated :\n", hash->name, state );
357         DBGC_HDA ( state, 0, orig_data, orig_len );
358
359         /* 8.  Return SUCCESS, returned_bits, and the new values of
360          *     Key, V and reseed_counter as the new_working_state
361          */
362         return 0;
363 }