stuff
[oweals/gnunet.git] / src / util / crypto_hash.c
index 8df4cc8f47837359222e02bd2dcdf27633870adf..60104b604263a2b0a6b95b20618e66cd379b9a6d 100644 (file)
@@ -214,10 +214,6 @@ sha512_transform (unsigned long long *state, const unsigned char *input)
   state[5] += f;
   state[6] += g;
   state[7] += h;
-
-  /* erase our data */
-  a = b = c = d = e = f = g = h = t1 = t2 = 0;
-  memset (W, 0, 80 * sizeof (unsigned long long));
 }
 
 static void
@@ -281,14 +277,12 @@ sha512_final (struct sha512_ctx *sctx, unsigned char *hash)
   static unsigned char padding[128] = { 0x80, };
 
   unsigned int t;
-  unsigned long long t2;
   unsigned char bits[128];
-  unsigned int index, pad_len;
+  unsigned int index;
+  unsigned int pad_len;
+  unsigned long long t2;
   int i, j;
 
-  index = pad_len = t = i = j = 0;
-  t2 = 0;
-
   /* Save number of bits */
   t = sctx->count[0];
   bits[15] = t;
@@ -356,6 +350,7 @@ sha512_final (struct sha512_ctx *sctx, unsigned char *hash)
   memset (sctx, 0, sizeof (struct sha512_ctx));
 }
 
+
 /**
  * Hash block of given size.
  *
@@ -364,8 +359,7 @@ sha512_final (struct sha512_ctx *sctx, unsigned char *hash)
  * @param ret pointer to where to write the hashcode
  */
 void
-GNUNET_CRYPTO_hash (const void *block, unsigned int size,
-                    GNUNET_HashCode * ret)
+GNUNET_CRYPTO_hash (const void *block, size_t size, GNUNET_HashCode * ret)
 {
   struct sha512_ctx ctx;
 
@@ -378,7 +372,7 @@ GNUNET_CRYPTO_hash (const void *block, unsigned int size,
 /**
  * Context used when hashing a file.
  */
-struct FileHashContext
+struct GNUNET_CRYPTO_FileHashContext
 {
 
   /**
@@ -402,34 +396,39 @@ struct 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.
    */
-  unsigned long long fsize;
+  uint64_t fsize;
 
   /**
    * Current offset.
    */
-  unsigned long long 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;
 
 };
 
@@ -439,7 +438,8 @@ struct FileHashContext
  * 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);
@@ -458,10 +458,11 @@ file_hash_finish (struct FileHashContext *fhc, const GNUNET_HashCode * res)
 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)
@@ -481,11 +482,10 @@ file_hash_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
       file_hash_finish (fhc, &res);
       return;
     }
-  GNUNET_SCHEDULER_add_after (tc->sched,
-                              fhc->run_on_shutdown,
-                              GNUNET_SCHEDULER_PRIORITY_KEEP,
-                              GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
-                              &file_hash_task, fhc);
+  fhc->task 
+    = GNUNET_SCHEDULER_add_after (tc->sched,
+                                 GNUNET_SCHEDULER_NO_TASK, 
+                                 &file_hash_task, fhc);
 }
 
 
@@ -494,27 +494,27 @@ file_hash_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  *
  * @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;
@@ -522,25 +522,43 @@ GNUNET_CRYPTO_hash_file (struct GNUNET_SCHEDULER_Handle *sched,
   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_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_PREREQUISITE_TASK,
-                              &file_hash_task, fhc);
+  fhc->task 
+    = GNUNET_SCHEDULER_add_with_priority (sched, priority, 
+                                         &file_hash_task, fhc);
+  return fhc;
+}
+
+
+/**
+ * Cancel a file hashing operation.
+ *
+ * @param fhc operation to cancel (callback must not yet have been invoked)
+ */
+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 *************** */
 
 /**
@@ -565,9 +583,9 @@ getValue__ (unsigned char a)
  * small number of characters.  The GNUnet encoding uses 102
  * characters plus a null terminator.
  *
- * @param block the GNUNET_CRYPTO_hash code
+ * @param block the hash code
  * @param result where to store the encoding (struct GNUNET_CRYPTO_HashAsciiEncoded can be
- *  safely cast to char*, a '\0' termination is set).
+ *  safely cast to char*, a '\\0' termination is set).
  */
 void
 GNUNET_CRYPTO_hash_to_enc (const GNUNET_HashCode * block,
@@ -665,12 +683,12 @@ GNUNET_CRYPTO_hash_distance_u32 (const GNUNET_HashCode * a,
 }
 
 void
-GNUNET_CRYPTO_hash_create_random (GNUNET_HashCode * result)
+GNUNET_CRYPTO_hash_create_random (enum GNUNET_CRYPTO_Quality mode,
+                                  GNUNET_HashCode * result)
 {
   int i;
-  for (i = (sizeof (GNUNET_HashCode) / sizeof (unsigned int)) - 1; i >= 0;
-       i--)
-    result->bits[i] = rand ();
+  for (i = (sizeof (GNUNET_HashCode) / sizeof (uint32_t)) - 1; i >= 0; i--)
+    result->bits[i] = GNUNET_CRYPTO_random_u32 (mode, (uint32_t) - 1);
 }
 
 void
@@ -709,7 +727,7 @@ GNUNET_CRYPTO_hash_xor (const GNUNET_HashCode * a,
  * Convert a hashcode into a key.
  */
 void
-GNUNET_CRYPTO_hash_to_AES_key (const GNUNET_HashCode * hc,
+GNUNET_CRYPTO_hash_to_aes_key (const GNUNET_HashCode * hc,
                                struct GNUNET_CRYPTO_AesSessionKey *skey,
                                struct GNUNET_CRYPTO_AesInitializationVector
                                *iv)
@@ -789,4 +807,4 @@ GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1,
   return 0;
 }
 
-/* end of hashing.c */
+/* end of crypto_hash.c */