4
* Purple is the legal property of its developers, whose names are too numerous
5
* to list here. Please refer to the COPYRIGHT file distributed with this
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
27
PurpleCipherContext *hash;
34
hmac_init(PurpleCipherContext *context, gpointer extra)
36
struct HMAC_Context *hctx;
37
hctx = g_new0(struct HMAC_Context, 1);
38
purple_cipher_context_set_data(context, hctx);
39
purple_cipher_context_reset(context, extra);
43
hmac_reset(PurpleCipherContext *context, gpointer extra)
45
struct HMAC_Context *hctx;
47
hctx = purple_cipher_context_get_data(context);
52
purple_cipher_context_destroy(hctx->hash);
60
hmac_set_opt(PurpleCipherContext *context, const gchar *name, void *value)
62
struct HMAC_Context *hctx;
64
hctx = purple_cipher_context_get_data(context);
66
if (purple_strequal(name, "hash")) {
69
purple_cipher_context_destroy(hctx->hash);
70
hctx->name = g_strdup((char*)value);
71
hctx->hash = purple_cipher_context_new_by_name((char *)value, NULL);
72
hctx->blocksize = purple_cipher_context_get_block_size(hctx->hash);
77
hmac_get_opt(PurpleCipherContext *context, const gchar *name)
79
struct HMAC_Context *hctx;
81
hctx = purple_cipher_context_get_data(context);
83
if (purple_strequal(name, "hash")) {
91
hmac_append(PurpleCipherContext *context, const guchar *data, size_t len)
93
struct HMAC_Context *hctx = purple_cipher_context_get_data(context);
95
g_return_if_fail(hctx->hash != NULL);
97
purple_cipher_context_append(hctx->hash, data, len);
101
hmac_digest(PurpleCipherContext *context, size_t in_len, guchar *out, size_t *out_len)
103
struct HMAC_Context *hctx = purple_cipher_context_get_data(context);
104
PurpleCipherContext *hash = hctx->hash;
109
g_return_val_if_fail(hash != NULL, FALSE);
111
inner_hash = g_malloc(100); /* TODO: Should be enough for now... */
112
result = purple_cipher_context_digest(hash, 100, inner_hash, &hash_len);
114
purple_cipher_context_reset(hash, NULL);
116
purple_cipher_context_append(hash, hctx->opad, hctx->blocksize);
117
purple_cipher_context_append(hash, inner_hash, hash_len);
121
result = result && purple_cipher_context_digest(hash, in_len, out, out_len);
127
hmac_uninit(PurpleCipherContext *context)
129
struct HMAC_Context *hctx;
131
purple_cipher_context_reset(context, NULL);
133
hctx = purple_cipher_context_get_data(context);
139
hmac_set_key_with_len(PurpleCipherContext *context, const guchar * key, size_t key_len)
141
struct HMAC_Context *hctx = purple_cipher_context_get_data(context);
146
g_return_if_fail(hctx->hash != NULL);
150
blocksize = hctx->blocksize;
151
ipad = g_malloc(blocksize);
152
hctx->opad = g_malloc(blocksize);
154
if (key_len > blocksize) {
155
purple_cipher_context_reset(hctx->hash, NULL);
156
purple_cipher_context_append(hctx->hash, key, key_len);
157
full_key = g_malloc(100); /* TODO: Should be enough for now... */
158
purple_cipher_context_digest(hctx->hash, 100, full_key, &key_len);
160
full_key = g_memdup(key, key_len);
162
if (key_len < blocksize) {
163
full_key = g_realloc(full_key, blocksize);
164
memset(full_key + key_len, 0, blocksize - key_len);
167
for(i = 0; i < blocksize; i++) {
168
ipad[i] = 0x36 ^ full_key[i];
169
hctx->opad[i] = 0x5c ^ full_key[i];
174
purple_cipher_context_reset(hctx->hash, NULL);
175
purple_cipher_context_append(hctx->hash, ipad, blocksize);
180
hmac_set_key(PurpleCipherContext *context, const guchar * key)
182
hmac_set_key_with_len(context, key, strlen((char *)key));
186
hmac_get_block_size(PurpleCipherContext *context)
188
struct HMAC_Context *hctx = purple_cipher_context_get_data(context);
190
return hctx->blocksize;
193
static PurpleCipherOps HMACOps = {
194
hmac_set_opt, /* Set option */
195
hmac_get_opt, /* Get option */
196
hmac_init, /* init */
197
hmac_reset, /* reset */
198
hmac_uninit, /* uninit */
200
hmac_append, /* append */
201
hmac_digest, /* digest */
205
NULL, /* get salt size */
206
hmac_set_key, /* set key */
207
NULL, /* get key size */
208
NULL, /* set batch mode */
209
NULL, /* get batch mode */
210
hmac_get_block_size, /* get block size */
211
hmac_set_key_with_len /* set key with len */
215
purple_hmac_cipher_get_ops(void) {