diff options
author | Paul Aurich <darkrain42@pidgin.im> | 2009-07-04 23:13:23 +0000 |
---|---|---|
committer | Paul Aurich <darkrain42@pidgin.im> | 2009-07-04 23:13:23 +0000 |
commit | 003b0f0506abcb025de0d6366659bf1da0f21008 (patch) | |
tree | 33bdefac58f850e64173e0fbfb59b7d60582fc97 /libpurple/cipher.c | |
parent | 5b3275b1bd6c93ddcf3ed666570f3e5a288f2397 (diff) | |
download | pidgin-003b0f0506abcb025de0d6366659bf1da0f21008.tar.gz |
Use glib's SHA1, SHA256, and MD5 implementations when available (glib 2.16)
These SHA1 and SHA256 implementations do not expose any options, which
the built-in ones do (for getting/setting sizeHi, sizeLo, and lenW).
Nothing in Pidgin uses those (and I can't think of a decent use case),
so I think this is OK. Feel free to disagree.
As I mentioned on the mailing list, glib's SHA1 implementation was just
under 3x as fast on my system.
Diffstat (limited to 'libpurple/cipher.c')
-rw-r--r-- | libpurple/cipher.c | 276 |
1 files changed, 255 insertions, 21 deletions
diff --git a/libpurple/cipher.c b/libpurple/cipher.c index 15def7c393..890572b3f6 100644 --- a/libpurple/cipher.c +++ b/libpurple/cipher.c @@ -61,11 +61,152 @@ #include "signals.h" #include "value.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); + + if (len > (gsize)G_MAXSSIZE) { + /* + * g_checksum_update takes a gssize, whereas we handle gsizes. To + * be pedantically correct, we need to handle this case. In real life, + * I think this couldn't actually occur. + */ + const guchar *buf = data; + gssize chunk_size; + while (len > 0) { + chunk_size = MIN(G_MAXSSIZE, len); + g_checksum_update(checksum, buf, chunk_size); + len -= chunk_size; + buf += chunk_size; + } + } else + 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; +} +#endif + + /******************************************************************************* * MD5 ******************************************************************************/ #define MD5_HMAC_BLOCK_SIZE 64 +static size_t +md5_get_block_size(PurpleCipherContext *context) +{ + /* This does not change (in this case) */ + return MD5_HMAC_BLOCK_SIZE; +} + +#if GLIB_CHECK_VERSION(2,16,0) + +static void +md5_init(PurpleCipherContext *context, void *extra) +{ + purple_g_checksum_init(context, G_CHECKSUM_MD5); +} + +static void +md5_reset(PurpleCipherContext *context, void *extra) +{ + purple_g_checksum_reset(context, G_CHECKSUM_MD5); +} + +static gboolean +md5_digest(PurpleCipherContext *context, gsize in_len, guchar digest[16], + size_t *out_len) +{ + return purple_g_checksum_digest(context, G_CHECKSUM_MD5, in_len, + digest, out_len); +} + +static PurpleCipherOps MD5Ops = { + NULL, /* Set Option */ + NULL, /* Get Option */ + md5_init, /* init */ + md5_reset, /* reset */ + purple_g_checksum_uninit, /* uninit */ + NULL, /* set iv */ + purple_g_checksum_append, /* append */ + md5_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 */ + md5_get_block_size, /* get block size */ + NULL /* set key with len */ +}; + +#else /* GLIB_CHECK_VERSION(2,16,0) */ + struct MD5Context { guint32 total[2]; guint32 state[4]; @@ -327,13 +468,6 @@ md5_digest(PurpleCipherContext *context, size_t in_len, guchar digest[16], return TRUE; } -static size_t -md5_get_block_size(PurpleCipherContext *context) -{ - /* This does not change (in this case) */ - return MD5_HMAC_BLOCK_SIZE; -} - static PurpleCipherOps MD5Ops = { NULL, /* Set option */ NULL, /* Get option */ @@ -355,6 +489,8 @@ static PurpleCipherOps MD5Ops = { NULL /* set key with len */ }; +#endif /* GLIB_CHECK_VERSION(2,16,0) */ + /******************************************************************************* * MD4 ******************************************************************************/ @@ -1613,6 +1749,61 @@ static PurpleCipherOps DES3Ops = { * SHA-1 ******************************************************************************/ #define SHA1_HMAC_BLOCK_SIZE 64 + +static size_t +sha1_get_block_size(PurpleCipherContext *context) +{ + /* This does not change (in this case) */ + return SHA1_HMAC_BLOCK_SIZE; +} + + +#if GLIB_CHECK_VERSION(2,16,0) + +static void +sha1_init(PurpleCipherContext *context, void *extra) +{ + purple_g_checksum_init(context, G_CHECKSUM_SHA1); +} + +static void +sha1_reset(PurpleCipherContext *context, void *extra) +{ + purple_g_checksum_reset(context, G_CHECKSUM_SHA1); +} + +static gboolean +sha1_digest(PurpleCipherContext *context, gsize in_len, guchar digest[20], + gsize *out_len) +{ + return purple_g_checksum_digest(context, G_CHECKSUM_SHA1, in_len, + digest, out_len); +} + +static PurpleCipherOps SHA1Ops = { + NULL, /* Set Option */ + NULL, /* Get Option */ + sha1_init, /* init */ + sha1_reset, /* reset */ + purple_g_checksum_uninit, /* uninit */ + NULL, /* set iv */ + purple_g_checksum_append, /* append */ + sha1_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 */ + sha1_get_block_size, /* get block size */ + NULL /* set key with len */ +}; + +#else /* GLIB_CHECK_VERSION(2,16,0) */ + +#define SHA1_HMAC_BLOCK_SIZE 64 #define SHA1_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xFFFFFFFF) struct SHA1Context { @@ -1833,13 +2024,6 @@ sha1_digest(PurpleCipherContext *context, size_t in_len, guchar digest[20], return TRUE; } -static size_t -sha1_get_block_size(PurpleCipherContext *context) -{ - /* This does not change (in this case) */ - return SHA1_HMAC_BLOCK_SIZE; -} - static PurpleCipherOps SHA1Ops = { sha1_set_opt, /* Set Option */ sha1_get_opt, /* Get Option */ @@ -1861,10 +2045,65 @@ static PurpleCipherOps SHA1Ops = { NULL /* set key with len */ }; +#endif /* GLIB_CHECK_VERSION(2,16,0) */ + /******************************************************************************* * SHA-256 ******************************************************************************/ #define SHA256_HMAC_BLOCK_SIZE 64 + +static size_t +sha256_get_block_size(PurpleCipherContext *context) +{ + /* This does not change (in this case) */ + return SHA256_HMAC_BLOCK_SIZE; +} + +#if GLIB_CHECK_VERSION(2,16,0) + +static void +sha256_init(PurpleCipherContext *context, void *extra) +{ + purple_g_checksum_init(context, G_CHECKSUM_SHA256); +} + +static void +sha256_reset(PurpleCipherContext *context, void *extra) +{ + purple_g_checksum_reset(context, G_CHECKSUM_SHA256); +} + +static gboolean +sha256_digest(PurpleCipherContext *context, gsize in_len, guchar digest[20], + gsize *out_len) +{ + return purple_g_checksum_digest(context, G_CHECKSUM_SHA256, in_len, + digest, out_len); +} + +static PurpleCipherOps SHA256Ops = { + NULL, /* Set Option */ + NULL, /* Get Option */ + sha256_init, /* init */ + sha256_reset, /* reset */ + purple_g_checksum_uninit, /* uninit */ + NULL, /* set iv */ + purple_g_checksum_append, /* append */ + sha256_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 */ + sha256_get_block_size, /* get block size */ + NULL /* set key with len */ +}; + +#else /* GLIB_CHECK_VERSION(2,16,0) */ + #define SHA256_ROTR(X,n) ((((X) >> (n)) | ((X) << (32-(n)))) & 0xFFFFFFFF) static const guint32 sha256_K[64] = @@ -2088,13 +2327,6 @@ sha256_digest(PurpleCipherContext *context, size_t in_len, guchar digest[32], return TRUE; } -static size_t -sha256_get_block_size(PurpleCipherContext *context) -{ - /* This does not change (in this case) */ - return SHA256_HMAC_BLOCK_SIZE; -} - static PurpleCipherOps SHA256Ops = { sha256_set_opt, /* Set Option */ sha256_get_opt, /* Get Option */ @@ -2116,6 +2348,8 @@ static PurpleCipherOps SHA256Ops = { NULL /* set key with len */ }; +#endif /* GLIB_CHECK_VERSION(2,16,0) */ + /******************************************************************************* * RC4 ******************************************************************************/ |