1 /*
2  * Copyright (c) 1999, 2000, 2002 X-Way Rights BV
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  */
19 
20 /*!\file hmac.c
21  * \brief HMAC algorithm.
22  *
23  * \see RFC2104 HMAC: Keyed-Hashing for Message Authentication.
24  *                    H. Krawczyk, M. Bellare, R. Canetti.
25  *
26  * \author Bob Deblier <bob.deblier@pandore.be>
27  * \ingroup HMAC_m
28  */
29 
30 #define BEECRYPT_DLL_EXPORT
31 
32 #if HAVE_CONFIG_H
33 # include "config.h"
34 #endif
35 
36 #include "beecrypt/hmac.h"
37 
38 /*!\addtogroup HMAC_m
39  * \{
40  */
41 
42 #define HMAC_IPAD	0x36
43 #define HMAC_OPAD	0x5c
44 
hmacSetup(byte * kxi,byte * kxo,const hashFunction * hash,hashFunctionParam * param,const byte * key,size_t keybits)45 int hmacSetup(byte* kxi, byte* kxo, const hashFunction* hash, hashFunctionParam* param, const byte* key, size_t keybits)
46 {
47 	register unsigned int i;
48 
49 	size_t keybytes = keybits >> 3;
50 
51 	/* if the key is too large, hash it first */
52 	if (keybytes > hash->blocksize)
53 	{
54 		/* if the hash digest is too large, this doesn't help; this is really a sanity check */
55 		if (hash->digestsize > hash->blocksize)
56 			return -1;
57 
58 		if (hash->reset(param))
59 			return -1;
60 
61 		if (hash->update(param, key, keybytes))
62 			return -1;
63 
64 		if (hash->digest(param, kxi))
65 			return -1;
66 
67 		memcpy(kxo, kxi, keybytes = hash->digestsize);
68 	}
69 	else if (keybytes > 0)
70 	{
71 		memcpy(kxi, key, keybytes);
72 		memcpy(kxo, key, keybytes);
73 	}
74 	else
75 		return -1;
76 
77 	for (i = 0; i < keybytes; i++)
78 	{
79 		kxi[i] ^= HMAC_IPAD;
80 		kxo[i] ^= HMAC_OPAD;
81 	}
82 
83 	for (i = keybytes; i < hash->blocksize; i++)
84 	{
85 		kxi[i] = HMAC_IPAD;
86 		kxo[i] = HMAC_OPAD;
87 	}
88 
89 	return hmacReset(kxi, hash, param);
90 }
91 
hmacReset(const byte * kxi,const hashFunction * hash,hashFunctionParam * param)92 int hmacReset(const byte* kxi, const hashFunction* hash, hashFunctionParam* param)
93 {
94 	if (hash->reset(param))
95 		return -1;
96 	if (hash->update(param, kxi, hash->blocksize))
97 		return -1;
98 
99 	return 0;
100 }
101 
hmacUpdate(const hashFunction * hash,hashFunctionParam * param,const byte * data,size_t size)102 int hmacUpdate(const hashFunction* hash, hashFunctionParam* param, const byte* data, size_t size)
103 {
104 	return hash->update(param, data, size);
105 }
106 
hmacDigest(const byte * kxo,const hashFunction * hash,hashFunctionParam * param,byte * data)107 int hmacDigest(const byte* kxo, const hashFunction* hash, hashFunctionParam* param, byte* data)
108 {
109 	if (hash->digest(param, data))
110 		return -1;
111 	if (hash->update(param, kxo, hash->blocksize))
112 		return -1;
113 	if (hash->update(param, data, hash->digestsize))
114 		return -1;
115 	if (hash->digest(param, data))
116 		return -1;
117 
118 	return 0;
119 }
120 
121 /*!\}
122  */
123