RSA BSAFE Crypto-C

Cryptographic Components for C

Search

dhagree.c

/* $Id: dhagree.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 a key agreed upon value using a previously-
 *  generated DH parameters.  You would not want the DH parameters hard-coded
 *  in a real application.
 */

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

B_ALGORITHM_METHOD *DH_AGREE_SAMPLE_CHOOSER[] = {
  &AM_DH_KEY_AGREE,
  (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 dhagreeMain
#else
#define MAIN main
#endif

int MAIN(int argc, char *argv[])
{
  ITEM dhParametersBER;

  unsigned char dhParamsBER[154] = {
    0x30, 0x81, 0x97, 0x06, 0x09, 0x2a, 0x86, 0x48,
    0x86, 0xf7, 0x0d, 0x01, 0x03, 0x01, 0x30, 0x81,
    0x89, 0x02, 0x41, 0x00, 0xaf, 0xbb, 0x7e, 0xe7,
    0xf3, 0xc2, 0x6c, 0xa0, 0x4e, 0xab, 0x0d, 0x62,
    0xea, 0x0d, 0x3f, 0xdd, 0xce, 0x97, 0x8b, 0xe1,
    0xe8, 0x6b, 0xbe, 0x67, 0x21, 0x1c, 0x59, 0x5c,
    0x15, 0x41, 0x0e, 0x5b, 0xe4, 0xe5, 0x47, 0x39,
    0xc6, 0x0d, 0x3f, 0xc3, 0x22, 0xb9, 0x64, 0x58,
    0xc8, 0x40, 0x4c, 0x0e, 0x61, 0xea, 0xb7, 0x33,
    0xfa, 0xfa, 0x2a, 0xa5, 0x4c, 0x6a, 0x06, 0x48,
    0x60, 0xa8, 0x7f, 0xc1, 0x02, 0x40, 0x68, 0x66,
    0x62, 0x61, 0x34, 0x6b, 0x19, 0x5e, 0xd6, 0x73,
    0x38, 0x6a, 0x94, 0x21, 0xeb, 0xd0, 0x61, 0x4f,
    0x20, 0xc6, 0x33, 0xc1, 0x69, 0x08, 0x67, 0xd0,
    0x40, 0x03, 0xac, 0x00, 0x69, 0x5e, 0x2e, 0x34,
    0x0e, 0xca, 0x38, 0xb2, 0x1b, 0x18, 0x65, 0x52,
    0x32, 0x16, 0x08, 0x9a, 0x4f, 0x68, 0x8b, 0x01,
    0x4f, 0x0a, 0xb3, 0x6a, 0xfd, 0xa7, 0x16, 0xad,
    0xe7, 0x90, 0x4c, 0x8a, 0x73, 0xbf, 0x02, 0x02,
    0x01, 0xf8
  };

  B_ALGORITHM_OBJ randomAlgorithm = (B_ALGORITHM_OBJ)NULL_PTR;
  B_ALGORITHM_OBJ dhKeyAgreeAlg = (B_ALGORITHM_OBJ)NULL_PTR;
  B_ALGORITHM_OBJ otherPartyAlg = (B_ALGORITHM_OBJ)NULL_PTR;

  A_SURRENDER_CTX generalSurrenderContext;
  int generalFlag;

  A_DH_KEY_AGREE_PARAMS *getParams;

  unsigned char *myPublicValue = NULL_PTR;
  unsigned int myPublicValueLen;

  unsigned char *otherPublicValue = NULL_PTR;
  unsigned int otherPublicValueLen;

  unsigned char *agreedUponSecretValue = NULL_PTR;
  unsigned int agreedUponSecretValueLen;

  unsigned char *otherAgreedUponValue = NULL_PTR;
  unsigned int otherAgreedUponValueLen;

  int status;

  /* see samples/common/source/surrctx.c for RSA_GeneralSurrenderFunction */
  generalSurrenderContext.Surrender = RSA_GeneralSurrenderFunction;
  generalSurrenderContext.handle = (POINTER)&generalFlag;
  generalSurrenderContext.reserved = NULL_PTR;

  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 ("Diffie-Hellman Key Agreement Algorithm\n");
    RSA_PrintMessage ("======================================\n");

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

    RSA_PrintMessage ("\n   Use previously-generated DH parameters\n");
    RSA_PrintMessage ("   ======================================\n");

    dhParametersBER.len = 154;
    dhParametersBER.data = (unsigned char *)dhParamsBER;

    RSA_PrintMessage ("\n   Key Agreement -- Phase 1\n");
    RSA_PrintMessage ("   ========================\n");

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

    if ((status = B_CreateAlgorithmObject (&otherPartyAlg)) != 0)
      break;

    /*  Set the algorithm object to AI_DHKeyAgreeBER  */
    if ((status = B_SetAlgorithmInfo (dhKeyAgreeAlg, AI_DHKeyAgreeBER,
                                      (POINTER)&dhParametersBER)) != 0)
      break;

    if ((status = B_SetAlgorithmInfo (otherPartyAlg, AI_DHKeyAgreeBER,
                                      (POINTER)&dhParametersBER)) != 0)
      break;

    /*  Init  */
    if ((status = B_KeyAgreeInit (dhKeyAgreeAlg, (B_KEY_OBJ)NULL_PTR,
                                  DH_AGREE_SAMPLE_CHOOSER,
                                  (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    if ((status = B_KeyAgreeInit (otherPartyAlg, (B_KEY_OBJ)NULL_PTR,
                                  DH_AGREE_SAMPLE_CHOOSER,
                                  (A_SURRENDER_CTX *)NULL_PTR)) != 0)
      break;

    /*  Phase 1  */
    /*  Find out how big the prime is so we know how many bytes to
        allocate for the public value buffer.  */
    if ((status = B_GetAlgorithmInfo ((POINTER *)&getParams, dhKeyAgreeAlg,
                                      AI_DHKeyAgree)) != 0)
      break;

    myPublicValue = T_malloc (getParams->prime.len);
    if (myPublicValue == NULL_PTR) {
      status = RSA_DEMO_E_ALLOC;
      break;
    }

    otherPublicValue = T_malloc (getParams->prime.len);
    if (otherPublicValue == NULL_PTR) {
      status = RSA_DEMO_E_ALLOC;
      break;
    }

    /*  generalFlag is for the surrender function */
    generalFlag = 0;
    if ((status = B_KeyAgreePhase1 (dhKeyAgreeAlg, myPublicValue,
                                    &myPublicValueLen, getParams->prime.len,
                                    randomAlgorithm,
                                    &generalSurrenderContext)) != 0)
      break;

    RSA_PrintBuf ("Public value to give to other party", myPublicValue,
                  myPublicValueLen);

    generalFlag = 0;
    if ((status = B_KeyAgreePhase1 (otherPartyAlg, otherPublicValue,
                                    &otherPublicValueLen, getParams->prime.len,
                                    randomAlgorithm,
                                    &generalSurrenderContext)) != 0)
      break;

    RSA_PrintBuf ("Public value received from other party", otherPublicValue,
                  otherPublicValueLen);

    RSA_PrintMessage ("\n   Key Agreement -- Phase 2\n");
    RSA_PrintMessage ("   ========================\n");

    /*  Phase 2 */
    /*  The other party should send their public value and its length.  */
    agreedUponSecretValue = T_malloc (getParams->prime.len);
    if (agreedUponSecretValue == NULL_PTR) {
      status = RSA_DEMO_E_ALLOC;
      break;
    }

    otherAgreedUponValue = T_malloc (getParams->prime.len);
    if (otherAgreedUponValue == NULL_PTR) {
      status = RSA_DEMO_E_ALLOC;
      break;
    }

    generalFlag = 0;
    if ((status = B_KeyAgreePhase2 (dhKeyAgreeAlg, agreedUponSecretValue,
                                    &agreedUponSecretValueLen,
                                    getParams->prime.len, otherPublicValue,
                                    otherPublicValueLen,
                                    &generalSurrenderContext)) != 0)
      break;

    RSA_PrintBuf ("Value derived by me", agreedUponSecretValue,
                  agreedUponSecretValueLen);

    generalFlag = 0;
    if ((status = B_KeyAgreePhase2 (otherPartyAlg, otherAgreedUponValue,
                                    &otherAgreedUponValueLen,
                                    getParams->prime.len, myPublicValue,
                                    myPublicValueLen,
                                    &generalSurrenderContext)) != 0)
      break;

    RSA_PrintBuf ("Value derived by other party", otherAgreedUponValue,
                  otherAgreedUponValueLen);

    if (agreedUponSecretValueLen != otherAgreedUponValueLen) {
      status = RSA_DEMO_E_INFO_DOES_NOT_VERIFY;
      break;
    }

    if (T_memcmp (agreedUponSecretValue, otherAgreedUponValue,
                  agreedUponSecretValueLen) != 0) {
      status = RSA_DEMO_E_INFO_DOES_NOT_VERIFY;
      break;
    }

    RSA_PrintMessage ("\nSuccess!  Keys agree\n");
  } while (0);

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

  /*  Destroy the algorithm objects  */
  B_DestroyAlgorithmObject (&dhKeyAgreeAlg);
  B_DestroyAlgorithmObject (&otherPartyAlg);
  B_DestroyAlgorithmObject (&randomAlgorithm);

  /*  Free up any memory allocated  */
  if (myPublicValue != NULL_PTR)
    T_free (myPublicValue);

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

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

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

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

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