github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/tpm2/openssl_helpers.cc (about) 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/types.h> 4 #include <sys/stat.h> 5 #include <fcntl.h> 6 #include <unistd.h> 7 #include <string.h> 8 #include <tpm20.h> 9 #include <tpm2_lib.h> 10 #include <errno.h> 11 12 #include <tpm2.pb.h> 13 14 #include <openssl_helpers.h> 15 #include <openssl/rsa.h> 16 #include <openssl/x509.h> 17 #include <openssl/ssl.h> 18 #include <openssl/evp.h> 19 #include <openssl/asn1.h> 20 #include <openssl/err.h> 21 #include <openssl/aes.h> 22 #include <openssl/hmac.h> 23 #include <openssl/rand.h> 24 25 #include <string> 26 using std::string; 27 28 // 29 // Copyright 2015 Google Corporation, All Rights Reserved. 30 // 31 // Licensed under the Apache License, Version 2.0 (the "License"); 32 // you may not use this file except in compliance with the License. 33 // You may obtain a copy of the License at 34 // http://www.apache.org/licenses/LICENSE-2.0 35 // or in the the file LICENSE-2.0.txt in the top level sourcedirectory 36 // Unless required by applicable law or agreed to in writing, software 37 // distributed under the License is distributed on an "AS IS" BASIS, 38 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 39 // See the License for the specific language governing permissions and 40 // limitations under the License 41 // 42 // Portions of this code were derived TPM2.0-TSS published 43 // by Intel under the license set forth in intel_license.txt 44 // and downloaded on or about August 6, 2015. 45 // File: openssl_helpers.cc 46 47 // standard buffer size 48 #define MAX_SIZE_PARAMS 4096 49 50 void print_cert_request_message(x509_cert_request_parameters_message& req_message) { 51 if (req_message.has_common_name()) { 52 printf("common name: %s\n", req_message.common_name().c_str()); 53 } 54 if (req_message.has_country_name()) { 55 printf("country name: %s\n", req_message.country_name().c_str()); 56 } 57 if (req_message.has_state_name()) { 58 printf("state name: %s\n", req_message.state_name().c_str()); 59 } 60 if (req_message.has_locality_name()) { 61 printf("locality name: %s\n", req_message.locality_name().c_str()); 62 } 63 if (req_message.has_organization_name()) { 64 printf("organization name: %s\n", req_message.organization_name().c_str()); 65 } 66 if (req_message.has_suborganization_name()) { 67 printf("suborganization name: %s\n", 68 req_message.suborganization_name().c_str()); 69 } 70 if (!req_message.has_key()) 71 return; 72 if (req_message.key().has_key_type()) { 73 printf("key_type name: %s\n", req_message.key().key_type().c_str()); 74 } 75 if (req_message.key().rsa_key().has_key_name()) { 76 printf("key name: %s\n", req_message.key().rsa_key().key_name().c_str()); 77 } 78 if (req_message.key().rsa_key().has_bit_modulus_size()) { 79 printf("modulus bit size: %d\n", 80 req_message.key().rsa_key().bit_modulus_size()); 81 } 82 if (req_message.key().rsa_key().has_exponent()) { 83 string exp = req_message.key().rsa_key().exponent(); 84 printf("exponent: "); 85 PrintBytes(exp.size(), (byte*)exp.data()); 86 printf("\n"); 87 } 88 if (req_message.key().rsa_key().has_modulus()) { 89 string mod = req_message.key().rsa_key().modulus(); 90 printf("modulus : "); 91 PrintBytes(mod.size(), (byte*)mod.data()); 92 printf("\n"); 93 } 94 } 95 96 void print_internal_private_key(RSA& key) { 97 if (key.n != nullptr) { 98 printf("\nModulus: \n"); 99 BN_print_fp(stdout, key.n); 100 printf("\n"); 101 } 102 if (key.e != nullptr) { 103 printf("\ne: \n"); 104 BN_print_fp(stdout, key.e); 105 printf("\n"); 106 } 107 if (key.d != nullptr) { 108 printf("\nd: \n"); 109 BN_print_fp(stdout, key.d); 110 printf("\n"); 111 } 112 if (key.p != nullptr) { 113 printf("\np: \n"); 114 BN_print_fp(stdout, key.p); 115 printf("\n"); 116 } 117 if (key.q != nullptr) { 118 printf("\nq: \n"); 119 BN_print_fp(stdout, key.q); 120 printf("\n"); 121 } 122 #if 0 123 if (key.dmp1 != nullptr) { 124 printf("\ndmp1: \n"); 125 BN_print_fp(stdout, key.dmp1); 126 printf("\n"); 127 } 128 if (key.dmq1 != nullptr) { 129 printf("\ndmq1: \n"); 130 BN_print_fp(stdout, key.dmq1); 131 printf("\n"); 132 } 133 if (key.iqmp != nullptr) { 134 printf("\niqmp: \n"); 135 BN_print_fp(stdout, key.iqmp); 136 printf("\n"); 137 } 138 #endif 139 } 140 141 BIGNUM* bin_to_BN(int len, byte* buf) { 142 BIGNUM* bn = BN_bin2bn(buf, len, nullptr); 143 return bn; 144 } 145 146 string* BN_to_bin(BIGNUM& n) { 147 byte buf[MAX_SIZE_PARAMS]; 148 149 int len = BN_bn2bin(&n, buf); 150 return new string((const char*)buf, len); 151 } 152 153 bool GenerateX509CertificateRequest(x509_cert_request_parameters_message& 154 params, bool sign_request, X509_REQ* req) { 155 RSA* rsa = RSA_new(); 156 X509_NAME* subject = X509_NAME_new(); 157 EVP_PKEY* pKey = new EVP_PKEY(); 158 159 X509_REQ_set_version(req, 2L); 160 if (params.key().key_type() != "RSA") { 161 printf("Only rsa keys supported %s\n", params.key().key_type().c_str()); 162 return false; 163 } 164 if (subject == nullptr) { 165 printf("Can't alloc x509 name\n"); 166 return false; 167 } 168 if (params.has_common_name()) { 169 int nid = OBJ_txt2nid("CN"); 170 X509_NAME_ENTRY* ent = X509_NAME_ENTRY_create_by_NID(nullptr, nid, 171 MBSTRING_ASC, (byte*)params.common_name().c_str(), -1); 172 if (ent == nullptr) { 173 printf("X509_NAME_ENTRY return is null, nid: %d\n", nid); 174 return false; 175 } 176 if (X509_NAME_add_entry(subject, ent, -1, 0) != 1) { 177 printf("Can't add name ent\n"); 178 return false; 179 } 180 } 181 // TODO: do the foregoing for the other name components 182 if (X509_REQ_set_subject_name(req, subject) != 1) { 183 printf("Can't set x509 subject\n"); 184 return false; 185 } 186 187 if (!GetPublicRsaKeyFromParameters(params.key().rsa_key(), rsa)) { 188 printf("Can't make rsa key\n"); 189 return false; 190 } 191 192 EVP_PKEY_assign_RSA(pKey, rsa); 193 194 // fill key parameters in request 195 if (sign_request) { 196 const EVP_MD* digest = EVP_sha256(); 197 if (!X509_REQ_sign(req, pKey, digest)) { 198 printf("Sign request fails\n"); 199 printf("ERR: %s\n", ERR_lib_error_string(ERR_get_error())); 200 } 201 } 202 pKey->type = EVP_PKEY_RSA; 203 if (X509_REQ_set_pubkey(req, pKey) ==0) { 204 printf("X509_REQ_set_pubkey failed\n"); 205 } 206 207 return true; 208 } 209 210 bool GetPublicRsaKeyFromParameters(const rsa_public_key_message& key_msg, 211 RSA* rsa) { 212 rsa->e = bin_to_BN(key_msg.exponent().size(), (byte*)key_msg.exponent().data()); 213 rsa->n = bin_to_BN(key_msg.modulus().size(), (byte*)key_msg.modulus().data()); 214 return rsa->e != nullptr && rsa->n != nullptr; 215 } 216 217 bool GetPrivateRsaKeyFromParameters(const rsa_public_key_message& key_msg, 218 RSA* rsa) { 219 return false; 220 } 221 222 class extEntry { 223 public: 224 char* key_; 225 char* value_; 226 227 extEntry(const char* k, const char* v); 228 extEntry(); 229 char* getKey(); 230 char* getValue(); 231 }; 232 233 extEntry::extEntry(const char* k, const char* v) { 234 key_ = (char*)strdup(k); 235 value_ = (char*)strdup(v); 236 } 237 238 extEntry::extEntry() { 239 key_ = nullptr; 240 value_ = nullptr; 241 } 242 243 char* extEntry::getKey() { 244 return key_; 245 } 246 247 char* extEntry::getValue() { 248 return value_; 249 } 250 251 bool addExtensionsToCert(int num_entry, extEntry** entries, X509* cert) { 252 #if 1 253 // Temporary because of go verification 254 return true; 255 #endif 256 // add extensions 257 for (int i = 0; i < num_entry; i++) { 258 int nid = OBJ_txt2nid(entries[i]->getKey()); 259 ASN1_OCTET_STRING* val = ASN1_OCTET_STRING_new(); 260 ASN1_STRING_set(val, (const void *)entries[i]->getValue(), 261 strlen(entries[i]->getValue())); 262 X509_EXTENSION* ext = X509_EXTENSION_create_by_NID(NULL, nid, 0, val); 263 if (ext == 0) { 264 printf("Bad ext_conf %d\n", i); 265 printf("ERR: %s\n", ERR_lib_error_string(ERR_get_error())); 266 return false; 267 } 268 if (!X509_add_ext(cert, ext, -1)) { 269 printf("Bad add ext %d\n", i); 270 printf("ERR: %s\n", ERR_lib_error_string(ERR_get_error())); 271 return false; 272 } 273 X509_EXTENSION_free(ext); 274 } 275 return true; 276 } 277 278 bool SignX509Certificate(RSA* signing_key, bool f_isCa, 279 signing_instructions_message& signing_instructions, 280 EVP_PKEY* signedKey, 281 X509_REQ* req, bool verify_req_sig, X509* cert) { 282 if (signedKey == nullptr) 283 signedKey = X509_REQ_get_pubkey(req); 284 if (signedKey == nullptr) { 285 printf("Can't get pubkey\n"); 286 return false; 287 } 288 289 if (verify_req_sig) { 290 if (X509_REQ_verify(req, signedKey) != 1) { 291 printf("Req does not verify\n"); 292 // return false; 293 } 294 } 295 296 uint64_t serial = 1; 297 EVP_PKEY* pSigningKey= EVP_PKEY_new(); 298 const EVP_MD* digest = EVP_sha256(); 299 X509_NAME* name; 300 EVP_PKEY_set1_RSA(pSigningKey, signing_key); 301 pSigningKey->type = EVP_PKEY_RSA; 302 X509_set_version(cert, 2L); 303 ASN1_INTEGER_set(X509_get_serialNumber(cert), serial++); 304 305 name = X509_REQ_get_subject_name(req); 306 if (X509_set_subject_name(cert, name) != 1) { 307 printf("Can't set subject name\n"); 308 return false; 309 } 310 if (X509_set_pubkey(cert, signedKey) != 1) { 311 printf("Can't set pubkey\n"); 312 return false; 313 } 314 if (!X509_gmtime_adj(X509_get_notBefore(cert), 0)) { 315 printf("Can't adj notBefore\n"); 316 return false; 317 } 318 if (!X509_gmtime_adj(X509_get_notAfter(cert), 319 signing_instructions.duration())) { 320 printf("Can't adj notAfter\n"); 321 return false; 322 } 323 X509_NAME* issuer = X509_NAME_new(); 324 int nid = OBJ_txt2nid("CN"); 325 X509_NAME_ENTRY* ent = X509_NAME_ENTRY_create_by_NID(nullptr, nid, 326 MBSTRING_ASC, (byte*)signing_instructions.issuer().c_str(), -1); 327 if (X509_NAME_add_entry(issuer, ent, -1, 0) != 1) { 328 printf("Can't add issuer name ent: %s, %ld\n", 329 signing_instructions.issuer().c_str(), (long unsigned)ent); 330 printf("ERR: %s\n", ERR_lib_error_string(ERR_get_error())); 331 return false; 332 } 333 if (X509_set_issuer_name(cert, issuer) != 1) { 334 printf("Can't set issuer name\n"); 335 return false; 336 } 337 338 // add extensions 339 extEntry* entries[4]; 340 int n = 0; 341 if (f_isCa) 342 entries[n++] = new extEntry("basicConstraints", "critical,CA:TRUE"); 343 // entries[n++] = new extEntry("subjectKeyIdentifier", "hash"); 344 entries[n++] = new extEntry("keyUsage", signing_instructions.purpose().c_str()); 345 if (!addExtensionsToCert(n, entries, cert)) { 346 printf("Can't add extensions\n"); 347 return false; 348 } 349 350 if (!X509_sign(cert, pSigningKey, digest)) { 351 printf("Bad PKEY type\n"); 352 return false; 353 } 354 355 printf("digest->size: %d\n", digest->md_size); 356 PrintBytes(digest->md_size, (byte*)digest->final); 357 printf("\n"); 358 return true; 359 } 360 361 void XorBlocks(int size, byte* in1, byte* in2, byte* out) { 362 int i; 363 364 for (i = 0; i < size; i++) 365 out[i] = in1[i] ^ in2[i]; 366 } 367 368 bool KDFa(uint16_t hashAlg, string& key, string& label, string& contextU, 369 string& contextV, int bits, int out_size, byte* out) { 370 HMAC_CTX ctx; 371 uint32_t len = 32; 372 uint32_t counter = 0; 373 int bytes_left = (bits + 7) / 8; 374 byte* current_out = out; 375 int size_buf = 0; 376 byte buf[MAX_SIZE_PARAMS]; 377 int n; 378 379 memset(buf, 0, 128); 380 ChangeEndian32(&counter, (uint32_t*)&buf[size_buf]); 381 size_buf += sizeof(uint32_t); 382 n = strlen(label.c_str()) + 1; 383 if ((size_buf + n) > MAX_SIZE_PARAMS) return false; 384 memcpy(&buf[size_buf], label.data(), n); 385 size_buf += n; 386 if ((size_buf + contextU.size()) > MAX_SIZE_PARAMS) return false; 387 memcpy(&buf[size_buf], contextU.data(), contextU.size()); 388 size_buf += contextU.size(); 389 if ((size_buf + contextV.size()) > MAX_SIZE_PARAMS) return false; 390 memcpy(&buf[size_buf], contextV.data(), contextV.size()); 391 size_buf += contextV.size(); 392 if ((size_buf + sizeof(uint32_t)) > MAX_SIZE_PARAMS) return false; 393 ChangeEndian32((uint32_t*)&bits, (uint32_t*)&buf[size_buf]); 394 size_buf += sizeof(uint32_t); 395 396 while (bytes_left > 0) { 397 counter++; 398 ChangeEndian32(&counter, (uint32_t*)buf); 399 400 HMAC_CTX_init(&ctx); 401 if (hashAlg == TPM_ALG_SHA1 ) { 402 HMAC_Init_ex(&ctx, key.data(), key.size(), EVP_sha1(), nullptr); 403 } else { 404 HMAC_Init_ex(&ctx, key.data(), key.size(), EVP_sha256(), nullptr); 405 } 406 HMAC_Update(&ctx, buf, size_buf); 407 HMAC_Final(&ctx, current_out, &len); 408 HMAC_CTX_cleanup(&ctx); 409 current_out += len; 410 bytes_left -= len; 411 } 412 return true; 413 } 414 415 bool AesCtrCrypt(int key_size_bits, byte* key, int size, 416 byte* in, byte* out) { 417 AES_KEY ectx; 418 uint64_t ctr[2] = {0ULL, 0ULL}; 419 byte block[32]; 420 421 if (key_size_bits != 128) { 422 return false; 423 } 424 425 AES_set_encrypt_key(key, 128, &ectx); 426 while (size > 0) { 427 ctr[1]++; 428 AES_encrypt((byte*)ctr, block, &ectx); 429 XorBlocks(16, block, in, out); 430 in += 16; 431 out += 16; 432 size -= 16; 433 } 434 return true; 435 } 436 437 #define AESBLKSIZE 16 438 439 bool AesCFBEncrypt(byte* key, int in_size, byte* in, int iv_size, byte* iv, 440 int* out_size, byte* out) { 441 byte last_cipher[32]; 442 byte cipher_block[32]; 443 int size = 0; 444 int current_size; 445 446 AES_KEY ectx; 447 AES_set_encrypt_key(key, 128, &ectx); 448 449 // Don't write iv, called already knows it 450 if(iv_size != AESBLKSIZE) return false; 451 memcpy(last_cipher, iv, AESBLKSIZE); 452 453 while (in_size > 0) { 454 if ((size + AESBLKSIZE) > *out_size) return false; 455 // C[0] = IV, C[i] = P[i] ^ E(K, C[i-1]) 456 AES_encrypt(last_cipher, cipher_block, &ectx); 457 if (in_size >= AESBLKSIZE) 458 current_size = AESBLKSIZE; 459 else 460 current_size = in_size; 461 XorBlocks(AESBLKSIZE, cipher_block, in, last_cipher); 462 memcpy(out, last_cipher, current_size); 463 out += current_size; 464 size += current_size; 465 in += current_size; 466 in_size -= current_size; 467 } 468 *out_size = size; 469 return true; 470 } 471 472 bool AesCFBDecrypt(byte* key, int in_size, byte* in, int iv_size, byte* iv, 473 int* out_size, byte* out) { 474 byte last_cipher[32]; 475 byte cipher_block[32]; 476 int size = 0; 477 int current_size; 478 479 AES_KEY ectx; 480 AES_set_encrypt_key(key, 128, &ectx); 481 482 // Don't write iv, called already knows it 483 if(iv_size != AESBLKSIZE) return false; 484 memcpy(last_cipher, iv, AESBLKSIZE); 485 486 while (in_size > 0) { 487 if ((size + AESBLKSIZE) > *out_size) return false; 488 // P[i] = C[i] ^ E(K, C[i-1]) 489 AES_encrypt(last_cipher, cipher_block, &ectx); 490 if (in_size >= AESBLKSIZE) 491 current_size = AESBLKSIZE; 492 else 493 current_size = in_size; 494 XorBlocks(current_size, cipher_block, in, out); 495 memcpy(last_cipher, in, current_size); 496 out += current_size; 497 size += current_size; 498 in += current_size; 499 in_size -= current_size; 500 } 501 *out_size = size; 502 return true; 503 } 504 505 int SizeHash(TPM_ALG_ID hash) { 506 switch(hash) { 507 case TPM_ALG_SHA1: 508 return 20; 509 case TPM_ALG_SHA256: 510 return 32; 511 default: 512 return -1; 513 } 514 }