Files
media_cas_packager_sdk_source/common/rot_id_generator.cc
2020-01-27 16:05:15 -08:00

108 lines
3.4 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// Copyright 2019 Google LLC.
//
// This software is licensed under the terms defined in the Widevine Master
// License Agreement. For a copy of this agreement, please contact
// widevine-licensing@google.com.
////////////////////////////////////////////////////////////////////////////////
//
// Description:
// Classes for generating and decrypting the root of trust id which is
// included in generated DRM Certificates.
#include "common/rot_id_generator.h"
#include <memory>
#include "glog/logging.h"
#include "absl/strings/str_cat.h"
#include "common/crypto_util.h"
#include "common/ec_key.h"
#include "common/rot_id_util.h"
#include "common/sha_util.h"
#include "common/status.h"
#include "protos/public/drm_certificate.pb.h"
namespace {
constexpr char kRotIdLabel[] = "ROOT_OF_TRUST_ID ENCRYPTION LABEL";
constexpr int32_t kKeyId = 0;
std::string GenerateContext(uint32_t system_id) {
return absl::StrCat(kRotIdLabel, system_id);
}
} // anonymous namespace
namespace widevine {
Status RootOfTrustIdGenerator::Generate(uint32_t system_id,
const std::string& unique_id,
RootOfTrustId* root_of_trust_id) const {
CHECK(root_of_trust_id != nullptr) << "root_of_trust_id was null.";
if (system_id == 0) {
return Status(error::INVALID_ARGUMENT, "system id should not be 0.");
}
if (unique_id.empty()) {
return Status(error::INVALID_ARGUMENT,
"The unique id should not be empty.");
}
root_of_trust_id->set_version(
widevine::RootOfTrustId::ROOT_OF_TRUST_ID_VERSION_1);
root_of_trust_id->set_key_id(kKeyId);
if (!ecies_encryptor_->Encrypt(
unique_id, GenerateContext(system_id),
root_of_trust_id->mutable_encrypted_unique_id())) {
root_of_trust_id->Clear();
return Status(error::INTERNAL, "Encrypt failed.");
}
std::string unique_id_hash = GenerateUniqueIdHash(unique_id);
if (unique_id_hash.empty()) {
root_of_trust_id->Clear();
return Status(error::INTERNAL, "Could not generate unique id hash.");
}
root_of_trust_id->set_unique_id_hash(GenerateRotIdHash(
root_of_trust_id->encrypted_unique_id(), system_id, unique_id_hash));
if (root_of_trust_id->unique_id_hash().empty()) {
root_of_trust_id->Clear();
return Status(error::INTERNAL, "Failed to generate revoked id hash.");
}
return OkStatus();
}
std::string RootOfTrustIdGenerator::GenerateUniqueIdHash(
const std::string& unique_id) const {
if (unique_id.empty()) {
LOG(WARNING) << "unique_id should not be empty.";
return "";
}
return Sha256_Hash(absl::StrCat(unique_id, wv_shared_salt_));
}
Status RootOfTrustIdDecryptor::DecryptUniqueId(
uint32_t system_id, const std::string& rot_encrypted_id,
std::string* unique_id) const {
CHECK(unique_id != nullptr) << "unique_id was null.";
if (system_id == 0) {
return Status(error::INVALID_ARGUMENT, "system id should not be 0.");
}
if (rot_encrypted_id.empty()) {
return Status(error::INVALID_ARGUMENT,
"The rot_encrypted_id should not be empty.");
}
if (!ecies_decryptor_->Decrypt(rot_encrypted_id, GenerateContext(system_id),
unique_id)) {
return Status(error::INTERNAL, "Failed to decrypt rot_encrypted_id");
}
return OkStatus();
}
} // namespace widevine