1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
#include <cipher.h>
#if GLIB_CHECK_VERSION(2,16,0)
static void
purple_g_checksum_init(PurpleCipherContext *context, GChecksumType type)
{
GChecksum *checksum;
checksum = g_checksum_new(type);
purple_cipher_context_set_data(context, checksum);
}
static void
purple_g_checksum_reset(PurpleCipherContext *context, GChecksumType type)
{
GChecksum *checksum;
checksum = purple_cipher_context_get_data(context);
g_return_if_fail(checksum != NULL);
#if GLIB_CHECK_VERSION(2,18,0)
g_checksum_reset(checksum);
#else
g_checksum_free(checksum);
checksum = g_checksum_new(type);
purple_cipher_context_set_data(context, checksum);
#endif
}
static void
purple_g_checksum_uninit(PurpleCipherContext *context)
{
GChecksum *checksum;
checksum = purple_cipher_context_get_data(context);
g_return_if_fail(checksum != NULL);
g_checksum_free(checksum);
}
static void
purple_g_checksum_append(PurpleCipherContext *context, const guchar *data,
gsize len)
{
GChecksum *checksum;
checksum = purple_cipher_context_get_data(context);
g_return_if_fail(checksum != NULL);
while (len >= G_MAXSSIZE) {
g_checksum_update(checksum, data, G_MAXSSIZE);
len -= G_MAXSSIZE;
data += G_MAXSSIZE;
}
if (len)
g_checksum_update(checksum, data, len);
}
static gboolean
purple_g_checksum_digest(PurpleCipherContext *context, GChecksumType type,
gsize len, guchar *digest, gsize *out_len)
{
GChecksum *checksum;
const gssize required_length = g_checksum_type_get_length(type);
checksum = purple_cipher_context_get_data(context);
g_return_val_if_fail(len >= required_length, FALSE);
g_return_val_if_fail(checksum != NULL, FALSE);
g_checksum_get_digest(checksum, digest, &len);
purple_cipher_context_reset(context, NULL);
if (out_len)
*out_len = len;
return TRUE;
}
/******************************************************************************
* Macros
*****************************************************************************/
#define PURPLE_G_CHECKSUM_IMPLEMENTATION(lower, camel, type, block_size) \
static size_t \
lower##_get_block_size(PurpleCipherContext *context) { \
return (block_size); \
} \
\
static void \
lower##_init(PurpleCipherContext *context, gpointer extra) { \
purple_g_checksum_init(context, (type)); \
} \
\
static void \
lower##_reset(PurpleCipherContext *context, gpointer extra) { \
purple_g_checksum_reset(context, (type)); \
} \
\
static gboolean \
lower##_digest(PurpleCipherContext *context, gsize in_len, \
guchar digest[], size_t *out_len) \
{ \
return purple_g_checksum_digest(context, (type), in_len, digest, \
out_len); \
} \
\
static PurpleCipherOps camel##Ops = { \
NULL, /* Set option */ \
NULL, /* Get option */ \
lower##_init, /* init */ \
lower##_reset, /* reset */ \
purple_g_checksum_uninit, /* uninit */ \
NULL, /* set iv */ \
purple_g_checksum_append, /* append */ \
lower##_digest, /* digest */ \
NULL, /* encrypt */ \
NULL, /* decrypt */ \
NULL, /* set salt */ \
NULL, /* get salt size */ \
NULL, /* set key */ \
NULL, /* get key size */ \
NULL, /* set batch mode */ \
NULL, /* get batch mode */ \
lower##_get_block_size, /* get block size */ \
NULL /* set key with len */ \
}; \
\
PurpleCipherOps * \
purple_##lower##_cipher_get_ops(void) { \
return &camel##Ops; \
}
/******************************************************************************
* Macro Expansion
*****************************************************************************/
PURPLE_G_CHECKSUM_IMPLEMENTATION(md5, MD5, G_CHECKSUM_MD5, 64);
PURPLE_G_CHECKSUM_IMPLEMENTATION(sha1, SHA1, G_CHECKSUM_SHA1, 64);
PURPLE_G_CHECKSUM_IMPLEMENTATION(sha256, SHA256, G_CHECKSUM_SHA256, 64);
#endif /* GLIB_CHECK_VERSION(2,16,0) */
|