On Tue 2015-09-15 11:14:17 -0400, Werner Koch wrote:
> Good, that works.  However, the actual burn_cycles code is more like:
>
> static int
> burn_cycles(unsigned long count)
> {
>   char buffer[16];
>   return gcry_kdf_derive ("123456789abcdef0", 16,
>                           GCRY_KDF_ITERSALTED_S2K,
>                           GCR_MD_SHA1, "saltsalt", 8,
>                           count, buffer, 16);
> }
>
> and thus does a lot of SHA-1 operations in Libgcrypt.

Yep, i wanted the initial test to happen without libgcrypt.

Below is a new version that uses gcrypt (fixing a couple typos in
Werner's example above).  It should be compiled with:

 gcc -lgcrypt -Wall -Werror --pedantic -o test-csail test-csail.c

i'm tracking this test code in git, if anyone is interested:
  git clone git://lair.fifthhorseman.net/~dkg/789246

Kurt, can we try this out on x86-csail-01 ?

      --dkg

#include <time.h>
#include <sys/times.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <gcrypt.h>

/* Daniel Kahn Gillmor <d...@fifthhorseman.net>

   Code extracted for testing from calibration routines in GnuPG's
   agent/protect.c 

   see https://bugs.debian.org/789246 
*/

struct calibrate_time_s
{
  clock_t ticks;
};

static void BUG()
{
  exit(2);
}

static void
calibrate_get_time (struct calibrate_time_s *data)
{
  struct tms tmp;

  times (&tmp);
  data->ticks = tmp.tms_utime;
}


static unsigned long
calibrate_elapsed_time (struct calibrate_time_s *starttime)
{
  struct calibrate_time_s stoptime;

  calibrate_get_time (&stoptime);

  return (unsigned long)((((double) (stoptime.ticks - starttime->ticks))
                          /CLOCKS_PER_SEC)*10000000);
}

static int
burn_cycles(unsigned long count)
{
  char buffer[16];
  return gcry_kdf_derive ("123456789abcdef0", 16,
                          GCRY_KDF_ITERSALTED_S2K,
                          GCRY_MD_SHA1, "saltsalt", 8,
                          count, 16, buffer);
}

/* Run a test hashing for COUNT and return the time required in
   milliseconds.  */
static unsigned long
calibrate_s2k_count_one (unsigned long count)
{
  int rc;
  struct calibrate_time_s starttime;

  calibrate_get_time (&starttime);

  rc = burn_cycles(count);
  if (rc)
    BUG ();
  return calibrate_elapsed_time (&starttime);
}

/* Measure the time we need to do the hash operations and deduce an
   S2K count which requires about 100ms of time.  */
static unsigned long
calibrate_s2k_count (void)
{
  unsigned long count;
  unsigned long ms;

  for (count = 2; count; count *= 2)
    {
      ms = calibrate_s2k_count_one (count);
      printf ("S2K calibration: %lu -> %lums\n", count, ms);
      if (ms > 100)
        break;
    }

  count = (unsigned long)(((double)count / ms) * 100);

  ms = calibrate_s2k_count_one (count);
  printf ("S2K calibration: %lu -> %lums\n", count, ms);

  return count;
}


void initialize()
{
  if (!gcry_check_version (GCRYPT_VERSION))
    {
      fputs ("libgcrypt version mismatch\n", stderr);
      exit (2);
    }
}

int main(int argc, const char* argv[])
{
  unsigned long x = 0;
  initialize();
  x = calibrate_s2k_count();
  printf("x: %lu\n", x);
  return 0;
}

Reply via email to