#include #include #include #include #include #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); }