pbkdf2.c

Basic pbkdf2 implementation
git clone git://git.finwo.net/lib/pbkdf2.c
Log | Files | Refs | README | LICENSE

test.c (6805B)


      1 #define _POSIX_C_SOURCE 200809L
      2 
      3 #include <stdio.h>
      4 #include <string.h>
      5 #include <stdlib.h>
      6 #include <openssl/hmac.h>
      7 #include <openssl/evp.h>
      8 
      9 #include "src/pbkdf2.h"
     10 
     11 int passed = 0;
     12 int failed = 0;
     13 
     14 static void print_hex(const uint8_t *data, size_t len) {
     15   for (size_t i = 0; i < len; i++) printf("%02x", data[i]);
     16 }
     17 
     18 static int compare_hex(const uint8_t *data, const char *expected, size_t len) {
     19   for (size_t i = 0; i < len; i++) {
     20     unsigned int val;
     21     if (sscanf(expected + i * 2, "%2x", &val) != 1) return 0;
     22     if (data[i] != val) return 0;
     23   }
     24   return 1;
     25 }
     26 
     27 void test_sha1(void) {
     28   struct sha1_ctx ctx;
     29   uint8_t hash[20];
     30 
     31   printf("SHA-1 Tests\n");
     32   printf("-----------\n");
     33 
     34   sha1_init(&ctx);
     35   sha1_update(&ctx, (uint8_t *)"abc", 3);
     36   sha1_final(&ctx, hash);
     37   printf("  SHA1(abc): ");
     38   if (compare_hex(hash, "a9993e364706816aba3e25717850c26c9cd0d89d", 20)) {
     39     printf("PASSED\n");
     40     passed++;
     41   } else {
     42     printf("FAILED\n    Expected: a9993e364706816aba3e25717850c26c9cd0d89d\n    Got:      ");
     43     print_hex(hash, 20);
     44     printf("\n");
     45     failed++;
     46   }
     47 
     48   sha1_init(&ctx);
     49   sha1_final(&ctx, hash);
     50   printf("  SHA1(empty): ");
     51   if (compare_hex(hash, "da39a3ee5e6b4b0d3255bfef95601890afd80709", 20)) {
     52     printf("PASSED\n");
     53     passed++;
     54   } else {
     55     printf("FAILED\n");
     56     failed++;
     57   }
     58 
     59   sha1_init(&ctx);
     60   sha1_update(&ctx, (uint8_t *)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56);
     61   sha1_final(&ctx, hash);
     62   printf("  SHA1(long): ");
     63   if (compare_hex(hash, "84983e441c3bd26ebaae4aa1f95129e5e54670f1", 20)) {
     64     printf("PASSED\n");
     65     passed++;
     66   } else {
     67     printf("FAILED\n");
     68     failed++;
     69   }
     70 }
     71 
     72 void test_sha256(void) {
     73   struct sha256_ctx ctx;
     74   uint8_t hash[32];
     75 
     76   printf("\nSHA-256 Tests\n");
     77   printf("-------------\n");
     78 
     79   sha256_init(&ctx);
     80   sha256_update(&ctx, (uint8_t *)"abc", 3);
     81   sha256_final(&ctx, hash);
     82   printf("  SHA256(abc): ");
     83   if (compare_hex(hash, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", 32)) {
     84     printf("PASSED\n");
     85     passed++;
     86   } else {
     87     printf("FAILED\n");
     88     failed++;
     89   }
     90 
     91   sha256_init(&ctx);
     92   sha256_final(&ctx, hash);
     93   printf("  SHA256(empty): ");
     94   if (compare_hex(hash, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 32)) {
     95     printf("PASSED\n");
     96     passed++;
     97   } else {
     98     printf("FAILED\n");
     99     failed++;
    100   }
    101 }
    102 
    103 void test_hmac_sha1(void) {
    104   uint8_t hash[20];
    105   uint8_t openssl_hash[20];
    106   unsigned int len;
    107 
    108   printf("\nHMAC-SHA1 Tests\n");
    109   printf("---------------\n");
    110 
    111   const uint8_t key[] = {
    112     0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
    113     0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
    114     0x0b, 0x0b, 0x0b, 0x0b
    115   };
    116   const uint8_t data[] = "Hi There";
    117 
    118   HMAC(EVP_sha1(), key, 20, data, 8, openssl_hash, &len);
    119   hmac_sha1(key, 20, data, 8, hash);
    120 
    121   printf("  HMAC-SHA1 (vs OpenSSL): ");
    122   if (memcmp(hash, openssl_hash, 20) == 0) {
    123     printf("PASSED\n");
    124     passed++;
    125   } else {
    126     printf("FAILED\n    OpenSSL: ");
    127     print_hex(openssl_hash, 20);
    128     printf("\n    Ours:   ");
    129     print_hex(hash, 20);
    130     printf("\n");
    131     failed++;
    132   }
    133 
    134   const uint8_t key2[] = "key";
    135   const uint8_t data2[] = "The quick brown fox jumps over the lazy dog";
    136 
    137   HMAC(EVP_sha1(), key2, 3, data2, 43, openssl_hash, &len);
    138   hmac_sha1(key2, 3, data2, 43, hash);
    139 
    140   printf("  HMAC-SHA1 (short key): ");
    141   if (memcmp(hash, openssl_hash, 20) == 0) {
    142     printf("PASSED\n");
    143     passed++;
    144   } else {
    145     printf("FAILED\n");
    146     failed++;
    147   }
    148 }
    149 
    150 void test_hmac_sha256(void) {
    151   uint8_t hash[32];
    152   uint8_t openssl_hash[32];
    153   unsigned int len;
    154 
    155   printf("\nHMAC-SHA256 Tests\n");
    156   printf("-----------------\n");
    157 
    158   const uint8_t key[] = {
    159     0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
    160     0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
    161     0x0b, 0x0b, 0x0b, 0x0b
    162   };
    163   const uint8_t data[] = "Hi There";
    164 
    165   HMAC(EVP_sha256(), key, 20, data, 8, openssl_hash, &len);
    166   hmac_sha256(key, 20, data, 8, hash);
    167 
    168   printf("  HMAC-SHA256 (vs OpenSSL): ");
    169   if (memcmp(hash, openssl_hash, 32) == 0) {
    170     printf("PASSED\n");
    171     passed++;
    172   } else {
    173     printf("FAILED\n    OpenSSL: ");
    174     print_hex(openssl_hash, 32);
    175     printf("\n    Ours:   ");
    176     print_hex(hash, 32);
    177     printf("\n");
    178     failed++;
    179   }
    180 }
    181 
    182 void test_pbkdf2(void) {
    183   uint8_t output[128];
    184   uint8_t openssl_output[128];
    185 
    186   printf("\nPBKDF2 Tests (vs OpenSSL)\n");
    187   printf("-------------------------\n");
    188 
    189   const char *password = "password";
    190   const char *salt = "salt";
    191   uint64_t iterations = 4096;
    192 
    193   /* PBKDF2-SHA1 */
    194   PKCS5_PBKDF2_HMAC(password, 8, (unsigned char *)salt, 4, iterations, EVP_sha1(), 20, openssl_output);
    195   pbkdf2((uint8_t *)password, 8, (uint8_t *)salt, 4, iterations, PBKDF2_SHA1, output, 20);
    196 
    197   printf("  PBKDF2-SHA1 (c=4096, dkLen=20): ");
    198   if (memcmp(output, openssl_output, 20) == 0) {
    199     printf("PASSED\n");
    200     passed++;
    201   } else {
    202     printf("FAILED\n    OpenSSL: ");
    203     print_hex(openssl_output, 20);
    204     printf("\n    Ours:   ");
    205     print_hex(output, 20);
    206     printf("\n");
    207     failed++;
    208   }
    209 
    210   /* PBKDF2-SHA256 */
    211   PKCS5_PBKDF2_HMAC(password, 8, (unsigned char *)salt, 4, iterations, EVP_sha256(), 32, openssl_output);
    212   pbkdf2((uint8_t *)password, 8, (uint8_t *)salt, 4, iterations, PBKDF2_SHA256, output, 32);
    213 
    214   printf("  PBKDF2-SHA256 (c=4096, dkLen=32): ");
    215   if (memcmp(output, openssl_output, 32) == 0) {
    216     printf("PASSED\n");
    217     passed++;
    218   } else {
    219     printf("FAILED\n    OpenSSL: ");
    220     print_hex(openssl_output, 32);
    221     printf("\n    Ours:   ");
    222     print_hex(output, 32);
    223     printf("\n");
    224     failed++;
    225   }
    226 
    227   /* Longer output (block chaining) */
    228   const char *password2 = "passwordPASSWORD";
    229   const char *salt2 = "saltSALTsaltSALTsaltSALTsaltSALTsalt";
    230   size_t dk_len = 25;
    231 
    232   PKCS5_PBKDF2_HMAC(password2, 16, (unsigned char *)salt2, 36, iterations, EVP_sha1(), dk_len, openssl_output);
    233   pbkdf2((uint8_t *)password2, 16, (uint8_t *)salt2, 36, iterations, PBKDF2_SHA1, output, dk_len);
    234 
    235   printf("  PBKDF2-SHA1 (dkLen=25, chaining): ");
    236   if (memcmp(output, openssl_output, dk_len) == 0) {
    237     printf("PASSED\n");
    238     passed++;
    239   } else {
    240     printf("FAILED\n    OpenSSL: ");
    241     print_hex(openssl_output, dk_len);
    242     printf("\n    Ours:   ");
    243     print_hex(output, dk_len);
    244     printf("\n");
    245     failed++;
    246   }
    247 }
    248 
    249 int main() {
    250   printf("\n========================================\n");
    251   printf("    PBKDF2 Library Test Suite\n");
    252   printf("========================================\n\n");
    253 
    254   test_sha1();
    255   test_sha256();
    256   test_hmac_sha1();
    257   test_hmac_sha256();
    258   test_pbkdf2();
    259 
    260   printf("\n========================================\n");
    261   printf("Results: %d passed, %d failed\n", passed, failed);
    262   printf("========================================\n");
    263 
    264   return failed > 0 ? 1 : 0;
    265 }