diff options
author | Perberos <[email protected]> | 2011-11-06 17:13:49 -0300 |
---|---|---|
committer | Perberos <[email protected]> | 2011-11-06 17:13:49 -0300 |
commit | 13e6e4ab1290cda9426eaedfeda70f7491b6b083 (patch) | |
tree | 2b9b2e1eac4cc6a161bea6f2197de4513ff1ddf7 /src/skey/sha1.c | |
download | mate-terminal-13e6e4ab1290cda9426eaedfeda70f7491b6b083.tar.bz2 mate-terminal-13e6e4ab1290cda9426eaedfeda70f7491b6b083.tar.xz |
initial
Diffstat (limited to 'src/skey/sha1.c')
-rw-r--r-- | src/skey/sha1.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/skey/sha1.c b/src/skey/sha1.c new file mode 100644 index 0000000..ac34ccc --- /dev/null +++ b/src/skey/sha1.c @@ -0,0 +1,112 @@ +#include <config.h> + +#include <string.h> +#include <stdlib.h> +#include <arpa/inet.h> + +#include <glib.h> + +#include "skey.h" +#include "skeyutil.h" +#include "sha1.h" + + +#define SHA1_DIGESTSIZE 20 +#define SHA1_BLOCKSIZE 64 + +#define HTONDIGEST(x) { \ + x[0] = htonl(x[0]); \ + x[1] = htonl(x[1]); \ + x[2] = htonl(x[2]); \ + x[3] = htonl(x[3]); \ + x[4] = htonl(x[4]); } + +#ifdef WORDS_BIGENDIAN +/* + * Note: this code is harmless on little-endian machines. + */ +static void byteReverse(unsigned char *buf, unsigned longs) +{ + guint32 t; + do { + t = (guint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(guint32 *) buf = t; + buf += 4; + } while (--longs); +} +#endif + + +int SHA1Keycrunch(char *result, const char *seed, const char *passphrase) +{ + char *buf; + gsize len; + GChecksum *checksum; + guint8 digest[20]; + gsize digest_len = sizeof (digest); + guint32 *results; + + len = strlen(seed) + strlen(passphrase); + if ((buf = (char *)g_try_malloc(len+1)) == NULL) + return -1; + + strcpy(buf, seed); + skey_lowcase(buf); + strcat(buf, passphrase); + skey_sevenbit(buf); + + checksum = g_checksum_new (G_CHECKSUM_SHA1); + g_checksum_update (checksum, (const guchar *) buf, len); + g_free(buf); + + g_checksum_get_digest (checksum, digest, &digest_len); + g_assert (digest_len == 20); + + results = (guint32 *) digest; + +#ifndef WORDS_BIGENDIAN + HTONDIGEST(results); +#else + byteReverse((unsigned char *)digest, 5); +#endif + + results = (guint32 *) digest; + results[0] ^= results[2]; + results[1] ^= results[3]; + results[0] ^= results[4]; + + memcpy((void *)result, (void *)results, SKEY_SIZE); + + g_checksum_free (checksum); + + return 0; +} + +void SHA1SKey(char *x) +{ + GChecksum *checksum; + guint8 digest[20]; + gsize digest_len = sizeof (digest); + guint32 *results; + + checksum = g_checksum_new (G_CHECKSUM_SHA1); + g_checksum_update (checksum, (const guchar *) x, SKEY_SIZE); + g_checksum_get_digest (checksum, digest, &digest_len); + g_assert (digest_len == 20); + + results = (guint32 *) digest; +#ifndef WORDS_BIGENDIAN + HTONDIGEST(results); +#else + byteReverse((unsigned char *)digest, 5); +#endif + + results[0] ^= results[2]; + results[1] ^= results[3]; + results[0] ^= results[4]; + + memcpy((void *)x, (void *)results, SKEY_SIZE); + + g_checksum_free (checksum); +} |