Browse Source

Added HMAC code from TLS project

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
218314e712
2 changed files with 150 additions and 0 deletions
  1. 120
    0
      src/crypto/hmac.c
  2. 30
    0
      src/include/gpxe/hmac.h

+ 120
- 0
src/crypto/hmac.c View File

@@ -0,0 +1,120 @@
1
+/*
2
+ * Copyright (C) 2007 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
+/**
20
+ * @file
21
+ *
22
+ * Keyed-Hashing for Message Authentication
23
+ */
24
+
25
+#include <string.h>
26
+#include <assert.h>
27
+#include <gpxe/crypto.h>
28
+#include <gpxe/hmac.h>
29
+
30
+/**
31
+ * Reduce HMAC key length
32
+ *
33
+ * @v digest		Digest algorithm to use
34
+ * @v digest_ctx	Digest context
35
+ * @v key		Key
36
+ * @v key_len		Length of key
37
+ */
38
+static void hmac_reduce_key ( struct crypto_algorithm *digest,
39
+			      void *key, size_t *key_len ) {
40
+	uint8_t digest_ctx[digest->ctxsize];
41
+
42
+	digest_init ( digest, digest_ctx );
43
+	digest_update ( digest, digest_ctx, key, *key_len );
44
+	digest_final ( digest, digest_ctx, key );
45
+	*key_len = digest->digestsize;
46
+}
47
+
48
+/**
49
+ * Initialise HMAC
50
+ *
51
+ * @v digest		Digest algorithm to use
52
+ * @v digest_ctx	Digest context
53
+ * @v key		Key
54
+ * @v key_len		Length of key
55
+ *
56
+ * The length of the key should be less than the block size of the
57
+ * digest algorithm being used.  (If the key length is greater, it
58
+ * will be replaced with its own digest, and key_len will be updated
59
+ * accordingly).
60
+ */
61
+void hmac_init ( struct crypto_algorithm *digest, void *digest_ctx,
62
+		 void *key, size_t *key_len ) {
63
+	unsigned char k_ipad[digest->blocksize];
64
+	unsigned int i;
65
+
66
+	/* Reduce key if necessary */
67
+	if ( *key_len > sizeof ( k_ipad ) )
68
+		hmac_reduce_key ( digest, key, key_len );
69
+
70
+	/* Construct input pad */
71
+	memset ( k_ipad, 0, sizeof ( k_ipad ) );
72
+	memcpy ( k_ipad, key, *key_len );
73
+	for ( i = 0 ; i < sizeof ( k_ipad ) ; i++ ) {
74
+		k_ipad[i] ^= 0x36;
75
+	}
76
+	
77
+	/* Start inner hash */
78
+	digest_init ( digest, digest_ctx );
79
+	digest_update ( digest, digest_ctx, k_ipad, sizeof ( k_ipad ) );
80
+}
81
+
82
+/**
83
+ * Finalise HMAC
84
+ *
85
+ * @v digest		Digest algorithm to use
86
+ * @v digest_ctx	Digest context
87
+ * @v key		Key
88
+ * @v key_len		Length of key
89
+ * @v hmac		HMAC digest to fill in
90
+ *
91
+ * The length of the key should be less than the block size of the
92
+ * digest algorithm being used.  (If the key length is greater, it
93
+ * will be replaced with its own digest, and key_len will be updated
94
+ * accordingly).
95
+ */
96
+void hmac_final ( struct crypto_algorithm *digest, void *digest_ctx,
97
+		  void *key, size_t *key_len, void *hmac ) {
98
+	unsigned char k_opad[digest->blocksize];
99
+	unsigned int i;
100
+
101
+	/* Reduce key if necessary */
102
+	if ( *key_len > sizeof ( k_opad ) )
103
+		hmac_reduce_key ( digest, key, key_len );
104
+
105
+	/* Construct output pad */
106
+	memset ( k_opad, 0, sizeof ( k_opad ) );
107
+	memcpy ( k_opad, key, *key_len );
108
+	for ( i = 0 ; i < sizeof ( k_opad ) ; i++ ) {
109
+		k_opad[i] ^= 0x5c;
110
+	}
111
+	
112
+	/* Finish inner hash */
113
+	digest_final ( digest, digest_ctx, hmac );
114
+
115
+	/* Perform outer hash */
116
+	digest_init ( digest, digest_ctx );
117
+	digest_update ( digest, digest_ctx, k_opad, sizeof ( k_opad ) );
118
+	digest_update ( digest, digest_ctx, hmac, digest->digestsize );
119
+	digest_final ( digest, digest_ctx, hmac );
120
+}

+ 30
- 0
src/include/gpxe/hmac.h View File

@@ -0,0 +1,30 @@
1
+#ifndef _GPXE_HMAC_H
2
+#define _GPXE_HMAC_H
3
+
4
+/** @file
5
+ *
6
+ * Keyed-Hashing for Message Authentication
7
+ */
8
+
9
+#include <gpxe/crypto.h>
10
+
11
+/**
12
+ * Update HMAC
13
+ *
14
+ * @v digest		Digest algorithm to use
15
+ * @v digest_ctx	Digest context
16
+ * @v data		Data
17
+ * @v len		Length of data
18
+ */
19
+static inline void hmac_update ( struct crypto_algorithm *digest,
20
+				 void *digest_ctx, const void *data,
21
+				 size_t len ) {
22
+	digest_update ( digest, digest_ctx, data, len );
23
+}
24
+
25
+extern void hmac_init ( struct crypto_algorithm *digest, void *digest_ctx,
26
+			void *key, size_t *key_len );
27
+extern void hmac_final ( struct crypto_algorithm *digest, void *digest_ctx,
28
+			 void *key, size_t *key_len, void *hmac );
29
+
30
+#endif /* _GPXE_HMAC_H */

Loading…
Cancel
Save