RSA BSAFE Crypto-C

Cryptographic Components for C

Search

scrtshar.c

/* $Id: scrtshar.c,v 1.5 2004/12/03 02:08:40 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 create a number of shares from a secret key.
 *  It then recovers the information by collecting a declared number of the
 *  shares.
 */
     
#include "bsafe.h"
#include "demoutil.h"  /* in samples/common/include */
#include "bsfutil.h"   /* in samples/common/include */

#define SECRET_SIZE   16
#define TOTAL_SHARES   4

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

int MAIN(int argc, char *argv[])
{
  B_ALGORITHM_OBJ secretSplitter = (B_ALGORITHM_OBJ)NULL_PTR;
  B_SECRET_SHARING_PARAMS secretSharingParams;

  B_ALGORITHM_OBJ randomAlgorithm = (B_ALGORITHM_OBJ)NULL_PTR;

  unsigned char secretKey[SECRET_SIZE] = {
    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
    0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  };
  unsigned char *secretShare[TOTAL_SHARES];
  unsigned int secretShareLen[TOTAL_SHARES];
  int count;      

  B_ALGORITHM_OBJ secretReconstructer = (B_ALGORITHM_OBJ)NULL_PTR;
  unsigned char getSecret[SECRET_SIZE];
  unsigned int getSecretLen;
  unsigned int outputLenUpdate, outputLenFinal;
  
  int status;
  
  do {
    for (count = 0; count < TOTAL_SHARES; ++count)
      secretShare[count] = NULL_PTR;

    /* 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 ("Secret Sharing Algorithm\n");
    RSA_PrintMessage ("========================\n");

    /*  Initialize a random algorithm object using a procedure described in
        samples/common/include/bsfutil.h  */
    if ((status = RSA_CreateRandomAlgorithmObject (&randomAlgorithm)) != 0)
      break;

    RSA_PrintMessage ("\nHere's your secret key to be split into %i shares:\n",
                      TOTAL_SHARES);
    RSA_PrintBuf (NULL, secretKey, SECRET_SIZE);

    RSA_PrintMessage ("\n   Generating the shares\n");
    RSA_PrintMessage ("   =====================\n");

    /*  Create algorithm object  */
    if ((status = B_CreateAlgorithmObject (&secretSplitter)) != 0)
      break;

    /*  Set algorithm object to AI_BSSecretSharing  */
    secretSharingParams.threshold = 2;
    if ((status = B_SetAlgorithmInfo (secretSplitter, AI_BSSecretSharing,
                                      (POINTER)&secretSharingParams)) != 0)
      break;

    /*  Init  */
    if ((status = B_EncryptInit (secretSplitter, (B_KEY_OBJ)NULL_PTR,
                                 (B_ALGORITHM_CHOOSER)NULL_PTR,
                                 (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    /*  Update  */
    for (count = 0; count < TOTAL_SHARES; ++count) {
      secretShare[count] = T_malloc (SECRET_SIZE + 1);
      if ((status = (secretShare[count] == NULL_PTR)) != 0)
        break;

      if ((status = B_EncryptUpdate (secretSplitter, secretShare[count],
                                     &(secretShareLen[count]), SECRET_SIZE + 1,
                                     secretKey, SECRET_SIZE, randomAlgorithm,
                                     (A_SURRENDER_CTX *)NULL_PTR)) != 0)
        break;

      RSA_PrintMessage ("Secret share #%i = \n", (count+1));
      RSA_PrintBuf (NULL, secretShare[count], secretShareLen[count]);
    } /*  end for  */
    if (status != 0)
      break;

    /*  Final */
    if ((status = B_EncryptFinal (secretSplitter, NULL_PTR,
                                  &outputLenFinal, 0,
                                  (B_ALGORITHM_OBJ)NULL_PTR,
                                  (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;
    /* Now reconstruct the secret */
    RSA_PrintMessage ("\n   Reconstructing the secret\n");
    RSA_PrintMessage ("   =========================\n");

    /*  Create algorithm object  */
    if ((status = B_CreateAlgorithmObject (&secretReconstructer)) != 0)
      break;

    /*  Set algorithm object to AI_BSSecretSharing  */
    secretSharingParams.threshold = 2;
    if ((status = B_SetAlgorithmInfo (secretReconstructer, AI_BSSecretSharing,
                                      (POINTER)&secretSharingParams)) != 0)
      break;

    /*  Init  */
    if ((status = B_DecryptInit (secretReconstructer, (B_KEY_OBJ)NULL_PTR,
                                 (B_ALGORITHM_CHOOSER)NULL_PTR,
                                 (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    /*  Update   */
    for (count = 0; count < (int)secretSharingParams.threshold; ++count) {
      if ((status = B_DecryptUpdate (secretReconstructer, NULL_PTR,
                                     &outputLenUpdate, 0,
                                     secretShare[count], secretShareLen[count],
                                     (B_ALGORITHM_OBJ)NULL_PTR,
                                     (A_SURRENDER_CTX *)NULL_PTR)) != 0)
        break;
    } /*  end for  */
    if (status != 0)
      break;

    /*  Final */
    if ((status = B_DecryptFinal (secretReconstructer, getSecret,
                                  &getSecretLen, SECRET_SIZE,
                                  (B_ALGORITHM_OBJ)NULL_PTR,
                                  (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;


    RSA_PrintMessage ("Your secret key has been reconstructed using ");
    RSA_PrintMessage ("%i shares.\n", secretSharingParams.threshold);
    RSA_PrintBuf ("This is your secret key", getSecret, getSecretLen);

    if ((getSecretLen == SECRET_SIZE) &&
        (T_memcmp (getSecret, secretKey, getSecretLen)) == 0) {
      RSA_PrintMessage ("Success!  The reconstructed key matches ");
      RSA_PrintMessage ("the original secret key.\n");
    } else {
      RSA_PrintMessage ("The reconstructed key does not match the original ");
      RSA_PrintMessage ("secret key.");
      status = RSA_DEMO_E_INFO_DOES_NOT_VERIFY;
    }    
  } while (0);

  if (status != 0)
    RSA_PrintError ("scrtshar", status);
  
  /*  Destroy all objects   */
  B_DestroyAlgorithmObject (&secretSplitter);           
  B_DestroyAlgorithmObject (&randomAlgorithm);
  B_DestroyAlgorithmObject (&secretReconstructer);

  /*  Free up any memory allocated   */
  for (count = 0; count < TOTAL_SHARES; ++count)
    T_free (secretShare[count]);

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

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