These are a set of CLs merged from the wv cdm repo to the android repo. * Make Android NDK Builds Work With Latest BoringSSL Author: John W. Bruce <juce@google.com> [ Merge of http://go/wvgerrit/37000 ] The latest updates to BoringSSL require C99 or later. Our NDK-based builds (OEMCrypto Variants & Fastball) were not specifying a C standard. This patch adds compiler flags so that C files are compiled as C11 now. Note that this is about the *C* standard in use, not the *C++* standard, which this patch leaves untouched. BUG: 67907873 Test: build_android_mock.sh * Update BoringSSL to f7412cb072cc6b1847140e0c4f8b3ceeccd0e708 Author: John W. Bruce <juce@google.com> [ Merge of http://go/wvgerrit/36761 ] This is the result of running UPDATE_BORINGSSL.sh. Future runs of this script should produce much smaller sets of changed files, but because the BoringSSL revision already in this directory was so old and contained many extraneous files from the Android operating system, the set of changed files is extensive this time. BUG: 67907873 * Refactoring the build files. Author: Vasantha Rao Polipelli <vasanthap@google.com> [ Merge of http://go/wvgerrit/37041 ] Move all common build dependencies to .gypi so that all fuzz test binary targets can be added to .gyp file without repeating code. * Introduce service certificate request property Author: Rahul Frias <rfrias@google.com> [ Merge of http://go/wvgerrit/36941 ] Platforms differ on whether they allows service certificates to be requested if privacy mode is enabled and a certificate is not present. This property allows behavior to be configurable. Generating the service certificate request will be introduced in a follow on CL. BUG: 68328352 * Deprecate using keyboxes as identification Author: Rahul Frias <rfrias@google.com> [ Merge of http://go/wvgerrit/36740 ] Previously some platforms supported using keyboxes rather than certificates as the identification tokens in the license request message. All platforms that share core CDM code of the master branch now either provision using a keybox and use a DRM certificate or an OEM certificate as identification. No future usage of keyboxes as identifying tokens is planned. Since the platform property use_certificates_as_identification is always set to true, the negative code paths are never taken and can be removed. * OEMCrypto_GenerateSignature API Fuzz Test. Author: Vasantha Rao Polipelli <vasanthap@google.com> [ Merge of http://go/wvgerrit/36863 ] - The first automated API fuzz test. - Also sumitting the corpus for the API fuzzed. * Add Script to Update BoringSSL from Source Author: John W. Bruce <juce@google.com> [ Merge of http://go/wvgerrit/36760 ] Adds a script to third_party/boringssl/ that, when run, deletes all the auto-generated files in the generated/ directory and regenerates them from scratch, starting from the latest public HEAD of BoringSSL. Bug: 67907873 * Fix Fastball / OEMCrypto Variant BoringSSL Makefiles Author: John W. Bruce <juce@google.com> [ Merge of http://go/wvgerrit/36926 ] Previously, when moving the BoringSSL source within the tree, I was not able to verify that I had not broken the NDK-compatible makefiles used by Fastball because that build is broken on master. I had to make a best-guess as to how they should be updated and hope. Now, however, I have been informed that the OEMCrypto Variants also use these makefiles, and I have been able to use that build to find where I broke them and get them fully working. Bug: 67386164 Test: build_android_mock.sh * Add kit/ to BoringSSL Include Path for Fastball & OEMCrypto Variants Author: John W. Bruce <juce@google.com> [ Merge of http://go/wvgerrit/36925 ] When I moved the BoringSSL source in the tree, I updated the Android.mk files that pointed to it in order to build it. I did not realize that some makefiles outside that directory also contained hardcoded pointers into that directory. These references broke after the move. This patch fixes those paths to point to the new BoringSSL location. Bug: 67386164 Test: build_android_mock.sh * OEMCrypto Unit Test Refactor. Author: Vasantha Rao Polipelli <vasanthap@google.com> [ Merge of http://go/wvgerrit/36562 ] Refactoring OEMCrypto Tests so the Session Utility test code can be reused in fuzz tests. * Reorder license server config table to match ids Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/36743 ] * Separate Hand-Written BoringSSL Files from Downloaded/Generated Ones Author: John W. Bruce <juce@google.com> [ Merge of http://go/wvgerrit/36561 ] I want to make updating BoringSSL as simple as possible for us going forward. A future commit will add a script that automatically downloads and sets up the latest version of BoringSSL. To facilitate this script, a clear distinction needs to be made between the files that can be downloaded with / regenerated from the BoringSSL source and the files that are maintained by us by hand. The version of BoringSSL in this change is exactly the same as the one already in this directory. It has just been moved one folder deeper. Bug: 67907873 * Remove BoringSSL Symlinks, They Are Confusing Gerrit Author: John W. Bruce <juce@google.com> [ Merge of http://go/wvgerrit/36560 ] There are some symlinks in the current copy of BoringSSL that are causing headaches when I try to upload future changes to Gerrit. These were inherited from the Android OS and are not used by our build anywhere. They would be wiped out when I update BoringSSL anyway, but wiping them out in a separate change before I upload any other changes avoids confusing Gerrit. Bug: 67907873 * Add group master key id to support sublicense master key rotation, and content identification. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/36180 ] * OEMCrypto Fuzzer test framework Author: Vasantha Rao Polipelli <vasanthap@google.com> [ Merge of http://go/wvgerrit/36280 ] - Adding a sample fuzz test. - Adding build scripts for building the new Fuzz Tests to come. Design doc: go/oemcrypt_ref_impl_fuzz * Build Mod Mock with C++ 11 Author: Fred Gylys-Colwell <fredgc@google.com> [ Merge of http://go/wvgerrit/36328 ] This should fix the android oemcrypto mock build: http://go/wvbuild/job/Android_OEMCrypto_Variants BUG: 71650075 Test: Not currently passing. Will be addressed in a subsequent commit in the chain. Change-Id: Ic4d5be3118ef97e3f7d386149a2b5d9be8f0a87e
304 lines
13 KiB
C++
304 lines
13 KiB
C++
// Copyright 2012 Google Inc. All Rights Reserved.
|
|
|
|
#ifndef WVCDM_CORE_CRYPTO_SESSSION_H_
|
|
#define WVCDM_CORE_CRYPTO_SESSSION_H_
|
|
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "OEMCryptoCENC.h"
|
|
#include "lock.h"
|
|
#include "metrics_collections.h"
|
|
#include "oemcrypto_adapter.h"
|
|
#include "OEMCryptoCENC.h"
|
|
#include "scoped_ptr.h"
|
|
#include "timer_metric.h"
|
|
#include "wv_cdm_types.h"
|
|
|
|
namespace wvcdm {
|
|
|
|
class CryptoKey;
|
|
class UsageTableHeader;
|
|
|
|
typedef std::map<std::string, CryptoKey*> CryptoKeyMap;
|
|
typedef std::map<std::string, CryptoSessionId> SubLicenseSessionMap;
|
|
|
|
class KeySession {
|
|
protected:
|
|
KeySession(metrics::CryptoMetrics* metrics) : metrics_(metrics) {}
|
|
|
|
public:
|
|
typedef enum { kDefault, kSubLicense } KeySessionType;
|
|
virtual ~KeySession() {}
|
|
virtual KeySessionType Type() = 0;
|
|
virtual bool GenerateDerivedKeys(const std::string& message) = 0;
|
|
virtual bool GenerateDerivedKeys(const std::string& message,
|
|
const std::string& session_key) = 0;
|
|
virtual OEMCryptoResult LoadKeys(const std::string& message,
|
|
const std::string& signature,
|
|
const std::string& mac_key_iv,
|
|
const std::string& mac_key,
|
|
const std::vector<CryptoKey>& keys,
|
|
const std::string& provider_session_token,
|
|
CdmCipherMode* cipher_mode,
|
|
const std::string& srm_requirement) = 0;
|
|
virtual OEMCryptoResult SelectKey(const std::string& key_id) = 0;
|
|
virtual OEMCryptoResult Decrypt(
|
|
const CdmDecryptionParameters& params,
|
|
OEMCrypto_DestBufferDesc& buffer_descriptor,
|
|
OEMCrypto_CENCEncryptPatternDesc& pattern_descriptor) = 0;
|
|
|
|
protected:
|
|
metrics::CryptoMetrics* metrics_;
|
|
};
|
|
|
|
class CryptoSession {
|
|
public:
|
|
typedef OEMCrypto_HDCP_Capability HdcpCapability;
|
|
typedef enum {
|
|
kUsageDurationsInvalid = 0,
|
|
kUsageDurationPlaybackNotBegun = 1,
|
|
kUsageDurationsValid = 2,
|
|
} UsageDurationStatus;
|
|
|
|
struct SupportedCertificateTypes {
|
|
bool rsa_2048_bit;
|
|
bool rsa_3072_bit;
|
|
bool rsa_cast;
|
|
};
|
|
|
|
// Creates an instance of CryptoSession with the given |crypto_metrics|.
|
|
// |crypto_metrics| is owned by the caller, must NOT be null, and must
|
|
// exist as long as the new CryptoSession exists.
|
|
explicit CryptoSession(metrics::CryptoMetrics* crypto_metrics);
|
|
virtual ~CryptoSession();
|
|
|
|
virtual bool GetClientToken(std::string* client_token);
|
|
virtual bool GetProvisioningToken(std::string* client_token);
|
|
virtual CdmClientTokenType GetPreProvisionTokenType() {
|
|
return pre_provision_token_type_;
|
|
}
|
|
virtual CdmSecurityLevel GetSecurityLevel();
|
|
virtual bool GetInternalDeviceUniqueId(std::string* device_id);
|
|
virtual bool GetExternalDeviceUniqueId(std::string* device_id);
|
|
virtual bool GetApiVersion(uint32_t* version);
|
|
virtual bool GetSystemId(uint32_t* system_id);
|
|
virtual bool GetProvisioningId(std::string* provisioning_id);
|
|
virtual uint8_t GetSecurityPatchLevel();
|
|
|
|
virtual CdmResponseType Open() { return Open(kLevelDefault); }
|
|
virtual CdmResponseType Open(SecurityLevel requested_security_level);
|
|
virtual void Close();
|
|
|
|
virtual bool IsOpen() { return open_; }
|
|
virtual CryptoSessionId oec_session_id() { return oec_session_id_; }
|
|
|
|
// Key request/response
|
|
virtual bool GenerateRequestId(std::string* req_id_str);
|
|
virtual bool PrepareRequest(const std::string& key_deriv_message,
|
|
bool is_provisioning, std::string* signature);
|
|
virtual bool PrepareRenewalRequest(const std::string& message,
|
|
std::string* signature);
|
|
virtual CdmResponseType LoadKeys(const std::string& message,
|
|
const std::string& signature,
|
|
const std::string& mac_key_iv,
|
|
const std::string& mac_key,
|
|
const std::vector<CryptoKey>& key_array,
|
|
const std::string& provider_session_token,
|
|
const std::string& srm_requirement);
|
|
virtual bool LoadCertificatePrivateKey(std::string& wrapped_key);
|
|
virtual bool RefreshKeys(const std::string& message,
|
|
const std::string& signature, int num_keys,
|
|
const CryptoKey* key_array);
|
|
virtual bool GenerateNonce(uint32_t* nonce);
|
|
virtual bool GenerateDerivedKeys(const std::string& message);
|
|
virtual bool GenerateDerivedKeys(const std::string& message,
|
|
const std::string& session_key);
|
|
virtual bool RewrapCertificate(const std::string& signed_message,
|
|
const std::string& signature,
|
|
const std::string& nonce,
|
|
const std::string& private_key,
|
|
const std::string& iv,
|
|
const std::string& wrapping_key,
|
|
std::string* wrapped_private_key);
|
|
|
|
// Media data path
|
|
virtual CdmResponseType Decrypt(const CdmDecryptionParameters& params);
|
|
|
|
// Usage related methods
|
|
virtual bool UsageInformationSupport(bool* has_support);
|
|
virtual CdmResponseType UpdateUsageInformation(); // only for OEMCrypto v9-12
|
|
virtual CdmResponseType DeactivateUsageInformation(
|
|
const std::string& provider_session_token);
|
|
virtual CdmResponseType GenerateUsageReport(
|
|
const std::string& provider_session_token, std::string* usage_report,
|
|
UsageDurationStatus* usage_duration_status,
|
|
int64_t* seconds_since_started, int64_t* seconds_since_last_played);
|
|
virtual CdmResponseType ReleaseUsageInformation(
|
|
const std::string& message, const std::string& signature,
|
|
const std::string& provider_session_token);
|
|
// Delete a usage information for a single token. This does not require
|
|
// a signed message from the server.
|
|
virtual CdmResponseType DeleteUsageInformation(
|
|
const std::string& provider_session_token);
|
|
// Delete usage information for a list of tokens. This does not require
|
|
// a signed message from the server.
|
|
virtual CdmResponseType DeleteMultipleUsageInformation(
|
|
const std::vector<std::string>& provider_session_tokens);
|
|
virtual CdmResponseType DeleteAllUsageReports();
|
|
virtual bool IsAntiRollbackHwPresent();
|
|
|
|
virtual bool GetHdcpCapabilities(HdcpCapability* current,
|
|
HdcpCapability* max);
|
|
virtual bool GetSupportedCertificateTypes(SupportedCertificateTypes* support);
|
|
virtual bool GetRandom(size_t data_length, uint8_t* random_data);
|
|
virtual bool GetNumberOfOpenSessions(size_t* count);
|
|
virtual bool GetMaxNumberOfSessions(size_t* max);
|
|
|
|
virtual bool GetSrmVersion(uint16_t* srm_version);
|
|
virtual bool IsSrmUpdateSupported();
|
|
virtual bool LoadSrm(const std::string& srm);
|
|
|
|
virtual CdmResponseType GenericEncrypt(const std::string& in_buffer,
|
|
const std::string& key_id,
|
|
const std::string& iv,
|
|
CdmEncryptionAlgorithm algorithm,
|
|
std::string* out_buffer);
|
|
virtual CdmResponseType GenericDecrypt(const std::string& in_buffer,
|
|
const std::string& key_id,
|
|
const std::string& iv,
|
|
CdmEncryptionAlgorithm algorithm,
|
|
std::string* out_buffer);
|
|
virtual CdmResponseType GenericSign(const std::string& message,
|
|
const std::string& key_id,
|
|
CdmSigningAlgorithm algorithm,
|
|
std::string* signature);
|
|
virtual CdmResponseType GenericVerify(const std::string& message,
|
|
const std::string& key_id,
|
|
CdmSigningAlgorithm algorithm,
|
|
const std::string& signature);
|
|
|
|
// Usage table header and usage entry related methods
|
|
virtual UsageTableHeader* GetUsageTableHeader() {
|
|
return usage_table_header_;
|
|
}
|
|
virtual CdmResponseType GetUsageSupportType(CdmUsageSupportType* type);
|
|
virtual CdmResponseType CreateUsageTableHeader(
|
|
CdmUsageTableHeader* usage_table_header);
|
|
virtual CdmResponseType LoadUsageTableHeader(
|
|
const CdmUsageTableHeader& usage_table_header);
|
|
virtual CdmResponseType CreateUsageEntry(uint32_t* entry_number);
|
|
virtual CdmResponseType LoadUsageEntry(uint32_t entry_number,
|
|
const CdmUsageEntry& usage_entry);
|
|
virtual CdmResponseType UpdateUsageEntry(
|
|
CdmUsageTableHeader* usage_table_header,
|
|
CdmUsageEntry* usage_entry);
|
|
virtual CdmResponseType ShrinkUsageTableHeader(
|
|
uint32_t new_entry_count, CdmUsageTableHeader* usage_table_header);
|
|
virtual CdmResponseType MoveUsageEntry(uint32_t new_entry_number);
|
|
virtual bool CreateOldUsageEntry(
|
|
uint64_t time_since_license_received,
|
|
uint64_t time_since_first_decrypt,
|
|
uint64_t time_since_last_decrypt,
|
|
UsageDurationStatus status,
|
|
const std::string& server_mac_key,
|
|
const std::string& client_mac_key,
|
|
const std::string& provider_session_token);
|
|
virtual CdmResponseType CopyOldUsageEntry(
|
|
const std::string& provider_session_token);
|
|
virtual metrics::CryptoMetrics* GetCryptoMetrics() { return metrics_; }
|
|
|
|
virtual CdmResponseType AddSubSession(const std::string& sub_session_key_id,
|
|
const std::string& group_master_key_id);
|
|
// TODO(jfore): exists is set based on whether a sub session exists. For now,
|
|
// that is not assumed to be an error.
|
|
virtual bool GenerateSubSessionNonce(const std::string& sub_session_key_id,
|
|
bool* exists, uint32_t* nonce);
|
|
|
|
private:
|
|
bool GetProvisioningMethod(CdmClientTokenType* token_type);
|
|
void Init();
|
|
void Terminate();
|
|
bool GetTokenFromKeybox(std::string* token);
|
|
bool GetTokenFromOemCert(std::string* token);
|
|
bool GenerateSignature(const std::string& message, std::string* signature);
|
|
bool GenerateRsaSignature(const std::string& message, std::string* signature);
|
|
|
|
bool SetDestinationBufferType();
|
|
|
|
bool RewrapDeviceRSAKey(
|
|
const std::string& message, const std::string& signature,
|
|
const std::string& nonce, const std::string& enc_rsa_key,
|
|
const std::string& rsa_key_iv, std::string* wrapped_rsa_key);
|
|
|
|
bool RewrapDeviceRSAKey30(
|
|
const std::string& message, const std::string& nonce,
|
|
const std::string& private_key, const std::string& iv,
|
|
const std::string& wrapping_key, std::string* wrapped_private_key);
|
|
|
|
CdmResponseType SelectKey(const std::string& key_id);
|
|
|
|
static const OEMCrypto_Algorithm kInvalidAlgorithm =
|
|
static_cast<OEMCrypto_Algorithm>(-1);
|
|
|
|
OEMCrypto_Algorithm GenericSigningAlgorithm(CdmSigningAlgorithm algorithm);
|
|
OEMCrypto_Algorithm GenericEncryptionAlgorithm(
|
|
CdmEncryptionAlgorithm algorithm);
|
|
size_t GenericEncryptionBlockSize(CdmEncryptionAlgorithm algorithm);
|
|
|
|
// These methods are used when a subsample exceeds the maximum buffer size
|
|
// that the device can handle.
|
|
OEMCryptoResult CopyBufferInChunks(
|
|
const CdmDecryptionParameters& params,
|
|
OEMCrypto_DestBufferDesc buffer_descriptor);
|
|
OEMCryptoResult DecryptInChunks(
|
|
const CdmDecryptionParameters& params,
|
|
const OEMCrypto_DestBufferDesc& full_buffer_descriptor,
|
|
const OEMCrypto_CENCEncryptPatternDesc& pattern_descriptor,
|
|
size_t max_chunk_size);
|
|
static void IncrementIV(uint64_t increase_by, std::vector<uint8_t>* iv_out);
|
|
|
|
static const size_t kAes128BlockSize = 16; // Block size for AES_CBC_128
|
|
static const size_t kSignatureSize = 32; // size for HMAC-SHA256 signature
|
|
static Lock crypto_lock_;
|
|
static bool initialized_;
|
|
static int session_count_;
|
|
|
|
metrics::CryptoMetrics* metrics_;
|
|
metrics::TimerMetric life_span_;
|
|
|
|
bool open_;
|
|
CdmClientTokenType pre_provision_token_type_;
|
|
std::string oem_token_; // Cached OEMCrypto Public Key
|
|
bool update_usage_table_after_close_session_;
|
|
CryptoSessionId oec_session_id_;
|
|
SubLicenseSessionMap sub_license_oec_sessions_;
|
|
// Used for sub license sessions.
|
|
std::string wrapped_key_;
|
|
scoped_ptr<KeySession> key_session_;
|
|
|
|
OEMCryptoBufferType destination_buffer_type_;
|
|
bool is_destination_buffer_type_valid_;
|
|
SecurityLevel requested_security_level_;
|
|
|
|
KeyId cached_key_id_;
|
|
|
|
bool is_usage_support_type_valid_;
|
|
CdmUsageSupportType usage_support_type_;
|
|
UsageTableHeader* usage_table_header_;
|
|
static UsageTableHeader* usage_table_header_l1_;
|
|
static UsageTableHeader* usage_table_header_l3_;
|
|
|
|
uint64_t request_id_base_;
|
|
static uint64_t request_id_index_;
|
|
|
|
CdmCipherMode cipher_mode_;
|
|
|
|
CORE_DISALLOW_COPY_AND_ASSIGN(CryptoSession);
|
|
};
|
|
|
|
} // namespace wvcdm
|
|
|
|
#endif // WVCDM_CORE_CRYPTO_SESSSION_H_
|