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

📄 writeenv.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 3 页
字号:
        break;
*/
      /* Currently, this code supports only block ciphers in CBC mode
       * with P5 padding. So this is how to compute outputLen.
       */
#if VT_64_BIT_LENGTH == 64
      encryptedDataLen = obj->dataLen64 / ((VtUInt64)(envCtx->blockSize));
#else
      encryptedDataLen = obj->dataLen / envCtx->blockSize;
#endif

      if (envCtx->blockSize != 1)
        encryptedDataLen++;

#if VT_64_BIT_LENGTH == 64
      encryptedDataLen *= (VtUInt64)(envCtx->blockSize);
#else
      encryptedDataLen *= envCtx->blockSize;
#endif

      /* Add in the total length of encrypted data so all other lengths
       * will be computed correctly. Then later on, subtract the amount
       * of encryptedData we will not output.
       */
#if VT_64_BIT_LENGTH == 64
      outputLen = (VtUInt64)VoltDetermineDerLengthLen (
        (UInt32)encryptedDataLen, (UInt32)(encryptedDataLen >> 32));
      outputLen += (1 + encryptedDataLen);
#else
      outputLen = VoltDetermineDerLengthLen (
        (UInt32)encryptedDataLen, (UInt32)0);
      outputLen += (1 + encryptedDataLen);
#endif

      /* Add in the symmetric encryption algID and the Data OID.
       * Don't add amounts twice.
       */
#if VT_64_BIT_LENGTH == 64
      encContentInfoLen =
        (VtUInt64)(envCtx->symEncryptorAlgId.len + VoltP7DataOidBytesLen + 2);
      encContentInfoLen += outputLen;
      outputLen = (VtUInt64)VoltDetermineDerLengthLen (
        (UInt32)encContentInfoLen, (UInt32)(encContentInfoLen >> 32));
      outputLen += encContentInfoLen + 1;
#else
      encContentInfoLen =
        outputLen + envCtx->symEncryptorAlgId.len + VoltP7DataOidBytesLen + 2;
      outputLen = VoltDetermineDerLengthLen (
        (UInt32)encContentInfoLen, (UInt32)0);
      outputLen += encContentInfoLen + 1;
#endif

      /* What is the SET OF for RecipientInfos going to be? Add in the
       * version.
       */
#if VT_64_BIT_LENGTH == 64
      outputLen += (VtUInt64)VoltDetermineDerLengthLen (
        (UInt32)(envCtx->totalRecipInfoLen), (UInt32)0);
      outputLen += (VtUInt64)(envCtx->totalRecipInfoLen + 4);
#else
      outputLen += VoltDetermineDerLengthLen (
        (UInt32)(envCtx->totalRecipInfoLen), (UInt32)0);
      outputLen += envCtx->totalRecipInfoLen + 4;
#endif

      /* Now add in the SEQUENCE that is the EnvelopedData.
       */
      seqLen = outputLen;
#if VT_64_BIT_LENGTH == 64
      outputLen += (VtUInt64)VoltDetermineDerLengthLen (
        (UInt32)outputLen, (UInt32)(outputLen >> 32));
#else
      outputLen += VoltDetermineDerLengthLen ((UInt32)outputLen, (UInt32)0);
#endif
      outputLen++;

      /* Next is the EXPLICIT.
       */
      expLen = outputLen;
#if VT_64_BIT_LENGTH == 64
      outputLen += (VtUInt64)VoltDetermineDerLengthLen (
        (UInt32)outputLen, (UInt32)(outputLen >> 32));
#else
      outputLen += VoltDetermineDerLengthLen ((UInt32)outputLen, (UInt32)0);
#endif
      outputLen++;

      /* Add in the EnvelopedData OID.
       */
      outputLen += VoltP7EnvDataOidBytesLen + 2;

      /* Now comes the overall SEQUENCE.
       */
      totalLen = outputLen;
#if VT_64_BIT_LENGTH == 64
      outputLen += (VtUInt64)VoltDetermineDerLengthLen (
        (UInt32)outputLen, (UInt32)(outputLen >> 32));
#else
      outputLen += VoltDetermineDerLengthLen ((UInt32)outputLen, (UInt32)0);
#endif
      outputLen++;

#if VT_64_BIT_LENGTH == 64
      /* Save the output len so we can return it if need be.
       */
      obj->outputLen64 = outputLen;
#endif

      /* If the actual inputLen is not the same as what the total input
       * len is going to be, subtract off the encryptedDataLen, then add
       * the actual inputLen.
       */
#if VT_64_BIT_LENGTH == 64
      if ((VtUInt64)inputDataLen != obj->dataLen64)
      {
        outputLen -= encryptedDataLen;

        index = inputDataLen / envCtx->blockSize;
        tempLen = index * envCtx->blockSize;

        outputLen += (VtUInt64)tempLen;

        VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VT_ERROR_INVALID_INPUT_LENGTH;
        if (outputLen > (VtUInt64)0xffffffff)
          break;
      }
      *messageLen = (UInt32)outputLen;
#else
      if (inputDataLen != obj->dataLen)
      {
        outputLen -= encryptedDataLen;

        index = inputDataLen / envCtx->blockSize;
        tempLen = index * envCtx->blockSize;

        outputLen += tempLen;
      }
      *messageLen = (UInt32)outputLen;
#endif

      /* Is the buffer big enough?
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_BUFFER_TOO_SMALL;
      if (bufferSize < outputLen)
        break;

      /* If the caller passed NULL input with non-zero inputLen, they
       * just wanted the length, don't process.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      if ( (inputData == (unsigned char *)0) && (inputDataLen != 0) )
        break;

      /* The buffer is big enough, write out the prefix.
       * First, the 30 len of the overall contentInfo.
       */
#if VT_64_BIT_LENGTH == 64
      offset = VoltWriteDerTagAndLen (
        message, 0x30, (UInt32)totalLen, (UInt32)(totalLen >> 32));
#else
      offset = VoltWriteDerTagAndLen (
        message, 0x30, (UInt32)totalLen, (UInt32)0);
#endif
      /* Write out the EnvelopedData OID.
       */
      offset += VoltWriteDerTagAndLen (
        message + offset, 0x06, (UInt32)VoltP7EnvDataOidBytesLen, (UInt32)0);
      Z2Memcpy (message + offset, envDataOid, VoltP7EnvDataOidBytesLen);
      offset += VoltP7EnvDataOidBytesLen;
      /* EXPLICIT and SEQUENCE
       */
#if VT_64_BIT_LENGTH == 64
      offset += VoltWriteDerTagAndLen (
        message + offset, 0xA0, (UInt32)expLen, (UInt32)(expLen >> 32));
      offset += VoltWriteDerTagAndLen (
        message + offset, 0x30, (UInt32)seqLen, (UInt32)(seqLen >> 32));
#else
      offset += VoltWriteDerTagAndLen (
        message + offset, 0xA0, (UInt32)expLen, (UInt32)0);
      offset += VoltWriteDerTagAndLen (
        message + offset, 0x30, (UInt32)seqLen, (UInt32)0);
#endif
      /* version (we support only version 0).
       */
      message[offset] = 0x02;
      offset++;
      message[offset] = 0x01;
      offset++;
      message[offset] = 0x00;
      offset++;
      /* SET OF.
       */
      offset += VoltWriteDerTagAndLen (
        message + offset, 0x31,
        (UInt32)(envCtx->totalRecipInfoLen), (UInt32)0);
      /* Write out each of the RecipientInfos.
       */
      for (index = 0; index < envCtx->recipientsCount; ++index)
      {
        if (envCtx->recipients[index].recipInfoLen == 0)
          continue;

        VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VT_ERROR_INVALID_INPUT;
        temp = message + offset;
        recipOutLen = i2d_Asn1RecipientInfo (
          envCtx->recipients[index].recipInfo, &temp);
        if (recipOutLen != envCtx->recipients[index].recipInfoLen)
          break;

        offset += recipOutLen;
        status = 0;
      }
      if (status != 0)
        break;

      /* Next is the EncryptedContentInfo.
       */
#if VT_64_BIT_LENGTH == 64
      offset += VoltWriteDerTagAndLen (
        message + offset, 0x30, (UInt32)encContentInfoLen,
        (UInt32)(encContentInfoLen >> 32));
#else
      offset += VoltWriteDerTagAndLen (
        message + offset, 0x30, (UInt32)encContentInfoLen, (UInt32)0);
#endif
      /* The OID of the data being encrypted: Data.
       */
      offset += VoltWriteDerTagAndLen (
        message + offset, 0x06, (UInt32)VoltP7DataOidBytesLen, (UInt32)0);
      Z2Memcpy (message + offset, dataOid, VoltP7DataOidBytesLen);
      offset += VoltP7DataOidBytesLen;
      /* The symmetric algorithm ID.
       */
      Z2Memcpy (
        message + offset, envCtx->symEncryptorAlgId.data,
        envCtx->symEncryptorAlgId.len);
      offset += envCtx->symEncryptorAlgId.len;
      /* EncryptedContent, IMPLICIT.
       */
#if VT_64_BIT_LENGTH == 64
      offset += VoltWriteDerTagAndLen (
        message + offset, 0x80, (UInt32)encryptedDataLen,
        (UInt32)(encryptedDataLen >> 32));
#else
      offset += VoltWriteDerTagAndLen (
        message + offset, 0x80, (UInt32)encryptedDataLen, (UInt32)0);
#endif
    }
    else if (obj->state == VOLT_P7_STATE_ENV_WRITE_UPDATE)
    {
      /* If Update, make sure the amount of input does not exceed the
       * dataLen.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_INPUT_LENGTH;
#if VT_64_BIT_LENGTH == 64
      if (((VtUInt64)inputDataLen + obj->inputLen64) > obj->dataLen64)
#else
      if ((inputDataLen + obj->inputLen) > obj->dataLen)
#endif
        break;

      /* Is the output buffer big enough?
       */
      *messageLen = 0;
      status = 0;
      if (inputDataLen == 0)
        break;

      tempLen = inputDataLen + envCtx->unprocessedDataLen;

      /* If this is the last of the input data, we'll call
       * EncryptFinal, if not, we'll call EncryptUpdate.
       */
#if VT_64_BIT_LENGTH == 64
      if (((VtUInt64)inputDataLen + obj->inputLen64) < obj->dataLen64)
#else
      if ((inputDataLen + obj->inputLen) < obj->dataLen)
#endif
      {
        /* For the moment, this does not work with NULL input, so
         * compute the required output size explicitly.
         */
/*        status = VtEncryptUpdate (
          envCtx->symEncryptor, random, (unsigned char *)0, inputDataLen,
          (unsigned char *)0, 0, &tempLen);
 */
        index = tempLen / envCtx->blockSize;
        tempLen = index * envCtx->blockSize;
        VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VT_ERROR_BUFFER_TOO_SMALL;
      }
      else
      {
        /* For the moment, this does not work with NULL input, so
         * compute the required output size explicitly.
         */
/*        status = VtEncryptFinal (
          envCtx->symEncryptor, random, inputData, inputDataLen,
          (unsigned char *)0, 0, &tempLen);
 */
        index = tempLen / envCtx->blockSize;
        if (envCtx->blockSize != 1)
          index++;
        tempLen = index * envCtx->blockSize;
        VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VT_ERROR_BUFFER_TOO_SMALL;
      }
      if (status == 0)
        status = VT_ERROR_GENERAL;
      if (status != VT_ERROR_BUFFER_TOO_SMALL)
        break;

      *messageLen = tempLen;
      if (bufferSize < tempLen)
        break;

      /* If the caller passed NULL input with non-zero inputLen, they
       * just wanted the length, don't process.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      if ( (inputData == (unsigned char *)0) && (inputDataLen != 0) )
        break;

      offset = 0;
    }
    else
    {
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_CALL_ORDER;
      break;
    }

    /* Encrypt the bytes given.
     */
#if VT_64_BIT_LENGTH == 64
    if (((VtUInt64)inputDataLen + obj->inputLen64) < obj->dataLen64)
#else
    if ((inputDataLen + obj->inputLen) < obj->dataLen)
#endif
    {
      /* For the moment we need to compute unprocessedDataLen. When we
       * fix the NULL input issue, we can get rid of this.
       */
      tempLen = inputDataLen + envCtx->unprocessedDataLen;
      index = tempLen / envCtx->blockSize;
      envCtx->unprocessedDataLen = tempLen - (index * envCtx->blockSize);
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtEncryptUpdate (
        envCtx->symEncryptor, random, inputData, inputDataLen,
        message + offset, bufferSize - offset, &tempLen);
    }
    else
    {
      envCtx->unprocessedDataLen = 0;
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtEncryptFinal (
        envCtx->symEncryptor, random, inputData, inputDataLen,
        message + offset, bufferSize - offset, &tempLen);
    }
    if (status != 0)
      break;

#if VT_64_BIT_LENGTH == 64
    obj->inputLen64 += (VtUInt64)inputDataLen;
#else
    obj->inputLen += inputDataLen;
#endif

    obj->state = VOLT_P7_STATE_ENV_WRITE_UPDATE;

  } while (0);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, pkcs7Obj, status, 0, errorType,
    (char *)0, "VoltP7EnvWriteUpdate", fnctLine, (char *)0)

  return (status);
}

int VoltP7EnvWriteFinal (
   VtPkcs7Object pkcs7Obj,
   VtRandomObject random,
   unsigned char *inputData,
   unsigned int inputDataLen,
   unsigned char *message,
   unsigned int bufferSize,
   unsigned int *messageLen
   )
{
  int status;
  VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  *messageLen = 0;

  do
  {
    /* If there's no "predicted" len yet, the input len from this call
     * is that length.
     */
#if VT_64_BIT_LENGTH == 64
    if (obj->dataLen64 == 0)
      obj->dataLen64 = (VtUInt64)inputDataLen;
#else
    if (obj->dataLen == 0)
      obj->dataLen = inputDataLen;
#endif

⌨️ 快捷键说明

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