Arun kumar Sekar | 2ac5633 | 2018-03-30 11:20:30 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2018 Intel Corporation |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | // Author: Arun Kumar Sekar |
| 17 | |
| 18 | #include "crypto_aux.h" |
| 19 | #include "util.h" |
| 20 | |
| 21 | UINT32 (*HmacFunctionPtr)( TPMI_ALG_HASH hashAlg, TPM2B *key,TPM2B **bufferList, TPM2B_DIGEST *result ) = OpenSslHmac; |
| 22 | |
| 23 | |
| 24 | int RSA_OAEP_Enc(TPM2B_PUBLIC_KEY_RSA *plain, // plain text to encrypt |
| 25 | //Size of plain (0 <= pl <= kl - (2 * hashLen + 2) |
| 26 | TPM2B_PUBLIC_KEY_RSA *cipher, // must be same size as key in bytes |
| 27 | TPM2B_PUBLIC_KEY_RSA *key, // Key in big endian byte array |
| 28 | TPM2B_DATA *encoding_params // Null terminated string like |
| 29 | // ((unsigned char*)"DUPLICATE") |
| 30 | // length of encoding parameter includes \0 |
| 31 | // (10 in DUPLICATE case..) |
| 32 | ) |
| 33 | { |
| 34 | RSA *rsa = NULL; |
| 35 | unsigned char encoded[256]; |
| 36 | int RC; |
| 37 | BIGNUM* bne; |
| 38 | BIGNUM* n; |
| 39 | |
| 40 | //Encoding |
| 41 | RC = RSA_padding_add_PKCS1_OAEP_mgf1(encoded, key->b.size, plain->b.buffer, plain->b.size, |
| 42 | encoding_params->b.buffer, encoding_params->b.size, EVP_sha256(), NULL); |
| 43 | |
| 44 | if(RC!=1)goto cleanup; |
| 45 | |
| 46 | // Creating OpenSSL structure with the supplied TPM public: |
| 47 | bne = BN_new(); |
| 48 | RC = BN_set_word(bne,RSA_F4); // the TPM's public exponent (2^16 + 1) |
| 49 | if(RC!=1)goto cleanup; |
| 50 | |
| 51 | rsa = RSA_new(); |
| 52 | RC = RSA_generate_key_ex(rsa, 2048, bne, NULL); // could be done in better way i guess... just for filling up fields.. |
| 53 | if(RC!=1)goto cleanup; |
| 54 | |
| 55 | // Over-writing the public N: |
| 56 | //rsa->n = BN_bin2bn(key->b.buffer, key->b.size, rsa->n); |
| 57 | n = BN_bin2bn(key->b.buffer, key->b.size, NULL); |
| 58 | RSA_set0_key(rsa,n,NULL, NULL); |
| 59 | |
| 60 | //if(rsa->n == NULL) goto cleanup; |
| 61 | if(n == NULL) goto cleanup; |
| 62 | |
| 63 | // Encrypting |
| 64 | RC = RSA_public_encrypt(key->b.size, encoded, cipher->b.buffer, rsa, RSA_NO_PADDING); |
| 65 | |
| 66 | //if(RC<0)goto cleanup; |
| 67 | cipher->b.size = key->b.size; |
| 68 | |
| 69 | cleanup: |
| 70 | RSA_free(rsa); |
| 71 | BN_free(bne); |
| 72 | return RC; |
| 73 | } |
| 74 | |
| 75 | |
| 76 | |
| 77 | void AES_128_CFB_enc_dec( |
| 78 | TPM2B *in, |
| 79 | TPM2B *out, |
| 80 | const TPM2B *const key, |
| 81 | const TPM2B *const ivIn, |
| 82 | TPM2B *ivOut, |
| 83 | const TPMI_YES_NO enc) |
| 84 | { |
| 85 | TPM2B_SYM_KEY ivTemp = {{0}}; |
| 86 | ivTemp.b.size = 16; |
| 87 | |
| 88 | if(ivOut == NULL) |
| 89 | ivOut = &(ivTemp.b); |
| 90 | |
| 91 | memccpy(ivOut->buffer, ivIn->buffer, 0, ivIn->size); |
| 92 | AES_KEY aes; |
| 93 | AES_set_encrypt_key(key->buffer, 128, &aes); |
| 94 | int block, j; |
| 95 | for(block=0; block < (in->size) ;block+=16) |
| 96 | { |
| 97 | unsigned char encIV[16]; |
| 98 | AES_encrypt(ivOut->buffer, encIV, &aes); |
| 99 | |
| 100 | for(j=0;j<16;j++) |
| 101 | { |
| 102 | if(j+block >= (in->size)) |
| 103 | ivOut->buffer[j]=0; |
| 104 | else if(enc) |
| 105 | ivOut->buffer[j] = out->buffer[block+j] = encIV[j]^(in->buffer[block+j]); |
| 106 | else |
| 107 | { |
| 108 | ivOut->buffer[j] = in->buffer[block+j]; |
| 109 | out->buffer[block+j] = encIV[j]^(in->buffer[block+j]); |
| 110 | } |
| 111 | } |
| 112 | } |
| 113 | out->size = in->size; |
| 114 | |
| 115 | } |
| 116 | |
| 117 | |
| 118 | UINT32 ChangeEndianDword( UINT32 p ) |
| 119 | { |
| 120 | return( ((const UINT32)(((p)& 0xFF) << 24)) | \ |
| 121 | ((const UINT32)(((p)& 0xFF00) << 8)) | \ |
| 122 | ((const UINT32)(((p)& 0xFF0000) >> 8)) | \ |
| 123 | ((const UINT32)(((p)& 0xFF000000) >> 24))); |
| 124 | } |
| 125 | |
| 126 | |
| 127 | TPM_RC KDFa( TPMI_ALG_HASH hashAlg, TPM2B *key, char *label, |
| 128 | TPM2B *contextU, TPM2B *contextV, UINT16 bits, TPM2B_MAX_BUFFER *resultKey ) |
| 129 | { |
| 130 | |
| 131 | TPM2B_DIGEST tmpResult; |
| 132 | TPM2B_DIGEST tpm2bLabel, tpm2bBits, tpm2b_i_2; |
| 133 | UINT8 *tpm2bBitsPtr = &tpm2bBits.t.buffer[0]; |
| 134 | UINT8 *tpm2b_i_2Ptr = &tpm2b_i_2.t.buffer[0]; |
| 135 | TPM2B_DIGEST *bufferList[8]; |
| 136 | UINT32 bitsSwizzled, i_Swizzled; |
| 137 | TPM_RC rval; |
| 138 | int i, j; |
| 139 | UINT16 bytes = bits / 8; |
| 140 | |
| 141 | #ifdef DEBUG |
| 142 | DebugPrintf( 0, "KDFA, hashAlg = %4.4x\n", hashAlg ); |
| 143 | DebugPrintf( 0, "\n\nKDFA, key = \n" ); |
| 144 | PrintSizedBuffer( key ); |
| 145 | #endif |
| 146 | |
| 147 | resultKey->t .size = 0; |
| 148 | |
| 149 | tpm2b_i_2.t.size = 4; |
| 150 | |
| 151 | tpm2bBits.t.size = 4; |
| 152 | bitsSwizzled = ChangeEndianDword( bits ); |
| 153 | *(UINT32 *)tpm2bBitsPtr = bitsSwizzled; |
| 154 | |
| 155 | for(i = 0; label[i] != 0 ;i++ ); |
| 156 | |
| 157 | tpm2bLabel.t.size = i+1; |
| 158 | for( i = 0; i < tpm2bLabel.t.size; i++ ) |
| 159 | { |
| 160 | tpm2bLabel.t.buffer[i] = label[i]; |
| 161 | } |
| 162 | |
| 163 | #ifdef DEBUG |
| 164 | DebugPrintf( 0, "\n\nKDFA, tpm2bLabel = \n" ); |
| 165 | PrintSizedBuffer( (TPM2B *)&tpm2bLabel ); |
| 166 | |
| 167 | DebugPrintf( 0, "\n\nKDFA, contextU = \n" ); |
| 168 | PrintSizedBuffer( contextU ); |
| 169 | |
| 170 | DebugPrintf( 0, "\n\nKDFA, contextV = \n" ); |
| 171 | PrintSizedBuffer( contextV ); |
| 172 | #endif |
| 173 | |
| 174 | resultKey->t.size = 0; |
| 175 | |
| 176 | i = 1; |
| 177 | |
| 178 | while( resultKey->t.size < bytes ) |
| 179 | { |
| 180 | // Inner loop |
| 181 | |
| 182 | i_Swizzled = ChangeEndianDword( i ); |
| 183 | *(UINT32 *)tpm2b_i_2Ptr = i_Swizzled; |
| 184 | |
| 185 | j = 0; |
| 186 | bufferList[j++] = (TPM2B_DIGEST *)&(tpm2b_i_2.b); |
| 187 | bufferList[j++] = (TPM2B_DIGEST *)&(tpm2bLabel.b); |
| 188 | bufferList[j++] = (TPM2B_DIGEST *)contextU; |
| 189 | bufferList[j++] = (TPM2B_DIGEST *)contextV; |
| 190 | bufferList[j++] = (TPM2B_DIGEST *)&(tpm2bBits.b); |
| 191 | bufferList[j++] = (TPM2B_DIGEST *)0; |
| 192 | #ifdef DEBUG |
| 193 | for( j = 0; bufferList[j] != 0; j++ ) |
| 194 | { |
| 195 | DebugPrintf( 0, "\n\nbufferlist[%d]:\n", j ); |
| 196 | PrintSizedBuffer( &( bufferList[j]->b ) ); |
| 197 | } |
| 198 | #endif |
| 199 | rval = (*HmacFunctionPtr )( hashAlg, key, (TPM2B **)&( bufferList[0] ), &tmpResult ); |
| 200 | if( rval != TPM_RC_SUCCESS ) |
| 201 | { |
| 202 | return( rval ); |
| 203 | } |
| 204 | |
| 205 | ConcatSizedByteBuffer( resultKey, &(tmpResult.b) ); |
| 206 | } |
| 207 | |
| 208 | // Truncate the result to the desired size. |
| 209 | resultKey->t.size = bytes; |
| 210 | |
| 211 | #ifdef DEBUG |
| 212 | DebugPrintf( 0, "\n\nKDFA, resultKey = \n" ); |
| 213 | PrintSizedBuffer( &( resultKey->b ) ); |
| 214 | #endif |
| 215 | |
| 216 | return TPM_RC_SUCCESS; |
| 217 | } |
| 218 | |
| 219 | |
| 220 | UINT32 OpenSslHmac( TPMI_ALG_HASH hashAlg, TPM2B *key,TPM2B **bufferList, TPM2B_DIGEST *result ) |
| 221 | { |
| 222 | if(hashAlg != TPM_ALG_SHA256)return -1; |
| 223 | |
| 224 | UINT32 RC = 0; |
| 225 | HMAC_CTX *hmac = HMAC_CTX_new(); |
| 226 | UINT32 resLen=0; |
| 227 | |
| 228 | int i=0; |
| 229 | |
| 230 | HMAC_Init_ex(hmac, key->buffer, key->size, EVP_sha256(), NULL); |
| 231 | |
| 232 | for(i=0;bufferList[i];i++) |
| 233 | { |
| 234 | HMAC_Update(hmac, bufferList[i]->buffer, bufferList[i]->size); |
| 235 | } |
| 236 | |
| 237 | HMAC_Final(hmac, result->b.buffer, &resLen); |
| 238 | result->b.size = resLen; |
| 239 | |
| 240 | HMAC_CTX_free(hmac); |
| 241 | |
| 242 | return RC; |
| 243 | } |
| 244 | |
| 245 | void print_buff(char * data, int len, const PBYTE buff) |
| 246 | { |
| 247 | printf("%s \n",data); |
| 248 | int i = 0; |
| 249 | for(;i<len;i++) |
| 250 | printf("0x%02X, ", buff[i]); |
| 251 | printf("\n"); |
| 252 | |
| 253 | } |
| 254 | |