return (x >> y) | (x << (64 - y));
}
-const unsigned long long sha512_K[80] = {
- 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
- 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
- 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
- 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
- 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
- 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
- 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
- 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
- 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
- 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
- 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
- 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
- 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
- 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
- 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
- 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
- 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
- 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
- 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
- 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
- 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
- 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
- 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
- 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
- 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
- 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
- 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
-};
-
#define e0(x) (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39))
#define e1(x) (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41))
#define s0(x) (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7))
static void
sha512_transform (unsigned long long *state, const unsigned char *input)
{
+ static const unsigned long long sha512_K[80] = {
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
+ 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
+ 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
+ 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
+ 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
+ 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
+ 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
+ 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
+ 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
+ 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
+ 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
+ 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
+ 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
+ 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
+ };
+
unsigned long long a, b, c, d, e, f, g, h, t1, t2;
unsigned long long W[80];
unsigned long long t0;
* @param ret pointer to where to write the hashcode
*/
void
-GNUNET_CRYPTO_hash (const void *block,
- size_t size,
- GNUNET_HashCode * ret)
+GNUNET_CRYPTO_hash (const void *block, size_t size, GNUNET_HashCode * ret)
{
struct sha512_ctx ctx;
-
+
sha512_init (&ctx);
sha512_update (&ctx, block, size);
sha512_final (&ctx, (unsigned char *) ret);
/**
* Context used when hashing a file.
*/
-struct FileHashContext
+struct GNUNET_CRYPTO_FileHashContext
{
/**
char *filename;
/**
- * Cummulated hash.
+ * File descriptor.
*/
- struct sha512_ctx hctx;
+ struct GNUNET_DISK_FileHandle *fh;
/**
- * Blocksize.
+ * Our scheduler.
*/
- size_t bsize;
+ struct GNUNET_SCHEDULER_Handle *sched;
+
+ /**
+ * Cummulated hash.
+ */
+ struct sha512_ctx hctx;
/**
* Size of the file.
* Current offset.
*/
uint64_t offset;
-
+
/**
- * Run on shutdown?
+ * Current task for hashing.
*/
- int run_on_shutdown;
+ GNUNET_SCHEDULER_TaskIdentifier task;
/**
- * File descriptor.
+ * Blocksize.
*/
- struct GNUNET_DISK_FileHandle *fh;
+ size_t bsize;
};
* and free associated resources.
*/
static void
-file_hash_finish (struct FileHashContext *fhc, const GNUNET_HashCode * res)
+file_hash_finish (struct GNUNET_CRYPTO_FileHashContext *fhc,
+ const GNUNET_HashCode * res)
{
fhc->callback (fhc->callback_cls, res);
GNUNET_free (fhc->filename);
static void
file_hash_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct FileHashContext *fhc = cls;
+ struct GNUNET_CRYPTO_FileHashContext *fhc = cls;
GNUNET_HashCode res;
size_t delta;
+ fhc->task = GNUNET_SCHEDULER_NO_TASK;
GNUNET_assert (fhc->offset < fhc->fsize);
delta = fhc->bsize;
if (fhc->fsize - fhc->offset < delta)
file_hash_finish (fhc, &res);
return;
}
- GNUNET_SCHEDULER_add_after (tc->sched,
- fhc->run_on_shutdown,
- GNUNET_SCHEDULER_PRIORITY_KEEP,
- GNUNET_SCHEDULER_NO_TASK,
- &file_hash_task, fhc);
+ fhc->task
+ = GNUNET_SCHEDULER_add_after (tc->sched,
+ GNUNET_SCHEDULER_NO_TASK,
+ &file_hash_task, fhc);
}
*
* @param sched scheduler to use
* @param priority scheduling priority to use
- * @param run_on_shutdown should we complete even on shutdown?
* @param filename name of file to hash
* @param blocksize number of bytes to process in one task
* @param callback function to call upon completion
* @param callback_cls closure for callback
+ * @return NULL on (immediate) errror
*/
-void
+struct GNUNET_CRYPTO_FileHashContext *
GNUNET_CRYPTO_hash_file (struct GNUNET_SCHEDULER_Handle *sched,
enum GNUNET_SCHEDULER_Priority priority,
- int run_on_shutdown,
const char *filename,
size_t blocksize,
GNUNET_CRYPTO_HashCompletedCallback callback,
void *callback_cls)
{
- struct FileHashContext *fhc;
+ struct GNUNET_CRYPTO_FileHashContext *fhc;
GNUNET_assert (blocksize > 0);
- fhc = GNUNET_malloc (sizeof (struct FileHashContext) + blocksize);
+ fhc = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_FileHashContext) + blocksize);
fhc->callback = callback;
fhc->callback_cls = callback_cls;
+ fhc->sched = sched;
fhc->buffer = (unsigned char *) &fhc[1];
fhc->filename = GNUNET_strdup (filename);
fhc->fh = NULL;
fhc->bsize = blocksize;
if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO))
{
- file_hash_finish (fhc, NULL);
- return;
+ GNUNET_free (fhc->filename);
+ GNUNET_free (fhc);
+ return NULL;
}
- fhc->run_on_shutdown = run_on_shutdown;
fhc->fh = GNUNET_DISK_file_open (filename,
- GNUNET_DISK_OPEN_READ,
- GNUNET_DISK_PERM_NONE);
+ GNUNET_DISK_OPEN_READ,
+ GNUNET_DISK_PERM_NONE);
if (!fhc->fh)
{
- file_hash_finish (fhc, NULL);
- return;
+ GNUNET_free (fhc->filename);
+ GNUNET_free (fhc);
+ return NULL;
}
- GNUNET_SCHEDULER_add_after (sched,
- run_on_shutdown,
- priority,
- GNUNET_SCHEDULER_NO_TASK,
- &file_hash_task, fhc);
+ fhc->task
+ = GNUNET_SCHEDULER_add_with_priority (sched, priority,
+ &file_hash_task, fhc);
+ return fhc;
}
-/* ***************** binary-ASCII encoding *************** */
-
/**
- * 32 characters for encoding (GNUNET_CRYPTO_hash => 32 characters)
+ * Cancel a file hashing operation.
+ *
+ * @param fhc operation to cancel (callback must not yet have been invoked)
*/
-static char *encTable__ = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
+void
+GNUNET_CRYPTO_hash_file_cancel (struct GNUNET_CRYPTO_FileHashContext *fhc)
+{
+ GNUNET_SCHEDULER_cancel (fhc->sched,
+ fhc->task);
+ GNUNET_free (fhc->filename);
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fhc->fh));
+ GNUNET_free (fhc);
+}
+
+
+
+/* ***************** binary-ASCII encoding *************** */
static unsigned int
getValue__ (unsigned char a)
GNUNET_CRYPTO_hash_to_enc (const GNUNET_HashCode * block,
struct GNUNET_CRYPTO_HashAsciiEncoded *result)
{
+ /**
+ * 32 characters for encoding (GNUNET_CRYPTO_hash => 32 characters)
+ */
+ static char *encTable__ = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
unsigned int wpos;
unsigned int rpos;
unsigned int bits;
* fast, not involve bits[0] or bits[4] (they're used elsewhere), and be
* somewhat consistent. And of course, the result should be a positive
* number.
- *
- * @returns a positive number which is a measure for
+ *
+ * @param a some hash code
+ * @param b some hash code
+ * @return a positive number which is a measure for
* hashcode proximity.
*/
unsigned int
}
void
-GNUNET_CRYPTO_hash_create_random (enum GNUNET_CRYPTO_Quality mode, GNUNET_HashCode * result)
+GNUNET_CRYPTO_hash_create_random (enum GNUNET_CRYPTO_Quality mode,
+ GNUNET_HashCode * result)
{
int i;
- for (i = (sizeof (GNUNET_HashCode) / sizeof (uint32_t)) - 1; i >= 0;
- i--)
- result->bits[i] = GNUNET_CRYPTO_random_u32 (mode, (uint32_t)-1);
+ for (i = (sizeof (GNUNET_HashCode) / sizeof (uint32_t)) - 1; i >= 0; i--)
+ result->bits[i] = GNUNET_CRYPTO_random_u32 (mode, UINT32_MAX);
}
void
GNUNET_CRYPTO_hash_difference (const GNUNET_HashCode * a,
- const GNUNET_HashCode * b,
- GNUNET_HashCode * result)
+ const GNUNET_HashCode * b,
+ GNUNET_HashCode * result)
{
int i;
for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0;
void
GNUNET_CRYPTO_hash_sum (const GNUNET_HashCode * a,
- const GNUNET_HashCode * delta,
- GNUNET_HashCode * result)
+ const GNUNET_HashCode * delta,
+ GNUNET_HashCode * result)
{
int i;
for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0;
void
GNUNET_CRYPTO_hash_xor (const GNUNET_HashCode * a,
- const GNUNET_HashCode * b, GNUNET_HashCode * result)
+ const GNUNET_HashCode * b, GNUNET_HashCode * result)
{
int i;
for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0;
*/
void
GNUNET_CRYPTO_hash_to_aes_key (const GNUNET_HashCode * hc,
- struct GNUNET_CRYPTO_AesSessionKey *skey,
- struct GNUNET_CRYPTO_AesInitializationVector
- *iv)
+ struct GNUNET_CRYPTO_AesSessionKey *skey,
+ struct GNUNET_CRYPTO_AesInitializationVector
+ *iv)
{
GNUNET_assert (sizeof (GNUNET_HashCode) >=
- GNUNET_CRYPTO_AES_KEY_LENGTH +
- sizeof (struct GNUNET_CRYPTO_AesInitializationVector));
+ GNUNET_CRYPTO_AES_KEY_LENGTH +
+ sizeof (struct GNUNET_CRYPTO_AesInitializationVector));
memcpy (skey, hc, GNUNET_CRYPTO_AES_KEY_LENGTH);
skey->crc32 =
htonl (GNUNET_CRYPTO_crc32_n (skey, GNUNET_CRYPTO_AES_KEY_LENGTH));
memcpy (iv, &((char *) hc)[GNUNET_CRYPTO_AES_KEY_LENGTH],
- sizeof (struct GNUNET_CRYPTO_AesInitializationVector));
+ sizeof (struct GNUNET_CRYPTO_AesInitializationVector));
}
/**
*/
int
GNUNET_CRYPTO_hash_cmp (const GNUNET_HashCode * h1,
- const GNUNET_HashCode * h2)
+ const GNUNET_HashCode * h2)
{
unsigned int *i1;
unsigned int *i2;
int i;
-
+
i1 = (unsigned int *) h1;
i2 = (unsigned int *) h2;
for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0;
i--)
{
if (i1[i] > i2[i])
- return 1;
+ return 1;
if (i1[i] < i2[i])
- return -1;
+ return -1;
}
return 0;
}
*/
int
GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1,
- const GNUNET_HashCode * h2,
- const GNUNET_HashCode * target)
+ const GNUNET_HashCode * h2,
+ const GNUNET_HashCode * target)
{
int i;
unsigned int d1;
unsigned int d2;
-
+
for (i = sizeof (GNUNET_HashCode) / sizeof (unsigned int) - 1; i >= 0; i--)
{
d1 = ((unsigned int *) h1)[i] ^ ((unsigned int *) target)[i];
d2 = ((unsigned int *) h2)[i] ^ ((unsigned int *) target)[i];
if (d1 > d2)
- return 1;
+ return 1;
else if (d1 < d2)
- return -1;
+ return -1;
}
return 0;
}
+
+/**
+ * Calculate HMAC of a message (RFC 2104)
+ *
+ * @param key secret key
+ * @param plaintext input plaintext
+ * @param plaintext_len length of plaintext
+ * @param hmac where to store the hmac
+ */
+void
+GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AesSessionKey *key,
+ const void *plaintext,
+ size_t plaintext_len,
+ GNUNET_HashCode *hmac)
+{
+ GNUNET_HashCode kh;
+ GNUNET_HashCode ipad;
+ GNUNET_HashCode opad;
+ GNUNET_HashCode him;
+ struct sha512_ctx sctx;
+
+ memset (&kh, 0, sizeof (kh));
+ GNUNET_assert (sizeof (GNUNET_HashCode) > sizeof (struct GNUNET_CRYPTO_AesSessionKey));
+ memcpy (&kh, key, sizeof (struct GNUNET_CRYPTO_AesSessionKey));
+ memset (&ipad, 0x5c, sizeof (ipad));
+ memset (&opad, 0x36, sizeof (opad));
+ GNUNET_CRYPTO_hash_xor (&ipad, &kh, &ipad);
+ GNUNET_CRYPTO_hash_xor (&opad, &kh, &opad);
+ sha512_init (&sctx);
+ sha512_update (&sctx, (const unsigned char*) &ipad, sizeof (ipad));
+ sha512_update (&sctx, plaintext, plaintext_len);
+ sha512_final (&sctx, (unsigned char*) &him);
+ sha512_init (&sctx);
+ sha512_update (&sctx, (const unsigned char*) &opad, sizeof (opad));
+ sha512_update (&sctx, (const unsigned char*) &him, sizeof (him));
+ sha512_final (&sctx, (unsigned char*) hmac);
+}
+
+
/* end of crypto_hash.c */