Use vec.data() instead of &vec[0].

[ Merge of http://go/wvgerrit/67984 ]

Getting the address of the first element is invalid when the size is
0.  Calling data() is valid when the size is zero so long as we
don't use the resulting pointer.  This is important when we pass the
pointer to low-level functions like memcpy.

Also, MSVC is stricter about this and doesn't allow indexing the 0-th
element when it is empty.  But GCC/Clang seem to be fine with it so
long as the object isn't used.

Test: WV unit/integration tests

Change-Id: Ic5d11da41dd3a185a63f86a6ea91e9b954fd699a
This commit is contained in:
Rahul Frias
2018-12-13 12:04:10 -08:00
parent e22d0ab48c
commit 3c350b677f
4 changed files with 400 additions and 376 deletions

View File

@@ -405,7 +405,7 @@ bool SessionContext::ValidateMessage(const uint8_t* given_message,
uint8_t computed_signature[SHA256_DIGEST_LENGTH];
memset(computed_signature, 0, SHA256_DIGEST_LENGTH);
unsigned int md_len = SHA256_DIGEST_LENGTH;
if (!HMAC(EVP_sha256(), &mac_key_server_[0], mac_key_server_.size(),
if (!HMAC(EVP_sha256(), mac_key_server_.data(), mac_key_server_.size(),
given_message, message_length, computed_signature, &md_len)) {
LOGE("ValidateMessage: Could not compute signature.");
return false;

View File

@@ -325,7 +325,7 @@ OEMCryptoResult UsageTableEntry::CopyOldUsageEntry(
} else {
data_.pst_length = pst.size();
}
memcpy(data_.pst, &pst[0], data_.pst_length);
memcpy(data_.pst, pst.data(), data_.pst_length);
data_.pst[data_.pst_length] = '\0';
return OEMCrypto_SUCCESS;
}

View File

@@ -212,7 +212,7 @@ void Session::DeriveKey(const uint8_t* key, const vector<uint8_t>& context,
message.push_back(counter);
message.insert(message.end(), context.begin(), context.end());
ASSERT_EQ(1, CMAC_Update(cmac_ctx, &message[0], message.size()));
ASSERT_EQ(1, CMAC_Update(cmac_ctx, message.data(), message.size()));
size_t reslen;
uint8_t res[128];
@@ -248,9 +248,9 @@ void Session::GenerateDerivedKeysFromKeybox(
vector<uint8_t> enc_context;
FillDefaultContext(&mac_context, &enc_context);
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_GenerateDerivedKeys(session_id(), &mac_context[0],
mac_context.size(), &enc_context[0],
enc_context.size()));
OEMCrypto_GenerateDerivedKeys(
session_id(), mac_context.data(), mac_context.size(),
enc_context.data(), enc_context.size()));
DeriveKeys(keybox.device_key_, mac_context, enc_context);
}
@@ -267,11 +267,11 @@ void Session::GenerateDerivedKeysFromSessionKey() {
FillDefaultContext(&mac_context, &enc_context);
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_DeriveKeysFromSessionKey(
session_id(), &enc_session_key[0], enc_session_key.size(),
&mac_context[0], mac_context.size(), &enc_context[0],
session_id(), enc_session_key.data(), enc_session_key.size(),
mac_context.data(), mac_context.size(), enc_context.data(),
enc_context.size()));
DeriveKeys(&session_key[0], mac_context, enc_context);
DeriveKeys(session_key.data(), mac_context, enc_context);
}
void Session::LoadTestKeys(const std::string& provider_session_token,
@@ -288,16 +288,17 @@ void Session::LoadTestKeys(const std::string& provider_session_token,
if (new_mac_keys) {
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_LoadKeys(
session_id(), message_ptr(), message_size_, &signature_[0],
session_id(), message_ptr(), message_size_, signature_.data(),
signature_.size(), enc_mac_keys_iv, enc_mac_keys, num_keys_,
key_array_, pst, GetSubstring(), OEMCrypto_ContentLicense));
// Update new generated keys.
memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE);
memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE, MAC_KEY_SIZE);
memcpy(mac_key_server_.data(), license_.mac_keys, MAC_KEY_SIZE);
memcpy(mac_key_client_.data(), license_.mac_keys + MAC_KEY_SIZE,
MAC_KEY_SIZE);
} else {
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_LoadKeys(
session_id(), message_ptr(), message_size_, &signature_[0],
session_id(), message_ptr(), message_size_, signature_.data(),
signature_.size(), GetSubstring(), GetSubstring(), num_keys_,
key_array_, pst, GetSubstring(), OEMCrypto_ContentLicense));
}
@@ -320,17 +321,19 @@ void Session::LoadEntitlementTestKeys(const std::string& provider_session_token,
ASSERT_EQ(
expected_sts,
OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
&signature_[0], signature_.size(), enc_mac_keys_iv,
enc_mac_keys, num_keys_, key_array_, pst,
GetSubstring(), OEMCrypto_EntitlementLicense));
signature_.data(), signature_.size(),
enc_mac_keys_iv, enc_mac_keys, num_keys_,
key_array_, pst, GetSubstring(),
OEMCrypto_EntitlementLicense));
// Update new generated keys.
memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE);
memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE, MAC_KEY_SIZE);
memcpy(mac_key_server_.data(), license_.mac_keys, MAC_KEY_SIZE);
memcpy(mac_key_client_.data(), license_.mac_keys + MAC_KEY_SIZE,
MAC_KEY_SIZE);
} else {
ASSERT_EQ(
expected_sts,
OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
&signature_[0], signature_.size(), GetSubstring(),
signature_.data(), signature_.size(), GetSubstring(),
GetSubstring(), num_keys_, key_array_, pst,
GetSubstring(), OEMCrypto_EntitlementLicense));
}
@@ -381,10 +384,8 @@ void Session::FillEntitledKeyArray() {
void Session::LoadEntitledContentKeys(OEMCryptoResult expected_sts) {
encrypted_entitled_message_ = entitled_message_;
std::vector<OEMCrypto_EntitledContentKeyObject> encrypted_entitled_key_array;
encrypted_entitled_key_array.resize(num_keys_);
memcpy(&encrypted_entitled_key_array[0], &entitled_key_array_[0],
sizeof(OEMCrypto_EntitledContentKeyObject) * num_keys_);
std::vector<OEMCrypto_EntitledContentKeyObject> encrypted_entitled_key_array(
entitled_key_array_, entitled_key_array_ + num_keys_);
for (size_t i = 0; i < num_keys_; ++i) {
// Load the entitlement key from |key_array_|.
@@ -416,7 +417,7 @@ void Session::LoadEntitledContentKeys(OEMCryptoResult expected_sts) {
session_id(),
reinterpret_cast<const uint8_t*>(encrypted_entitled_message_.data()),
encrypted_entitled_message_.size(), num_keys_,
&encrypted_entitled_key_array[0]));
encrypted_entitled_key_array.data()));
if (expected_sts != OEMCrypto_SUCCESS) {
return;
}
@@ -479,11 +480,11 @@ void Session::RefreshTestKeys(const size_t key_count, uint32_t control_bits,
FillRefreshMessage(key_count, control_bits, nonce);
ServerSignBuffer(reinterpret_cast<const uint8_t*>(&padded_message_),
message_size_, &signature_);
OEMCrypto_KeyRefreshObject key_array[key_count];
FillRefreshArray(key_array, key_count);
std::vector<OEMCrypto_KeyRefreshObject> key_array(key_count);
FillRefreshArray(key_array.data(), key_count);
OEMCryptoResult sts = OEMCrypto_RefreshKeys(
session_id(), message_ptr(), message_size_, &signature_[0],
signature_.size(), key_count, key_array);
session_id(), message_ptr(), message_size_, signature_.data(),
signature_.size(), key_count, key_array.data());
ASSERT_EQ(expected_result, sts);
ASSERT_NO_FATAL_FAILURE(TestDecryptCTR());
@@ -625,7 +626,7 @@ void Session::SetLoadKeysSubstringParams() {
load_keys_params_.resize(4);
std::string message =
wvcdm::BytesToString(message_ptr(), sizeof(MessageData));
OEMCrypto_Substring* enc_mac_keys_iv = &load_keys_params_[0];
OEMCrypto_Substring* enc_mac_keys_iv = load_keys_params_.data();
*enc_mac_keys_iv = GetSubstring(
message, wvcdm::BytesToString(encrypted_license().mac_key_iv,
sizeof(encrypted_license().mac_key_iv)));
@@ -648,7 +649,7 @@ void Session::EncryptAndSign() {
uint8_t iv_buffer[16];
memcpy(iv_buffer, &license_.mac_key_iv[0], KEY_IV_SIZE);
AES_KEY aes_key;
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
AES_set_encrypt_key(enc_key_.data(), 128, &aes_key);
AES_cbc_encrypt(&license_.mac_keys[0], &encrypted_license().mac_keys[0],
2 * MAC_KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
@@ -661,7 +662,7 @@ void Session::EncryptAndSign() {
KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
memcpy(iv_buffer, &license_.keys[i].key_iv[0], KEY_IV_SIZE);
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
AES_set_encrypt_key(enc_key_.data(), 128, &aes_key);
AES_cbc_encrypt(
&license_.keys[i].key_data[0], &encrypted_license().keys[i].key_data[0],
license_.keys[i].key_data_length, &aes_key, iv_buffer, AES_ENCRYPT);
@@ -695,7 +696,7 @@ void Session::ServerSignBuffer(const uint8_t* data, size_t data_length,
ASSERT_LE(data_length, kMaxMessageSize);
signature->assign(SHA256_DIGEST_LENGTH, 0);
unsigned int md_len = SHA256_DIGEST_LENGTH;
HMAC(EVP_sha256(), &mac_key_server_[0], mac_key_server_.size(), data,
HMAC(EVP_sha256(), mac_key_server_.data(), mac_key_server_.size(), data,
data_length, &(signature->front()), &md_len);
}
@@ -703,7 +704,7 @@ void Session::ClientSignMessage(const vector<uint8_t>& data,
std::vector<uint8_t>* signature) {
signature->assign(SHA256_DIGEST_LENGTH, 0);
unsigned int md_len = SHA256_DIGEST_LENGTH;
HMAC(EVP_sha256(), &mac_key_client_[0], mac_key_client_.size(),
HMAC(EVP_sha256(), mac_key_client_.data(), mac_key_client_.size(),
&(data.front()), data.size(), &(signature->front()), &md_len);
}
@@ -714,13 +715,14 @@ void Session::VerifyClientSignature(size_t data_length) {
for (size_t i = 0; i < data.size(); i++) data[i] = i % 0xFF;
OEMCryptoResult sts;
size_t gen_signature_length = 0;
sts = OEMCrypto_GenerateSignature(session_id(), &data[0], data.size(), NULL,
&gen_signature_length);
sts = OEMCrypto_GenerateSignature(session_id(), data.data(), data.size(),
NULL, &gen_signature_length);
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts);
ASSERT_EQ(static_cast<size_t>(32), gen_signature_length);
vector<uint8_t> gen_signature(gen_signature_length);
sts = OEMCrypto_GenerateSignature(session_id(), &data[0], data.size(),
&gen_signature[0], &gen_signature_length);
sts = OEMCrypto_GenerateSignature(session_id(), data.data(), data.size(),
gen_signature.data(),
&gen_signature_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
std::vector<uint8_t> expected_signature;
ClientSignMessage(data, &expected_signature);
@@ -809,12 +811,12 @@ void Session::TestDecryptCTR(bool select_key_first,
vector<uint8_t> unencryptedData(256);
for (size_t i = 0; i < unencryptedData.size(); i++)
unencryptedData[i] = i % 256;
EXPECT_EQ(1, GetRandBytes(&unencryptedData[0], unencryptedData.size()));
EXPECT_EQ(1, GetRandBytes(unencryptedData.data(), unencryptedData.size()));
vector<uint8_t> encryptionIv(KEY_IV_SIZE);
EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], KEY_IV_SIZE));
EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), KEY_IV_SIZE));
vector<uint8_t> encryptedData(unencryptedData.size());
EncryptCTR(unencryptedData, license_.keys[key_index].key_data,
&encryptionIv[0], &encryptedData);
encryptionIv.data(), &encryptedData);
// Describe the output
vector<uint8_t> outputBuffer(256);
@@ -828,8 +830,8 @@ void Session::TestDecryptCTR(bool select_key_first,
pattern.offset = 0;
// Decrypt the data
sts = OEMCrypto_DecryptCENC(
session_id(), &encryptedData[0], encryptedData.size(), true,
&encryptionIv[0], 0, &destBuffer, &pattern,
session_id(), encryptedData.data(), encryptedData.size(), true,
encryptionIv.data(), 0, &destBuffer, &pattern,
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample);
// We only have a few errors that we test are reported.
if (expected_result == OEMCrypto_SUCCESS) { // No error.
@@ -886,7 +888,7 @@ void Session::LoadOEMCert(bool verify_cert) {
ASSERT_LT(0u, public_cert_length);
public_cert.resize(public_cert_length);
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_GetOEMPublicCertificate(session_id(), &public_cert[0],
OEMCrypto_GetOEMPublicCertificate(session_id(), public_cert.data(),
&public_cert_length));
// Load the certificate chain into a BoringSSL X509 Stack
@@ -921,7 +923,7 @@ void Session::LoadOEMCert(bool verify_cert) {
X509_NAME* name = X509_get_subject_name(x509_cert);
printf(" OEM Certificate Name: %s\n",
X509_NAME_oneline(name, &buffer[0], buffer.size()));
X509_NAME_oneline(name, buffer.data(), buffer.size()));
boringssl_ptr<X509_STORE, X509_STORE_free> store(X509_STORE_new());
ASSERT_TRUE(store.NotNull());
boringssl_ptr<X509_STORE_CTX, X509_STORE_CTX_free> store_ctx(
@@ -979,16 +981,17 @@ void Session::RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted,
const uint8_t* message_ptr = reinterpret_cast<const uint8_t*>(&encrypted);
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
OEMCrypto_RewrapDeviceRSAKey(
session_id(), message_ptr, message_size, &signature[0],
session_id(), message_ptr, message_size, signature.data(),
signature.size(), &encrypted.nonce, encrypted.rsa_key,
encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL,
&wrapped_key_length));
wrapped_key->clear();
wrapped_key->assign(wrapped_key_length, 0);
OEMCryptoResult sts = OEMCrypto_RewrapDeviceRSAKey(
session_id(), message_ptr, message_size, &signature[0], signature.size(),
&encrypted.nonce, encrypted.rsa_key, encrypted.rsa_key_length,
encrypted.rsa_key_iv, &(wrapped_key->front()), &wrapped_key_length);
session_id(), message_ptr, message_size, signature.data(),
signature.size(), &encrypted.nonce, encrypted.rsa_key,
encrypted.rsa_key_length, encrypted.rsa_key_iv, &(wrapped_key->front()),
&wrapped_key_length);
if (force) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
}
@@ -1003,14 +1006,14 @@ void Session::RewrapRSAKey30(const struct RSAPrivateKeyMessage& encrypted,
size_t wrapped_key_length = 0;
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
OEMCrypto_RewrapDeviceRSAKey30(
session_id(), &nonce_, &encrypted_message_key[0],
session_id(), &nonce_, encrypted_message_key.data(),
encrypted_message_key.size(), encrypted.rsa_key,
encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL,
&wrapped_key_length));
wrapped_key->clear();
wrapped_key->assign(wrapped_key_length, 0);
OEMCryptoResult sts = OEMCrypto_RewrapDeviceRSAKey30(
session_id(), &nonce_, &encrypted_message_key[0],
session_id(), &nonce_, encrypted_message_key.data(),
encrypted_message_key.size(), encrypted.rsa_key, encrypted.rsa_key_length,
encrypted.rsa_key_iv, &(wrapped_key->front()), &wrapped_key_length);
if (force) {
@@ -1121,16 +1124,18 @@ void Session::VerifyRSASignature(const vector<uint8_t>& message,
boringssl_ptr<EVP_PKEY, EVP_PKEY_free> pkey(EVP_PKEY_new());
ASSERT_EQ(1, EVP_PKEY_set1_RSA(pkey.get(), public_rsa_));
const bool ok = VerifyPSSSignature(pkey.get(), &message[0], message.size(),
signature, signature_length);
const bool ok = VerifyPSSSignature(
pkey.get(), message.data(), message.size(), signature,
signature_length);
EXPECT_TRUE(ok) << "PSS signature check failed.";
} else if (padding_scheme == kSign_PKCS1_Block1) {
vector<uint8_t> padded_digest(signature_length);
int size;
// RSA_public_decrypt decrypts the signature, and then verifies that
// it was padded with RSA PKCS1 padding.
size = RSA_public_decrypt(signature_length, signature, &padded_digest[0],
public_rsa_, RSA_PKCS1_PADDING);
size = RSA_public_decrypt(
signature_length, signature, padded_digest.data(), public_rsa_,
RSA_PKCS1_PADDING);
EXPECT_GT(size, 0);
padded_digest.resize(size);
EXPECT_EQ(message, padded_digest);
@@ -1161,7 +1166,7 @@ bool Session::GenerateRSASessionKey(vector<uint8_t>* session_key,
void Session::InstallRSASessionTestKey(const vector<uint8_t>& wrapped_rsa_key) {
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_LoadDeviceRSAKey(session_id(), &wrapped_rsa_key[0],
OEMCrypto_LoadDeviceRSAKey(session_id(), wrapped_rsa_key.data(),
wrapped_rsa_key.size()));
GenerateDerivedKeysFromSessionKey();
}
@@ -1189,8 +1194,8 @@ void Session::UpdateUsageEntry(std::vector<uint8_t>* header_buffer) {
encrypted_usage_entry_.resize(entry_buffer_length);
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_UpdateUsageEntry(
session_id(), &(header_buffer->front()), &header_buffer_length,
&encrypted_usage_entry_[0], &entry_buffer_length));
session_id(), header_buffer->data(), &header_buffer_length,
encrypted_usage_entry_.data(), &entry_buffer_length));
}
void Session::DeactivateUsageEntry(const std::string& pst) {
@@ -1205,7 +1210,8 @@ void Session::LoadUsageEntry(uint32_t index, const vector<uint8_t>& buffer) {
encrypted_usage_entry_ = buffer;
ASSERT_EQ(
OEMCrypto_SUCCESS,
OEMCrypto_LoadUsageEntry(session_id(), index, &buffer[0], buffer.size()));
OEMCrypto_LoadUsageEntry(
session_id(), index, buffer.data(), buffer.size()));
}
void Session::MoveUsageEntry(uint32_t new_index,
@@ -1233,7 +1239,7 @@ void Session::GenerateReport(const std::string& pst,
size_t length = 0;
OEMCryptoResult sts = OEMCrypto_ReportUsage(
session_id(), reinterpret_cast<const uint8_t*>(pst.c_str()), pst.length(),
&pst_report_buffer_[0], &length);
pst_report_buffer_.data(), &length);
if (expected_result == OEMCrypto_SUCCESS) {
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts);
}
@@ -1243,7 +1249,7 @@ void Session::GenerateReport(const std::string& pst,
}
sts = OEMCrypto_ReportUsage(session_id(),
reinterpret_cast<const uint8_t*>(pst.c_str()),
pst.length(), &pst_report_buffer_[0], &length);
pst.length(), pst_report_buffer_.data(), &length);
ASSERT_EQ(expected_result, sts);
if (expected_result != OEMCrypto_SUCCESS) {
return;
@@ -1251,10 +1257,10 @@ void Session::GenerateReport(const std::string& pst,
ASSERT_EQ(pst_report_buffer_.size(), length);
vector<uint8_t> computed_signature(SHA_DIGEST_LENGTH);
unsigned int sig_len = SHA_DIGEST_LENGTH;
HMAC(EVP_sha1(), &mac_key_client_[0], mac_key_client_.size(),
HMAC(EVP_sha1(), mac_key_client_.data(), mac_key_client_.size(),
&pst_report_buffer_[SHA_DIGEST_LENGTH], length - SHA_DIGEST_LENGTH,
&computed_signature[0], &sig_len);
EXPECT_EQ(0, memcmp(&computed_signature[0], pst_report().signature(),
computed_signature.data(), &sig_len);
EXPECT_EQ(0, memcmp(computed_signature.data(), pst_report().signature(),
SHA_DIGEST_LENGTH));
EXPECT_GE(kInactiveUnused, pst_report().status());
EXPECT_GE(kHardwareSecureClock, pst_report().clock_security_level());
@@ -1287,14 +1293,14 @@ void Session::VerifyPST(const Test_PST_Report& expected) {
}
std::vector<uint8_t> signature(SHA_DIGEST_LENGTH);
unsigned int md_len = SHA_DIGEST_LENGTH;
if (!HMAC(EVP_sha1(), &mac_key_client_[0], mac_key_client_.size(),
&pst_report_buffer_[0] + SHA_DIGEST_LENGTH,
pst_report_buffer_.size() - SHA_DIGEST_LENGTH,
&signature[0], &md_len)) {
if (!HMAC(EVP_sha1(), mac_key_client_.data(), mac_key_client_.size(),
pst_report_buffer_.data() + SHA_DIGEST_LENGTH,
pst_report_buffer_.size() - SHA_DIGEST_LENGTH,
signature.data(), &md_len)) {
cout << "Error computing HMAC.\n";
dump_boringssl_error();
}
EXPECT_EQ(0, memcmp(computed.signature(), &signature[0],
EXPECT_EQ(0, memcmp(computed.signature(), signature.data(),
SHA_DIGEST_LENGTH));
}
@@ -1336,8 +1342,8 @@ void Session::CreateOldEntry(const Test_PST_Report& report) {
report.seconds_since_license_received,
report.seconds_since_first_decrypt,
report.seconds_since_last_decrypt,
report.status, &mac_key_server_[0],
&mac_key_client_[0],
report.status, mac_key_server_.data(),
mac_key_client_.data(),
reinterpret_cast<const uint8_t*>(report.pst.c_str()),
report.pst.length());
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) return;

File diff suppressed because it is too large Load Diff