Fix some functions descriptions
[pidgin-git.git] / libpurple / cipher.c
blobc839d577d87876c21642e7672e55b2ba4c3458b6
1 /* purple
3 * Purple is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
5 * source distribution.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
21 #include "internal.h"
22 #include "cipher.h"
23 #include "debug.h"
25 /******************************************************************************
26 * PurpleCipher API
27 *****************************************************************************/
28 GType
29 purple_cipher_get_type(void) {
30 static GType type = 0;
32 if(type == 0) {
33 static const GTypeInfo info = {
34 sizeof(PurpleCipherClass),
35 NULL,
36 NULL,
37 NULL,
38 NULL,
39 NULL,
40 sizeof(PurpleCipher),
42 NULL,
43 NULL
46 type = g_type_register_static(G_TYPE_OBJECT,
47 "PurpleCipher",
48 &info, G_TYPE_FLAG_ABSTRACT);
51 return type;
54 static const gchar *
55 purple_cipher_get_name(PurpleCipher *cipher)
57 PurpleCipherClass *klass;
58 const gchar *name;
60 if (!PURPLE_IS_CIPHER(cipher))
61 return "(error: not a cipher)";
63 klass = PURPLE_CIPHER_GET_CLASS(cipher);
64 if (!klass)
65 return "(error: unknown cipher class)";
67 name = g_type_name(G_TYPE_FROM_CLASS(klass));
68 if (!name)
69 return "(error: unknown cipher name)";
71 return name;
74 static const gchar *
75 purple_hash_get_name(PurpleHash *hash)
77 PurpleHashClass *klass;
78 const gchar *name;
80 if (!PURPLE_IS_HASH(hash))
81 return "(error: not a hash)";
83 klass = PURPLE_HASH_GET_CLASS(hash);
84 if (!klass)
85 return "(error: unknown hash class)";
87 name = g_type_name(G_TYPE_FROM_CLASS(klass));
88 if (!name)
89 return "(error: unknown hash name)";
91 return name;
94 void
95 purple_cipher_reset(PurpleCipher *cipher) {
96 PurpleCipherClass *klass = NULL;
98 g_return_if_fail(PURPLE_IS_CIPHER(cipher));
100 klass = PURPLE_CIPHER_GET_CLASS(cipher);
102 if (klass && klass->reset)
103 klass->reset(cipher);
104 else {
105 purple_debug_warning("cipher", "the %s cipher does not "
106 "implement the reset method",
107 purple_cipher_get_name(cipher));
111 void
112 purple_cipher_reset_state(PurpleCipher *cipher) {
113 PurpleCipherClass *klass = NULL;
115 g_return_if_fail(PURPLE_IS_CIPHER(cipher));
117 klass = PURPLE_CIPHER_GET_CLASS(cipher);
119 if (klass && klass->reset_state)
120 klass->reset_state(cipher);
121 else {
122 purple_debug_warning("cipher", "the %s cipher does not "
123 "implement the reset_state method",
124 purple_cipher_get_name(cipher));
128 void
129 purple_cipher_set_iv(PurpleCipher *cipher, guchar *iv, size_t len)
131 PurpleCipherClass *klass = NULL;
133 g_return_if_fail(PURPLE_IS_CIPHER(cipher));
134 g_return_if_fail(iv);
136 klass = PURPLE_CIPHER_GET_CLASS(cipher);
138 if (klass && klass->set_iv)
139 klass->set_iv(cipher, iv, len);
140 else {
141 purple_debug_warning("cipher", "the %s cipher does not "
142 "implement the set_iv method",
143 purple_cipher_get_name(cipher));
147 void
148 purple_cipher_append(PurpleCipher *cipher, const guchar *data,
149 size_t len)
151 PurpleCipherClass *klass = NULL;
153 g_return_if_fail(PURPLE_IS_CIPHER(cipher));
155 klass = PURPLE_CIPHER_GET_CLASS(cipher);
157 if (klass && klass->append)
158 klass->append(cipher, data, len);
159 else {
160 purple_debug_warning("cipher", "the %s cipher does not "
161 "implement the append method",
162 purple_cipher_get_name(cipher));
166 gboolean
167 purple_cipher_digest(PurpleCipher *cipher, guchar digest[], size_t len)
169 PurpleCipherClass *klass = NULL;
171 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), FALSE);
173 klass = PURPLE_CIPHER_GET_CLASS(cipher);
175 if (klass && klass->digest)
176 return klass->digest(cipher, digest, len);
177 else {
178 purple_debug_warning("cipher", "the %s cipher does not "
179 "implement the digest method",
180 purple_cipher_get_name(cipher));
183 return FALSE;
186 gboolean
187 purple_cipher_digest_to_str(PurpleCipher *cipher, gchar digest_s[], size_t len)
189 /* 8k is a bit excessive, will tweak later. */
190 guchar digest[BUF_LEN * 4];
191 size_t digest_size, n;
193 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), FALSE);
194 g_return_val_if_fail(digest_s, FALSE);
196 digest_size = purple_cipher_get_digest_size(cipher);
198 g_return_val_if_fail(digest_size <= BUF_LEN * 4, FALSE);
200 if(!purple_cipher_digest(cipher, digest, sizeof(digest)))
201 return FALSE;
203 /* Every digest byte occupies 2 chars + the NUL at the end. */
204 g_return_val_if_fail(digest_size * 2 + 1 <= len, FALSE);
206 for(n = 0; n < digest_size; n++)
207 sprintf(digest_s + (n * 2), "%02x", digest[n]);
209 digest_s[n * 2] = '\0';
211 return TRUE;
214 size_t
215 purple_cipher_get_digest_size(PurpleCipher *cipher)
217 PurpleCipherClass *klass = NULL;
219 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), FALSE);
221 klass = PURPLE_CIPHER_GET_CLASS(cipher);
223 if (klass && klass->get_digest_size)
224 return klass->get_digest_size(cipher);
225 else {
226 purple_debug_warning("cipher", "the %s cipher does not "
227 "implement the get_digest_size method",
228 purple_cipher_get_name(cipher));
231 return FALSE;
234 ssize_t
235 purple_cipher_encrypt(PurpleCipher *cipher, const guchar input[],
236 size_t in_len, guchar output[], size_t out_size)
238 PurpleCipherClass *klass = NULL;
240 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), -1);
241 g_return_val_if_fail(input != NULL, -1);
242 g_return_val_if_fail(output != NULL, -1);
243 g_return_val_if_fail(out_size >= in_len, -1);
245 klass = PURPLE_CIPHER_GET_CLASS(cipher);
247 if (klass && klass->encrypt)
248 return klass->encrypt(cipher, input, in_len, output, out_size);
249 else {
250 purple_debug_warning("cipher", "the %s cipher does not "
251 "implement the encrypt method",
252 purple_cipher_get_name(cipher));
255 return -1;
258 ssize_t
259 purple_cipher_decrypt(PurpleCipher *cipher, const guchar input[],
260 size_t in_len, guchar output[], size_t out_size)
262 PurpleCipherClass *klass = NULL;
264 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), -1);
265 g_return_val_if_fail(input != NULL, -1);
266 g_return_val_if_fail(output != NULL, -1);
268 klass = PURPLE_CIPHER_GET_CLASS(cipher);
270 if (klass && klass->decrypt)
271 return klass->decrypt(cipher, input, in_len, output, out_size);
272 else {
273 purple_debug_warning("cipher", "the %s cipher does not "
274 "implement the decrypt method",
275 purple_cipher_get_name(cipher));
278 return -1;
281 void
282 purple_cipher_set_salt(PurpleCipher *cipher, const guchar *salt, size_t len) {
283 PurpleCipherClass *klass = NULL;
285 g_return_if_fail(PURPLE_IS_CIPHER(cipher));
287 klass = PURPLE_CIPHER_GET_CLASS(cipher);
289 if (klass && klass->set_salt)
290 klass->set_salt(cipher, salt, len);
291 else {
292 purple_debug_warning("cipher", "the %s cipher does not "
293 "implement the set_salt method",
294 purple_cipher_get_name(cipher));
298 void
299 purple_cipher_set_key(PurpleCipher *cipher, const guchar *key, size_t len) {
300 PurpleCipherClass *klass = NULL;
302 g_return_if_fail(PURPLE_IS_CIPHER(cipher));
304 klass = PURPLE_CIPHER_GET_CLASS(cipher);
306 if (klass && klass->set_key)
307 klass->set_key(cipher, key, len);
308 else {
309 purple_debug_warning("cipher", "the %s cipher does not "
310 "implement the set_key method",
311 purple_cipher_get_name(cipher));
315 size_t
316 purple_cipher_get_key_size(PurpleCipher *cipher) {
317 PurpleCipherClass *klass = NULL;
319 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), -1);
321 klass = PURPLE_CIPHER_GET_CLASS(cipher);
323 if (klass && klass->get_key_size)
324 return klass->get_key_size(cipher);
325 else {
326 purple_debug_warning("cipher", "the %s cipher does not "
327 "implement the get_key_size method",
328 purple_cipher_get_name(cipher));
331 return -1;
334 void
335 purple_cipher_set_batch_mode(PurpleCipher *cipher,
336 PurpleCipherBatchMode mode)
338 PurpleCipherClass *klass = NULL;
340 g_return_if_fail(PURPLE_IS_CIPHER(cipher));
342 klass = PURPLE_CIPHER_GET_CLASS(cipher);
344 if (klass && klass->set_batch_mode)
345 klass->set_batch_mode(cipher, mode);
346 else {
347 purple_debug_warning("cipher", "the %s cipher does not "
348 "implement the set_batch_mode method",
349 purple_cipher_get_name(cipher));
353 PurpleCipherBatchMode
354 purple_cipher_get_batch_mode(PurpleCipher *cipher)
356 PurpleCipherClass *klass = NULL;
358 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), -1);
360 klass = PURPLE_CIPHER_GET_CLASS(cipher);
362 if (klass && klass->get_batch_mode)
363 return klass->get_batch_mode(cipher);
364 else {
365 purple_debug_warning("cipher", "the %s cipher does not "
366 "implement the get_batch_mode method",
367 purple_cipher_get_name(cipher));
370 return -1;
373 size_t
374 purple_cipher_get_block_size(PurpleCipher *cipher)
376 PurpleCipherClass *klass = NULL;
378 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher), -1);
380 klass = PURPLE_CIPHER_GET_CLASS(cipher);
382 if (klass && klass->get_block_size)
383 return klass->get_block_size(cipher);
384 else {
385 purple_debug_warning("cipher", "the %s cipher does not "
386 "implement the get_block_size method",
387 purple_cipher_get_name(cipher));
390 return -1;
393 /******************************************************************************
394 * PurpleHash API
395 *****************************************************************************/
396 GType
397 purple_hash_get_type(void) {
398 static GType type = 0;
400 if(type == 0) {
401 static const GTypeInfo info = {
402 sizeof(PurpleHashClass),
403 NULL,
404 NULL,
405 NULL,
406 NULL,
407 NULL,
408 sizeof(PurpleHash),
410 NULL,
411 NULL
414 type = g_type_register_static(G_TYPE_OBJECT,
415 "PurpleHash",
416 &info, G_TYPE_FLAG_ABSTRACT);
419 return type;
422 void
423 purple_hash_reset(PurpleHash *hash) {
424 PurpleHashClass *klass = NULL;
426 g_return_if_fail(PURPLE_IS_HASH(hash));
428 klass = PURPLE_HASH_GET_CLASS(hash);
430 if (klass && klass->reset)
431 klass->reset(hash);
432 else {
433 purple_debug_warning("hash", "the %s hash does not implement "
434 "the reset method", purple_hash_get_name(hash));
438 void
439 purple_hash_reset_state(PurpleHash *hash) {
440 PurpleHashClass *klass = NULL;
442 g_return_if_fail(PURPLE_IS_HASH(hash));
444 klass = PURPLE_HASH_GET_CLASS(hash);
446 if (klass && klass->reset_state)
447 klass->reset_state(hash);
448 else {
449 purple_debug_warning("hash", "the %s hash does not implement "
450 "the reset_state method", purple_hash_get_name(hash));
454 void
455 purple_hash_append(PurpleHash *hash, const guchar *data,
456 size_t len)
458 PurpleHashClass *klass = NULL;
460 g_return_if_fail(PURPLE_IS_HASH(hash));
462 klass = PURPLE_HASH_GET_CLASS(hash);
464 if (klass && klass->append)
465 klass->append(hash, data, len);
466 else {
467 purple_debug_warning("hash", "the %s hash does not implement "
468 "the append method", purple_hash_get_name(hash));
472 gboolean
473 purple_hash_digest(PurpleHash *hash, guchar digest[], size_t len)
475 PurpleHashClass *klass = NULL;
477 g_return_val_if_fail(PURPLE_IS_HASH(hash), FALSE);
479 klass = PURPLE_HASH_GET_CLASS(hash);
481 if (klass && klass->digest)
482 return klass->digest(hash, digest, len);
483 else {
484 purple_debug_warning("hash", "the %s hash does not implement "
485 "the digest method", purple_hash_get_name(hash));
488 return FALSE;
491 gboolean
492 purple_hash_digest_to_str(PurpleHash *hash, gchar digest_s[], size_t len)
494 /* 8k is a bit excessive, will tweak later. */
495 guchar digest[BUF_LEN * 4];
496 size_t digest_size, n;
498 g_return_val_if_fail(PURPLE_IS_HASH(hash), FALSE);
499 g_return_val_if_fail(digest_s, FALSE);
501 digest_size = purple_hash_get_digest_size(hash);
503 g_return_val_if_fail(digest_size <= BUF_LEN * 4, FALSE);
505 if(!purple_hash_digest(hash, digest, sizeof(digest)))
506 return FALSE;
508 /* Every digest byte occupies 2 chars + the NUL at the end. */
509 g_return_val_if_fail(digest_size * 2 + 1 <= len, FALSE);
511 for(n = 0; n < digest_size; n++)
512 sprintf(digest_s + (n * 2), "%02x", digest[n]);
514 digest_s[n * 2] = '\0';
516 return TRUE;
519 size_t
520 purple_hash_get_digest_size(PurpleHash *hash)
522 PurpleHashClass *klass = NULL;
524 g_return_val_if_fail(PURPLE_IS_HASH(hash), FALSE);
526 klass = PURPLE_HASH_GET_CLASS(hash);
528 if (klass && klass->get_digest_size)
529 return klass->get_digest_size(hash);
530 else {
531 purple_debug_warning("hash", "the %s hash does not implement "
532 "the get_digest_size method", purple_hash_get_name(hash));
535 return FALSE;
538 size_t
539 purple_hash_get_block_size(PurpleHash *hash)
541 PurpleHashClass *klass = NULL;
543 g_return_val_if_fail(PURPLE_IS_HASH(hash), -1);
545 klass = PURPLE_HASH_GET_CLASS(hash);
547 if (klass && klass->get_block_size)
548 return klass->get_block_size(hash);
549 else {
550 purple_debug_warning("hash", "the %s hash does not implement "
551 "the get_block_size method", purple_hash_get_name(hash));
554 return -1;