These are a set of CLs merged from the wv cdm repo to the android repo. * Enable Cast for Android Things build. Author: Thoren Paulson <thoren@google.com> [ Merge of http://go/wvgerrit/29941 ] Added a path to make_cast_libwvlevel3 for Android Things. Added the new system id to the preprocessor guards in android_keybox.cpp. Guarded the references to stderr in page_allocator.cpp because for some reason they don't get resolved when we link against the resulting library. BUG: 63443584 * Resolve memory leaks in use of OpenSSL. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/32700 ] Use of EVP_CIPHER_CTX requires a call to EVP_CIPHER_CTX_cleanup(). * Memory leak in OpenSSL RSA key handling. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/32621 ] This fixes a range of tests. --gtest_filter="CdmDecrypt*" runs five tests and still loses 5 objects totalling 1320 bytes (down from 6200 bytes). * Unit test and mock OEMCrypto memory leaks. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/32640 ] More memory leak cleanup. All remaining leaks are due to calls to CRYPTO_malloc() without the matching free (i.e., calls into openssl). * Clean up memory leaks in tests. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/32600 ] This is the first pass at cleaning up memory leaks. These leaks were affecting a lot of tests, making it hard to identify more serious leaks. Switch to unique_ptr<> pointers for CdmEngine in generic_crypto_unittest tests for FileSystem object in mock OEMCrypto's CryptoEngine object. * Fix broken tests - linux-only & address sanitizer failures. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/32460 ] Fix broken test: WvCdmEnginePreProvTestStaging.ServiceCertificateInitialNoneTest Fix failures found by address sanitizer: DeviceFilesUsageInfoTest.RetrieveByProviderSessionToken DeviceFilesUsageInfoTest.UpdateUsageInfo NOTE: address sanitizer cannot handle EXPECT_CALL macros containing a call with a Contains matcher as an argument, e.g.: EXPECT_CALL(file, Write(Contains(certificate, wrapped_private_key, 0), Gt(certificate.size() + wrapped_private_key.size()))) The address sanitizer reports a crash, issues a report, and stops. A temporary fix is to replace the "Contains()" argument with "_". * Usage license handling corrections Author: Rahul Frias <rfrias@google.com> [ Merge of http://go/wvgerrit/28540 ] Validate that offline licenses that do not contain a provider session token are not handled by the TEE. BUG: 38490468 Test: WV Unit/integration tests, GtsMediaTestCases, WvCdmRequestLicenseTest.ReleaseRetryL3OfflineKeySessionUsageDisabledTest * UsageTableEntry::CopyOldUsageEntry memcpy read out of range. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/32220 ] The function copies the pst from a variable length input vector into a 256 byte character array. But the length argument was a fixed value - MAC_KEY_SIZE. Depending on the actual PST length this can lead to memcpy reading out of bounds or the PST getting truncated. BUG: 71650075 Test: Not currently passing. Will be addressed in a subsequent commit in the chain. Change-Id: I81a4593d7d04d0ef6069ce48d0601b6fbdd85de9
261 lines
12 KiB
C++
261 lines
12 KiB
C++
// Copyright 2016 Google Inc. All Rights Reserved.
|
|
//
|
|
// This file contains definitions for metrics being collected throughout the
|
|
// CDM.
|
|
|
|
#ifndef WVCDM_METRICS_METRICS_GROUP_H_
|
|
#define WVCDM_METRICS_METRICS_GROUP_H_
|
|
|
|
#include <ostream>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include "event_metric.h"
|
|
#include "metrics.pb.h"
|
|
#include "OEMCryptoCENC.h"
|
|
#include "wv_cdm_types.h"
|
|
|
|
// This definition indicates that a given metric does not need timing
|
|
// stats. Example:
|
|
//
|
|
// M_RECORD(my_metrics, my_metric_name, NO_TIME);
|
|
#define NO_TIME 0
|
|
|
|
// Used to record metric timing and additional information about a specific
|
|
// event. Assumes that a microsecond timing has been provided. Example:
|
|
//
|
|
// long total_time = 0;
|
|
// long error_code = TimeSomeOperation(&total_time);
|
|
// M_RECORD(my_metrics, my_metric_name, total_time, error_code);
|
|
#define M_RECORD(GROUP, METRIC, TIME, ...) \
|
|
if ( GROUP ) { \
|
|
( GROUP ) -> METRIC . Record( TIME, ##__VA_ARGS__ ); \
|
|
}
|
|
|
|
// This definition automatically times an operation and records the time and
|
|
// additional information such as error code to the provided metric.
|
|
// Example:
|
|
//
|
|
// OEMCryptoResult sts;
|
|
// M_TIME(
|
|
// sts = OEMCrypto_Initialize(),
|
|
// my_metrics_collection,
|
|
// oemcrypto_initialize_,
|
|
// sts);
|
|
#define M_TIME(CALL, GROUP, METRIC, ...) \
|
|
if ( GROUP ) { \
|
|
wvcdm::metrics::TimerMetric timer; \
|
|
timer.Start(); \
|
|
CALL; \
|
|
( GROUP ) -> METRIC . Record(timer.AsUs(), ##__VA_ARGS__ ); \
|
|
} else { \
|
|
CALL; \
|
|
}
|
|
|
|
namespace wvcdm {
|
|
namespace metrics {
|
|
|
|
// This enum defines the conditions encountered during OEMCrypto Initialization
|
|
// in oemcrypto_adapter_dynamic.
|
|
typedef enum OEMCryptoInitializationMode {
|
|
OEMCrypto_INITIALIZED_USING_IN_APP = 0,
|
|
OEMCrypto_INITIALIZED_FORCING_L3 = 1,
|
|
OEMCrypto_INITIALIZED_USING_L3_NO_L1_LIBRARY_PATH = 2,
|
|
OEMCrypto_INITIALIZED_USING_L3_L1_OPEN_FAILED = 3,
|
|
OEMCrypto_INITIALIZED_USING_L3_L1_LOAD_FAILED = 4,
|
|
OEMCrypto_INITIALIZED_USING_L3_COULD_NOT_INITIALIZE_L1 = 5,
|
|
OEMCrypto_INITIALIZED_USING_L3_WRONG_L1_VERSION = 6,
|
|
OEMCrypto_INITIALIZED_USING_L1_WITH_KEYBOX = 7,
|
|
OEMCrypto_INITIALIZED_USING_L1_WITH_CERTIFICATE = 8,
|
|
OEMCrypto_INITIALIZED_USING_L1_CERTIFICATE_MIX = 9,
|
|
OEMCrypto_INITIALIZED_USING_L3_BAD_KEYBOX = 10,
|
|
OEMCrypto_INITIALIZED_USING_L3_COULD_NOT_OPEN_FACTORY_KEYBOX = 11,
|
|
OEMCrypto_INITIALIZED_USING_L3_COULD_NOT_INSTALL_KEYBOX = 12,
|
|
OEMCrypto_INITIALIZED_USING_L1_INSTALLED_KEYBOX = 13,
|
|
OEMCrypto_INITIALIZED_USING_L3_INVALID_L1 = 14,
|
|
OEMCrypto_INITIALIZED_USING_L1_WITH_PROVISIONING_3_0 = 15,
|
|
OEMCrypto_INITIALIZED_L3_INITIALIZATION_FAILED = 16
|
|
} OEMCryptoInitializationMode;
|
|
|
|
|
|
// This class contains metrics for Crypto Session and OEM Crypto.
|
|
class CryptoMetrics {
|
|
public:
|
|
CryptoMetrics();
|
|
|
|
void Serialize(drm_metrics::MetricsGroup* metrics);
|
|
|
|
/* CRYPTO SESSION */
|
|
EventMetric<CdmResponseType> crypto_session_delete_all_usage_reports_;
|
|
EventMetric<CdmResponseType> crypto_session_delete_multiple_usage_information_;
|
|
EventMetric<CdmResponseType, Pow2Bucket, CdmEncryptionAlgorithm> crypto_session_generic_decrypt_;
|
|
EventMetric<CdmResponseType, Pow2Bucket, CdmEncryptionAlgorithm> crypto_session_generic_encrypt_;
|
|
EventMetric<CdmResponseType, Pow2Bucket, CdmSigningAlgorithm> crypto_session_generic_sign_;
|
|
EventMetric<CdmResponseType, Pow2Bucket, CdmSigningAlgorithm> crypto_session_generic_verify_;
|
|
EventMetric<bool> crypto_session_get_device_unique_id_;
|
|
EventMetric<CdmSecurityLevel> crypto_session_get_security_level_;
|
|
EventMetric<bool, uint32_t> crypto_session_get_system_id_;
|
|
EventMetric<bool> crypto_session_get_token_;
|
|
EventMetric<> crypto_session_life_span_;
|
|
EventMetric<bool> crypto_session_load_certificate_private_key_;
|
|
EventMetric<CdmResponseType, SecurityLevel> crypto_session_open_;
|
|
EventMetric<CdmResponseType> crypto_session_update_usage_information_;
|
|
EventMetric<bool> crypto_session_usage_information_support_;
|
|
/* OEMCRYPTO */
|
|
EventMetric<uint32_t, SecurityLevel> oemcrypto_api_version_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_close_session_;
|
|
EventMetric<OEMCryptoResult, SecurityLevel, Pow2Bucket> oemcrypto_copy_buffer_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_deactivate_usage_entry_;
|
|
EventMetric<OEMCryptoResult, Pow2Bucket> oemcrypto_decrypt_cenc_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_delete_usage_entry_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_delete_usage_table_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_derive_keys_from_session_key_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_force_delete_usage_entry_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_generate_derived_keys_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_generate_nonce_;
|
|
EventMetric<OEMCryptoResult, Pow2Bucket> oemcrypto_generate_rsa_signature_;
|
|
EventMetric<OEMCryptoResult, Pow2Bucket> oemcrypto_generate_signature_;
|
|
EventMetric<OEMCryptoResult, Pow2Bucket> oemcrypto_generic_decrypt_;
|
|
EventMetric<OEMCryptoResult, Pow2Bucket> oemcrypto_generic_encrypt_;
|
|
EventMetric<OEMCryptoResult, Pow2Bucket> oemcrypto_generic_sign_;
|
|
EventMetric<OEMCryptoResult, Pow2Bucket> oemcrypto_generic_verify_;
|
|
EventMetric<OEMCryptoResult, SecurityLevel> oemcrypto_get_device_id_;
|
|
EventMetric<OEMCryptoResult, SecurityLevel> oemcrypto_get_hdcp_capability_;
|
|
EventMetric<OEMCryptoResult, Pow2Bucket, SecurityLevel> oemcrypto_get_key_data_;
|
|
EventMetric<OEMCryptoResult, SecurityLevel> oemcrypto_get_max_number_of_sessions_;
|
|
EventMetric<OEMCryptoResult, SecurityLevel> oemcrypto_get_number_of_open_sessions_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_get_oem_public_certificate_;
|
|
EventMetric<OEMCrypto_ProvisioningMethod, SecurityLevel> oemcrypto_get_provisioning_method_;
|
|
EventMetric<OEMCryptoResult, Pow2Bucket> oemcrypto_get_random_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_initialize_;
|
|
EventMetric<OEMCryptoResult, SecurityLevel> oemcrypto_install_keybox_;
|
|
EventMetric<bool, SecurityLevel> oemcrypto_is_anti_rollback_hw_present_;
|
|
EventMetric<OEMCryptoResult, SecurityLevel> oemcrypto_is_keybox_valid_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_load_device_rsa_key_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_load_keys_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_load_test_keybox_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_load_test_rsa_key_;
|
|
EventMetric<OEMCryptoResult, SecurityLevel> oemcrypto_open_session_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_refresh_keys_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_report_usage_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_rewrap_device_rsa_key_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_rewrap_device_rsa_key_30_;
|
|
EventMetric<CdmSecurityLevel, SecurityLevel> oemcrypto_security_level_;
|
|
EventMetric<uint8_t, SecurityLevel> oemcrypto_security_patch_level_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_select_key_;
|
|
EventMetric<OEMCryptoResult, SecurityLevel> oemcrypto_supports_usage_table_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_update_usage_table_;
|
|
EventMetric<OEMCryptoResult> oemcrypto_wrap_keybox_;
|
|
|
|
/* Internal OEMCrypto Metrics */
|
|
EventMetric<OEMCryptoInitializationMode> oemcrypto_initialization_mode_;
|
|
EventMetric<uint32_t, uint32_t> oemcrypto_l1_api_version_;
|
|
};
|
|
|
|
// This class contains session-scoped metrics. All properties and
|
|
// statistics related to operations within a single session are
|
|
// recorded here.
|
|
class SessionMetrics {
|
|
public:
|
|
SessionMetrics();
|
|
|
|
// Sets the session id of the metrics group. This allows the session
|
|
// id to be captured and reported as part of the collection of metrics.
|
|
void SetSessionId(const CdmSessionId& session_id) {
|
|
session_id_ = session_id; }
|
|
|
|
// Returns the session id or an empty session id if it has not been set.
|
|
const CdmSessionId& GetSessionId() const { return session_id_; }
|
|
|
|
// Marks the metrics object as completed and ready for serialization.
|
|
void SetCompleted() { completed_ = true; }
|
|
|
|
// Returns true if the object is completed. This is used to determine
|
|
// when the stats are ready to be published.
|
|
bool IsCompleted() const { return completed_; }
|
|
|
|
// Returns a pointer to the crypto metrics belonging to the engine instance.
|
|
// This instance retains ownership of the object.
|
|
CryptoMetrics* GetCryptoMetrics() { return &crypto_metrics_; }
|
|
|
|
// Metrics collected at the session level.
|
|
EventMetric<> cdm_session_life_span_;
|
|
EventMetric<CdmResponseType> cdm_session_renew_key_;
|
|
EventMetric<CdmResponseType> cdm_session_restore_offline_session_;
|
|
EventMetric<CdmResponseType> cdm_session_restore_usage_session_;
|
|
|
|
// Serialize the session metrics to the provided |metric_group|.
|
|
// |metric_group| is owned by the caller and must not be null.
|
|
void Serialize(drm_metrics::MetricsGroup* metric_group);
|
|
|
|
private:
|
|
void SerializeSessionMetrics(drm_metrics::MetricsGroup* metric_group);
|
|
CdmSessionId session_id_;
|
|
bool completed_;
|
|
CryptoMetrics crypto_metrics_;
|
|
};
|
|
|
|
// This class contains engine-scoped metrics. All properties and
|
|
// statistics related to operations within the engine, but outside
|
|
// the scope of a session are recorded here.
|
|
class EngineMetrics {
|
|
public:
|
|
EngineMetrics();
|
|
~EngineMetrics();
|
|
|
|
// Add a new SessionMetrics instance and return a pointer to the caller.
|
|
// The new SessionMetrics instance is owned by this EngineMetrics instance
|
|
// and will exist until RemoveSession is called or this object is deleted.
|
|
SessionMetrics* AddSession();
|
|
|
|
// Removes the metrics object for the given session id. This should only
|
|
// be called when the SessionMetrics instance is no longer in use.
|
|
void RemoveSession(CdmSessionId session_id);
|
|
|
|
// Returns a pointer to the crypto metrics belonging to the engine instance.
|
|
// The CryptoMetrics instance is still owned by this object and will exist
|
|
// until this object is deleted.
|
|
CryptoMetrics* GetCryptoMetrics() { return &crypto_metrics_; }
|
|
|
|
// Serialize engine and session metrics into a serialized MetricsGroup
|
|
// instance and output that instance to the provided |metric_group|.
|
|
// |metric_group| is owned by the caller and must NOT be null.
|
|
// |completed_only| indicates that this call should only publish
|
|
// SessionMetrics instances that are marked as completed.
|
|
// |clear_sessions| indicates that this call should clear sessions metrics
|
|
// for those sessions that were serialized. This allows atomic
|
|
// serialization and closing of session-level metrics.
|
|
void Serialize(drm_metrics::MetricsGroup* metric_group, bool completed_only,
|
|
bool clear_serialized_sessions);
|
|
|
|
// Metrics recorded at the engine level.
|
|
EventMetric<CdmResponseType> cdm_engine_add_key_;
|
|
EventMetric<CdmResponseType> cdm_engine_close_session_;
|
|
EventMetric<CdmResponseType> cdm_engine_decrypt_;
|
|
EventMetric<bool> cdm_engine_find_session_for_key_;
|
|
EventMetric<CdmResponseType> cdm_engine_generate_key_request_;
|
|
EventMetric<CdmResponseType> cdm_engine_get_provisioning_request_;
|
|
EventMetric<CdmResponseType> cdm_engine_get_usage_info_;
|
|
EventMetric<CdmResponseType> cdm_engine_handle_provisioning_response_;
|
|
EventMetric<> cdm_engine_life_span_;
|
|
EventMetric<CdmResponseType> cdm_engine_open_key_set_session_;
|
|
EventMetric<CdmResponseType> cdm_engine_open_session_;
|
|
EventMetric<CdmResponseType> cdm_engine_query_key_status_;
|
|
EventMetric<CdmResponseType> cdm_engine_release_all_usage_info_;
|
|
EventMetric<CdmResponseType> cdm_engine_release_usage_info_;
|
|
EventMetric<CdmResponseType> cdm_engine_remove_keys_;
|
|
EventMetric<CdmResponseType> cdm_engine_restore_key_;
|
|
EventMetric<CdmResponseType, CdmSecurityLevel> cdm_engine_unprovision_;
|
|
|
|
private:
|
|
Lock session_metrics_lock_;
|
|
std::vector<metrics::SessionMetrics*> session_metrics_list_;
|
|
CryptoMetrics crypto_metrics_;
|
|
|
|
void SerializeEngineMetrics(drm_metrics::MetricsGroup* out);
|
|
};
|
|
|
|
} // namespace metrics
|
|
} // namespace wvcdm
|
|
#endif
|