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

📄 rsa.c

📁 xen 3.2.2 源码
💻 C
字号:
// ===================================================================// // Copyright (c) 2005, Intel Corp.// All rights reserved.//// Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met:////   * Redistributions of source code must retain the above copyright //     notice, this list of conditions and the following disclaimer.//   * Redistributions in binary form must reproduce the above //     copyright notice, this list of conditions and the following //     disclaimer in the documentation and/or other materials provided //     with the distribution.//   * Neither the name of Intel Corporation nor the names of its //     contributors may be used to endorse or promote products derived//     from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED// OF THE POSSIBILITY OF SUCH DAMAGE.// ===================================================================// // rsa.c// //  This file will handle all the TPM RSA crypto functionality// // ==================================================================#include <string.h>#include <openssl/crypto.h>#include <openssl/evp.h>#include <openssl/bn.h>#include <openssl/rsa.h>#include <openssl/rand.h>#include <openssl/x509.h>#include <openssl/err.h>#include <stdio.h>#include "tcg.h"#include "buffer.h"#include "crypto.h"#include "log.h"void Crypto_RSACreateKey(   /*in*/ UINT32 keySize,                            /*in*/ UINT32 pubExpSize,                             /*in*/ BYTE *pubExp,                            /*out*/ UINT32 *privExpSize,                             /*out*/ BYTE *privExp,                            /*out*/ UINT32 *modulusSize,                                    /*out*/ BYTE *modulus,                            /*out*/ CRYPTO_INFO *keys) {  unsigned long e_value;    if (pubExpSize == 0) // Default e = 2^16+1    e_value = (0x01 << 16) + 1;  else {    // This is not supported, but the following line MIGHT work    // under then assumption that the format is BigNum compatable    // Though it's not in the spec, so who knows what it is.    // Forcing the default.    //BN_bin2bn(pubExp, pubExpSize, NULL);    e_value = (0x01 << 16) + 1;  }  RSA *rsa = RSA_generate_key(keySize, e_value, NULL, NULL);    if (keys) {    keys->keyInfo = rsa;    keys->algorithmID = CRYPTO_ALGORITH_RSA;  }    if (modulus)   *modulusSize   = BN_bn2bin(rsa->n, modulus);  if (privExp)   *privExpSize   = BN_bn2bin(rsa->d, privExp);}// Create a CRYPTO_INFO struct from the BYTE * key parts. // If pubExp info is NULL, use TCG default.// If there is a remainder while calculating the privExp, return FALSE.void Crypto_RSABuildCryptoInfo( /*[IN]*/ UINT32 pubExpSize,                                 /*[IN]*/ BYTE *pubExp,                                /*[IN]*/ UINT32 privExpSize,                                 /*[IN]*/ BYTE *privExp,                                /*[IN]*/ UINT32 modulusSize,                                 /*[IN]*/ BYTE *modulus,                                 CRYPTO_INFO* cryptoInfo) {  cryptoInfo->keyInfo = RSA_new();  RSA *rsa = (RSA *) cryptoInfo->keyInfo;    rsa->e = BN_new();    if (pubExpSize == 0) { // Default e = 2^16+1    BN_set_bit(rsa->e, 16);    BN_set_bit(rsa->e, 0);  } else {    // This is not supported, but the following line MIGHT work    // under then assumption that the format is BigNum compatable    // Though it's not in the spec, so who knows what it is.    // Forcing the default.    //BN_bin2bn(pubExp, pubExpSize, NULL);    BN_set_bit(rsa->e, 16);    BN_set_bit(rsa->e, 0);  }    rsa->n = BN_bin2bn(modulus, modulusSize, NULL);  rsa->d = BN_bin2bn(privExp, privExpSize, NULL);}// Create a CRYPTO_INFO struct from the BYTE * key parts. // If pubExp info is NULL, use TCG default.// If there is a remainder while calculating the privExp, return FALSE.void Crypto_RSABuildCryptoInfoPublic(   /*[IN]*/ UINT32 pubExpSize,                                         /*[IN]*/ BYTE *pubExp,                                        /*[IN]*/ UINT32 modulusSize,                                         /*[IN]*/ BYTE *modulus,                                         CRYPTO_INFO* cryptoInfo) {  cryptoInfo->keyInfo = RSA_new();  RSA *rsa = (RSA *) cryptoInfo->keyInfo;    rsa->e = BN_new();    if (pubExpSize == 0) { // Default e = 2^16+1    BN_set_bit(rsa->e, 16);    BN_set_bit(rsa->e, 0);  } else {    // This is not supported, but the following line MIGHT work    // under then assumption that the format is BigNum compatable    // Though it's not in the spec, so who knows what it is.    // Forcing the default.    //BN_bin2bn(pubExp, pubExpSize, NULL);    BN_set_bit(rsa->e, 16);    BN_set_bit(rsa->e, 0);  }    rsa->n = BN_bin2bn(modulus, modulusSize, NULL);  }int Crypto_RSAEnc(  CRYPTO_INFO *key,		    UINT32 inDataSize,		    BYTE *inData,		    /*out*/ UINT32 *outDataSize,		    /*out*/ BYTE *outData) {  RSA *rsa = (RSA *) key->keyInfo;  UINT32 paddedDataSize = RSA_size (rsa);  BYTE *paddedData = (BYTE *)malloc(sizeof(BYTE) * paddedDataSize);  int rc;      if (paddedData == NULL)     return -1;  *outDataSize = 0;    switch (key->encScheme) {  case CRYPTO_ES_RSAESPKCSv15:    if (RSA_padding_add_PKCS1_type_2(paddedData, paddedDataSize, inData, inDataSize) <= 0) {      rc = -1;       goto abort_egress;    }    break;  case CRYPTO_ES_RSAESOAEP_SHA1_MGF1:    if (RSA_padding_add_PKCS1_OAEP(paddedData,paddedDataSize,inData,inDataSize, (BYTE *) OAEP_P,OAEP_P_SIZE) <= 0 ) {      rc = -1;       goto abort_egress;    }    break;  default:    rc = -1;     goto abort_egress;  }    rc = RSA_public_encrypt(paddedDataSize, paddedData, outData, rsa, RSA_NO_PADDING);  if (rc == -1)    goto abort_egress;      *outDataSize = rc;    if (rc > 0) rc = 0;    goto egress;   abort_egress: egress:    if (paddedData)     free (paddedData);  return rc;  }int Crypto_RSADec(  CRYPTO_INFO *key,                    UINT32 inDataSize,                    BYTE *inData,                    /*out*/ UINT32 *outDataSize,                    /*out*/ BYTE *outData) {    RSA *rsa = (RSA *) key->keyInfo;  UINT32 paddedDataSize = RSA_size (rsa);  BYTE *paddedData = (BYTE *)malloc(sizeof(BYTE) * paddedDataSize);  int rc;    if (paddedData == NULL)    goto abort_egress;    rc = RSA_private_decrypt(inDataSize, inData, paddedData, rsa, RSA_NO_PADDING);  if (rc == -1) {    vtpmlogerror(VTPM_LOG_CRYPTO, "RSA_private_decrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));    goto abort_egress;  }    paddedDataSize = rc;    switch (key->encScheme) {  case CRYPTO_ES_RSAESPKCSv15:    rc = RSA_padding_check_PKCS1_type_2 (outData, paddedDataSize,					 paddedData + 1, paddedDataSize - 1,					 RSA_size(rsa));    if (rc == -1) {      vtpmlogerror(VTPM_LOG_CRYPTO, "RSA_padding_check_PKCS1_type_2: %s\n", 	      ERR_error_string(ERR_get_error(), NULL));      goto abort_egress;    }    *outDataSize = rc;    break;  case CRYPTO_ES_RSAESOAEP_SHA1_MGF1:    rc = RSA_padding_check_PKCS1_OAEP(outData, paddedDataSize,				      paddedData + 1, paddedDataSize - 1,				      RSA_size(rsa),				      (BYTE *) OAEP_P, OAEP_P_SIZE);    if (rc == -1) {      vtpmlogerror(VTPM_LOG_CRYPTO, "RSA_padding_check_PKCS1_OAEP: %s\n",	      ERR_error_string(ERR_get_error(), NULL));      goto abort_egress;    }    *outDataSize = rc;    break;  default:    *outDataSize = 0;  }    free(paddedData); paddedData = NULL;  goto egress;   abort_egress:    if (paddedData)     free (paddedData);  return -1;   egress:  return 0;}// Signs either a SHA1 digest of a message or a DER encoding of a message// Textual messages MUST be encoded or Hashed before sending into this function// It will NOT SHA the message.int Crypto_RSASign( CRYPTO_INFO *key,                    UINT32 inDataSize,                    BYTE *inData,                    /*out*/ UINT32 *sigSize,                    /*out*/ BYTE *sig) {  int status;  unsigned int intSigSize;    switch(key->sigScheme) {  case CRYPTO_SS_RSASSAPKCS1v15_SHA1:     status = RSA_sign(NID_sha1, inData, inDataSize, sig, &intSigSize, (RSA *) key->keyInfo);    break;  case CRYPTO_SS_RSASSAPKCS1v15_DER:    //        status = Crypto_RSA_sign_DER(NID_md5_sha1, inData, inDataSize, sig, &intSigSize, key);    vtpmlogerror(VTPM_LOG_CRYPTO, "Crypto: Unimplemented sign type (%d)\n", key->sigScheme);    status = 0;    break;  default:    status = 0;  }    if (status == 0) {    *sigSize = 0;    vtpmlogerror(VTPM_LOG_CRYPTO, "%s\n", ERR_error_string(ERR_get_error(), NULL));    return -1;  }    *sigSize = (UINT32) intSigSize;  return 0;}bool Crypto_RSAVerify(  CRYPTO_INFO *key,                        UINT32 inDataSize,                        BYTE *inData,                        UINT32 sigSize,                        BYTE *sig) {  int status;    switch(key->sigScheme){  case CRYPTO_SS_RSASSAPKCS1v15_SHA1:     status = RSA_verify(NID_sha1, inData, inDataSize, sig, sigSize, (RSA *) key->keyInfo);    break;  case CRYPTO_SS_RSASSAPKCS1v15_DER:    //status = Crypto_RSA_verify_DER(NID_md5_sha1, inData, inDataSize, sig, sigSize, key);    vtpmlogerror(VTPM_LOG_CRYPTO, "Crypto: Unimplemented sign type (%d)\n", key->sigScheme);    status = 0;    break;  default:    status = 0;  }    if (status)     return(1);  else {    vtpmlogerror(VTPM_LOG_CRYPTO, "RSA verify: %s\n", ERR_error_string(ERR_get_error(), NULL));    return(0);  }  }// helper which packs everything into a BIO!// packs the parameters first, then the private key, then the public key// if *io_buf is NULL, allocate it here as needed. otherwise its size is in// *io_buflenTPM_RESULT Crypto_RSAPackCryptoInfo (const CRYPTO_INFO* cryptoInfo,                                      BYTE ** io_buf, UINT32 * io_buflen) {  TPM_RESULT status = TPM_SUCCESS;  BYTE * buf;  long len, outlen = *io_buflen;    const long PARAMSLEN = 3*sizeof(UINT32);    RSA *rsa = (RSA *) cryptoInfo->keyInfo;    BIO *mem = BIO_new(BIO_s_mem());      // write the openssl keys to the BIO  if ( i2d_RSAPrivateKey_bio (mem, rsa) == 0 ) {    ERR_print_errors_fp (stderr);    ERRORDIE (TPM_SIZE);  }  if ( i2d_RSAPublicKey_bio (mem, rsa) == 0 ) {    ERR_print_errors_fp (stderr);    ERRORDIE (TPM_SIZE);  }    // get the buffer out  len = BIO_get_mem_data (mem, &buf);    // see if we need to allocate a return buffer  if (*io_buf == NULL) {    *io_buf = (BYTE*) malloc (PARAMSLEN + len);    if (*io_buf == NULL)       ERRORDIE (TPM_SIZE);  } else {                      // *io_buf is already allocated    if (outlen < len + PARAMSLEN)       ERRORDIE (TPM_SIZE); // but not large enough!    }    // copy over the parameters (three UINT32's starting at algorithmID)  memcpy (*io_buf, &cryptoInfo->algorithmID, PARAMSLEN);    // copy over the DER keys  memcpy (*io_buf + PARAMSLEN, buf, len);    *io_buflen = len + PARAMSLEN;    goto egress;     abort_egress: egress:    BIO_free (mem);    return status;}// sets up ci, and returns the number of bytes read in o_lenreadTPM_RESULT Crypto_RSAUnpackCryptoInfo (CRYPTO_INFO * ci,                                        BYTE * in, UINT32 len,                                        UINT32 * o_lenread) {    TPM_RESULT status = TPM_SUCCESS;  long l;  BIO *mem;  RSA *rsa;    // first load up the params  l = 3 * sizeof(UINT32);  memcpy (&ci->algorithmID, in, l);  len -= l;  in += l;    // and now the openssl keys, private first  mem = BIO_new_mem_buf (in, len);    if ( (rsa = d2i_RSAPrivateKey_bio (mem, NULL)) == NULL ) {    ERR_print_errors_fp (stderr);    ERRORDIE (TPM_BAD_PARAMETER);  }  // now use the same RSA object and fill in the private key  if ( d2i_RSAPublicKey_bio (mem, &rsa) == NULL ) {    ERR_print_errors_fp (stderr);    ERRORDIE (TPM_BAD_PARAMETER);  }    ci->keyInfo = rsa;          // needs to be freed somehow later    // FIXME: havent figured out yet how to tell how many bytes were read in the  // above oprations! so o_lenread is not set    goto egress;   abort_egress: egress:    BIO_free (mem);   return status;  }

⌨️ 快捷键说明

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