1 // 2 // Copyright (C) 2015 The Android Open Source Project 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 17 #include "attestation/common/crypto_utility_impl.h" 18 19 #include <limits> 20 #include <string> 21 22 #include <arpa/inet.h> 23 #include <base/sha1.h> 24 #include <base/stl_util.h> 25 #include <crypto/scoped_openssl_types.h> 26 #include <crypto/secure_util.h> 27 #include <crypto/sha2.h> 28 #include <openssl/bio.h> 29 #include <openssl/err.h> 30 #include <openssl/evp.h> 31 #include <openssl/hmac.h> 32 #include <openssl/rand.h> 33 #include <openssl/rsa.h> 34 #include <openssl/sha.h> 35 #include <openssl/x509.h> 36 37 namespace { 38 39 const size_t kAesKeySize = 32; 40 const size_t kAesBlockSize = 16; 41 42 std::string GetOpenSSLError() { 43 BIO* bio = BIO_new(BIO_s_mem()); 44 ERR_print_errors(bio); 45 char* data = nullptr; 46 int data_len = BIO_get_mem_data(bio, &data); 47 std::string error_string(data, data_len); 48 BIO_free(bio); 49 return error_string; 50 } 51 52 unsigned char* StringAsOpenSSLBuffer(std::string* s) { 53 return reinterpret_cast<unsigned char*>(string_as_array(s)); 54 } 55 56 } // namespace 57 58 namespace attestation { 59 60 CryptoUtilityImpl::CryptoUtilityImpl(TpmUtility* tpm_utility) 61 : tpm_utility_(tpm_utility) { 62 OpenSSL_add_all_algorithms(); 63 ERR_load_crypto_strings(); 64 } 65 66 CryptoUtilityImpl::~CryptoUtilityImpl() { 67 EVP_cleanup(); 68 ERR_free_strings(); 69 } 70 71 bool CryptoUtilityImpl::GetRandom(size_t num_bytes, 72 std::string* random_data) const { 73 // OpenSSL takes a signed integer. 74 if (num_bytes > static_cast<size_t>(std::numeric_limits<int>::max())) { 75 return false; 76 } 77 random_data->resize(num_bytes); 78 unsigned char* buffer = StringAsOpenSSLBuffer(random_data); 79 return (RAND_bytes(buffer, num_bytes) == 1); 80 } 81 82 bool CryptoUtilityImpl::CreateSealedKey(std::string* aes_key, 83 std::string* sealed_key) { 84 if (!GetRandom(kAesKeySize, aes_key)) { 85 LOG(ERROR) << __func__ << ": GetRandom failed."; 86 return false; 87 } 88 if (!tpm_utility_->SealToPCR0(*aes_key, sealed_key)) { 89 LOG(ERROR) << __func__ << ": Failed to seal cipher key."; 90 return false; 91 } 92 return true; 93 } 94 95 bool CryptoUtilityImpl::EncryptData(const std::string& data, 96 const std::string& aes_key, 97 const std::string& sealed_key, 98 std::string* encrypted_data) { 99 std::string iv; 100 if (!GetRandom(kAesBlockSize, &iv)) { 101 LOG(ERROR) << __func__ << ": GetRandom failed."; 102 return false; 103 } 104 std::string raw_encrypted_data; 105 if (!AesEncrypt(data, aes_key, iv, &raw_encrypted_data)) { 106 LOG(ERROR) << __func__ << ": AES encryption failed."; 107 return false; 108 } 109 EncryptedData encrypted_pb; 110 encrypted_pb.set_wrapped_key(sealed_key); 111 encrypted_pb.set_iv(iv); 112 encrypted_pb.set_encrypted_data(raw_encrypted_data); 113 encrypted_pb.set_mac(HmacSha512(iv + raw_encrypted_data, aes_key)); 114 if (!encrypted_pb.SerializeToString(encrypted_data)) { 115 LOG(ERROR) << __func__ << ": Failed to serialize protobuf."; 116 return false; 117 } 118 return true; 119 } 120 121 bool CryptoUtilityImpl::UnsealKey(const std::string& encrypted_data, 122 std::string* aes_key, 123 std::string* sealed_key) { 124 EncryptedData encrypted_pb; 125 if (!encrypted_pb.ParseFromString(encrypted_data)) { 126 LOG(ERROR) << __func__ << ": Failed to parse protobuf."; 127 return false; 128 } 129 *sealed_key = encrypted_pb.wrapped_key(); 130 if (!tpm_utility_->Unseal(*sealed_key, aes_key)) { 131 LOG(ERROR) << __func__ << ": Cannot unseal aes key."; 132 return false; 133 } 134 return true; 135 } 136 137 bool CryptoUtilityImpl::DecryptData(const std::string& encrypted_data, 138 const std::string& aes_key, 139 std::string* data) { 140 EncryptedData encrypted_pb; 141 if (!encrypted_pb.ParseFromString(encrypted_data)) { 142 LOG(ERROR) << __func__ << ": Failed to parse protobuf."; 143 return false; 144 } 145 std::string mac = HmacSha512( 146 encrypted_pb.iv() + encrypted_pb.encrypted_data(), 147 aes_key); 148 if (mac.length() != encrypted_pb.mac().length()) { 149 LOG(ERROR) << __func__ << ": Corrupted data in encrypted pb."; 150 return false; 151 } 152 if (!crypto::SecureMemEqual(mac.data(), encrypted_pb.mac().data(), 153 mac.length())) { 154 LOG(ERROR) << __func__ << ": Corrupted data in encrypted pb."; 155 return false; 156 } 157 if (!AesDecrypt(encrypted_pb.encrypted_data(), aes_key, encrypted_pb.iv(), 158 data)) { 159 LOG(ERROR) << __func__ << ": AES decryption failed."; 160 return false; 161 } 162 return true; 163 } 164 165 bool CryptoUtilityImpl::GetRSASubjectPublicKeyInfo( 166 const std::string& public_key, 167 std::string* public_key_info) { 168 auto asn1_ptr = reinterpret_cast<const unsigned char*>(public_key.data()); 169 crypto::ScopedRSA rsa(d2i_RSAPublicKey(nullptr, &asn1_ptr, 170 public_key.size())); 171 if (!rsa.get()) { 172 LOG(ERROR) << __func__ << ": Failed to decode public key: " 173 << GetOpenSSLError(); 174 return false; 175 } 176 unsigned char* buffer = nullptr; 177 int length = i2d_RSA_PUBKEY(rsa.get(), &buffer); 178 if (length <= 0) { 179 LOG(ERROR) << __func__ << ": Failed to encode public key: " 180 << GetOpenSSLError(); 181 return false; 182 } 183 crypto::ScopedOpenSSLBytes scoped_buffer(buffer); 184 public_key_info->assign(reinterpret_cast<char*>(buffer), length); 185 return true; 186 } 187 188 bool CryptoUtilityImpl::GetRSAPublicKey(const std::string& public_key_info, 189 std::string* public_key) { 190 auto asn1_ptr = reinterpret_cast<const unsigned char*>( 191 public_key_info.data()); 192 crypto::ScopedRSA rsa(d2i_RSA_PUBKEY(NULL, &asn1_ptr, 193 public_key_info.size())); 194 if (!rsa.get()) { 195 LOG(ERROR) << __func__ << ": Failed to decode public key: " 196 << GetOpenSSLError(); 197 return false; 198 } 199 unsigned char* buffer = NULL; 200 int length = i2d_RSAPublicKey(rsa.get(), &buffer); 201 if (length <= 0) { 202 LOG(ERROR) << __func__ << ": Failed to encode public key: " 203 << GetOpenSSLError(); 204 return false; 205 } 206 crypto::ScopedOpenSSLBytes scoped_buffer(buffer); 207 public_key->assign(reinterpret_cast<char*>(buffer), length); 208 return true; 209 } 210 211 bool CryptoUtilityImpl::EncryptIdentityCredential( 212 const std::string& credential, 213 const std::string& ek_public_key_info, 214 const std::string& aik_public_key, 215 EncryptedIdentityCredential* encrypted) { 216 const char kAlgAES256 = 9; // This comes from TPM_ALG_AES256. 217 const char kEncModeCBC = 2; // This comes from TPM_SYM_MODE_CBC. 218 const char kAsymContentHeader[] = 219 {0, 0, 0, kAlgAES256, 0, kEncModeCBC, 0, kAesKeySize}; 220 const char kSymContentHeader[12] = {}; 221 222 // Generate an AES key and encrypt the credential. 223 std::string aes_key; 224 if (!GetRandom(kAesKeySize, &aes_key)) { 225 LOG(ERROR) << __func__ << ": GetRandom failed."; 226 return false; 227 } 228 std::string encrypted_credential; 229 if (!TssCompatibleEncrypt(credential, aes_key, &encrypted_credential)) { 230 LOG(ERROR) << __func__ << ": Failed to encrypt credential."; 231 return false; 232 } 233 234 // Construct a TPM_ASYM_CA_CONTENTS structure. 235 std::string asym_header(std::begin(kAsymContentHeader), 236 std::end(kAsymContentHeader)); 237 std::string asym_content = asym_header + aes_key + 238 base::SHA1HashString(aik_public_key); 239 240 // Encrypt the TPM_ASYM_CA_CONTENTS with the EK public key. 241 auto asn1_ptr = reinterpret_cast<const unsigned char*>( 242 ek_public_key_info.data()); 243 crypto::ScopedRSA rsa(d2i_RSA_PUBKEY(NULL, &asn1_ptr, 244 ek_public_key_info.size())); 245 if (!rsa.get()) { 246 LOG(ERROR) << __func__ << ": Failed to decode EK public key: " 247 << GetOpenSSLError(); 248 return false; 249 } 250 std::string encrypted_asym_content; 251 if (!TpmCompatibleOAEPEncrypt(asym_content, rsa.get(), 252 &encrypted_asym_content)) { 253 LOG(ERROR) << __func__ << ": Failed to encrypt with EK public key."; 254 return false; 255 } 256 257 // Construct a TPM_SYM_CA_ATTESTATION structure. 258 uint32_t length = htonl(encrypted_credential.size()); 259 auto length_bytes = reinterpret_cast<const char*>(&length); 260 std::string length_blob(length_bytes, sizeof(uint32_t)); 261 std::string sym_header(std::begin(kSymContentHeader), 262 std::end(kSymContentHeader)); 263 std::string sym_content = length_blob + sym_header + encrypted_credential; 264 265 encrypted->set_asym_ca_contents(encrypted_asym_content); 266 encrypted->set_sym_ca_attestation(sym_content); 267 return true; 268 } 269 270 bool CryptoUtilityImpl::EncryptForUnbind(const std::string& public_key, 271 const std::string& data, 272 std::string* encrypted_data) { 273 // Construct a TPM_BOUND_DATA structure. 274 const char kBoundDataHeader[] = {1, 1, 0, 0, 2 /* TPM_PT_BIND */}; 275 std::string header(std::begin(kBoundDataHeader), std::end(kBoundDataHeader)); 276 std::string bound_data = header + data; 277 278 // Encrypt using the TPM_ES_RSAESOAEP_SHA1_MGF1 scheme. 279 auto asn1_ptr = reinterpret_cast<const unsigned char*>(public_key.data()); 280 crypto::ScopedRSA rsa(d2i_RSA_PUBKEY(NULL, &asn1_ptr, public_key.size())); 281 if (!rsa.get()) { 282 LOG(ERROR) << __func__ << ": Failed to decode public key: " 283 << GetOpenSSLError(); 284 return false; 285 } 286 if (!TpmCompatibleOAEPEncrypt(bound_data, rsa.get(), encrypted_data)) { 287 LOG(ERROR) << __func__ << ": Failed to encrypt with public key."; 288 return false; 289 } 290 return true; 291 } 292 293 bool CryptoUtilityImpl::VerifySignature(const std::string& public_key, 294 const std::string& data, 295 const std::string& signature) { 296 auto asn1_ptr = reinterpret_cast<const unsigned char*>(public_key.data()); 297 crypto::ScopedRSA rsa(d2i_RSA_PUBKEY(NULL, &asn1_ptr, public_key.size())); 298 if (!rsa.get()) { 299 LOG(ERROR) << __func__ << ": Failed to decode public key: " 300 << GetOpenSSLError(); 301 return false; 302 } 303 std::string digest = crypto::SHA256HashString(data); 304 auto digest_buffer = reinterpret_cast<const unsigned char*>(digest.data()); 305 std::string mutable_signature(signature); 306 unsigned char* signature_buffer = StringAsOpenSSLBuffer(&mutable_signature); 307 return (RSA_verify(NID_sha256, digest_buffer, digest.size(), 308 signature_buffer, signature.size(), rsa.get()) == 1); 309 } 310 311 bool CryptoUtilityImpl::AesEncrypt(const std::string& data, 312 const std::string& key, 313 const std::string& iv, 314 std::string* encrypted_data) { 315 if (key.size() != kAesKeySize || iv.size() != kAesBlockSize) { 316 return false; 317 } 318 if (data.size() > static_cast<size_t>(std::numeric_limits<int>::max())) { 319 // EVP_EncryptUpdate takes a signed int. 320 return false; 321 } 322 std::string mutable_data(data); 323 unsigned char* input_buffer = StringAsOpenSSLBuffer(&mutable_data); 324 std::string mutable_key(key); 325 unsigned char* key_buffer = StringAsOpenSSLBuffer(&mutable_key); 326 std::string mutable_iv(iv); 327 unsigned char* iv_buffer = StringAsOpenSSLBuffer(&mutable_iv); 328 // Allocate enough space for the output (including padding). 329 encrypted_data->resize(data.size() + kAesBlockSize); 330 auto output_buffer = reinterpret_cast<unsigned char*>( 331 string_as_array(encrypted_data)); 332 int output_size = 0; 333 const EVP_CIPHER* cipher = EVP_aes_256_cbc(); 334 EVP_CIPHER_CTX encryption_context; 335 EVP_CIPHER_CTX_init(&encryption_context); 336 if (!EVP_EncryptInit_ex(&encryption_context, cipher, nullptr, key_buffer, 337 iv_buffer)) { 338 LOG(ERROR) << __func__ << ": " << GetOpenSSLError(); 339 return false; 340 } 341 if (!EVP_EncryptUpdate(&encryption_context, output_buffer, &output_size, 342 input_buffer, data.size())) { 343 LOG(ERROR) << __func__ << ": " << GetOpenSSLError(); 344 EVP_CIPHER_CTX_cleanup(&encryption_context); 345 return false; 346 } 347 size_t total_size = output_size; 348 output_buffer += output_size; 349 output_size = 0; 350 if (!EVP_EncryptFinal_ex(&encryption_context, output_buffer, &output_size)) { 351 LOG(ERROR) << __func__ << ": " << GetOpenSSLError(); 352 EVP_CIPHER_CTX_cleanup(&encryption_context); 353 return false; 354 } 355 total_size += output_size; 356 encrypted_data->resize(total_size); 357 EVP_CIPHER_CTX_cleanup(&encryption_context); 358 return true; 359 } 360 361 bool CryptoUtilityImpl::AesDecrypt(const std::string& encrypted_data, 362 const std::string& key, 363 const std::string& iv, 364 std::string* data) { 365 if (key.size() != kAesKeySize || iv.size() != kAesBlockSize) { 366 return false; 367 } 368 if (encrypted_data.size() > 369 static_cast<size_t>(std::numeric_limits<int>::max())) { 370 // EVP_DecryptUpdate takes a signed int. 371 return false; 372 } 373 std::string mutable_encrypted_data(encrypted_data); 374 unsigned char* input_buffer = StringAsOpenSSLBuffer(&mutable_encrypted_data); 375 std::string mutable_key(key); 376 unsigned char* key_buffer = StringAsOpenSSLBuffer(&mutable_key); 377 std::string mutable_iv(iv); 378 unsigned char* iv_buffer = StringAsOpenSSLBuffer(&mutable_iv); 379 // Allocate enough space for the output. 380 data->resize(encrypted_data.size()); 381 unsigned char* output_buffer = StringAsOpenSSLBuffer(data); 382 int output_size = 0; 383 const EVP_CIPHER* cipher = EVP_aes_256_cbc(); 384 EVP_CIPHER_CTX decryption_context; 385 EVP_CIPHER_CTX_init(&decryption_context); 386 if (!EVP_DecryptInit_ex(&decryption_context, cipher, nullptr, key_buffer, 387 iv_buffer)) { 388 LOG(ERROR) << __func__ << ": " << GetOpenSSLError(); 389 return false; 390 } 391 if (!EVP_DecryptUpdate(&decryption_context, output_buffer, &output_size, 392 input_buffer, encrypted_data.size())) { 393 LOG(ERROR) << __func__ << ": " << GetOpenSSLError(); 394 EVP_CIPHER_CTX_cleanup(&decryption_context); 395 return false; 396 } 397 size_t total_size = output_size; 398 output_buffer += output_size; 399 output_size = 0; 400 if (!EVP_DecryptFinal_ex(&decryption_context, output_buffer, &output_size)) { 401 LOG(ERROR) << __func__ << ": " << GetOpenSSLError(); 402 EVP_CIPHER_CTX_cleanup(&decryption_context); 403 return false; 404 } 405 total_size += output_size; 406 data->resize(total_size); 407 EVP_CIPHER_CTX_cleanup(&decryption_context); 408 return true; 409 } 410 411 std::string CryptoUtilityImpl::HmacSha512(const std::string& data, 412 const std::string& key) { 413 unsigned char mac[SHA512_DIGEST_LENGTH]; 414 std::string mutable_data(data); 415 unsigned char* data_buffer = StringAsOpenSSLBuffer(&mutable_data); 416 HMAC(EVP_sha512(), key.data(), key.size(), data_buffer, data.size(), mac, 417 nullptr); 418 return std::string(std::begin(mac), std::end(mac)); 419 } 420 421 bool CryptoUtilityImpl::TssCompatibleEncrypt(const std::string& input, 422 const std::string& key, 423 std::string* output) { 424 CHECK(output); 425 CHECK_EQ(key.size(), kAesKeySize); 426 std::string iv; 427 if (!GetRandom(kAesBlockSize, &iv)) { 428 LOG(ERROR) << __func__ << ": GetRandom failed."; 429 return false; 430 } 431 std::string encrypted; 432 if (!AesEncrypt(input, key, iv, &encrypted)) { 433 LOG(ERROR) << __func__ << ": Encryption failed."; 434 return false; 435 } 436 *output = iv + encrypted; 437 return true; 438 } 439 440 bool CryptoUtilityImpl::TpmCompatibleOAEPEncrypt(const std::string& input, 441 RSA* key, 442 std::string* output) { 443 CHECK(output); 444 // The custom OAEP parameter as specified in TPM Main Part 1, Section 31.1.1. 445 const unsigned char oaep_param[4] = {'T', 'C', 'P', 'A'}; 446 std::string padded_input; 447 padded_input.resize(RSA_size(key)); 448 auto padded_buffer = reinterpret_cast<unsigned char*>( 449 string_as_array(&padded_input)); 450 auto input_buffer = reinterpret_cast<const unsigned char*>(input.data()); 451 int result = RSA_padding_add_PKCS1_OAEP(padded_buffer, padded_input.size(), 452 input_buffer, input.size(), 453 oaep_param, arraysize(oaep_param)); 454 if (!result) { 455 LOG(ERROR) << __func__ << ": Failed to add OAEP padding: " 456 << GetOpenSSLError(); 457 return false; 458 } 459 output->resize(padded_input.size()); 460 auto output_buffer = reinterpret_cast<unsigned char*>( 461 string_as_array(output)); 462 result = RSA_public_encrypt(padded_input.size(), padded_buffer, 463 output_buffer, key, RSA_NO_PADDING); 464 if (result == -1) { 465 LOG(ERROR) << __func__ << ": Failed to encrypt OAEP padded input: " 466 << GetOpenSSLError(); 467 return false; 468 } 469 return true; 470 } 471 472 } // namespace attestation 473