diff options
author | Arun kumar Sekar <arunkumarsit@gmail.com> | 2018-03-30 11:20:30 -0700 |
---|---|---|
committer | Arun kumar sekar <arunkumarsit@gmail.com> | 2018-04-03 21:14:48 +0000 |
commit | 2ac563372735668ac9687c57e35e39c3e4553ff0 (patch) | |
tree | 4f276f8feba53a700f73a4aa9f2f55187444dff5 /tpm-util/duplicate/crypto_aux.c | |
parent | 3d5e48d877919ec8d33e1d1ee3682fb1f0bc0532 (diff) |
Utility to Import external RSA pem key into TPM
Duplicate tool - Takes RSA private key in
pem format as input and generates
TPM structured buffers as expected by tpm Import
Import tool - Takes input buffers from
Duplicate tool and results in pub/priv blobs
which can be used to load the key in tpm
storage heirarchy's as child to primary key
Change-Id: I0af6676895ce0cc22c70e5546908e905b78bb71e
Issue-ID: AAF-207
Signed-off-by: Arun kumar Sekar <arunkumarsit@gmail.com>
Diffstat (limited to 'tpm-util/duplicate/crypto_aux.c')
-rw-r--r-- | tpm-util/duplicate/crypto_aux.c | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/tpm-util/duplicate/crypto_aux.c b/tpm-util/duplicate/crypto_aux.c new file mode 100644 index 0000000..2737ded --- /dev/null +++ b/tpm-util/duplicate/crypto_aux.c @@ -0,0 +1,254 @@ +/* + * Copyright 2018 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Author: Arun Kumar Sekar + +#include "crypto_aux.h" +#include "util.h" + +UINT32 (*HmacFunctionPtr)( TPMI_ALG_HASH hashAlg, TPM2B *key,TPM2B **bufferList, TPM2B_DIGEST *result ) = OpenSslHmac; + + +int RSA_OAEP_Enc(TPM2B_PUBLIC_KEY_RSA *plain, // plain text to encrypt + //Size of plain (0 <= pl <= kl - (2 * hashLen + 2) + TPM2B_PUBLIC_KEY_RSA *cipher, // must be same size as key in bytes + TPM2B_PUBLIC_KEY_RSA *key, // Key in big endian byte array + TPM2B_DATA *encoding_params // Null terminated string like + // ((unsigned char*)"DUPLICATE") + // length of encoding parameter includes \0 + // (10 in DUPLICATE case..) + ) +{ + RSA *rsa = NULL; + unsigned char encoded[256]; + int RC; + BIGNUM* bne; + BIGNUM* n; + + //Encoding + RC = RSA_padding_add_PKCS1_OAEP_mgf1(encoded, key->b.size, plain->b.buffer, plain->b.size, + encoding_params->b.buffer, encoding_params->b.size, EVP_sha256(), NULL); + + if(RC!=1)goto cleanup; + + // Creating OpenSSL structure with the supplied TPM public: + bne = BN_new(); + RC = BN_set_word(bne,RSA_F4); // the TPM's public exponent (2^16 + 1) + if(RC!=1)goto cleanup; + + rsa = RSA_new(); + RC = RSA_generate_key_ex(rsa, 2048, bne, NULL); // could be done in better way i guess... just for filling up fields.. + if(RC!=1)goto cleanup; + + // Over-writing the public N: + //rsa->n = BN_bin2bn(key->b.buffer, key->b.size, rsa->n); + n = BN_bin2bn(key->b.buffer, key->b.size, NULL); + RSA_set0_key(rsa,n,NULL, NULL); + + //if(rsa->n == NULL) goto cleanup; + if(n == NULL) goto cleanup; + + // Encrypting + RC = RSA_public_encrypt(key->b.size, encoded, cipher->b.buffer, rsa, RSA_NO_PADDING); + + //if(RC<0)goto cleanup; + cipher->b.size = key->b.size; + +cleanup: + RSA_free(rsa); + BN_free(bne); + return RC; +} + + + +void AES_128_CFB_enc_dec( + TPM2B *in, + TPM2B *out, + const TPM2B *const key, + const TPM2B *const ivIn, + TPM2B *ivOut, + const TPMI_YES_NO enc) +{ + TPM2B_SYM_KEY ivTemp = {{0}}; + ivTemp.b.size = 16; + + if(ivOut == NULL) + ivOut = &(ivTemp.b); + + memccpy(ivOut->buffer, ivIn->buffer, 0, ivIn->size); + AES_KEY aes; + AES_set_encrypt_key(key->buffer, 128, &aes); + int block, j; + for(block=0; block < (in->size) ;block+=16) + { + unsigned char encIV[16]; + AES_encrypt(ivOut->buffer, encIV, &aes); + + for(j=0;j<16;j++) + { + if(j+block >= (in->size)) + ivOut->buffer[j]=0; + else if(enc) + ivOut->buffer[j] = out->buffer[block+j] = encIV[j]^(in->buffer[block+j]); + else + { + ivOut->buffer[j] = in->buffer[block+j]; + out->buffer[block+j] = encIV[j]^(in->buffer[block+j]); + } + } + } + out->size = in->size; + +} + + +UINT32 ChangeEndianDword( UINT32 p ) +{ + return( ((const UINT32)(((p)& 0xFF) << 24)) | \ + ((const UINT32)(((p)& 0xFF00) << 8)) | \ + ((const UINT32)(((p)& 0xFF0000) >> 8)) | \ + ((const UINT32)(((p)& 0xFF000000) >> 24))); +} + + +TPM_RC KDFa( TPMI_ALG_HASH hashAlg, TPM2B *key, char *label, + TPM2B *contextU, TPM2B *contextV, UINT16 bits, TPM2B_MAX_BUFFER *resultKey ) +{ + + TPM2B_DIGEST tmpResult; + TPM2B_DIGEST tpm2bLabel, tpm2bBits, tpm2b_i_2; + UINT8 *tpm2bBitsPtr = &tpm2bBits.t.buffer[0]; + UINT8 *tpm2b_i_2Ptr = &tpm2b_i_2.t.buffer[0]; + TPM2B_DIGEST *bufferList[8]; + UINT32 bitsSwizzled, i_Swizzled; + TPM_RC rval; + int i, j; + UINT16 bytes = bits / 8; + +#ifdef DEBUG + DebugPrintf( 0, "KDFA, hashAlg = %4.4x\n", hashAlg ); + DebugPrintf( 0, "\n\nKDFA, key = \n" ); + PrintSizedBuffer( key ); +#endif + + resultKey->t .size = 0; + + tpm2b_i_2.t.size = 4; + + tpm2bBits.t.size = 4; + bitsSwizzled = ChangeEndianDword( bits ); + *(UINT32 *)tpm2bBitsPtr = bitsSwizzled; + + for(i = 0; label[i] != 0 ;i++ ); + + tpm2bLabel.t.size = i+1; + for( i = 0; i < tpm2bLabel.t.size; i++ ) + { + tpm2bLabel.t.buffer[i] = label[i]; + } + +#ifdef DEBUG + DebugPrintf( 0, "\n\nKDFA, tpm2bLabel = \n" ); + PrintSizedBuffer( (TPM2B *)&tpm2bLabel ); + + DebugPrintf( 0, "\n\nKDFA, contextU = \n" ); + PrintSizedBuffer( contextU ); + + DebugPrintf( 0, "\n\nKDFA, contextV = \n" ); + PrintSizedBuffer( contextV ); +#endif + + resultKey->t.size = 0; + + i = 1; + + while( resultKey->t.size < bytes ) + { + // Inner loop + + i_Swizzled = ChangeEndianDword( i ); + *(UINT32 *)tpm2b_i_2Ptr = i_Swizzled; + + j = 0; + bufferList[j++] = (TPM2B_DIGEST *)&(tpm2b_i_2.b); + bufferList[j++] = (TPM2B_DIGEST *)&(tpm2bLabel.b); + bufferList[j++] = (TPM2B_DIGEST *)contextU; + bufferList[j++] = (TPM2B_DIGEST *)contextV; + bufferList[j++] = (TPM2B_DIGEST *)&(tpm2bBits.b); + bufferList[j++] = (TPM2B_DIGEST *)0; +#ifdef DEBUG + for( j = 0; bufferList[j] != 0; j++ ) + { + DebugPrintf( 0, "\n\nbufferlist[%d]:\n", j ); + PrintSizedBuffer( &( bufferList[j]->b ) ); + } +#endif + rval = (*HmacFunctionPtr )( hashAlg, key, (TPM2B **)&( bufferList[0] ), &tmpResult ); + if( rval != TPM_RC_SUCCESS ) + { + return( rval ); + } + + ConcatSizedByteBuffer( resultKey, &(tmpResult.b) ); + } + + // Truncate the result to the desired size. + resultKey->t.size = bytes; + +#ifdef DEBUG + DebugPrintf( 0, "\n\nKDFA, resultKey = \n" ); + PrintSizedBuffer( &( resultKey->b ) ); +#endif + + return TPM_RC_SUCCESS; +} + + +UINT32 OpenSslHmac( TPMI_ALG_HASH hashAlg, TPM2B *key,TPM2B **bufferList, TPM2B_DIGEST *result ) +{ + if(hashAlg != TPM_ALG_SHA256)return -1; + + UINT32 RC = 0; + HMAC_CTX *hmac = HMAC_CTX_new(); + UINT32 resLen=0; + + int i=0; + + HMAC_Init_ex(hmac, key->buffer, key->size, EVP_sha256(), NULL); + + for(i=0;bufferList[i];i++) + { + HMAC_Update(hmac, bufferList[i]->buffer, bufferList[i]->size); + } + + HMAC_Final(hmac, result->b.buffer, &resLen); + result->b.size = resLen; + + HMAC_CTX_free(hmac); + + return RC; +} + +void print_buff(char * data, int len, const PBYTE buff) +{ + printf("%s \n",data); + int i = 0; + for(;i<len;i++) + printf("0x%02X, ", buff[i]); + printf("\n"); + +} + |