1  /*
       2   * SHA-1 in C
       3   * By Steve Reid <sreid@sea-to-sky.net>
       4   * 100% Public Domain
       5  */
       6  
       7  #include "crypt-port.h"
       8  #include "alg-sha1.h"
       9  
      10  #include <stdio.h>
      11  
      12  #if INCLUDE_sha1crypt
      13  
      14  /* Test Vectors (from FIPS PUB 180-1) */
      15  const char *test_data[3] =
      16  {
      17    "abc",
      18    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
      19    "A million repetitions of 'a'"
      20  };
      21  
      22  const char *test_results[3] =
      23  {
      24    "a9993e364706816aba3e25717850c26c9cd0d89d",
      25    "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
      26    "34aa973cd4c4daa4f61eeb2bdbad27316534016f"
      27  };
      28  
      29  
      30  static void
      31  bin_to_hex (uint8_t *digest, char *output)
      32  {
      33    for (uint8_t i = 0; i < 20; ++i)
      34      {
      35        sprintf (output, "%02x", *digest);
      36        ++digest;
      37        output += 2;
      38      }
      39  }
      40  
      41  
      42  int
      43  main (void)
      44  {
      45    int k;
      46    struct sha1_ctx ctx;
      47    uint8_t digest[20];
      48    char output[80];
      49    uint8_t retval = 0;
      50  
      51    for (k = 0; k < 2; k++)
      52      {
      53        sha1_init_ctx (&ctx);
      54        sha1_process_bytes ((const uint8_t*)test_data[k], &ctx, strlen(test_data[k]));
      55        sha1_finish_ctx (&ctx, digest);
      56        bin_to_hex(digest, output);
      57  
      58        if (strcmp(output, test_results[k]))
      59          {
      60            fprintf(stdout, "FAIL\n");
      61            fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[k]);
      62            fprintf(stderr,"\t%s returned\n", output);
      63            fprintf(stderr,"\t%s is correct\n", test_results[k]);
      64            retval = 1;
      65          }
      66      }
      67    /* million 'a' vector we feed separately */
      68    sha1_init_ctx (&ctx);
      69    for (k = 0; k < 1000000; k++)
      70      sha1_process_bytes ((const uint8_t*)"a", &ctx, 1);
      71    sha1_finish_ctx (&ctx, digest);
      72    bin_to_hex(digest, output);
      73    if (strcmp(output, test_results[2]))
      74      {
      75        fprintf(stdout, "FAIL\n");
      76        fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[2]);
      77        fprintf(stderr,"\t%s returned\n", output);
      78        fprintf(stderr,"\t%s is correct\n", test_results[2]);
      79        retval = 1;
      80      }
      81  
      82    /* The same test as above, but with 1000 blocks of 1000 bytes.  */
      83    char buf[1000];
      84    memset (buf, 'a', sizeof (buf));
      85    sha1_init_ctx (&ctx);
      86    for (k = 0; k < 1000; ++k)
      87      sha1_process_bytes ((const uint8_t*)buf, &ctx, sizeof (buf));
      88    sha1_finish_ctx (&ctx, digest);
      89    bin_to_hex(digest, output);
      90    if (strcmp(output, test_results[2]))
      91      {
      92        fprintf(stdout, "FAIL\n");
      93        fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[2]);
      94        fprintf(stderr,"\t%s returned\n", output);
      95        fprintf(stderr,"\t%s is correct\n", test_results[2]);
      96        retval = 1;
      97      }
      98  
      99    /* success */
     100    return retval;
     101  }
     102  
     103  #else
     104  
     105  int
     106  main (void)
     107  {
     108    return 77; /* UNSUPPORTED */
     109  }
     110  
     111  #endif