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