RSA BSAFE Crypto-C

Cryptographic Components for C

Search

eces.c

/* $Id: eces.c,v 1.7 2004/12/03 02:08:37 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 program will generate an EC keypair, encrypt a block of data
 *  with the public key and decrypt with the private key, using the
 *  Elliptic Curve Encryption Scheme.
 */

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

B_ALGORITHM_METHOD *EC_CHOOSER[] = {
  &AM_ECFP_ENCRYPT,
  &AM_ECFP_DECRYPT,
  &AM_ECF2POLY_ENCRYPT,
  &AM_ECF2POLY_DECRYPT,
  (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 ecesMain
#else
#define MAIN main
#endif

int MAIN(int argc, char *argv[])
{
  int status;
  char userInput[RSA_DEMO_MAX_LINE_LEN];

  B_ALGORITHM_OBJ randomAlgorithm = (B_ALGORITHM_OBJ)NULL_PTR;
  B_ALGORITHM_OBJ ecParamsObj = (B_ALGORITHM_OBJ)NULL_PTR;
  B_ALGORITHM_OBJ ecesEncrypt = (B_ALGORITHM_OBJ)NULL_PTR;
  B_ALGORITHM_OBJ ecesDecrypt = (B_ALGORITHM_OBJ)NULL_PTR;

  B_KEY_OBJ publicKey = (B_KEY_OBJ)NULL_PTR;
  B_KEY_OBJ privateKey = (B_KEY_OBJ)NULL_PTR;

  A_EC_PARAMS *ecParamInfo;
  unsigned int fieldElementLen;

  ITEM accelerationTableItem = {NULL, 0};

  unsigned char dataToEncrypt[] = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  };
  unsigned int dataToEncryptLen = sizeof(dataToEncrypt);

  unsigned char *encryptedData = NULL_PTR;
  unsigned char *decryptedData = NULL_PTR;
  unsigned int maxEncryptedDataLen, maxDecryptedDataLen;
  unsigned int outputLenUpdate, outputLenFinal, outputLenTotal;

  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 ("EC ES encryption and decryption example\n");
    RSA_PrintMessage ("=======================================\n");

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

    if ((status = RSA_GetCommand (userInput, sizeof (userInput),
                                  "Generate new parameters (y/n)")) != 0)
      break;

    if ((userInput[0] == 'y') || (userInput[0] == 'Y')) {
      if ((status = RSA_CreateECParamsObject (&ecParamsObj,
                                              randomAlgorithm)) != 0)
        break;
    } else {
      if ((status = RSA_CreateECParamsObject (&ecParamsObj,
                                              NULL)) != 0)
        break;
    }

    if ((status = RSA_PrintECParamInfo (ecParamsObj, AI_ECParameters)) != 0)
      break;

    /*  Retrieve useful information from the EC Parameters  */
    if ((status = B_GetAlgorithmInfo ((POINTER *)&ecParamInfo, ecParamsObj,
                                      AI_ECParameters)) != 0)
      break;

    fieldElementLen = (ecParamInfo->fieldElementBits + 7) / 8;
    RSA_PrintMessage ("EC Parameters:  Field element length = %u bytes\n",
                      fieldElementLen);

    if ((status = RSA_GetCommand (userInput, sizeof (userInput),
                                  "Generate accelerator tables (y/n)")) != 0)
      break;

    if ((userInput[0] == 'y') || (userInput[0] == 'Y')) {
      if ((status = RSA_BuildAccelTable (&accelerationTableItem,
                                         ecParamsObj)) != 0)
        break;
    }

    if ((status = RSA_CreateECKeys (&publicKey, &privateKey,
                                    ecParamsObj, randomAlgorithm,
                                    &accelerationTableItem)) != 0)
      break;

    /*  Print out key information  */
    if ((status = RSA_PrintECKeyInfo ("Public Key", KI_ECPublicComponent,
                                      publicKey, 0)) != 0)
      break;
    if ((status = RSA_PrintECKeyInfo ("Private Key", KI_ECPrivateComponent,
                                      privateKey, 0)) != 0)
      break;

    /* EC encryption */
    RSA_PrintMessage ("\nEncrypting Data...\n");
    RSA_PrintBuf ("Data to Encrypt", dataToEncrypt, dataToEncryptLen);

    /* Create. */
    if ((status = B_CreateAlgorithmObject (&ecesEncrypt)) != 0)
      break;

    /* Set.  */
    if ((status = B_SetAlgorithmInfo (ecesEncrypt, AI_EC_ES, NULL_PTR)) != 0)
      break;

    if (accelerationTableItem.data != NULL) {
      RSA_PrintMessage ("Using accelerator table for ECAES encryption...\n");

      if ((status = B_SetAlgorithmInfo (ecesEncrypt, AI_ECAcceleratorTable,
                                        (POINTER)&accelerationTableItem)) != 0)
        break;
    }

    /* Init.  */
    if ((status = B_EncryptInit (ecesEncrypt, publicKey, EC_CHOOSER,
                                 (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    /*  Update.  */
    /*  Allocate space to hold encrypted data  */
    maxEncryptedDataLen = 21 + (2 * fieldElementLen) + dataToEncryptLen;
    RSA_PrintMessage ("Expected size of encrypted data = %u bytes\n",
                      maxEncryptedDataLen);

    encryptedData = T_malloc (maxEncryptedDataLen);
    if (encryptedData == NULL_PTR) {
      status = RSA_DEMO_E_ALLOC;
      break;
    }

    if ((status = B_EncryptUpdate (ecesEncrypt, encryptedData,
                                   &outputLenUpdate, maxEncryptedDataLen,
                                   dataToEncrypt, dataToEncryptLen,
                                   (B_ALGORITHM_OBJ)NULL_PTR,
                                   (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    /* Final.  */
    if ((status = B_EncryptFinal (ecesEncrypt, encryptedData + outputLenUpdate,
                                  &outputLenFinal,
                                  maxEncryptedDataLen - outputLenUpdate,
                                  randomAlgorithm,
                                  (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    outputLenTotal = outputLenUpdate + outputLenFinal;

    RSA_PrintBuf ("Encrypted Data", encryptedData, outputLenTotal);

    /* EC decryption */
    RSA_PrintMessage("\nDecrypting Data...\n");

    /* Create. */
    if ((status = B_CreateAlgorithmObject (&ecesDecrypt)) != 0)
      break;

    /* Set.  */
    if ((status = B_SetAlgorithmInfo (ecesDecrypt, AI_EC_ES, NULL_PTR)) != 0)
      break;

    /* Init.  */
    if ((status = B_DecryptInit (ecesDecrypt, privateKey, EC_CHOOSER,
                                 (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    /*  Update.  */
    /*  Allocate space to hold decrypted data.
     *  The decrypted data will be smaller than the ciphertext. */
    maxDecryptedDataLen = outputLenTotal;
    RSA_PrintMessage ("Maximum size of decrypted data = %u bytes\n",
                      maxDecryptedDataLen);

    decryptedData = T_malloc (maxDecryptedDataLen);
    if (decryptedData == NULL_PTR) {
      status = RSA_DEMO_E_ALLOC;
      break;
    }

    if ((status = B_DecryptUpdate (ecesDecrypt, decryptedData,
                                   &outputLenUpdate, maxDecryptedDataLen,
                                   encryptedData, outputLenTotal,
                                   (B_ALGORITHM_OBJ)NULL_PTR,
                                   (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    /* Final.  */
    if ((status = B_DecryptFinal (ecesDecrypt, decryptedData + outputLenUpdate,
                                  &outputLenFinal,
                                  maxDecryptedDataLen - outputLenUpdate,
                                  (B_ALGORITHM_OBJ)NULL_PTR,
                                  (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    outputLenTotal = outputLenUpdate + outputLenFinal;

    RSA_PrintBuf ("Decrypted Data", decryptedData, outputLenTotal);

    if ((outputLenTotal == dataToEncryptLen) &&
        (T_memcmp (dataToEncrypt, decryptedData, outputLenTotal)) == 0) {
      RSA_PrintMessage ("Success!  ");
      RSA_PrintMessage ("Decrypted data matches the original data.\n");
    } else {
      RSA_PrintMessage ("Decrypted data does not match the original data.");
      status = RSA_DEMO_E_INFO_DOES_NOT_VERIFY;
    }
  } while (0);

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

  /* Destroy all key and algorithm objects and free memory.  */
  B_DestroyAlgorithmObject (&ecesEncrypt);
  B_DestroyAlgorithmObject (&ecesDecrypt);
  B_DestroyKeyObject (&publicKey);
  B_DestroyKeyObject (&privateKey);

  if (encryptedData != NULL_PTR)
    T_free (encryptedData);

  if (decryptedData != NULL_PTR)
    T_free (decryptedData);

  if (accelerationTableItem.data != NULL)
    T_free (accelerationTableItem.data);

  return (status);
}  /* end main */

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