⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhsecret.c

📁 IBE是一种非对称密码技术
💻 C
字号:
/* Copyright 2005-2006, Voltage Security, all rights reserved.
 */

#include "vibecrypto.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "algobj.h"
#include "keyobj.h"
#include "keyagree.h"
#include "dh.h"
#include "errorctx.h"

/* Gets the shared secret data out of a key object.
 *
 * @param object The object from which the data is to be extracted.
 * @param getInfo The address where the function will deposit the
 * pointer to the info.
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code.
 */
static int VOLT_CALLING_CONV VoltKeyGetDHSharedSecret VOLT_PROTO_LIST ((
   VtKeyObject object,
   Pointer *getInfo
));

int VtAlgorithmImplDHKeyAgree (
   VtAlgorithmObject *object,
   Pointer info,
   unsigned int flag
   )
{
  int status;
  unsigned int bufferSize;
  VoltAlgorithmObject *obj = (VoltAlgorithmObject *)(*object);
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  unsigned char *buffer = (unsigned char *)0;
  VoltKeyAgreeClassCtx *ctx;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Check the flag, it should be VOLT_ALG_SET_TYPE_FLAG.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_TYPE;
    if (flag != VOLT_ALG_SET_TYPE_FLAG)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_ASSOCIATED_INFO;
    if (info != (Pointer)0)
      break;

    /* Allocate space for the Key Agree Class Ctx.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    bufferSize = sizeof (VoltKeyAgreeClassCtx);
    buffer = (unsigned char *)Z3Malloc (bufferSize);
    if (buffer == (unsigned char *)0)
      break;
    Z2Memset (buffer, 0, bufferSize);

    ctx = (VoltKeyAgreeClassCtx *)buffer;
    ctx->algorithmImpl = VtAlgorithmImplDHKeyAgree;
    ctx->algorithmImplInfo = (Pointer)0;
    ctx->GenerateSharedSecret = VoltDHGenerateSharedSecret;

    obj->algClass = VOLT_CLASS_KEY_AGREE;
    obj->classCtx = (Pointer)ctx;
    obj->ClassCtxDestroy = VoltSimpleCtxDestroy;

    status = 0;

  } while (0);

  if (status == 0)
    return (0);

  /* If there was an error, destroy what we created but did not return.
   */
  if (buffer != (unsigned char *)0)
    Z2Free (buffer);

  obj->state = VOLT_STATE_ERROR;

  VOLT_LOG_ERROR_INFO (
    0, *object, status, 0, errorType,
    (char *)0, "VtAlgorithmImplDHKeyAgree", fnctLine, (char *)0)

  return (status);
}

int VoltDHGenerateSharedSecret (
   VoltAlgorithmObject *obj,
   VtKeyObject otherPartyPubKey,
   VtKeyObject myPriKey,
   VtKeyObject sharedSecret,
   VtRandomObject random
   )
{
  int status, cmpResult;
  unsigned int theSecretLen, sign;
  VoltKeyObject *pubKey = (VoltKeyObject *)otherPartyPubKey;
  VoltKeyObject *priKey = (VoltKeyObject *)myPriKey;
  VoltKeyObject *secret = (VoltKeyObject *)sharedSecret;
  VoltMpIntCtx *mpCtx = secret->mpCtx;
  VoltLibCtx *libCtx = (VoltLibCtx *)(secret->voltObject.libraryCtx);
  VtKeyObject tempPub = (VtKeyObject)0;
  VtKeyObject tempPri = (VtKeyObject)0;
  VoltMpInt *result = (VoltMpInt *)0;
  unsigned char *theSecret = (unsigned char *)0;
  VoltDHPublicKey *pubKeyData;
  VtDHPubKeyInfo *pubKeyInfo;
  VoltDHPrivateKey *priKeyData;
  VtDHPriKeyInfo *priKeyInfo;
  VtItem secretItem;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Make sure the keys are DH.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_KEY_OBJ;
    if ((pubKey->keyType & VOLT_KEY_TYPE_MASK_ASYM_ALG) != VOLT_KEY_ALG_DH)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if ((pubKey->keyType & VOLT_KEY_TYPE_PUBLIC) == 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if (pubKey->mpCtx == (VoltMpIntCtx *)0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if ((priKey->keyType & VOLT_KEY_TYPE_MASK_ASYM_ALG) != VOLT_KEY_ALG_DH)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if ((priKey->keyType & VOLT_KEY_TYPE_PRIVATE) == 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if (priKey->mpCtx == (VoltMpIntCtx *)0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if (secret->mpCtx == (VoltMpIntCtx *)0)
      break;

    /* Get the key data in a form we want and make sure the mpCtx in
     * pub and pri matches.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtGetKeyParam (
      otherPartyPubKey, VtKeyParamDHPublic, (Pointer *)&pubKeyInfo);
    if (status == VT_ERROR_GET_INFO_UNAVAILABLE)
      status = VT_ERROR_INVALID_KEY_OBJ;
    if (status != 0)
      break;

    /* Create a key object we know will possess the key data the way
     * we want it.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtCreateKeyObject (
      secret->voltObject.libraryCtx, VtKeyImplMpCtx,
      (Pointer)(secret->mpCtx), &tempPub);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtSetKeyParam (
      tempPub, VtKeyParamDHPublic, (Pointer)pubKeyInfo);
    if (status != 0)
      break;

    pubKey = (VoltKeyObject *)tempPub;
    pubKeyData = (VoltDHPublicKey *)(pubKey->keyData);

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtGetKeyParam (
      myPriKey, VtKeyParamDHPrivate, (Pointer *)&priKeyInfo);
    if (status == VT_ERROR_GET_INFO_UNAVAILABLE)
      status = VT_ERROR_INVALID_KEY_OBJ;
    if (status != 0)
      break;

    /* Create a key object we know will possess the key data the way
     * we want it.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtCreateKeyObject (
      secret->voltObject.libraryCtx, VtKeyImplMpCtx,
      (Pointer)(secret->mpCtx), &tempPri);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtSetKeyParam (
      tempPri, VtKeyParamDHPrivate, (Pointer)priKeyInfo);
    if (status != 0)
      break;

    priKey = (VoltKeyObject *)tempPri;
    priKeyData = (VoltDHPrivateKey *)(priKey->keyData);

    /* Make sure the pub key's base and prime are the same as the pri
     * key's base and prime.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->Compare (
      pubKeyData->primeP, priKeyData->primeP, &cmpResult);
    if (status != 0)
      break;

    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT;
    if (cmpResult != 0)
      break;

    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->Compare (
      pubKeyData->baseG, priKeyData->baseG, &cmpResult);
    if (status != 0)
      break;

    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT;
    if (cmpResult != 0)
      break;

    /* To generate the shared secret, find
     * (otherPub ^ myPri) mod prime. We'll need a result mpInt.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->CreateMpInt ((Pointer)mpCtx, &result);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->ModExp (
      pubKeyData->pubValY, priKeyData->priValX, pubKeyData->primeP,
      result);
    if (status != 0)
      break;

    /* Get the result as a byte array. First, how long.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->MpIntToOctetString (
      result, &sign, (unsigned char *)0, 0, &theSecretLen);
    if (status == 0)
      status = VT_ERROR_GENERAL;
    if (status != VT_ERROR_BUFFER_TOO_SMALL)
      break;

    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    theSecret = (unsigned char *)Z2Malloc (
      theSecretLen, VOLT_MEMORY_SENSITIVE);
    if (theSecret == (unsigned char *)0)
      break;

    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = mpCtx->MpIntToOctetString (
      result, &sign, theSecret, theSecretLen, &theSecretLen);
    if (status != 0)
      break;

    /* Set the secret key object with the shared secret.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    secretItem.data = theSecret;
    secretItem.len = theSecretLen;
    status = VtSetKeyParam (
      sharedSecret, VtKeyParamDHSharedSecret, (Pointer)&secretItem);

  } while (0);

  if (theSecret != (unsigned char *)0)
    Z2Free (theSecret);

  if (result != (VoltMpInt *)0)
    mpCtx->DestroyMpInt (&result);

  VtDestroyKeyObject (&tempPub);
  VtDestroyKeyObject (&tempPri);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, sharedSecret, status, 0, errorType,
    (char *)0, "VtSharedSecretGenDH", fnctLine, (char *)0)

  return (status);
}

int VtKeyParamDHSharedSecret (
   VtKeyObject object,
   Pointer info,
   unsigned int flag
   )
{
  int status;
  VoltKeyObject *obj = (VoltKeyObject *)object;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VtItem *keyInfo = (VtItem *)info;
  VtItem *localCopy = (VtItem *)0;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    if (flag == VOLT_KEY_GET_TYPE_FLAG)
    {
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltKeyGetDHSharedSecret (object, (Pointer *)info);
      break;
    }

    /* Check the flag, it should be VOLT_KEY_SET_TYPE_FLAG.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_TYPE;
    if (flag != VOLT_KEY_SET_TYPE_FLAG)
      break;

    /* The associated info should be a pointer to a VtItem.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_ASSOCIATED_INFO;
    if (info == (Pointer)0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if ( (keyInfo->data == (unsigned char *)0) || (keyInfo->len == 0) )
      break;

    /* Allocate space for a VtItem and the data.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    localCopy = (VtItem *)Z2Malloc (
      sizeof (VtItem) + keyInfo->len, VOLT_MEMORY_SENSITIVE);
    if (localCopy == (VtItem *)0)
      break;

    localCopy->data = ((unsigned char *)localCopy) + sizeof (VtItem);
    Z2Memcpy (localCopy->data, keyInfo->data, keyInfo->len);
    localCopy->len = keyInfo->len;

    obj->voltObject.CloneObject = VoltCloneDHSharedSecret;
    obj->keyData = (Pointer)localCopy;
    obj->KeyDataDestroy = VoltSimpleCtxDestroy;
    obj->keyType =
      VOLT_KEY_ALG_DH | VOLT_KEY_TYPE_AGREE | VOLT_KEY_TYPE_SHARED_SECRET |
      VOLT_KEY_TYPE_DATA;

    status = 0;

  } while (0);

  /* If everything worked, return 0.
   */
  if (status == 0)
    return (0);

  /* If something went wrong, indicate that this object is not usable.
   */
  obj->keyType = 0;

  if (localCopy != (VtItem *)0)
    Z2Free (localCopy);

  VOLT_LOG_ERROR_INFO (
    0, obj, status, 0, errorType,
    (char *)0, "VtKeyParamDHSharedSecret", fnctLine, (char *)0)

  return (status);
}

static int VoltKeyGetDHSharedSecret (
   VtKeyObject object,
   Pointer *getInfo
   )
{
  int status;
  VoltKeyObject *obj = (VoltKeyObject *)object;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Is there data?
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_GET_INFO_UNAVAILABLE;
    if (obj->keyData == (Pointer)0)
      break;

    /* Is the algorithm DH?
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    if ((obj->keyType & VOLT_KEY_TYPE_MASK_ASYM_ALG) != VOLT_KEY_ALG_DH)
      break;

    /* Check the keyType in the object, if must contain
     * VOLT_KEY_TYPE_SHARED_SECRET.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    if ((obj->keyType & VOLT_KEY_TYPE_SHARED_SECRET) == 0)
      break;

    /* Is the key in data form?
     */
    if ((obj->keyType & VOLT_KEY_TYPE_MASK_DATA) != VOLT_KEY_TYPE_DATA)
    {
      /* The data is not available, does the object have a GetData
       * function?
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      *getInfo = (Pointer)0;
      if (obj->GetKeyData == (VGetKeyData)0)
        break;

      /* Call the Get function.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = obj->GetKeyData ((VtKeyObject)obj, getInfo);
      break;
    }

    *getInfo = obj->keyData;
    status = 0;

  } while (0);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, object, status, 0, errorType,
    (char *)0, "VoltKeyGetDHSharedSecret", fnctLine, (char *)0)

  return (status);
}

int VoltCloneDHSharedSecret (
   Pointer sourceObject,
   Pointer *destObject
   )
{
  int status;
  VoltKeyObject *obj = (VoltKeyObject *)sourceObject;
  VtKeyObject newKey = (VtKeyObject)0;
  VtItem *getInfo;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* We know the source is an object, is it a key object?
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_KEY_OBJ;
    if (VOLT_OBJECT_TYPE_NOT_EQUAL (sourceObject, VOLT_OBJECT_TYPE_KEY))
      break;

    /* Is the object a DH shared secret?
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_KEY_OBJ;
    if ((obj->keyType & VOLT_KEY_TYPE_MASK_ASYM_ALG) != VOLT_KEY_ALG_DH)
      break;
    if ((obj->keyType & VOLT_KEY_TYPE_SHARED_SECRET) == 0)
      break;

    /* Get the DH key data out of the source object.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtGetKeyParam (
      (VtKeyObject)obj, VtKeyParamDHSharedSecret, (Pointer *)&getInfo);
    if (status != 0)
      break;

    /* Create and set a key object with this data.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtCreateKeyObject (
      obj->voltObject.libraryCtx, VtKeyImplMpCtx, (Pointer)(obj->mpCtx),
      &newKey);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtSetKeyParam (
      newKey, VtKeyParamDHSharedSecret, (Pointer)getInfo);
    if (status != 0)
      break;

    /* If all that worked, we have our clone.
     */
    *destObject = (Pointer)newKey;

  } while (0);

  /* If successful, return 0.
   */
  if (status == 0)
    return (0);

  /* If there was an error, destroy anything we created.
   */
  VtDestroyKeyObject (&newKey);

  VOLT_LOG_ERROR_INFO (
    0, obj, status, 0, 0,
    (char *)0, "VoltCloneDHSharedSecret", fnctLine, (char *)0)

  return (status);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -