RSA BSAFE Crypto-C

Cryptographic Components for C

Search

hmac.c

/* $Id: hmac.c,v 1.6 2004/12/03 02:08:36 sparki Exp $ */
/*
 * Copyright (C) 1998-2004 RSA Security Inc.
 *
 * This file shall only be used to demonstrate how to interface to an
 * RSA Security Inc. licensed development product.
 *
 * You have a royalty-free right to use, reproduce and distribute this
 * demonstration file, provided that you agree that RSA Security Inc.
 * has no warranty, implied or otherwise, or liability for this
 * demonstration file (including any modified version).  This software
 * is provided "as is" without warranties or representations of any
 * kind. RSA Security disclaims all conditions and warranties, statutory
 * and otherwise, both express and implied, with respect to the software,
 * its quality and performance, including but not limited to, all
 * implied warranties of merchantability, fitness for a particular
 * purpose, title and noninfringement of third party rights. Without
 * limiting the foregoing, RSA Security does not warrant that the
 * software is error-free or that errors in the product will be
 * corrected. You agree that RSA Security shall not be liable for any
 * direct, indirect, incidental, special, consequential, punitive or
 * other damages whatsoever resulting from your use of this software
 * or any modified version.
 *
 *
 */

/* This file demonstrates HMAC message authentication */

#include "bsafe.h"
#include "demoutil.h"  /* in samples/common/include */
#include "bsfutil.h"   /* in samples/common/include */

#define KEY_SIZE 24

#define DIGEST_LEN 20  /* for SHA1 */

B_ALGORITHM_METHOD *HMAC_CHOOSER[] = {
  &AM_SHA,
  (B_ALGORITHM_METHOD *)NULL_PTR

/* This will fix a problem that the IA64 compiler finds when *
 * seeing a short chooser list */
#ifdef IA64_FORCE_LARGE
                IA64_FORCE_LARGE
#endif
};


#ifdef CRYPTOC_APP
#define MAIN hmacMain
#else
#define MAIN main
#endif

int MAIN(int argc, char *argv[])
{
  B_ALGORITHM_OBJ HMACDigesterA = (B_ALGORITHM_OBJ)NULL_PTR;
  B_ALGORITHM_OBJ HMACDigesterB = (B_ALGORITHM_OBJ)NULL_PTR;
  B_ALGORITHM_OBJ randomAlgorithm = (B_ALGORITHM_OBJ)NULL_PTR;

  B_KEY_OBJ HMACKeyA = (B_KEY_OBJ)NULL_PTR;
  B_KEY_OBJ HMACKeyB = (B_KEY_OBJ)NULL_PTR;

  ITEM keyDataItem = {NULL, 0};
  unsigned char *keyData = NULL_PTR;

  unsigned char dataToDigest[] = "Digest this sentence.";
  unsigned int dataToDigestLen = T_strlen ((char *)dataToDigest);
  unsigned char *digestedData = NULL_PTR;
  unsigned int digestedDataLen;

  B_DIGEST_SPECIFIER hmacInfo;

  int status;

  do {
    /* The RSA_* demo code utilities are described in
       common/include/demoutil.h.  This procedure simply checks the
       command-line arguments for input or output options. */
    if ((status = RSA_SetOptions (argc, argv)) != 0)
      break;

    RSA_PrintMessage ("HMAC Authenticated Message Example\n");
    RSA_PrintMessage ("==================================\n");
    RSA_PrintMessage ("Hash algorithm = SHA1\n");

    if ((status = RSA_CreateRandomAlgorithmObject (&randomAlgorithm)) != 0)
      break;

    /* Create a key object */
    if ((status = B_CreateKeyObject (&HMACKeyA)) != 0)
      break;

    keyData = T_malloc (KEY_SIZE);
    if (keyData == NULL_PTR) {
      status = RSA_DEMO_E_ALLOC;
      break;
    }

    /* Generate KEY_SIZE bytes of random data for the key */
    if ((status = B_GenerateRandomBytes (randomAlgorithm, keyData, KEY_SIZE,
                                         (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    RSA_PrintBuf ("Random bytes supplied for key", keyData, KEY_SIZE);

    /* Set the key object */
    keyDataItem.data = keyData;
    keyDataItem.len = KEY_SIZE;
    if ((status = B_SetKeyInfo (HMACKeyA, KI_Item,
                                (POINTER)&keyDataItem)) != 0)
      break;

    /* Zeroize and free the key data memory, since Crypto-C has a copy */
    T_memset (keyData, 0, KEY_SIZE);
    T_free (keyData);
    keyData = NULL_PTR;

    RSA_PrintBuf ("Data to Digest", dataToDigest, dataToDigestLen);

    /* Create the HMAC digesting algorithm object */
    if ((status = B_CreateAlgorithmObject (&HMACDigesterA)) != 0)
      break;

    /* Set the algorithm object for HMAC using SHA1 */
    hmacInfo.digestInfoType = AI_SHA1;
    hmacInfo.digestInfoParams = NULL_PTR;

    if ((status = B_SetAlgorithmInfo (HMACDigesterA, AI_HMAC,
                                      (POINTER)&hmacInfo)) != 0)
      break;

    /* Initalize the algorithm object for digesting */
    if ((status = B_DigestInit (HMACDigesterA, HMACKeyA, HMAC_CHOOSER,
                                (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    /* Update */
    if ((status = B_DigestUpdate (HMACDigesterA, dataToDigest, dataToDigestLen,
                                  (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    /* Finalize the process */
    /* Allocate space for the digested data */
    digestedData = T_malloc (DIGEST_LEN);
    if (digestedData == NULL_PTR) {
      status = RSA_DEMO_E_ALLOC;
      break;
    }

    if ((status = B_DigestFinal (HMACDigesterA, digestedData, &digestedDataLen,
                                 DIGEST_LEN,
                                 (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    /* Print out the digest */
    RSA_PrintBuf ("Digest", digestedData, digestedDataLen);

    /* Zeroize and free the digest */
    T_memset (digestedData, 0, DIGEST_LEN);
    T_free (digestedData);
    digestedData = NULL_PTR;
    digestedDataLen = 0;

    /* Now hash again to demonstrate the process with another key */
    RSA_PrintMessage ("\nHashing again, using a different key...\n");

    /* Create a key object */
    if ((status = B_CreateKeyObject (&HMACKeyB)) != 0)
      break;

    keyData = T_malloc (KEY_SIZE);
    if (keyData == NULL_PTR) {
      status = RSA_DEMO_E_ALLOC;
      break;
    }

    /* Generate KEY_SIZE bytes of random data for the key */
    if ((status = B_GenerateRandomBytes (randomAlgorithm, keyData, KEY_SIZE,
                                         (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    RSA_PrintBuf ("Random bytes supplied for key", keyData, KEY_SIZE);

    /* Set the key object */
    keyDataItem.data = keyData;
    keyDataItem.len = KEY_SIZE;
    if ((status = B_SetKeyInfo (HMACKeyB, KI_Item,
                                (POINTER)&keyDataItem)) != 0)
      break;

    /* Zeroize and free the key data memory, since Crypto-C has a copy */
    T_memset (keyData, 0, KEY_SIZE);
    T_free (keyData);
    keyData = NULL_PTR;

    RSA_PrintBuf ("Data to Digest", dataToDigest, dataToDigestLen);

    /* Create the HMAC digesting algorithm object */
    if ((status = B_CreateAlgorithmObject (&HMACDigesterB)) != 0)
      break;

    /* Set the algorithm object */
    if ((status = B_SetAlgorithmInfo (HMACDigesterB, AI_HMAC,
                                      (POINTER)&hmacInfo)) != 0)
      break;

    /* Initalize the algorithm object for digesting */
    if ((status = B_DigestInit (HMACDigesterB, HMACKeyB, HMAC_CHOOSER,
                                (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    /* Update */
    if ((status = B_DigestUpdate (HMACDigesterB, dataToDigest, dataToDigestLen,
                                  (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    /* Finalize the process */
    /* Allocate space for the digested data */
    digestedData = T_malloc (DIGEST_LEN);
    if (digestedData == NULL_PTR) {
      status = RSA_DEMO_E_ALLOC;
      break;
    }

    if ((status = B_DigestFinal (HMACDigesterB, digestedData, &digestedDataLen,
                                 DIGEST_LEN,
                                 (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    /* Print out the digest */
    RSA_PrintBuf ("Digested Data", digestedData, digestedDataLen);

    /* Zeroize and free the digest */
    T_memset (digestedData, 0, DIGEST_LEN);
    T_free (digestedData);
    digestedData = NULL_PTR;
    digestedDataLen = 0;
  } while (0);

  if (status != 0)
    RSA_PrintError ("hmac", status);

  /* Destroy the key and algorithm objects */
  B_DestroyKeyObject (&HMACKeyA);
  B_DestroyKeyObject (&HMACKeyB);
  B_DestroyAlgorithmObject (&randomAlgorithm);
  B_DestroyAlgorithmObject (&HMACDigesterA);
  B_DestroyAlgorithmObject (&HMACDigesterB);

  if (digestedData != NULL_PTR) {
    T_free (digestedData);
    digestedData = NULL_PTR;
    digestedDataLen = 0;
  }

  if (keyData != NULL_PTR) {
    T_memset (keyData, 0, KEY_SIZE);
    T_free (keyData);
    keyData = NULL_PTR;
  }

  return (status);
}

Copyright (c) 1999-2005 RSA Security Inc. All rights reserved. 068-001001-6210-001-000 - 6.2.1