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