Преглед изворни кода

[rng] Add ANS X9.82 Approved Hash_df derivation function

ANS X9.82 specifies several Approved derivation functions for use in
distributing entropy throughout a buffer.  One such derivation
function is Hash_df, which can be implemented using the existing iPXE
SHA-1 functionality.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown пре 12 година
родитељ
комит
eec068253f
2 измењених фајлова са 164 додато и 0 уклоњено
  1. 134
    0
      src/crypto/hash_df.c
  2. 30
    0
      src/include/ipxe/hash_df.h

+ 134
- 0
src/crypto/hash_df.c Прегледај датотеку

@@ -0,0 +1,134 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+/** @file
22
+ *
23
+ * Hash-based derivation function (Hash_df)
24
+ *
25
+ * This algorithm is designed to comply with ANS X9.82 Part 3-2007
26
+ * Section 10.5.2.  This standard is not freely available, but most of
27
+ * the text appears to be shared with NIST SP 800-90, which can be
28
+ * downloaded from
29
+ *
30
+ *     http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
31
+ *
32
+ * Where possible, references are given to both documents.  In the
33
+ * case of any disagreement, ANS X9.82 takes priority over NIST SP
34
+ * 800-90.  (In particular, note that some algorithms that are
35
+ * Approved by NIST SP 800-90 are not Approved by ANS X9.82.)
36
+ */
37
+
38
+#include <stdint.h>
39
+#include <byteswap.h>
40
+#include <ipxe/crypto.h>
41
+#include <ipxe/hash_df.h>
42
+
43
+/**
44
+ * Distribute entropy throughout a buffer
45
+ *
46
+ * @v input		Input data
47
+ * @v input_len		Length of input data, in bytes
48
+ * @v output		Output buffer
49
+ * @v output_len	Length of output buffer, in bytes
50
+ *
51
+ * This is the Hash_df function defined in ANS X9.82 Part 3-2007
52
+ * Section 10.5.2 (NIST SP 800-90 Section 10.4.1).
53
+ *
54
+ * The number of bits requested is implicit in the length of the
55
+ * output buffer.  Requests must be for an integral number of bytes.
56
+ *
57
+ * The output buffer is filled incrementally with each iteration of
58
+ * the central loop, rather than constructing an overall "temp" and
59
+ * then taking the leftmost(no_of_bits_to_return) bits.
60
+ *
61
+ * There is no way for the Hash_df function to fail.  The returned
62
+ * status SUCCESS is implicit.
63
+ */
64
+void hash_df ( const void *input, size_t input_len, void *output,
65
+	      size_t output_len ) {
66
+	uint8_t context[HASH_DF_CTX_SIZE];
67
+	uint8_t digest[HASH_DF_OUTLEN_BYTES];
68
+	size_t frag_len;
69
+	struct {
70
+		uint8_t pad[3];
71
+		uint8_t counter;
72
+		uint32_t no_of_bits_to_return;
73
+	} __attribute__ (( packed )) prefix;
74
+	void *temp;
75
+	size_t remaining;
76
+
77
+	DBGC ( &hash_df, "HASH_DF input:\n" );
78
+	DBGC_HDA ( &hash_df, 0, input, input_len );
79
+
80
+	/* Sanity checks */
81
+	assert ( input != NULL );
82
+	assert ( output != NULL );
83
+
84
+	/* 1.  temp = the Null string
85
+	 * 2.  len = ceil ( no_of_bits_to_return / outlen )
86
+	 *
87
+	 * (Nothing to do.  We fill the output buffer incrementally,
88
+	 * rather than constructing the complete "temp" in-memory.
89
+	 * "len" is implicit in the number of iterations required to
90
+	 * fill the output buffer, and so is not calculated
91
+	 * explicitly.)
92
+	 */
93
+
94
+	/* 3.  counter = an 8-bit binary value representing the integer "1" */
95
+	prefix.counter = 1;
96
+
97
+	/* 4.  For i = 1 to len do */
98
+	for ( temp = output, remaining = output_len ; remaining > 0 ; ) {
99
+
100
+		/* Comment: in step 5.1 (sic), no_of_bits_to_return is
101
+		 * used as a 32-bit string.
102
+		 *
103
+		 * 4.1  temp = temp || Hash ( counter || no_of_bits_to_return
104
+		 *                            || input_string )
105
+		 */
106
+		prefix.no_of_bits_to_return = htonl ( output_len * 8 );
107
+		digest_init ( &hash_df_algorithm, context );
108
+		digest_update ( &hash_df_algorithm, context, &prefix.counter,
109
+				( sizeof ( prefix ) -
110
+				  offsetof ( typeof ( prefix ), counter ) ) );
111
+		digest_update ( &hash_df_algorithm, context, input, input_len );
112
+		digest_final ( &hash_df_algorithm, context, digest );
113
+
114
+		/* 4.2  counter = counter + 1 */
115
+		prefix.counter++;
116
+
117
+		/* 5.    requested_bits = Leftmost ( no_of_bits_to_return )
118
+		 *       of temp
119
+		 *
120
+		 * (We fill the output buffer incrementally.)
121
+		 */
122
+		frag_len = sizeof ( digest );
123
+		if ( frag_len > remaining )
124
+			frag_len = remaining;
125
+		memcpy ( temp, digest, frag_len );
126
+		temp += frag_len;
127
+		remaining -= frag_len;
128
+	}
129
+
130
+	/* 6.  Return SUCCESS and requested_bits */
131
+	DBGC ( &hash_df, "HASH_DF output:\n" );
132
+	DBGC_HDA ( &hash_df, 0, output, output_len );
133
+	return;
134
+}

+ 30
- 0
src/include/ipxe/hash_df.h Прегледај датотеку

@@ -0,0 +1,30 @@
1
+#ifndef _IPXE_HASH_DF_H
2
+#define _IPXE_HASH_DF_H
3
+
4
+/** @file
5
+ *
6
+ * Hash-based derivation function (Hash_df)
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER );
11
+
12
+#include <stdint.h>
13
+#include <ipxe/sha1.h>
14
+
15
+/** Use SHA-1 as the underlying hash algorithm
16
+ *
17
+ * Hash_df using SHA-1 is an Approved algorithm in ANS X9.82.
18
+ */
19
+#define hash_df_algorithm sha1_algorithm
20
+
21
+/** Underlying hash algorithm output length (in bytes) */
22
+#define HASH_DF_OUTLEN_BYTES SHA1_DIGEST_SIZE
23
+
24
+/** Underlying hash algorithm context size (in bytes) */
25
+#define HASH_DF_CTX_SIZE SHA1_CTX_SIZE
26
+
27
+extern void hash_df ( const void *input, size_t input_len, void *output,
28
+		      size_t output_len );
29
+
30
+#endif /* _IPXE_HASH_DF_H */

Loading…
Откажи
Сачувај