Esempio n. 1
0
File: hkdf.c Progetto: mkj/dropbear
/* This is mostly just a wrapper around hmac_memory */
int hkdf_extract(int hash_idx, const unsigned char *salt, unsigned long  saltlen,
                               const unsigned char *in,   unsigned long  inlen,
                                     unsigned char *out,  unsigned long *outlen)
{
   /* libtomcrypt chokes on a zero length HMAC key, so we need to check for
      that.  HMAC specifies that keys shorter than the hash's blocksize are
      0 padded to the block size.  HKDF specifies that a NULL salt is to be
      substituted with a salt comprised of hashLen 0 bytes.  HMAC's padding
      means that in either case the HMAC is actually using a blocksize long
      zero filled key.  Unless blocksize < hashLen (which wouldn't make any
      sense), we can use a single 0 byte as the HMAC key and still generate
      valid results for HKDF. */
   if (salt == NULL || saltlen == 0) {
      return hmac_memory(hash_idx, (const unsigned char *)"",   1,       in, inlen, out, outlen);
   } else {
      return hmac_memory(hash_idx, salt, saltlen, in, inlen, out, outlen);
   }
}
void hmac_gen(void)
{
   unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], *input;
   int x, y, z, err;
   FILE *out;
   unsigned long len;
  
   out = fopen("hmac_tv.txt", "w");

   fprintf(out, 
"HMAC Tests.  In these tests messages of N bytes long (00,01,02,...,NN-1) are HMACed.  The initial key is\n"
"of the same format (the same length as the HASH output size).  The HMAC key in step N+1 is the HMAC output of\n"
"step N.\n\n");

   for (x = 0; hash_descriptor[x].name != NULL; x++) {
      fprintf(out, "HMAC-%s\n", hash_descriptor[x].name);
      
      /* initial key */
      for (y = 0; y < (int)hash_descriptor[x].hashsize; y++) {
          key[y] = (y&255);
      }

      input = XMALLOC(hash_descriptor[x].blocksize * 2 + 1);
      if (input == NULL) {
         perror("Can't malloc memory");
         exit(EXIT_FAILURE);
      }
      
      for (y = 0; y <= (int)(hash_descriptor[x].blocksize * 2); y++) {
         for (z = 0; z < y; z++) {
            input[z] = (unsigned char)(z & 255);
         }
         len = sizeof(output);
         if ((err = hmac_memory(x, key, hash_descriptor[x].hashsize, input, y, output, &len)) != CRYPT_OK) {
            printf("Error hmacing: %s\n", error_to_string(err));
            exit(EXIT_FAILURE);
         }
         fprintf(out, "%3d: ", y);
         for (z = 0; z <(int) len; z++) {
            fprintf(out, "%02X", output[z]);
         }
         fprintf(out, "\n");

         /* forward the key */
         memcpy(key, output, hash_descriptor[x].hashsize);
      }
      XFREE(input);
      fprintf(out, "\n");
   }
   fclose(out);
}
Esempio n. 3
0
/* Like hmac_memory, but verifies */
int hmac_vrfymem(int hash,
                 const unsigned char *key,  unsigned long  keylen,
                 const unsigned char *in,   unsigned long  inlen,
                 const unsigned char *vrfy, unsigned long *outlen) {
  unsigned char *out = safe_malloc(*outlen);
  int err;
  if ((err = hmac_memory(hash, key, keylen, in, inlen, out, outlen)) != CRYPT_OK) {
    safe_free(out);
    fprintf(stderr, "hmac_vrfymem: hmac_memory failed\n");
    return err;
  }
  if (memcmp(vrfy, out, *outlen) != 0) {
    safe_free(out);
    return CRYPT_ERROR;
  }
  safe_free(out);
  return CRYPT_OK;
}
Esempio n. 4
0
/* compatibility wrapper */
static void HMAC_SHA1( uint8_t* secret, size_t secret_len,
                       uint8_t* in, size_t in_len,
                       uint8_t* out)
{
  int rv;
  unsigned long out_len;

  if (sha1_id < 0) {
    sha1_id = register_hash( &sha1_desc);
  }

  out_len = hash_descriptor[sha1_id].hashsize;
  rv = hmac_memory( sha1_id,
                    secret, secret_len,
                    in, in_len,
                    out, &out_len);
  if (rv) {
    abort();
  }
}
Esempio n. 5
0
/*
 * Computes a HMAC SHA-1 keyed hash of 'input' using the key 'key'
 */
bool hmacSha1(const unsigned char* key,
              const size_t keyLen,
              const unsigned char* input,
              const size_t inputLen,
              unsigned char* output,
              unsigned int* outputLen) {
    if (!key || !input || !output) {
        return false;
    }

    static int hashId = -1;
    if (hashId == -1) {
        register_hash(&sha1_desc);
        hashId = find_hash("sha1");
    }

    unsigned long sha1HashLen = 20;
    if (hmac_memory(hashId, key, keyLen, input, inputLen, output, &sha1HashLen) != CRYPT_OK) {
        return false;
    }

    *outputLen = sha1HashLen;
    return true;
}
Esempio n. 6
0
int hmac_test(void)
{
 #ifndef LTC_TEST
    return CRYPT_NOP;
 #else    
    unsigned char digest[MAXBLOCKSIZE];
    int i;

    static const struct hmac_test_case {
        int num;
        char *algo;
        unsigned char key[128];
        unsigned long keylen;
        unsigned char data[128];
        unsigned long datalen;
        unsigned char digest[MAXBLOCKSIZE];
    } cases[] = {
        /*
        3. Test Cases for HMAC-SHA-1

        test_case =     1
        key =           0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
        key_len =       20
        data =          "Hi Ther     20
        digest =        0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04
        digest-96 =     0x4c1a03424b55e07fe7f27be1
        */
        { 5, "sha1",
            {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 
             0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 
             0x0c, 0x0c, 0x0c, 0x0c}, 20,
            "Test With Truncation", 20,
            {0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2,
             0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04} },

        /*
        test_case =     6
        key =           0xaa repeated 80 times
        key_len =       80
        data =          "Test Using Larger Than Block-Size Key - Hash Key First"
        data_len =      54
        digest =        0xaa4ae5e15272d00e95705637ce8a3b55ed402112
        */
        { 6, "sha1",
            {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80,
            "Test Using Larger Than Block-Size Key - Hash Key First", 54,
            {0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e,
             0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, 
             0xed, 0x40, 0x21, 0x12} },

        /*
        test_case =     7
        key =           0xaa repeated 80 times
        key_len =       80
        data =          "Test Using Larger Than Block-Size Key and Larger
                        Than One Block-Size Data"
        data_len =      73
        digest =        0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91
        */
        { 7, "sha1",
            {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80,
            "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
            {0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d,
             0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91} },

        /*
        2. Test Cases for HMAC-MD5

        test_case =     1
        key =           0x0b 0b 0b 0b 
                          0b 0b 0b 0b
                          0b 0b 0b 0b
                          0b 0b 0b 0b
        key_len =       16
        data =          "Hi There"
        data_len =      8
        digest =        0x92 94 72 7a 
                          36 38 bb 1c 
                          13 f4 8e f8 
                          15 8b fc 9d
        */
        { 1, "md5",
            {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 
             0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}, 16,
            "Hi There", 8,
            {0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, 
             0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d}  },
        /*
        test_case =     2
        key =           "Jefe"
        key_len =       4
        data =          "what do ya want for nothing?"
        data_len =      28
        digest =        0x750c783e6ab0b503eaa86e310a5db738
        */
        { 2, "md5",
            "Jefe", 4,
            "what do ya want for nothing?", 28,
            {0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, 
             0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38} },

        /*
        test_case =     3
        key =           0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
        key_len         16
        data =          0xdd repeated 50 times
        data_len =      50
        digest =        0x56be34521d144c88dbb8c733f0e8b3f6
        */
        { 3, "md5",
            {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 16,
            {0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
             0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
             0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
             0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
             0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd}, 50,
            {0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
             0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6} },
        /*

        test_case =     4
        key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819
        key_len         25
        data =          0xcd repeated 50 times
        data_len =      50
        digest =        0x697eaf0aca3a3aea3a75164746ffaa79
        */
        { 4, "md5",
            {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
             0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
             0x15, 0x16, 0x17, 0x18, 0x19}, 25,
            {0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
             0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
             0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
             0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
             0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd}, 50,
            {0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, 
             0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79} },


        /*
 
        test_case =     5
        key =           0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
        key_len =       16
        data =          "Test With Truncation"
        data_len =      20
        digest =        0x56461ef2342edc00f9bab995690efd4c
        digest-96       0x56461ef2342edc00f9bab995
        */
        { 5, "md5",
            {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 
             0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c}, 16,
            "Test With Truncation", 20,
            {0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00, 
             0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c} },

        /*

        test_case =     6
        key =           0xaa repeated 80 times
        key_len =       80
        data =          "Test Using Larger Than Block-Size Key - Hash 
Key First"
        data_len =      54
        digest =        0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd
        */
        { 6, "md5",
            {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80,
            "Test Using Larger Than Block-Size Key - Hash Key First", 54,
            {0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, 
             0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd} },

        /*

        test_case =     7
        key =           0xaa repeated 80 times
        key_len =       80
        data =          "Test Using Larger Than Block-Size Key and Larger
                        Than One Block-Size Data"
        data_len =      73
        digest =        0x6f630fad67cda0ee1fb1f562db3aa53e
        */
        { 7, "md5",
            {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
             0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80,
            "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
            {0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
             0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e} }
    };

    unsigned long outlen;
    int err;
    int tested=0,failed=0;
    for(i=0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) {
        int hash = find_hash(cases[i].algo);
        if (hash == -1) continue;
        ++tested;
        outlen = sizeof(digest);
        if((err = hmac_memory(hash, cases[i].key, cases[i].keylen, cases[i].data, cases[i].datalen, digest, &outlen)) != CRYPT_OK) {
#if 0
            printf("HMAC-%s test #%d\n", cases[i].algo, cases[i].num);
#endif
            return err;
        }

        if(memcmp(digest, cases[i].digest, (size_t)hash_descriptor[hash].hashsize) != 0)  {
#if 0
            unsigned int j;
            printf("\nHMAC-%s test #%d:\n", cases[i].algo, cases[i].num);
            printf(  "Result:  0x");
            for(j=0; j < hash_descriptor[hash].hashsize; j++) {
                printf("%2x ", digest[j]);
            }
            printf("\nCorrect: 0x");
            for(j=0; j < hash_descriptor[hash].hashsize; j++) {
               printf("%2x ", cases[i].digest[j]);
            }
            printf("\n");
#endif
            failed++;
            //return CRYPT_ERROR;
        } else {
            /* printf("HMAC-%s test #%d: Passed\n", cases[i].algo, cases[i].num); */
        }
    }

    if (failed != 0) {
        return CRYPT_FAIL_TESTVECTOR;
    } else if (tested == 0) {
        return CRYPT_NOP;
    } else {
        return CRYPT_OK;
    }
 #endif
}
Esempio n. 7
0
int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, 
                const unsigned char *salt,     unsigned long salt_len,
                int iteration_count,           int hash_idx,
                unsigned char *out,            unsigned long *outlen)
{
   int err, itts;
   ulong32  blkno;
   unsigned long stored, left, x, y;
   unsigned char *buf[2];
   hmac_state    *hmac;

   LTC_ARGCHK(password != NULL);
   LTC_ARGCHK(salt     != NULL);
   LTC_ARGCHK(out      != NULL);
   LTC_ARGCHK(outlen   != NULL);

   /* test hash IDX */
   if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
      return err;
   }

   buf[0] = XMALLOC(MAXBLOCKSIZE * 2);
   hmac   = XMALLOC(sizeof(hmac_state));
   if (hmac == NULL || buf[0] == NULL) {
      if (hmac != NULL) {
         XFREE(hmac);
      }
      if (buf[0] != NULL) {
         XFREE(buf[0]);
      }
      return CRYPT_MEM;
   }
   /* buf[1] points to the second block of MAXBLOCKSIZE bytes */
   buf[1] = buf[0] + MAXBLOCKSIZE;

   left   = *outlen;
   blkno  = 1;
   stored = 0;
   while (left != 0) {
       /* process block number blkno */
       zeromem(buf[0], MAXBLOCKSIZE*2);
       
       /* store current block number and increment for next pass */
       STORE32H(blkno, buf[1]);
       ++blkno;

       /* get PRF(P, S||int(blkno)) */
       if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) { 
          goto LBL_ERR;
       }
       if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) {
          goto LBL_ERR;
       }
       if ((err = hmac_process(hmac, buf[1], 4)) != CRYPT_OK) {
          goto LBL_ERR;
       }
       x = MAXBLOCKSIZE;
       if ((err = hmac_done(hmac, buf[0], &x)) != CRYPT_OK) {
          goto LBL_ERR;
       }

       /* now compute repeated and XOR it in buf[1] */
       XMEMCPY(buf[1], buf[0], x);
       for (itts = 1; itts < iteration_count; ++itts) {
           if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) {
              goto LBL_ERR;
           }
           for (y = 0; y < x; y++) {
               buf[1][y] ^= buf[0][y];
           }
       }

       /* now emit upto x bytes of buf[1] to output */
       for (y = 0; y < x && left != 0; ++y) {
           out[stored++] = buf[1][y];
           --left;
       }
   }
   *outlen = stored;

   err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
   zeromem(buf[0], MAXBLOCKSIZE*2);
   zeromem(hmac, sizeof(hmac_state));
#endif

   XFREE(hmac);
   XFREE(buf[0]);

   return err;
}
Esempio n. 8
0
int multi_test(void)
{
   unsigned char key[32] = { 0 };
   unsigned char buf[2][MAXBLOCKSIZE];
   unsigned long len, len2;

/* register algos */
   register_hash(&sha256_desc);
   register_cipher(&aes_desc);

/* HASH testing */
   len = sizeof(buf[0]);
   hash_memory(find_hash("sha256"), (unsigned char*)"hello", 5, buf[0], &len);
   len2 = sizeof(buf[0]);
   hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"hello", 5, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL, 0);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }

#ifdef LTC_HMAC
   len = sizeof(buf[0]);
   hmac_memory(find_hash("sha256"), key, 16, (unsigned char*)"hello", 5, buf[0], &len);
   len2 = sizeof(buf[0]);
   hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
#endif

#ifdef LTC_OMAC
   len = sizeof(buf[0]);
   omac_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len);
   len2 = sizeof(buf[0]);
   omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
#endif

#ifdef LTC_PMAC
   len = sizeof(buf[0]);
   pmac_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len);
   len2 = sizeof(buf[0]);
   pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
#endif

#ifdef LTC_XCBC
   len = sizeof(buf[0]);
   xcbc_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len);
   len2 = sizeof(buf[0]);
   xcbc_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   xcbc_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   xcbc_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
#endif

#ifdef LTC_F9
   len = sizeof(buf[0]);
   f9_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len);
   len2 = sizeof(buf[0]);
   f9_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   f9_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   f9_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
#endif

#ifdef LTC_PELICAN
   /* TODO: there is no pelican_memory_multi(..) */
#endif

#ifdef LTC_POLY1305
   len = sizeof(buf[0]);
   poly1305_memory(key, 32, (unsigned char*)"hello", 5, buf[0], &len);
   len2 = sizeof(buf[0]);
   poly1305_memory_multi(key, 32, buf[1], &len2, (unsigned char*)"hello", 5, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   poly1305_memory_multi(key, 32, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = sizeof(buf[0]);
   poly1305_memory_multi(key, 32, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
#endif

#ifdef LTC_BLAKE2SMAC
   len = 32;
   blake2smac_memory(key, 16, (unsigned char*)"hello", 5, buf[0], &len);
   len2 = 32;
   blake2smac_memory_multi(key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = 32;
   blake2smac_memory_multi(key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = 32;
   blake2smac_memory_multi(key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
#endif

#ifdef LTC_BLAKE2BMAC
   len = 64;
   blake2bmac_memory(key, 16, (unsigned char*)"hello", 5, buf[0], &len);
   len2 = 64;
   blake2bmac_memory_multi(key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = 64;
   blake2bmac_memory_multi(key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
   len2 = 64;
   blake2bmac_memory_multi(key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return CRYPT_FAIL_TESTVECTOR;
   }
#endif

   return CRYPT_OK;
}
Esempio n. 9
0
/* IF YOU CALL THIS MULTIPLE TIMES WITH THE SAME KEY YOU MUST PROVIDE AN IV POINTER! */
int crypt_data(const unsigned char *data_in,
                     unsigned char *data_out,  size_t data_size,
               const unsigned char *data_mkey, size_t data_mkey_size,
                     unsigned char *data_new_hmac,
               const unsigned char *data_chk_hmac,
                     size_t data_hmac_size,
                     unsigned char **IV_start,
                     int mode) {
  if (mode != MODE_ENCRYPT && mode != MODE_DECRYPT) {
    fprintf(stderr, "crypt_data called with invalid mode %d\n", mode);
    return -1;
  }

  symmetric_CTR ctr;
#ifdef _POSIX_MEMLOCK_RANGE
  if (mlock(&ctr, sizeof(ctr)) != 0) {
    fprintf(stderr, "WARNING: mlock failed at %s:%d - ", __FILE__, __LINE__);
    perror("");
  }
#endif
  int err;
  int ret = 0; /* return code */
  unsigned char *IV;
  unsigned long  IV_size = 16;
  int hash_idx = find_hash("sha256");
  size_t data_ckey_size, data_hkey_size;
  data_ckey_size = data_hkey_size = data_mkey_size;
  unsigned char *subkeys = safe_malloc(data_ckey_size + data_hkey_size);
#ifdef _POSIX_MEMLOCK_RANGE
    if (mlock(subkeys, data_ckey_size + data_hkey_size) != 0) {
      fprintf(stderr, "WARNING: mlock failed at %s:%d - ", __FILE__, __LINE__);
      perror("");
    }
#endif
  unsigned char *data_ckey = subkeys + 0;
  unsigned char *data_hkey = subkeys + data_ckey_size;

  pbkdf2(data_mkey, data_mkey_size, "H", 1, SUBKEY_ITER, hash_idx, data_hkey, &data_hkey_size);
  pbkdf2(data_mkey, data_mkey_size, "C", 1, SUBKEY_ITER, hash_idx, data_ckey, &data_ckey_size);
  if (IV_start == NULL || *IV_start == NULL) {
    IV = safe_malloc(IV_size);
    /* fprintf(stderr, "Initializing key-based IV\n"); */
    /* This is at least as secure as starting with a zeroed IV */
    pbkdf2(data_mkey, data_mkey_size, "I", 1, SUBKEY_ITER, hash_idx, IV, &IV_size);
  }
  if (IV_start != NULL) {
    if (*IV_start != NULL) {
      /* fprintf(stderr, "IV = *IV_start\n"); */
      IV = *IV_start;
    } else {
      /* fprintf(stderr, "*IV_start = IV\n"); */
      *IV_start = IV;
    }
  }

  if (mode == MODE_DECRYPT && data_chk_hmac != NULL) {
    if ((err = hmac_vrfymem(hash_idx,
                            data_hkey, data_hkey_size,
                            data_in, data_size, data_chk_hmac,
                            (long unsigned int *)&data_hmac_size)) != CRYPT_OK) {
     crypt_data_return(THRCR_BADMAC);
    }
  }

  /* LTC_CTR_RFC3686 is needed to avoid reusing a counter value. */
  if ((err = ctr_start(find_cipher("aes"), IV, data_ckey, data_ckey_size, 0,
                       CTR_COUNTER_BIG_ENDIAN | LTC_CTR_RFC3686, &ctr)) != CRYPT_OK) {
    fprintf(stderr, "Error initializing cipher: %d\n", err);
    crypt_data_return(-1);
  }

  /* ctr_encrypt is used for both encryption and decryption */
  if ((err = ctr_encrypt(data_in, data_out, data_size, &ctr)) != CRYPT_OK) {
    fprintf(stderr, "ctr_encrypt error: %s\n", error_to_string(err));
    ctr_done(&ctr); /* done with cipher, clean up keys */
    crypt_data_return(-1);
  }
  ctr_done(&ctr); /* done with cipher, clean up keys */

  if (mode == MODE_ENCRYPT && data_new_hmac != NULL) {
    if ((err = hmac_memory(hash_idx,
                           data_hkey, data_hkey_size,
                           data_out, data_size, data_new_hmac,
                           (long unsigned int *)&data_hmac_size)) != CRYPT_OK) {
      fprintf(stderr, "hmac error: %s\n", error_to_string(err));
      crypt_data_return(-1);
    }
  }

  crypt_data_return:
  /* before actually returning, make sure key material isn't in memory */
  MEMWIPE(&ctr, sizeof(ctr));
  MEMWIPE(subkeys, data_ckey_size + data_hkey_size);
#ifdef _POSIX_MEMLOCK_RANGE
  munlock(subkeys, data_ckey_size + data_hkey_size);
#endif
  safe_free(subkeys);
  /* save the IV */
  if (IV_start != NULL && *IV_start != NULL) {
    /* fprintf(stderr, "*IV_start = ctr.ctr\n"); */
    ctr_getiv(*IV_start, &IV_size, &ctr);
  } else {
    safe_free(IV);
  }
  return ret;
}
Esempio n. 10
0
File: hkdf.c Progetto: mkj/dropbear
int hkdf_expand(int hash_idx, const unsigned char *info, unsigned long infolen,
                              const unsigned char *in,   unsigned long inlen,
                                    unsigned char *out,  unsigned long outlen)
{
   unsigned long hashsize;
   int err;
   unsigned char N;
   unsigned long Noutlen, outoff;

   unsigned char *T,  *dat;
   unsigned long Tlen, datlen;

   /* make sure hash descriptor is valid */
   if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
      return err;
   }

   hashsize = hash_descriptor[hash_idx].hashsize;

   /* RFC5869 parameter restrictions */
   if (inlen < hashsize || outlen > hashsize * 255)
      return CRYPT_INVALID_ARG;
   if (info == NULL && infolen != 0)
      return CRYPT_INVALID_ARG;
   LTC_ARGCHK(out != NULL);

   Tlen = hashsize + infolen + 1;
   T = XMALLOC(Tlen); /* Replace with static buffer? */
   if (T == NULL) {
      return CRYPT_MEM;
   }
   if (info != NULL) {
      XMEMCPY(T + hashsize, info, infolen);
   }

   /* HMAC data T(1) doesn't include a previous hash value */
   dat    = T    + hashsize;
   datlen = Tlen - hashsize;

   N = 0;
   outoff = 0; /* offset in out to write to */
   while (1) { /* an exit condition breaks mid-loop */
      Noutlen = MIN(hashsize, outlen - outoff);
      T[Tlen - 1] = ++N;
      if ((err = hmac_memory(hash_idx, in, inlen, dat, datlen,
                             out + outoff, &Noutlen)) != CRYPT_OK) {
         zeromem(T, Tlen);
         XFREE(T);
         return err;
      }
      outoff += Noutlen;

      if (outoff >= outlen) /* loop exit condition */
         break;

      /* All subsequent HMAC data T(N) DOES include the previous hash value */
      XMEMCPY(T, out + hashsize * (N-1), hashsize);
      if (N == 1) {
         dat = T;
         datlen = Tlen;
      }
   }
   zeromem(T, Tlen);
   XFREE(T);
   return CRYPT_OK;
}
Esempio n. 11
0
File: multi.c Progetto: 9heart/DT3
int main(void)
{
   unsigned char key[16], buf[2][MAXBLOCKSIZE];
   unsigned long len, len2;


/* register algos */
   register_hash(&sha256_desc);
   register_cipher(&aes_desc);

/* HASH testing */
   len = sizeof(buf[0]);
   hash_memory(find_hash("sha256"), (unsigned char*)"hello", 5, buf[0], &len);
   len2 = sizeof(buf[0]);
   hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"hello", 5, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return EXIT_FAILURE;
   }
   len2 = sizeof(buf[0]);
   hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL, 0);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return EXIT_FAILURE;
   }
   len2 = sizeof(buf[0]);
   hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return EXIT_FAILURE;
   }

/* LTC_HMAC */
   len = sizeof(buf[0]);
   hmac_memory(find_hash("sha256"), key, 16, (unsigned char*)"hello", 5, buf[0], &len);
   len2 = sizeof(buf[0]);
   hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return EXIT_FAILURE;
   }
   len2 = sizeof(buf[0]);
   hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return EXIT_FAILURE;
   }
   len2 = sizeof(buf[0]);
   hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return EXIT_FAILURE;
   }

/* LTC_OMAC */
   len = sizeof(buf[0]);
   omac_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len);
   len2 = sizeof(buf[0]);
   omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return EXIT_FAILURE;
   }
   len2 = sizeof(buf[0]);
   omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return EXIT_FAILURE;
   }
   len2 = sizeof(buf[0]);
   omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return EXIT_FAILURE;
   }

/* PMAC */
   len = sizeof(buf[0]);
   pmac_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len);
   len2 = sizeof(buf[0]);
   pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return EXIT_FAILURE;
   }
   len2 = sizeof(buf[0]);
   pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return EXIT_FAILURE;
   }
   len2 = sizeof(buf[0]);
   pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL);
   if (len != len2 || memcmp(buf[0], buf[1], len)) {
      printf("Failed: %d %lu %lu\n", __LINE__, len, len2);
      return EXIT_FAILURE;
   }


   printf("All passed\n");
   return EXIT_SUCCESS;
}