diff --git a/libwvdrmengine/Android.mk b/libwvdrmengine/Android.mk index 98b28a68..7f087bed 100644 --- a/libwvdrmengine/Android.mk +++ b/libwvdrmengine/Android.mk @@ -74,7 +74,6 @@ LOCAL_C_INCLUDES := \ vendor/widevine/libwvdrmengine/cdm/core/include \ vendor/widevine/libwvdrmengine/cdm/include \ vendor/widevine/libwvdrmengine/oemcrypto/include \ - vendor/widevine/libwvdrmengine/third_party/stringencoders/src LOCAL_HEADER_LIBRARIES := \ libutils_headers \ @@ -85,8 +84,6 @@ LOCAL_SHARED_LIBRARIES := \ SRC_DIR := cdm/src CORE_SRC_DIR := cdm/core/src LOCAL_SRC_FILES := \ - third_party/stringencoders/src/modp_b64.cpp \ - third_party/stringencoders/src/modp_b64w.cpp \ $(CORE_SRC_DIR)/properties.cpp \ $(CORE_SRC_DIR)/string_conversions.cpp \ $(SRC_DIR)/clock.cpp \ @@ -110,7 +107,6 @@ LOCAL_MODULE_CLASS := STATIC_LIBRARIES LOCAL_PROPRIETARY_MODULE := true CORE_PROTO_SRC_FILES := $(call all-proto-files-under, cdm/core/src) -METRICS_PROTO_SRC_FILES := $(call all-proto-files-under, cdm/metrics/src) LOCAL_SRC_FILES := $(CORE_PROTO_SRC_FILES) $(METRICS_PROTO_SRC_FILES) generated_sources_dir := $(call local-generated-sources-dir) @@ -123,8 +119,27 @@ generated_sources_dir := $(call local-generated-sources-dir) # with this path. LOCAL_EXPORT_C_INCLUDE_DIRS := \ $(generated_sources_dir)/proto \ - $(generated_sources_dir)/proto/$(LOCAL_PATH)/cdm/core/src \ - $(generated_sources_dir)/proto/$(LOCAL_PATH)/cdm/metrics/src + $(generated_sources_dir)/proto/$(LOCAL_PATH)/cdm/core/src + +include $(BUILD_STATIC_LIBRARY) + +# ----------------------------------------------------------------------------- +# Builds libhidl_utils.a +# +include $(CLEAR_VARS) + +LOCAL_MODULE := libhidl_utils + +LOCAL_MODULE_CLASS := STATIC_LIBRARIES + +LOCAL_C_INCLUDES := \ + vendor/widevine/libwvdrmengine/include_hidl + +LOCAL_SRC_FILES := \ + src_hidl/TypeConvert.cpp + +LOCAL_SHARED_LIBRARIES := \ + android.hardware.drm@1.0 include $(BUILD_STATIC_LIBRARY) @@ -221,6 +236,11 @@ LOCAL_STATIC_LIBRARIES := \ libwvdrmdrmplugin_hidl \ libwvlevel3 \ +# When the GNU linker sees a library, it discards all symbols that it doesn't +# need. libhidl_utils must come after both libwvdrmcryptoplugin and +# libwvdrmdrmplugin. +LOCAL_STATIC_LIBRARIES += libhidl_utils + LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ android.hidl.memory@1.0 \ diff --git a/libwvdrmengine/build_and_run_all_unit_tests.sh b/libwvdrmengine/build_and_run_all_unit_tests.sh index 65b9ad81..a0df822a 100755 --- a/libwvdrmengine/build_and_run_all_unit_tests.sh +++ b/libwvdrmengine/build_and_run_all_unit_tests.sh @@ -47,7 +47,7 @@ mm -j $NUM_CORES || mma -j $NUM_CORES # Detect the device and check if Verity is going to stop the script from working echo "waiting for device" -ADB_OUTPUT=`adb root && echo ". " && adb wait-for-device remount` +ADB_OUTPUT=`adb root && adb wait-for-device remount` echo $ADB_OUTPUT if echo $ADB_OUTPUT | grep -qi "verity"; then echo @@ -59,54 +59,42 @@ fi # Push the files to the device -# Given a local path to a file, this will try to push it to /data/bin. -# If that fails, an error message will be printed. +# Given a local path to a file, this will first try to push it to /vendor/bin +# and then, if that fails, to /data/widevine_tests. try_adb_push() { - # android-tests.zip requires /data/bin, we should use the same - if [ -f $OUT/data/bin/$1 ]; then - test_file=$OUT/data/bin/$1 - else - echo "I cannot find $1" - echo "I think it should be in $OUT/data/bin" - exit 1 + # Swallow the error message -- assume it is a read-only file system. + if ! adb push $@ /vendor/bin &> /dev/null; then + adb shell mkdir -p /data/widevine_tests + # If this fails, the user will get the error message. + adb push $@ /data/widevine_tests fi - adb shell mkdir -p /data/bin - adb push $test_file /data/bin/$1 } # Push the tests to the device -try_adb_push base64_test -try_adb_push buffer_reader_test -try_adb_push cdm_engine_test -try_adb_push cdm_feature_test -try_adb_push cdm_extended_duration_test -try_adb_push cdm_session_unittest -try_adb_push counter_metric_unittest -try_adb_push crypto_session_unittest -try_adb_push device_files_unittest -try_adb_push distribution_unittest -try_adb_push event_metric_unittest -try_adb_push file_store_unittest -try_adb_push file_utils_unittest -try_adb_push http_socket_test -try_adb_push initialization_data_unittest -try_adb_push libwvdrmdrmplugin_hidl_test -try_adb_push libwvdrmdrmplugin_test -try_adb_push libwvdrmengine_hidl_test -try_adb_push libwvdrmengine_test -try_adb_push libwvdrmmediacrypto_hidl_test -try_adb_push libwvdrmmediacrypto_test -try_adb_push license_keys_unittest -try_adb_push license_unittest -try_adb_push oemcrypto_test -try_adb_push policy_engine_constraints_unittest -try_adb_push policy_engine_unittest -try_adb_push request_license_test -try_adb_push service_certificate_unittest -try_adb_push timer_unittest -try_adb_push usage_table_header_unittest -try_adb_push value_metric_unittest -try_adb_push wv_cdm_metrics_test +try_adb_push $OUT/vendor/bin/oemcrypto_test +try_adb_push $OUT/vendor/bin/request_license_test +try_adb_push $OUT/vendor/bin/cdm_extended_duration_test +try_adb_push $OUT/vendor/bin/policy_engine_unittest +try_adb_push $OUT/vendor/bin/policy_engine_constraints_unittest +try_adb_push $OUT/vendor/bin/libwvdrmmediacrypto_test +try_adb_push $OUT/vendor/bin/libwvdrmmediacrypto_hidl_test +try_adb_push $OUT/vendor/bin/libwvdrmdrmplugin_test +try_adb_push $OUT/vendor/bin/libwvdrmdrmplugin_hidl_test +try_adb_push $OUT/vendor/bin/cdm_engine_test +try_adb_push $OUT/vendor/bin/cdm_session_unittest +try_adb_push $OUT/vendor/bin/file_store_unittest +try_adb_push $OUT/vendor/bin/file_utils_unittest +try_adb_push $OUT/vendor/bin/license_unittest +try_adb_push $OUT/vendor/bin/license_keys_unittest +try_adb_push $OUT/vendor/bin/initialization_data_unittest +try_adb_push $OUT/vendor/bin/device_files_unittest +try_adb_push $OUT/vendor/bin/service_certificate_unittest +try_adb_push $OUT/vendor/bin/timer_unittest +try_adb_push $OUT/vendor/bin/libwvdrmengine_test +try_adb_push $OUT/vendor/bin/libwvdrmengine_hidl_test +try_adb_push $OUT/vendor/bin/buffer_reader_test +try_adb_push $OUT/vendor/bin/distribution_test +try_adb_push $OUT/vendor/bin/event_metric_test # Run the tests using run_all_unit_tests.sh cd $ANDROID_BUILD_TOP/vendor/widevine/libwvdrmengine diff --git a/libwvdrmengine/cdm/Android.mk b/libwvdrmengine/cdm/Android.mk index 954cc5d2..17b918a3 100644 --- a/libwvdrmengine/cdm/Android.mk +++ b/libwvdrmengine/cdm/Android.mk @@ -9,16 +9,12 @@ LOCAL_C_INCLUDES := \ vendor/widevine/libwvdrmengine/cdm/metrics/include \ vendor/widevine/libwvdrmengine/cdm/include \ vendor/widevine/libwvdrmengine/oemcrypto/include \ - vendor/widevine/libwvdrmengine/third_party/stringencoders/src LOCAL_C_INCLUDES += \ external/jsmn \ external/protobuf/src \ -LOCAL_HEADER_LIBRARIES := \ - libutils_headers - -LOCAL_STATIC_LIBRARIES := libcdm_protos libcrypto +LOCAL_STATIC_LIBRARIES := libcdm_protos libcrypto_static SRC_DIR := src CORE_SRC_DIR := core/src @@ -28,6 +24,7 @@ LOCAL_SRC_FILES := \ $(CORE_SRC_DIR)/buffer_reader.cpp \ $(CORE_SRC_DIR)/cdm_engine.cpp \ $(CORE_SRC_DIR)/cdm_session.cpp \ + $(CORE_SRC_DIR)/cdm_session_map.cpp \ $(CORE_SRC_DIR)/certificate_provisioning.cpp \ $(CORE_SRC_DIR)/crypto_session.cpp \ $(CORE_SRC_DIR)/device_files.cpp \ @@ -38,18 +35,15 @@ LOCAL_SRC_FILES := \ $(CORE_SRC_DIR)/policy_engine.cpp \ $(CORE_SRC_DIR)/privacy_crypto_openssl.cpp \ $(CORE_SRC_DIR)/service_certificate.cpp \ - $(CORE_SRC_DIR)/usage_table_header.cpp \ $(SRC_DIR)/wv_content_decryption_module.cpp \ - $(METRICS_SRC_DIR)/counter_metric.cpp \ $(METRICS_SRC_DIR)/distribution.cpp \ $(METRICS_SRC_DIR)/event_metric.cpp \ - $(METRICS_SRC_DIR)/metrics_collections.cpp \ + $(METRICS_SRC_DIR)/metrics_front_end.cpp \ + $(METRICS_SRC_DIR)/metrics_group.cpp \ $(METRICS_SRC_DIR)/timer_metric.cpp \ - $(METRICS_SRC_DIR)/value_metric.cpp LOCAL_MODULE := libcdm LOCAL_MODULE_TAGS := optional -LOCAL_PROPRIETARY_MODULE := true include $(BUILD_STATIC_LIBRARY) diff --git a/libwvdrmengine/cdm/core/include/cdm_engine.h b/libwvdrmengine/cdm/core/include/cdm_engine.h index b600ad73..892578b1 100644 --- a/libwvdrmengine/cdm/core/include/cdm_engine.h +++ b/libwvdrmengine/cdm/core/include/cdm_engine.h @@ -3,20 +3,21 @@ #ifndef WVCDM_CORE_CDM_ENGINE_H_ #define WVCDM_CORE_CDM_ENGINE_H_ +#include #include #include +#include "cdm_session_map.h" #include "certificate_provisioning.h" #include "clock.h" #include "crypto_session.h" #include "file_store.h" #include "initialization_data.h" #include "lock.h" -#include "metrics_collections.h" #include "oemcrypto_adapter.h" #include "scoped_ptr.h" -#include "timer_metric.h" #include "service_certificate.h" +#include "timer_metric.h" #include "wv_cdm_constants.h" #include "wv_cdm_types.h" @@ -28,11 +29,9 @@ class CryptoEngine; class UsagePropertySet; class WvCdmEventListener; -typedef std::map CdmSessionMap; -typedef std::map< - CdmKeySetId, - std::pair > - CdmReleaseKeySetMap; +// Keep expiration time for each key set +typedef std::map > CdmReleaseKeySetMap; class CdmEngine { public: @@ -91,26 +90,7 @@ class CdmEngine { const CdmSessionId& session_id, const CdmKeySetId& key_set_id, const InitializationData& init_data, const CdmLicenseType license_type, CdmAppParameterMap& app_parameters, CdmKeyRequest* key_request); - // This API may - // (a) accept license response, extract key info and load keys. - // (b) accept a renewal response and update license policy information. - // (c) accept a release response and release an offline license or secure - // stop. - // (d) accept a service certificate and cache that information for the - // the lifetime of the session. - // - // |session_id| identifies the session that generated the request and can - // process the response. Should be empty if a release response. - // |key_data| is the license, renewal, release response or service - // certificate response. - // |key_set_id| should be non-null and specified if license release. - // If offline license or streaming license associated with - // a secure stop, |key_set_id| should be non-null and will - // be filled in on return. Use the |key_set_id| with - // RestoreKeys (to reload offline session) or - // GenerateKeyRequest (to release offline session/secure stop). - // |key_set_id| will be cleared if release or streaming - // (not associated with a secure stop). + // Accept license response and extract key info. virtual CdmResponseType AddKey(const CdmSessionId& session_id, const CdmKeyResponse& key_data, CdmKeySetId* key_set_id); @@ -178,25 +158,46 @@ class CdmEngine { // system. This will force the device to reprovision itself. virtual CdmResponseType Unprovision(CdmSecurityLevel security_level); + // Delete OEMCrypto usage tables. Used by Unprovision(). + virtual CdmResponseType DeleteUsageTable(CdmSecurityLevel security_level); + // Return the list of key_set_ids stored on the current (origin-specific) // file system. virtual CdmResponseType ListStoredLicenses( CdmSecurityLevel security_level, std::vector* key_set_ids); - // Delete OEMCrypto usage tables. Used by Unprovision(). - CdmResponseType DeleteUsageTable(CdmSecurityLevel security_level); + // Return the list of key_set_ids stored as usage records on the + // current (origin-specific) file system. + virtual CdmResponseType ListUsageRecords( + const std::string& app_id, CdmSecurityLevel security_level, + std::vector* ksids); + + // Delete the usage record for the given key_set_id. This removes the + // usage record in the file system and the OEMCrypto usage record. + virtual CdmResponseType DeleteUsageRecord(const std::string& app_id, + CdmSecurityLevel security_level, + const std::string& key_set_id); // Usage related methods for streaming licenses // Retrieve a random usage info from the list of all usage infos for this app // id. virtual CdmResponseType GetUsageInfo(const std::string& app_id, CdmUsageInfo* usage_info); + // Retrieve the usage info for the specified pst. // Returns UNKNOWN_ERROR if no usage info was found. virtual CdmResponseType GetUsageInfo(const std::string& app_id, const CdmSecureStopId& ssid, CdmUsageInfo* usage_info); + + // Release all usage records for the current origin. + virtual CdmResponseType ReleaseAllUsageInfo(const std::string& app_id, + CdmSecurityLevel security_level); + + // Release all usage records for the current origin. Span all + // security levels. virtual CdmResponseType ReleaseAllUsageInfo(const std::string& app_id); + virtual CdmResponseType ReleaseUsageInfo( const CdmUsageInfoReleaseMessage& message); virtual CdmResponseType LoadUsageSession(const CdmKeySetId& key_set_id, @@ -236,7 +237,7 @@ class CdmEngine { CdmSigningAlgorithm algorithm, const std::string& signature); - virtual size_t SessionSize() const { return sessions_.size(); } + virtual size_t SessionSize() const { return session_map_.Size(); } // Is the key known to any session? virtual bool IsKeyLoaded(const KeyId& key_id); @@ -256,7 +257,7 @@ class CdmEngine { // dead lock. virtual void OnTimerEvent(); - virtual metrics::EngineMetrics* GetMetrics() { return &metrics_; } + virtual metrics::MetricsGroup* GetMetrics() { return &metrics_; } private: // private methods @@ -279,7 +280,6 @@ class CdmEngine { // instance variables - /* * The metrics group must be the first variable declared to ensure * that it is the last member destroyed so that no child members @@ -287,10 +287,10 @@ class CdmEngine { * ensure that all data has been properly recorded in the group before * it is published. */ - metrics::EngineMetrics metrics_; + metrics::MetricsGroup metrics_; metrics::TimerMetric life_span_; - CdmSessionMap sessions_; + CdmSessionMap session_map_; CdmReleaseKeySetMap release_key_sets_; scoped_ptr cert_provisioning_; SecurityLevel cert_provisioning_requested_security_level_; @@ -311,14 +311,7 @@ class CdmEngine { scoped_ptr usage_property_set_; int64_t last_usage_information_update_time_; - // Locks the list of sessions, |sessions_|, for the event timer. It will be - // locked in OpenSession, CloseSession. It is also locked in OnTimerEvent and - // OnKeyReleaseEvent while the list of event listeners is being generated. - // The layer above the CDM implementation is expected to handle thread - // synchronization to make sure other functions that access sessions do not - // occur simultaneously with OpenSession or CloseSession. - Lock session_list_lock_; - + // Protect release_key_sets_ from non-thread-safe operations. Lock release_key_sets_lock_; CORE_DISALLOW_COPY_AND_ASSIGN(CdmEngine); diff --git a/libwvdrmengine/cdm/core/include/cdm_session.h b/libwvdrmengine/cdm/core/include/cdm_session.h index 8b46c298..468a8596 100644 --- a/libwvdrmengine/cdm/core/include/cdm_session.h +++ b/libwvdrmengine/cdm/core/include/cdm_session.h @@ -12,7 +12,7 @@ #include "file_store.h" #include "initialization_data.h" #include "license.h" -#include "metrics_collections.h" +#include "metrics_group.h" #include "oemcrypto_adapter.h" #include "policy_engine.h" #include "scoped_ptr.h" @@ -24,28 +24,16 @@ namespace wvcdm { class CdmClientPropertySet; class ServiceCertificate; class WvCdmEventListener; -class UsageTableHeader; class CdmSession { public: - // Creates a new instance of the CdmSession with the given |file_system| - // and |metrics| parameters. Both parameters are owned by the caller and - // must remain in scope througout the scope of the new instance. - CdmSession(FileSystem* file_system, metrics::SessionMetrics* metrics); + CdmSession(FileSystem* file_system); virtual ~CdmSession(); - // Initializes this instance of CdmSession with the given property set. - // |cdm_client_property_set| MAY be null, is owned by the caller, - // and must remain in scope throughout the scope of this session. - virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set); + void Close() { closed_ = true; } + bool IsClosed() { return closed_; } - // Initializes this instance of CdmSession with the given parmeters. - // All parameters are owned by the caller. - // |cdm_client_property_set| is caller owned, may be null, but must be - // in scope as long as the session is in scope. - // |forced_session_id| is caller owned and may be null. - // |event_listener| is caller owned, may be null, but must be in scope - // as long as the session is in scope. + virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set); virtual CdmResponseType Init(ServiceCertificate* service_certificate, CdmClientPropertySet* cdm_client_property_set, const CdmSessionId* forced_session_id, @@ -54,7 +42,7 @@ class CdmSession { virtual CdmResponseType RestoreOfflineSession( const CdmKeySetId& key_set_id, const CdmLicenseType license_type); virtual CdmResponseType RestoreUsageSession( - const DeviceFiles::CdmUsageData& usage_data); + const CdmKeyMessage& key_request, const CdmKeyResponse& key_response); virtual const CdmSessionId& session_id() { return session_id_; } virtual const CdmKeySetId& key_set_id() { return key_set_id_; } @@ -98,8 +86,6 @@ class CdmSession { // ReleaseKey() - Accept response and release key. virtual CdmResponseType ReleaseKey(const CdmKeyResponse& key_response); - virtual CdmResponseType DeleteUsageEntry(uint32_t usage_entry_number); - virtual bool IsKeyLoaded(const KeyId& key_id); virtual int64_t GetDurationRemaining(); @@ -118,8 +104,7 @@ class CdmSession { // Delete usage information for the list of tokens, |provider_session_tokens|. virtual CdmResponseType DeleteMultipleUsageInformation( const std::vector& provider_session_tokens); - virtual CdmResponseType UpdateUsageTableInformation(); - virtual CdmResponseType UpdateUsageEntryInformation(); + virtual CdmResponseType UpdateUsageInformation(); virtual bool is_initial_usage_update() { return is_initial_usage_update_; } virtual bool is_usage_update_needed() { return is_usage_update_needed_; } @@ -132,13 +117,6 @@ class CdmSession { virtual bool is_offline() { return is_offline_; } virtual bool is_temporary() { return is_temporary_; } virtual bool license_received() { return license_received_; } - virtual bool has_provider_session_token() { - return (license_parser_.get() != NULL && - license_parser_->provider_session_token().size() > 0); - } - - virtual CdmUsageSupportType get_usage_support_type() - { return usage_support_type_; } // ReleaseCrypto() - Closes the underlying crypto session but leaves this // object alive. It is invalid to call any method that requires a crypto @@ -182,7 +160,7 @@ class CdmSession { CdmSigningAlgorithm algorithm, const std::string& signature); - virtual metrics::SessionMetrics* GetMetrics() { return metrics_; } + virtual metrics::MetricsGroup* GetMetrics() { return &metrics_; } private: friend class CdmSessionTest; @@ -192,8 +170,6 @@ class CdmSession { CdmResponseType StoreLicense(); bool StoreLicense(DeviceFiles::LicenseState state); - bool UpdateUsageInfo(); - // These setters are for testing only. Takes ownership of the pointers. void set_license_parser(CdmLicense* license_parser); void set_crypto_session(CryptoSession* crypto_session); @@ -201,13 +177,20 @@ class CdmSession { void set_file_handle(DeviceFiles* file_handle); // instance variables - metrics::SessionMetrics* metrics_; - metrics::CryptoMetrics* crypto_metrics_; + + /* + * The metrics group must be the first variable declared to ensure + * that it is the last member destroyed so that no child members + * try to use a reference to it after it is destroyed. This will + * ensure that all data has been properly recorded in the group before + * it is published. + */ + metrics::MetricsGroup metrics_; metrics::TimerMetric life_span_; bool initialized_; + bool closed_; // Session closed, but final shared_ptr has not been released. CdmSessionId session_id_; - FileSystem* file_system_; scoped_ptr license_parser_; scoped_ptr crypto_session_; scoped_ptr policy_engine_; @@ -220,18 +203,11 @@ class CdmSession { SecurityLevel requested_security_level_; CdmAppParameterMap app_parameters_; - // decryption flags + // decryption and usage flags bool is_initial_decryption_; bool has_decrypted_since_last_report_; // ... last report to policy engine. - - // Usage related flags and data bool is_initial_usage_update_; bool is_usage_update_needed_; - CdmUsageSupportType usage_support_type_; - UsageTableHeader* usage_table_header_; - uint32_t usage_entry_number_; - CdmUsageEntry usage_entry_; - std::string usage_provider_session_token_; // information useful for offline and usage scenarios CdmKeyMessage key_request_; diff --git a/libwvdrmengine/cdm/core/include/certificate_provisioning.h b/libwvdrmengine/cdm/core/include/certificate_provisioning.h index 141cb7dc..10cb323e 100644 --- a/libwvdrmengine/cdm/core/include/certificate_provisioning.h +++ b/libwvdrmengine/cdm/core/include/certificate_provisioning.h @@ -6,8 +6,8 @@ #include #include "crypto_session.h" -#include "metrics_collections.h" #include "license_protocol.pb.h" +#include "metrics_group.h" #include "oemcrypto_adapter.h" #include "scoped_ptr.h" #include "wv_cdm_types.h" @@ -21,8 +21,8 @@ class ServiceCertificate; class CertificateProvisioning { public: - explicit CertificateProvisioning(metrics::CryptoMetrics* metrics, - ServiceCertificate* service_certificate) : + CertificateProvisioning(metrics::MetricsGroup* metrics, + ServiceCertificate* service_certificate) : crypto_session_(metrics), cert_type_(kCertificateWidevine), service_certificate_(service_certificate) {} @@ -39,10 +39,8 @@ class CertificateProvisioning { // Process the provisioning response. CdmResponseType HandleProvisioningResponse( - FileSystem* file_system, - const CdmProvisioningResponse& response, - std::string* cert, - std::string* wrapped_key); + FileSystem* file_system, const CdmProvisioningResponse& response, + std::string* cert, std::string* wrapped_key); private: bool GetProvisioningTokenType( @@ -54,12 +52,6 @@ class CertificateProvisioning { video_widevine::SignedProvisioningMessage::ProtocolVersion GetProtocolVersion(); - void ComposeJsonRequestAsQueryString(const std::string& message, - CdmProvisioningRequest* request); - bool ParseJsonResponse(const CdmProvisioningResponse& json_str, - const std::string& start_substr, - const std::string& end_substr, std::string* result); - CryptoSession crypto_session_; CdmCertificateType cert_type_; ServiceCertificate* service_certificate_; diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index eed80a62..3e4a46eb 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -9,7 +9,7 @@ #include "OEMCryptoCENC.h" #include "lock.h" -#include "metrics_collections.h" +#include "metrics_group.h" #include "oemcrypto_adapter.h" #include "timer_metric.h" #include "wv_cdm_types.h" @@ -17,8 +17,6 @@ namespace wvcdm { class CryptoKey; -class UsageTableHeader; - typedef std::map CryptoKeyMap; class CryptoSession { @@ -36,10 +34,7 @@ class CryptoSession { 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. - CryptoSession(metrics::CryptoMetrics* crypto_metrics); + CryptoSession(metrics::MetricsGroup* metrics); virtual ~CryptoSession(); virtual bool GetClientToken(std::string* client_token); @@ -83,6 +78,8 @@ class CryptoSession { 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, @@ -96,7 +93,7 @@ class CryptoSession { // Usage related methods virtual bool UsageInformationSupport(bool* has_support); - virtual CdmResponseType UpdateUsageInformation(); // only for OEMCrypto v9-12 + virtual CdmResponseType UpdateUsageInformation(); virtual CdmResponseType DeactivateUsageInformation( const std::string& provider_session_token); virtual CdmResponseType GenerateUsageReport( @@ -148,9 +145,6 @@ class CryptoSession { 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); @@ -165,28 +159,15 @@ class CryptoSession { 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_; } private: - friend class CryptoSessionForTest; - bool GetProvisioningMethod(CdmClientTokenType* token_type); void Init(); void Terminate(); bool GetTokenFromKeybox(std::string* token); bool GetTokenFromOemCert(std::string* token); - static bool ExtractSystemIdFromOemCert(const std::string& oem_cert, - uint32_t* system_id); void GenerateMacContext(const std::string& input_context, std::string* deriv_context); void GenerateEncryptContext(const std::string& input_context, @@ -234,12 +215,12 @@ class CryptoSession { static bool initialized_; static int session_count_; - metrics::CryptoMetrics* metrics_; + metrics::MetricsGroup* metrics_; metrics::TimerMetric life_span_; bool open_; CdmClientTokenType pre_provision_token_type_; - std::string oem_token_; // Cached OEMCrypto Public Key + std::string oem_token_; // Cached OEMCrypto Public Key bool update_usage_table_after_close_session_; CryptoSessionId oec_session_id_; @@ -249,11 +230,7 @@ class CryptoSession { 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_; diff --git a/libwvdrmengine/cdm/core/include/device_files.h b/libwvdrmengine/cdm/core/include/device_files.h index b0fa5ced..1f22860d 100644 --- a/libwvdrmengine/cdm/core/include/device_files.h +++ b/libwvdrmengine/cdm/core/include/device_files.h @@ -29,13 +29,17 @@ class DeviceFiles { kLicenseStateUnknown, } LicenseState; - struct CdmUsageData { - std::string provider_session_token; - CdmKeyMessage license_request; - CdmKeyResponse license; - std::string key_set_id; - CdmUsageEntry usage_entry; - uint32_t usage_entry_number; + typedef enum { + kStorageLicense, // persistent license + kStorageUsageInfo, // secure stop + } UsageEntryStorage; + + struct UsageEntryInfo { + UsageEntryStorage storage_type; + std::string key_set_id; // used when storage_type is kStorageLicense + std::string + provider_session_token; // used when storage_type is kStorageUsageInfo + std::string app_id; // used when storage_type is kStorageUsageInfo }; DeviceFiles(FileSystem*); @@ -65,8 +69,7 @@ class DeviceFiles { int64_t last_playback_time, int64_t grace_period_end_time, const CdmAppParameterMap& app_parameters, - const CdmUsageEntry& usage_entry, - uint32_t usage_entry_number); + const CdmUsageEntry& usage_entry); virtual bool RetrieveLicense( const std::string& key_set_id, LicenseState* state, CdmInitData* pssh_data, CdmKeyMessage* key_request, @@ -74,7 +77,7 @@ class DeviceFiles { CdmKeyResponse* key_renewal_response, std::string* release_server_url, int64_t* playback_start_time, int64_t* last_playback_time, int64_t* grace_period_end_time, CdmAppParameterMap* app_parameters, - CdmUsageEntry* usage_entry, uint32_t* usage_entry_number); + CdmUsageEntry* usage_entry); virtual bool DeleteLicense(const std::string& key_set_id); virtual bool ListLicenses(std::vector* key_set_ids); virtual bool DeleteAllFiles(); @@ -83,71 +86,54 @@ class DeviceFiles { virtual bool ReserveLicenseId(const std::string& key_set_id); virtual bool UnreserveLicenseId(const std::string& key_set_id); - // Use this method to create a |usage_info_file_name| from an |app_id| - static std::string GetUsageInfoFileName(const std::string& app_id); - - // The UsageInfo methods have been revised to use |usage_info_file_name| - // rather than |app_id| as a parameter. Use the helper method above to - // translate. - // OEMCrypto API 13 introduced big usage tables which required - // migration from usage tables stored by the TEE to usage table - // header+usage entries stored in unsecured persistent storage. The upgrade - // required creation of reverse lookup tables (CdmUsageEntryInfo). - // |app_id| however was hashed and unextractable, and necessitated the - // switch to |usage_info_file_name| + // Store a usage record to the set of usage information on the file system. virtual bool StoreUsageInfo(const std::string& provider_session_token, const CdmKeyMessage& key_request, const CdmKeyResponse& key_response, - const std::string& usage_info_file_name, + const std::string& app_id, const std::string& key_set_id, - const CdmUsageEntry& usage_entry, - uint32_t usage_entry_number); - virtual bool DeleteUsageInfo(const std::string& usage_info_file_name, + const CdmUsageEntry& usage_entry); + + // Extract KSIDs from usage information on the file system. + virtual bool ListUsageRecords(const std::string& app_id, + std::vector* ksids); + + // Get the provider session token for the given key_set_id. + virtual bool GetProviderSessionToken(const std::string& app_id, + const std::string& key_set_id, + std::string* provider_session_token); + + // Delete the usage record for the given PST. + virtual bool DeleteUsageInfo(const std::string& app_id, const std::string& provider_session_token); + // Delete usage information from the file system. Puts a list of all the // psts that were deleted from the file into |provider_session_tokens|. virtual bool DeleteAllUsageInfoForApp( - const std::string& usage_info_file_name, + const std::string& app_id, std::vector* provider_session_tokens); + // Retrieve one usage info from the file. Subsequent calls will retrieve // subsequent entries in the table for this app_id. virtual bool RetrieveUsageInfo( - const std::string& usage_info_file_name, + const std::string& app_id, std::vector >* usage_info); + // Retrieve the usage info entry specified by |provider_session_token|. // Returns false if the entry could not be found. - virtual bool RetrieveUsageInfo(const std::string& usage_info_file_name, + virtual bool RetrieveUsageInfo(const std::string& app_id, const std::string& provider_session_token, CdmKeyMessage* license_request, CdmKeyResponse* license_response, - CdmUsageEntry* usage_entry, - uint32_t* usage_entry_number); + CdmUsageEntry* usage_entry); + // Retrieve the usage info entry specified by |key_set_id|. // Returns false if the entry could not be found. - virtual bool RetrieveUsageInfoByKeySetId( - const std::string& usage_info_file_name, - const std::string& key_set_id, - std::string* provider_session_token, - CdmKeyMessage* license_request, - CdmKeyResponse* license_response, - CdmUsageEntry* usage_entry, - uint32_t* usage_entry_number); - - // These APIs support upgrading from usage tables to usage tabler header + - // entries introduced in OEMCrypto V13. - - virtual bool ListUsageInfoFiles(std::vector* usage_file_names); - virtual bool RetrieveUsageInfo(const std::string& usage_info_file_name, - std::vector* usage_data); - virtual bool RetrieveUsageInfo(const std::string& usage_info_file_name, - const std::string& provider_session_token, - CdmUsageData* usage_data); - // This method overwrites rather than appends data to the usage file - virtual bool StoreUsageInfo(const std::string& usage_info_file_name, - const std::vector& usage_data); - virtual bool UpdateUsageInfo(const std::string& usage_info_file_name, - const std::string& provider_session_token, - const CdmUsageData& usage_data); + virtual bool RetrieveUsageInfoByKeySetId(const std::string& app_id, + const std::string& key_set_id, + CdmKeyMessage* license_request, + CdmKeyResponse* license_response, + CdmUsageEntry* usage_entry); virtual bool StoreHlsAttributes(const std::string& key_set_id, const CdmHlsMethod method, @@ -159,11 +145,11 @@ class DeviceFiles { virtual bool StoreUsageTableInfo( const CdmUsageTableHeader& usage_table_header, - const std::vector& usage_entry_info); + const std::vector& usage_entry_info); virtual bool RetrieveUsageTableInfo( CdmUsageTableHeader* usage_table_header, - std::vector* usage_entry_info); + std::vector* usage_entry_info); private: // Helpers that wrap the File interface and automatically handle hashing, as @@ -182,6 +168,7 @@ class DeviceFiles { static std::string GetCertificateFileName(); static std::string GetHlsAttributesFileNameExtension(); static std::string GetLicenseFileNameExtension(); + static std::string GetUsageInfoFileName(const std::string& app_id); static std::string GetUsageTableFileName(); static std::string GetFileNameSafeHash(const std::string& input); diff --git a/libwvdrmengine/cdm/core/include/license.h b/libwvdrmengine/cdm/core/include/license.h index 5f8afb11..dbfa37f2 100644 --- a/libwvdrmengine/cdm/core/include/license.h +++ b/libwvdrmengine/cdm/core/include/license.h @@ -20,7 +20,6 @@ namespace wvcdm { class Clock; class CryptoSession; class PolicyEngine; -class CdmSession; class ServiceCertificate; class CdmLicense { @@ -39,8 +38,7 @@ class CdmLicense { std::string* server_url); virtual CdmResponseType PrepareKeyUpdateRequest( bool is_renewal, const CdmAppParameterMap& app_parameters, - CdmSession* cdm_session, CdmKeyMessage* signed_request, - std::string* server_url); + CdmKeyMessage* signed_request, std::string* server_url); virtual CdmResponseType HandleKeyResponse( const CdmKeyResponse& license_response); virtual CdmResponseType HandleKeyUpdateResponse( @@ -51,7 +49,7 @@ class CdmLicense { const CdmKeyResponse& license_response, const CdmKeyResponse& license_renewal_response, int64_t playback_start_time, int64_t last_playback_time, - int64_t grace_period_end_time, CdmSession* cdm_session); + int64_t grace_period_end_time); virtual bool RestoreLicenseForRelease(const CdmKeyMessage& license_request, const CdmKeyResponse& license_response); virtual bool HasInitData() { return stored_init_data_.get(); } @@ -65,10 +63,6 @@ class CdmLicense { return is_offline_; } - static bool ExtractProviderSessionToken( - const CdmKeyResponse& license_response, - std::string* provider_session_token); - private: CdmResponseType HandleKeyErrorResponse( diff --git a/libwvdrmengine/cdm/core/include/license_key_status.h b/libwvdrmengine/cdm/core/include/license_key_status.h index e14e3826..59689472 100644 --- a/libwvdrmengine/cdm/core/include/license_key_status.h +++ b/libwvdrmengine/cdm/core/include/license_key_status.h @@ -11,8 +11,6 @@ namespace wvcdm { -static const uint32_t kNoResolution = 0; - class LicenseKeyStatus; // Holds all content and operator session keys for a session. @@ -33,17 +31,11 @@ class LicenseKeys { virtual bool GetAllowedUsage(const KeyId& key_id, CdmKeyAllowedUsage* allowed_usage); - // Applies a new status, resolution, and/or HDCP level to each content key, - // updating their usability under their constraints. Returns true if any keys - // have changed usability, and sets new_usable_keys to true if the status - // changes resulted in at least one key becoming usable. - // - // Pass in NULL for any of the const-pointer arguments to leave that state - // unchanged. - virtual bool ApplyStatusChange( - const CdmKeyStatus* new_status, const uint32_t* new_resolution, - const CryptoSession::HdcpCapability* new_hdcp_level, - bool* new_usable_keys); + // Applies a new status to each content key. + // Returns true if any statuses changed, and sets new_usable_keys to + // true if the status changes resulted in keys becoming usable. + virtual bool ApplyStatusChange(CdmKeyStatus new_status, + bool* new_usable_keys); // Populates the CdmKeyStatusMap with the current content keys. virtual void ExtractKeyStatuses(CdmKeyStatusMap* content_keys); @@ -53,6 +45,11 @@ class LicenseKeys { // to the key, returns true. virtual bool MeetsConstraints(const KeyId& key_id); + // Applies a resolution and/or hdcp change to each key, updating their + // useability under their constraints. + virtual void ApplyConstraints(uint32_t new_resolution, + CryptoSession::HdcpCapability new_hdcp_level); + // Extracts the keys from a license and makes them available for // querying usage and constraint settings. virtual void SetFromLicense( @@ -88,24 +85,21 @@ class LicenseKeyStatus { // Returns the current status of the key. virtual CdmKeyStatus GetKeyStatus() const { return key_status_; } - // Applies a new status, resolution, and/or HDCP level, updating the key's - // usability under its constraints. Returns true if this results in a change - // to the key's usability, and sets newly_usable to true if the status - // changes resulted in the key becoming usable. - // - // Pass in NULL for any of the const-pointer arguments to leave that state - // unchanged. - virtual bool ApplyStatusChange( - const CdmKeyStatus* maybe_new_status, - const uint32_t* maybe_new_resolution, - const CryptoSession::HdcpCapability* maybe_new_hdcp_level, - bool* newly_usable); + // Applies a new status to this key. + // Returns true if the status changed, and sets new_usable_keys to + // true if the status changes resulted in the key becoming usable. + virtual bool ApplyStatusChange(CdmKeyStatus new_status, + bool* new_usable_keys); // Returns the current constraint status of this key. The result // may change due to calls to ApplyConstraints(). // Note: this will return true until the first call to ApplyConstraints(). virtual bool MeetsConstraints() const { return meets_constraints_; } + // Applies the given changes in resolution or HDCP settings. + virtual void ApplyConstraints( + uint32_t new_resolution, CryptoSession::HdcpCapability new_hdcp_level); + protected: typedef ::video_widevine::License::KeyContainer KeyContainer; typedef KeyContainer::OperatorSessionKeyPermissions @@ -127,14 +121,11 @@ class LicenseKeyStatus { bool HasConstraints() { return is_content_key_ && constraints_.size() != 0; } + void SetConstraints(const ConstraintList& constraints); - void ApplyConstraints(); bool is_content_key_; CdmKeyStatus key_status_; - uint32_t resolution_; - CryptoSession::HdcpCapability hdcp_level_; - bool can_check_constraints_; bool meets_constraints_; CdmKeyAllowedUsage allowed_usage_; CryptoSession::HdcpCapability default_hdcp_level_; diff --git a/libwvdrmengine/cdm/core/include/policy_engine.h b/libwvdrmengine/cdm/core/include/policy_engine.h index 7f99cb15..b0c36cb4 100644 --- a/libwvdrmengine/cdm/core/include/policy_engine.h +++ b/libwvdrmengine/cdm/core/include/policy_engine.h @@ -108,15 +108,9 @@ class PolicyEngine { friend class PolicyEngineConstraintsTest; void InitDevice(CryptoSession* crypto_session); - // Checks the keys against the current state of the hardware in case the HDCP - // level no longer meets their requirements. Will only check once every - // |kHdcpCheckInterval| seconds. Calls NotifyIfKeysChanged() to propagate any - // resultant changes to the OnKeysChange event. - void CheckDevice(int64_t current_time); - - void SetDeviceResolution(uint32_t width, uint32_t height) { - current_resolution_ = width * height; - } + void SetDeviceResolution(uint32_t width, uint32_t height); + void CheckDeviceHdcpStatusOnTimer(int64_t current_time); + void CheckDeviceHdcpStatus(); typedef enum { kLicenseStateInitial, @@ -147,22 +141,14 @@ class PolicyEngine { void UpdateRenewalRequest(int64_t current_time); - - // Updates the keys' status to |new_status|. Calls NotifyIfKeysChanged() to - // propagate any resultant changes to the OnKeysChange event. - void UpdateKeyStatus(CdmKeyStatus new_status); - - // Helper method that correctly fires the OnKeysChange event - if needed - - // depending on the parameters it is given. - void NotifyIfKeysChanged(bool keys_changed, bool new_usable_keys); + // Notifies updates in keys information and fire OnKeysChange event if + // key changes. + void NotifyKeysChange(CdmKeyStatus new_status); // Notifies updates in expiry time and fire OnExpirationUpdate event if // expiry time changes. void NotifyExpirationUpdate(int64_t current_time); - // Guard against clock rollbacks - int64_t GetCurrentTime(); - // set_clock() is for testing only. It alters ownership of the // passed-in pointer. void set_clock(Clock* clock); @@ -194,9 +180,6 @@ class PolicyEngine { // calculate the time where renewal retries should occur. int64_t next_renewal_time_; - // to assist in clock rollback checks - int64_t last_recorded_current_time_; - // Used to dispatch CDM events. CdmSessionId session_id_; WvCdmEventListener* event_listener_; diff --git a/libwvdrmengine/cdm/core/include/service_certificate.h b/libwvdrmengine/cdm/core/include/service_certificate.h index 1aa2193d..d185eecf 100644 --- a/libwvdrmengine/cdm/core/include/service_certificate.h +++ b/libwvdrmengine/cdm/core/include/service_certificate.h @@ -43,6 +43,10 @@ class ServiceCertificate { virtual bool HasProviderId() { return !provider_id_.empty(); } virtual const std::string& provider_id() { return provider_id_; } + // Verify the signature for a message. + virtual CdmResponseType VerifySignedMessage(const std::string& message, + const std::string& signature); + // Encrypt the ClientIdentification message for a provisioning or // licensing request. Encryption is performed using the current // service certificate. Return a failure if the service certificate is diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h index ea5f61ea..a5baf1bb 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h @@ -64,10 +64,6 @@ static const std::string QUERY_KEY_MAX_NUMBER_OF_SESSIONS = "MaxNumberOfSessions"; static const std::string QUERY_KEY_OEMCRYPTO_API_VERSION = "OemCryptoApiVersion"; -static const std::string QUERY_KEY_CURRENT_SRM_VERSION = "CurrentSRMVersion"; -static const std::string QUERY_KEY_SRM_UPDATE_SUPPORT = "SRMUpdateSupport"; - // whether OEM supports SRM update -static const std::string QUERY_KEY_WVCDM_VERSION = "WidevineCdmVersion"; static const std::string QUERY_VALUE_TRUE = "True"; static const std::string QUERY_VALUE_FALSE = "False"; @@ -77,7 +73,6 @@ static const std::string QUERY_VALUE_SECURITY_LEVEL_L1 = "L1"; static const std::string QUERY_VALUE_SECURITY_LEVEL_L2 = "L2"; static const std::string QUERY_VALUE_SECURITY_LEVEL_L3 = "L3"; static const std::string QUERY_VALUE_SECURITY_LEVEL_UNKNOWN = "Unknown"; -static const std::string QUERY_VALUE_SECURITY_LEVEL_DEFAULT = "Default"; static const std::string QUERY_VALUE_DISCONNECTED = "Disconnected"; static const std::string QUERY_VALUE_UNPROTECTED = "Unprotected"; static const std::string QUERY_VALUE_HDCP_V1 = "HDCP-1.x"; @@ -105,7 +100,10 @@ static const std::string HLS_URI_ATTRIBUTE = "URI"; static const char EMPTY_ORIGIN[] = ""; static const char EMPTY_SPOID[] = ""; -static const char EMPTY_APP_PACKAGE_NAME[] = ""; + +//Policy engine HDCP enforcement +static const uint32_t HDCP_UNSPECIFIED_VIDEO_RESOLUTION = 0; +static const int64_t HDCP_DEVICE_CHECK_INTERVAL = 10; } // namespace wvcdm #endif // WVCDM_CORE_WV_CDM_CONSTANTS_H_ diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index 7165b0cb..cfce6c07 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -274,8 +274,8 @@ enum CdmResponseType { MOVE_USAGE_ENTRY_UNKNOWN_ERROR, COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR, INVALID_PARAMETERS_ENG_22, - STORE_LICENSE_ERROR_4, - LIST_LICENSES_ERROR, /* 235 */ + LIST_LICENSE_ERROR_1, + LIST_LICENSE_ERROR_2, /* 235 */ INVALID_PARAMETERS_ENG_23, USAGE_INFORMATION_SUPPORT_FAILED, USAGE_SUPPORT_GET_API_FAILED, @@ -290,8 +290,8 @@ enum CdmResponseType { USAGE_STORE_LICENSE_FAILED, USAGE_STORE_USAGE_INFO_FAILED, USAGE_INVALID_LOAD_ENTRY, - RELEASE_ALL_USAGE_INFO_ERROR_4, /* 250 */ - RELEASE_ALL_USAGE_INFO_ERROR_5, + RELEASE_ALL_USAGE_INFO_ERROR_3, /* 250 */ + RELEASE_ALL_USAGE_INFO_ERROR_4, RELEASE_USAGE_INFO_FAILED, INCORRECT_USAGE_SUPPORT_TYPE_1, INCORRECT_USAGE_SUPPORT_TYPE_2, @@ -303,16 +303,6 @@ enum CdmResponseType { DELETE_USAGE_ERROR_1, /* 260 */ DELETE_USAGE_ERROR_2, DELETE_USAGE_ERROR_3, - PRIVACY_MODE_ERROR_1, - PRIVACY_MODE_ERROR_2, - PRIVACY_MODE_ERROR_3, /* 265 */ - EMPTY_RESPONSE_ERROR_1, - INVALID_PARAMETERS_ENG_24, - PARSE_RESPONSE_ERROR_1, - PARSE_RESPONSE_ERROR_2, - PARSE_RESPONSE_ERROR_3, /* 270 */ - PARSE_RESPONSE_ERROR_4, - RELEASE_ALL_USAGE_INFO_ERROR_6, }; enum CdmKeyStatus { @@ -392,28 +382,12 @@ enum CdmClientTokenType { // kUsageEntrySupport - usage information (table headers and entries) are // persisted in non-secure storage but are loaded and unloaded from // the TEE during use (OEMCrypto v13+) +// kUnknownUsageSupport - usage support type is uninitialized or unavailable enum CdmUsageSupportType { kNonSecureUsageSupport, kUsageTableSupport, kUsageEntrySupport, -}; - -enum CdmUsageEntryStorageType { - kStorageLicense, - kStorageUsageInfo, - kStorageUnknown, -}; - -struct CdmUsageEntryInfo { - CdmUsageEntryStorageType storage_type; - CdmKeySetId key_set_id; - std::string usage_info_file_name; - bool operator==(const CdmUsageEntryInfo& other) const { - return storage_type == other.storage_type && - key_set_id == other.key_set_id && - (storage_type != kStorageUsageInfo || - usage_info_file_name == other.usage_info_file_name); - } + kUnknownUsageSupport, }; class CdmKeyAllowedUsage { diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 80d66dd4..707ba68c 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -3,18 +3,20 @@ #include "cdm_engine.h" #include +#include #include #include #include -#include #include "cdm_session.h" +#include "cdm_session_map.h" #include "clock.h" #include "device_files.h" #include "file_store.h" #include "license_protocol.pb.h" #include "log.h" +#include "metrics_front_end.h" #include "properties.h" #include "string_conversions.h" #include "wv_cdm_constants.h" @@ -64,36 +66,16 @@ CdmEngine::CdmEngine(FileSystem* file_system, const std::string& spoid) usage_session_(NULL), last_usage_information_update_time_(0) { assert(file_system); + Properties::Init(); if (!seeded_) { - Properties::Init(); srand(clock_.GetCurrentTime()); seeded_ = true; } life_span_.Start(); - - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - metrics_.cdm_engine_creation_time_millis_.Record( - ts.tv_sec * 1000 + ts.tv_nsec / 1e6); - - std::string cdm_version; - if(Properties::GetWVCdmVersion(&cdm_version)) { - metrics_.cdm_engine_cdm_version_.Record(cdm_version); - } else { - // Set error "false", the return value of GetWVCdmVersion. - metrics_.cdm_engine_cdm_version_.SetError(false); - } } CdmEngine::~CdmEngine() { - AutoLock lock(session_list_lock_); - CdmSessionMap::iterator i(sessions_.begin()); - for (; i != sessions_.end(); ++i) { - delete i->second; - } - sessions_.clear(); - M_RECORD(&metrics_, cdm_engine_life_span_, life_span_.AsMs()); } @@ -132,15 +114,14 @@ CdmResponseType CdmEngine::OpenSession( } if (forced_session_id) { - if (sessions_.find(*forced_session_id) != sessions_.end()) { + if (session_map_.Exists(*forced_session_id)) { return DUPLICATE_SESSION_ID_SPECIFIED; } } CloseExpiredReleaseSessions(); - scoped_ptr new_session(new CdmSession(file_system_, - metrics_.AddSession())); + scoped_ptr new_session(new CdmSession(file_system_)); CdmResponseType sts = new_session->Init(&service_certificate_, property_set, forced_session_id, event_listener); if (sts != NO_ERROR) { @@ -157,8 +138,7 @@ CdmResponseType CdmEngine::OpenSession( } CdmSessionId id = new_session->session_id(); - AutoLock lock(session_list_lock_); - sessions_[id] = new_session.release(); + session_map_.Add(id, new_session.release()); if (session_id) *session_id = id; return NO_ERROR; } @@ -198,16 +178,11 @@ CdmResponseType CdmEngine::OpenKeySetSession( } CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) { - LOGV("CdmEngine::CloseSession: %s", session_id.c_str()); - AutoLock lock(session_list_lock_); - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + LOGI("CdmEngine::CloseSession"); + if (!session_map_.CloseSession(session_id)) { LOGE("CdmEngine::CloseSession: session not found = %s", session_id.c_str()); return SESSION_NOT_FOUND_1; } - CdmSession* session = iter->second; - sessions_.erase(session_id); - delete session; return NO_ERROR; } @@ -237,9 +212,7 @@ CdmResponseType CdmEngine::CloseKeySetSession(const CdmKeySetId& key_set_id) { } bool CdmEngine::IsOpenSession(const CdmSessionId& session_id) { - AutoLock lock(session_list_lock_); - CdmSessionMap::iterator iter = sessions_.find(session_id); - return iter != sessions_.end(); + return session_map_.Exists(session_id); } CdmResponseType CdmEngine::GenerateKeyRequest( @@ -277,8 +250,8 @@ CdmResponseType CdmEngine::GenerateKeyRequest( id = iter->second.first; } - CdmSessionMap::iterator iter = sessions_.find(id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(id, &session)) { LOGE("CdmEngine::GenerateKeyRequest: session_id not found = %s", id.c_str()); return SESSION_NOT_FOUND_2; @@ -292,11 +265,14 @@ CdmResponseType CdmEngine::GenerateKeyRequest( key_request->message.clear(); if (license_type == kLicenseTypeRelease && - !iter->second->license_received()) { - sts = iter->second->RestoreOfflineSession( - key_set_id, kLicenseTypeRelease), - iter->second->GetMetrics()->cdm_session_restore_offline_session_ - .Increment(sts); + !session->license_received()) { + M_TIME( + sts = session->RestoreOfflineSession( + key_set_id, + kLicenseTypeRelease), + session->GetMetrics(), + cdm_session_restore_offline_session_, + sts); if (sts != KEY_ADDED) { LOGE("CdmEngine::GenerateKeyRequest: key release restoration failed," "sts = %d", static_cast(sts)); @@ -304,16 +280,13 @@ CdmResponseType CdmEngine::GenerateKeyRequest( } } - sts = iter->second->GenerateKeyRequest( - init_data, - license_type, - app_parameters, - key_request); + sts = session->GenerateKeyRequest(init_data, license_type, app_parameters, + key_request); if (KEY_MESSAGE != sts) { if (sts == NEED_PROVISIONING) { cert_provisioning_requested_security_level_ = - iter->second->GetRequestedSecurityLevel(); + session->GetRequestedSecurityLevel(); } LOGE("CdmEngine::GenerateKeyRequest: key request generation failed, " "sts = %d", static_cast(sts)); @@ -356,9 +329,8 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, id = iter->second.first; } - CdmSessionMap::iterator iter = sessions_.find(id); - - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(id, &session)) { LOGE("CdmEngine::AddKey: session id not found = %s", id.c_str()); return SESSION_NOT_FOUND_3; } @@ -368,15 +340,9 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, return EMPTY_KEY_DATA_1; } - CdmResponseType sts = iter->second->AddKey(key_data); + CdmResponseType sts = session->AddKey(key_data); if (key_set_id) { - if ((iter->second->is_offline() || - iter->second->has_provider_session_token()) && - !license_type_release) { - *key_set_id = iter->second->key_set_id(); - } else { - key_set_id->clear(); - } + *key_set_id = session->key_set_id(); } switch (sts) { @@ -402,21 +368,25 @@ CdmResponseType CdmEngine::RestoreKey(const CdmSessionId& session_id, return EMPTY_KEYSET_ID_ENG_4; } - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::RestoreKey: session_id not found = %s ", session_id.c_str()); return SESSION_NOT_FOUND_4; } CdmResponseType sts; - sts = iter->second->RestoreOfflineSession( - key_set_id, kLicenseTypeOffline), - iter->second->GetMetrics()->cdm_session_restore_offline_session_ - .Increment(sts); + M_TIME( + sts = session->RestoreOfflineSession( + key_set_id, + kLicenseTypeOffline), + session->GetMetrics(), + cdm_session_restore_offline_session_, + sts); + if (sts == NEED_PROVISIONING) { cert_provisioning_requested_security_level_ = - iter->second->GetRequestedSecurityLevel(); + session->GetRequestedSecurityLevel(); } if (sts != KEY_ADDED && sts != GET_RELEASED_LICENSE_ERROR) { LOGE("CdmEngine::RestoreKey: restore offline session failed = %d", sts); @@ -427,14 +397,14 @@ CdmResponseType CdmEngine::RestoreKey(const CdmSessionId& session_id, CdmResponseType CdmEngine::RemoveKeys(const CdmSessionId& session_id) { LOGI("CdmEngine::RemoveKeys"); - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::RemoveKeys: session_id not found = %s", session_id.c_str()); return SESSION_NOT_FOUND_5; } - iter->second->ReleaseCrypto(); + session->ReleaseCrypto(); return NO_ERROR; } @@ -443,8 +413,8 @@ CdmResponseType CdmEngine::GenerateRenewalRequest( const CdmSessionId& session_id, CdmKeyRequest* key_request) { LOGI("CdmEngine::GenerateRenewalRequest"); - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::GenerateRenewalRequest: session_id not found = %s", session_id.c_str()); return SESSION_NOT_FOUND_6; @@ -457,7 +427,7 @@ CdmResponseType CdmEngine::GenerateRenewalRequest( key_request->message.clear(); - CdmResponseType sts = iter->second->GenerateRenewalRequest(key_request); + CdmResponseType sts = session->GenerateRenewalRequest(key_request); if (KEY_MESSAGE != sts) { LOGE("CdmEngine::GenerateRenewalRequest: key request gen. failed, sts=%d", @@ -472,8 +442,8 @@ CdmResponseType CdmEngine::RenewKey(const CdmSessionId& session_id, const CdmKeyResponse& key_data) { LOGI("CdmEngine::RenewKey"); - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::RenewKey: session_id not found = %s", session_id.c_str()); return SESSION_NOT_FOUND_7; } @@ -485,11 +455,12 @@ CdmResponseType CdmEngine::RenewKey(const CdmSessionId& session_id, CdmResponseType sts; M_TIME( - sts = iter->second->RenewKey( + sts = session->RenewKey( key_data), - iter->second->GetMetrics(), + session->GetMetrics(), cdm_session_renew_key_, sts); + if (KEY_ADDED != sts) { LOGE("CdmEngine::RenewKey: keys not added, sts=%d", static_cast(sts)); return sts; @@ -502,13 +473,13 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, const std::string& query_token, std::string* query_response) { LOGI("CdmEngine::QueryStatus"); - CryptoSession crypto_session(metrics_.GetCryptoMetrics()); + CryptoSession crypto_session(&metrics_); if (security_level == kLevel3) { CdmResponseType status; M_TIME( status = crypto_session.Open( kLevel3), - metrics_.GetCryptoMetrics(), + &metrics_, crypto_session_open_, status, kLevel3); @@ -521,9 +492,13 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, } if (query_token == QUERY_KEY_SECURITY_LEVEL) { - CdmSecurityLevel security_level; - security_level = crypto_session.GetSecurityLevel(); - switch (security_level) { + CdmSecurityLevel level; + M_TIME( + level = crypto_session.GetSecurityLevel(), + &metrics_, + crypto_session_get_security_level_, + level); + switch (level) { case kSecurityLevelL1: *query_response = QUERY_VALUE_SECURITY_LEVEL_L1; break; @@ -538,17 +513,18 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, *query_response = QUERY_VALUE_SECURITY_LEVEL_UNKNOWN; break; default: - LOGW("CdmEngine::QueryStatus: Unknown security level: %d", - security_level); + LOGW("CdmEngine::QueryStatus: Unknown security level: %d", level); return UNKNOWN_ERROR; } } else if (query_token == QUERY_KEY_DEVICE_ID) { - // TODO(gmorgan): this should not be performed before device is provisioned - // (except if keybox provisioned). std::string deviceId; - bool got_id = crypto_session.GetExternalDeviceUniqueId(&deviceId); - metrics_.GetCryptoMetrics()->crypto_session_get_device_unique_id_ - .Increment(got_id); + bool got_id; + M_TIME( + got_id = crypto_session.GetExternalDeviceUniqueId( + &deviceId), + &metrics_, + crypto_session_get_device_unique_id_, + got_id); if (!got_id) { LOGW("CdmEngine::QueryStatus: QUERY_KEY_DEVICE_ID unknown failure"); return UNKNOWN_ERROR; @@ -556,10 +532,15 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, *query_response = deviceId; } else if (query_token == QUERY_KEY_SYSTEM_ID) { - // TODO(gmorgan): this should not be performed before device is provisioned - // (except if keybox provisioned). uint32_t system_id; - bool got_id = crypto_session.GetSystemId(&system_id); + bool got_id; + M_TIME( + got_id = crypto_session.GetSystemId( + &system_id), + &metrics_, + crypto_session_get_system_id_, + got_id, + system_id); if (!got_id) { LOGW("CdmEngine::QueryStatus: QUERY_KEY_SYSTEM_ID unknown failure"); return UNKNOWN_ERROR; @@ -569,8 +550,6 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, system_id_stream << system_id; *query_response = system_id_stream.str(); } else if (query_token == QUERY_KEY_PROVISIONING_ID) { - // TODO(gmorgan): this should not be performed before device is provisioned - // (except if keybox provisioned). std::string provisioning_id; if (!crypto_session.GetProvisioningId(&provisioning_id)) { LOGW("CdmEngine::QueryStatus: GetProvisioningId failed"); @@ -591,17 +570,17 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, current_hdcp : max_hdcp); } else if (query_token == QUERY_KEY_USAGE_SUPPORT) { bool supports_usage_reporting; - bool got_info = crypto_session.UsageInformationSupport( - &supports_usage_reporting); - + bool got_info; + M_TIME( + got_info = crypto_session.UsageInformationSupport( + &supports_usage_reporting), + &metrics_, + crypto_session_usage_information_support_, + got_info); if (!got_info) { LOGW("CdmEngine::QueryStatus: UsageInformationSupport failed"); - metrics_.GetCryptoMetrics()->crypto_session_usage_information_support_ - .SetError(got_info); // Note that this reports false as the error. return UNKNOWN_ERROR; } - metrics_.GetCryptoMetrics()->crypto_session_usage_information_support_ - .Record(supports_usage_reporting); *query_response = supports_usage_reporting ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; @@ -627,7 +606,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, *query_response = max_sessions_stream.str(); } else if (query_token == QUERY_KEY_OEMCRYPTO_API_VERSION) { uint32_t api_version; - if (!crypto_session.GetApiVersion(&api_version)) { + if (crypto_session.GetApiVersion(&api_version)) { LOGW("CdmEngine::QueryStatus: GetApiVersion failed"); return UNKNOWN_ERROR; } @@ -635,28 +614,6 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, std::ostringstream api_version_stream; api_version_stream << api_version; *query_response = api_version_stream.str(); - } else if (query_token == QUERY_KEY_CURRENT_SRM_VERSION) { - uint16_t current_srm_version; - if (!crypto_session.GetSrmVersion(¤t_srm_version)) { - LOGW("CdmEngine::QueryStatus: GetCurrentSRMVersion failed"); - return UNKNOWN_ERROR; - } - - std::ostringstream current_srm_version_stream; - current_srm_version_stream << current_srm_version; - *query_response = current_srm_version_stream.str(); - } else if (query_token == QUERY_KEY_SRM_UPDATE_SUPPORT) { - bool is_srm_update_supported = crypto_session.IsSrmUpdateSupported(); - *query_response = - is_srm_update_supported ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; - } else if (query_token == QUERY_KEY_WVCDM_VERSION) { - std::string cdm_version; - if (!Properties::GetWVCdmVersion(&cdm_version)) { - LOGW("CdmEngine::QueryStatus: GetWVCdmVersion failed"); - return UNKNOWN_ERROR; - } - - *query_response = cdm_version; } else { LOGW("CdmEngine::QueryStatus: Unknown status requested, token = %s", query_token.c_str()); @@ -669,47 +626,47 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, CdmResponseType CdmEngine::QuerySessionStatus(const CdmSessionId& session_id, CdmQueryMap* query_response) { LOGI("CdmEngine::QuerySessionStatus"); - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::QuerySessionStatus: session_id not found = %s", session_id.c_str()); return SESSION_NOT_FOUND_8; } - return iter->second->QueryStatus(query_response); + return session->QueryStatus(query_response); } bool CdmEngine::IsReleaseSession(const CdmSessionId& session_id) { LOGI("CdmEngine::IsReleaseSession"); - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::IsReleaseSession: session_id not found = %s", session_id.c_str()); return false; } - return iter->second->is_release(); + return session->is_release(); } bool CdmEngine::IsOfflineSession(const CdmSessionId& session_id) { LOGI("CdmEngine::IsOfflineSession"); - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::IsOfflineSession: session_id not found = %s", session_id.c_str()); return false; } - return iter->second->is_offline(); + return session->is_offline(); } CdmResponseType CdmEngine::QueryKeyStatus(const CdmSessionId& session_id, CdmQueryMap* query_response) { LOGI("CdmEngine::QueryKeyStatus"); - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::QueryKeyStatus: session_id not found = %s", session_id.c_str()); return SESSION_NOT_FOUND_9; } - return iter->second->QueryKeyStatus(query_response); + return session->QueryKeyStatus(query_response); } CdmResponseType CdmEngine::QueryKeyAllowedUsage(const CdmSessionId& session_id, @@ -720,13 +677,13 @@ CdmResponseType CdmEngine::QueryKeyAllowedUsage(const CdmSessionId& session_id, LOGE("CdmEngine::QueryKeyAllowedUsage: no response destination"); return INVALID_PARAMETERS_ENG_12; } - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::QueryKeyAllowedUsage: session_id not found = %s", session_id.c_str()); return SESSION_NOT_FOUND_12; } - return iter->second->QueryKeyAllowedUsage(key_id, key_usage); + return session->QueryKeyAllowedUsage(key_id, key_usage); } CdmResponseType CdmEngine::QueryKeyAllowedUsage(const std::string& key_id, @@ -740,10 +697,13 @@ CdmResponseType CdmEngine::QueryKeyAllowedUsage(const std::string& key_id, return INVALID_PARAMETERS_ENG_7; } key_usage->Clear(); - for (CdmSessionMap::iterator iter = sessions_.begin(); - iter != sessions_.end(); ++iter) { - session_sts = iter->second->QueryKeyAllowedUsage( - key_id, &found_in_this_session); + + CdmSessionList sessions; + session_map_.GetSessionList(sessions); + + for (CdmSessionList::iterator iter = sessions.begin(); + iter != sessions.end(); ++iter) { + session_sts = (*iter)->QueryKeyAllowedUsage(key_id, &found_in_this_session); if (session_sts == NO_ERROR) { if (found) { // Found another key. If usage settings do not match, fail. @@ -768,13 +728,13 @@ CdmResponseType CdmEngine::QueryKeyAllowedUsage(const std::string& key_id, CdmResponseType CdmEngine::QueryOemCryptoSessionId( const CdmSessionId& session_id, CdmQueryMap* query_response) { LOGI("CdmEngine::QueryOemCryptoSessionId"); - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::QueryOemCryptoSessionId: session_id not found = %s", session_id.c_str()); return SESSION_NOT_FOUND_10; } - return iter->second->QueryOemCryptoSessionId(query_response); + return session->QueryOemCryptoSessionId(query_response); } /* @@ -800,8 +760,7 @@ CdmResponseType CdmEngine::GetProvisioningRequest( if (NULL == cert_provisioning_.get()) { cert_provisioning_.reset( - new CertificateProvisioning(metrics_.GetCryptoMetrics(), - &service_certificate_)); + new CertificateProvisioning(&metrics_, &service_certificate_)); } CdmResponseType ret = cert_provisioning_->GetProvisioningRequest( cert_provisioning_requested_security_level_, cert_type, cert_authority, @@ -843,12 +802,12 @@ CdmResponseType CdmEngine::HandleProvisioningResponse( if (NULL == cert_provisioning_.get()) { // Certificate provisioning object has been released. Check if a concurrent // provisioning attempt has succeeded before declaring failure. - CryptoSession crypto_session(metrics_.GetCryptoMetrics()); + CryptoSession crypto_session(&metrics_); CdmResponseType status; M_TIME( status = crypto_session.Open( cert_provisioning_requested_security_level_), - metrics_.GetCryptoMetrics(), + &metrics_, crypto_session_open_, status, cert_provisioning_requested_security_level_); @@ -858,7 +817,12 @@ CdmResponseType CdmEngine::HandleProvisioningResponse( "missing and crypto session open failed."); return EMPTY_PROVISIONING_CERTIFICATE_2; } - CdmSecurityLevel security_level = crypto_session.GetSecurityLevel(); + CdmSecurityLevel security_level; + M_TIME( + security_level = crypto_session.GetSecurityLevel(), + &metrics_, + crypto_session_get_security_level_, + security_level); if (!IsProvisioned(security_level)) { LOGE( "CdmEngine::HandleProvisioningResponse: provisioning object " @@ -910,19 +874,29 @@ CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) { } CdmResponseType CdmEngine::DeleteUsageTable(CdmSecurityLevel security_level) { - scoped_ptr crypto_session( - new CryptoSession(metrics_.GetCryptoMetrics())); - CdmResponseType status = crypto_session->Open( + scoped_ptr crypto_session(new CryptoSession(&metrics_)); + CdmResponseType status; + M_TIME( + status = crypto_session->Open( + security_level == kSecurityLevelL3 ? + kLevel3 : + kLevelDefault), + &metrics_, + crypto_session_open_, + status, security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault); if (NO_ERROR != status) { LOGE("CdmEngine::DeleteUsageTable: error opening crypto session: %d", status); return UNPROVISION_ERROR_4; } - status = crypto_session->DeleteAllUsageReports(); + M_TIME( + status = crypto_session->DeleteAllUsageReports(), + &metrics_, + crypto_session_delete_all_usage_reports_, + status); if (status != NO_ERROR) { - LOGE("CdmEngine::DeleteUsageTable: error deleting usage reports: %d", - status); + LOGE("CdmEngine::DeleteUsageTable: error deleteing usage reports: %d", status); } return status; } @@ -931,19 +905,74 @@ CdmResponseType CdmEngine::ListStoredLicenses( CdmSecurityLevel security_level, std::vector* key_set_ids) { DeviceFiles handle(file_system_); if (!key_set_ids) { - LOGE("CdmEngine::QueryStoredLicenses: no response destination"); + LOGE("CdmEngine::ListStoredLicenses: no response destination"); return INVALID_PARAMETERS_ENG_22; } if (!handle.Init(security_level)) { LOGE("CdmEngine::ListStoredLicenses: unable to initialize device files"); - return STORE_LICENSE_ERROR_4; + return LIST_LICENSE_ERROR_1; } if (!handle.ListLicenses(key_set_ids)) { - return LIST_LICENSES_ERROR; + LOGE("CdmEngine::ListStoredLicenses: ListLicenses call failed"); + return LIST_LICENSE_ERROR_2; } return NO_ERROR; } +CdmResponseType CdmEngine::ListUsageRecords(const std::string& app_id, + CdmSecurityLevel security_level, + std::vector* ksids) { + DeviceFiles handle(file_system_); + if (!ksids) { + LOGE("CdmEngine::ListUsageRecords: no response destination"); + return INVALID_PARAMETERS_ENG_23; + } + if (!handle.Init(security_level)) { + LOGE("CdmEngine::ListUsageRecords: unable to initialize device files"); + return LIST_USAGE_ERROR_1; + } + if (!handle.ListUsageRecords(app_id, ksids)) { + LOGE("CdmEngine::ListUsageRecords: ListUsageRecords call failed"); + return LIST_USAGE_ERROR_2; + } + return NO_ERROR; +} + +CdmResponseType CdmEngine::DeleteUsageRecord(const std::string& app_id, + CdmSecurityLevel security_level, + const std::string& key_set_id) { + std::string provider_session_token; + + DeviceFiles handle(file_system_); + if (!handle.Init(security_level)) { + LOGE("CdmEngine::DeleteUsageRecord: unable to initialize device files"); + return DELETE_USAGE_ERROR_1; + } + if (!handle.GetProviderSessionToken(app_id, key_set_id, + &provider_session_token)) { + LOGE("CdmEngine::DeleteUsageRecord: GetProviderSessionToken failed"); + return DELETE_USAGE_ERROR_2; + } + + // Got provider token. Remove from OEMCrypto. + scoped_ptr crypto_session(new CryptoSession(&metrics_)); + CdmResponseType status = crypto_session->Open( + security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault); + if (status == NO_ERROR) { + status = crypto_session->DeleteUsageInformation(provider_session_token); + } + if (status != NO_ERROR) { + LOGE("CdmEngine::DeleteUsageRecord: OEMCrypto failure"); + } + + // Remove from file system. + if (!handle.DeleteUsageInfo(app_id, provider_session_token)) { + LOGE("CdmEngine::DeleteUsageRecord: file system failure"); + return DELETE_USAGE_ERROR_3; + } + return status; +} + CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, const CdmSecureStopId& ssid, CdmUsageInfo* usage_info) { @@ -956,10 +985,10 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, } usage_property_set_->set_security_level(kLevelDefault); usage_property_set_->set_app_id(app_id); - usage_session_.reset(new CdmSession(file_system_, metrics_.AddSession())); + usage_session_.reset(new CdmSession(file_system_)); CdmResponseType status = usage_session_->Init(usage_property_set_.get()); if (NO_ERROR != status) { - LOGE("CdmEngine::GetUsageInfo: session init error: %d", status); + LOGE("CdmEngine::GetUsageInfo: session init error"); return status; } DeviceFiles handle(file_system_); @@ -971,12 +1000,11 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, CdmKeyMessage license_request; CdmKeyResponse license_response; std::string usage_entry; - DeviceFiles::CdmUsageData usage_data; - if (!handle.RetrieveUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id), - ssid, &usage_data)) { + if (!handle.RetrieveUsageInfo(app_id, ssid, &license_request, + &license_response, &usage_entry)) { usage_property_set_->set_security_level(kLevel3); usage_property_set_->set_app_id(app_id); - usage_session_.reset(new CdmSession(file_system_, metrics_.AddSession())); + usage_session_.reset(new CdmSession(file_system_)); status = usage_session_->Init(usage_property_set_.get()); if (NO_ERROR != status) { LOGE("CdmEngine::GetUsageInfo: session init error"); @@ -986,15 +1014,15 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, LOGE("CdmEngine::GetUsageInfo: device file init error"); return GET_USAGE_INFO_ERROR_2; } - if (!handle.RetrieveUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id), - ssid, &usage_data)) { + if (!handle.RetrieveUsageInfo(app_id, ssid, &license_request, + &license_response, &usage_entry)) { // No entry found for that ssid. return USAGE_INFO_NOT_FOUND; } } status = - usage_session_->RestoreUsageSession(usage_data); + usage_session_->RestoreUsageSession(license_request,license_response); if (KEY_ADDED != status) { LOGE("CdmEngine::GetUsageInfo: restore usage session error %d", status); @@ -1050,7 +1078,7 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, usage_property_set_->set_security_level(requested_security_level); usage_property_set_->set_app_id(app_id); - usage_session_.reset(new CdmSession(file_system_, metrics_.AddSession())); + usage_session_.reset(new CdmSession(file_system_)); CdmResponseType status = usage_session_->Init(usage_property_set_.get()); if (NO_ERROR != status) { @@ -1064,9 +1092,8 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, return GET_USAGE_INFO_ERROR_3; } - std::vector usage_data; - if (!handle.RetrieveUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id), - &usage_data)) { + std::vector > license_info; + if (!handle.RetrieveUsageInfo(app_id, &license_info)) { LOGE("CdmEngine::GetUsageInfo: unable to read usage information"); return GET_USAGE_INFO_ERROR_4; } @@ -1075,15 +1102,16 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, LOGE("CdmEngine::GetUsageInfo: no usage info destination"); return INVALID_PARAMETERS_ENG_10; } - if (0 == usage_data.size()) { + if (0 == license_info.size()) { usage_info->resize(0); return NO_ERROR; } usage_info->resize(kUsageReportsPerRequest); - uint32_t index = rand() % usage_data.size(); - status = usage_session_->RestoreUsageSession(usage_data[index]); + uint32_t index = rand() % license_info.size(); + status = usage_session_->RestoreUsageSession(license_info[index].first, + license_info[index].second); if (KEY_ADDED != status) { LOGE("CdmEngine::GetUsageInfo: restore usage session (%d) error %ld", index, status); @@ -1113,6 +1141,37 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, return status; } +CdmResponseType CdmEngine::ReleaseAllUsageInfo( + const std::string& app_id, CdmSecurityLevel security_level) { + DeviceFiles handle(file_system_); + if (!handle.Init(security_level)) { + LOGE("CdmEngine::ReleaseAllUsageInfo: unable to initialize device files"); + return RELEASE_ALL_USAGE_INFO_ERROR_3; + } + std::vector provider_session_tokens; + if (!handle.DeleteAllUsageInfoForApp(app_id, &provider_session_tokens)) { + LOGE("CdmEngine::ReleaseAllUsageInfo: failed to delete usage records"); + return RELEASE_ALL_USAGE_INFO_ERROR_4; + } + + if (provider_session_tokens.size() == 0UL) { + return NO_ERROR; + } + + // Got at least one provider token. Remove from OEMCrypto. + scoped_ptr crypto_session(new CryptoSession(&metrics_)); + CdmResponseType status = crypto_session->Open( + security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault); + if (status == NO_ERROR) { + status = crypto_session-> + DeleteMultipleUsageInformation(provider_session_tokens); + } + if (status != NO_ERROR) { + LOGE("CdmEngine::ReleaseAllUsageInfo: CryptoSession failure"); + } + return status; +} + CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) { if (NULL == usage_property_set_.get()) { usage_property_set_.reset(new UsagePropertySet()); @@ -1123,64 +1182,23 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) { for (int j = kSecurityLevelL1; j < kSecurityLevelUnknown; ++j) { DeviceFiles handle(file_system_); if (handle.Init(static_cast(j))) { - SecurityLevel security_level = - static_cast(j) == kSecurityLevelL3 - ? kLevel3 - : kLevelDefault; - usage_property_set_->set_security_level(security_level); - usage_session_.reset( - new CdmSession(file_system_, metrics_.AddSession())); - usage_session_->Init(usage_property_set_.get()); - - if (usage_session_->get_usage_support_type() == kUsageEntrySupport) { - std::vector usage_data; - // Retrieve all usage information but delete only one before - // refetching. This is because deleting the usage entry - // might cause other entries to be shifted and information updated. - do { - if (!handle.RetrieveUsageInfo( - DeviceFiles::GetUsageInfoFileName(app_id), - &usage_data)) { - status = RELEASE_ALL_USAGE_INFO_ERROR_4; - break; - } - - if (usage_data.empty()) break; - - status = usage_session_->DeleteUsageEntry( - usage_data[0].usage_entry_number); - - if (status != NO_ERROR) break; - - if (!handle.DeleteUsageInfo( - DeviceFiles::GetUsageInfoFileName(app_id), - usage_data[0].provider_session_token)) { - status = RELEASE_ALL_USAGE_INFO_ERROR_6; - break; - } - } while (status == NO_ERROR && !usage_data.empty()); - - std::vector provider_session_tokens; - if (!handle.DeleteAllUsageInfoForApp( - DeviceFiles::GetUsageInfoFileName(app_id), - &provider_session_tokens)) { - status = RELEASE_ALL_USAGE_INFO_ERROR_5; - } - } else if (usage_session_->get_usage_support_type() - == kUsageTableSupport) { - std::vector provider_session_tokens; - if (!handle.DeleteAllUsageInfoForApp( - DeviceFiles::GetUsageInfoFileName(app_id), - &provider_session_tokens)) { - LOGE("CdmEngine::ReleaseAllUsageInfo: failed to delete L%d secure" - "stops", j); - status = RELEASE_ALL_USAGE_INFO_ERROR_1; - } else { - CdmResponseType status2 = usage_session_-> - DeleteMultipleUsageInformation(provider_session_tokens); - if (status2 != NO_ERROR) { - status = status2; - } + std::vector provider_session_tokens; + if (!handle.DeleteAllUsageInfoForApp(app_id, &provider_session_tokens)) { + LOGE("CdmEngine::ReleaseAllUsageInfo: failed to delete L%d secure" + "stops", j); + status = RELEASE_ALL_USAGE_INFO_ERROR_1; + } else { + SecurityLevel security_level = + static_cast(j) == kSecurityLevelL3 + ? kLevel3 + : kLevelDefault; + usage_property_set_->set_security_level(security_level); + usage_session_.reset(new CdmSession(file_system_)); + usage_session_->Init(usage_property_set_.get()); + CdmResponseType status2 = usage_session_-> + DeleteMultipleUsageInformation(provider_session_tokens); + if (status2 != NO_ERROR) { + status = status2; } } } else { @@ -1220,8 +1238,8 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id, return EMPTY_KEYSET_ID_ENG_5; } - CdmSessionMap::iterator iter = sessions_.find(key_set_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(key_set_id, &session)) { LOGE("CdmEngine::LoadUsageSession: session_id not found = %s ", key_set_id.c_str()); return SESSION_NOT_FOUND_11; @@ -1233,35 +1251,39 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id, } DeviceFiles handle(file_system_); - if (!handle.Init(iter->second->GetSecurityLevel())) { + if (!handle.Init(session->GetSecurityLevel())) { LOGE("CdmEngine::LoadUsageSession: unable to initialize device files"); return LOAD_USAGE_INFO_FILE_ERROR; } std::string app_id; - iter->second->GetApplicationId(&app_id); + session->GetApplicationId(&app_id); - DeviceFiles::CdmUsageData usage_data; - if (!handle.RetrieveUsageInfoByKeySetId( - DeviceFiles::GetUsageInfoFileName(app_id), key_set_id, - &(usage_data.provider_session_token), - &(usage_data.license_request), - &(usage_data.license), &(usage_data.usage_entry), - &(usage_data.usage_entry_number))) { + CdmKeyMessage key_message; + CdmKeyResponse key_response; + std::string usage_entry; + if (!handle.RetrieveUsageInfoByKeySetId(app_id, key_set_id, &key_message, + &key_response, &usage_entry)) { LOGE("CdmEngine::LoadUsageSession: unable to find usage information"); return LOAD_USAGE_INFO_MISSING; } - CdmResponseType status = iter->second->RestoreUsageSession(usage_data); - iter->second->GetMetrics()->cdm_session_restore_usage_session_ - .Increment(status); + CdmResponseType status; + M_TIME( + status = session->RestoreUsageSession( + key_message, + key_response), + session->GetMetrics(), + cdm_session_restore_usage_session_, + status); + if (KEY_ADDED != status) { LOGE("CdmEngine::LoadUsageSession: usage session error %ld", status); return status; } CdmKeyRequest request; - status = iter->second->GenerateReleaseRequest(&request); + status = session->GenerateReleaseRequest(&request); *release_message = request.message; @@ -1269,8 +1291,8 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id, case KEY_MESSAGE: break; case KEY_CANCELED: - /* usage information not present in OEMCrypto, delete and try again */ - iter->second->DeleteLicense(); + // usage information not present in OEMCrypto, delete and try again + session->DeleteLicense(); break; default: LOGE("CdmEngine::LoadUsageSession: generate release request error: %d", @@ -1306,46 +1328,50 @@ CdmResponseType CdmEngine::Decrypt(const CdmSessionId& session_id, // else we must be level 1 direct and we don't need to return a buffer. } - AutoLock lock(session_list_lock_); - CdmSessionMap::iterator session_iter = sessions_.end(); + std::shared_ptr session; if (session_id.empty()) { + CdmSessionList sessions; + session_map_.GetSessionList(sessions); + // Loop through the sessions to find the session containing the key_id // with the longest remaining license validity. int64_t seconds_remaining = 0; - for (CdmSessionMap::iterator iter = sessions_.begin(); - iter != sessions_.end(); ++iter) { - if (iter->second->IsKeyLoaded(*parameters.key_id)) { - int64_t duration = iter->second->GetDurationRemaining(); + for (CdmSessionList::iterator iter = sessions.begin(); + iter != sessions.end(); ++iter) { + if ((*iter)->IsKeyLoaded(*parameters.key_id)) { + int64_t duration = (*iter)->GetDurationRemaining(); if (duration > seconds_remaining) { - session_iter = iter; + session = *iter; seconds_remaining = duration; } } } + if (session.get() == NULL) { + LOGE("CdmEngine::Decrypt: session not found: Empty session ID"); + return SESSION_NOT_FOUND_FOR_DECRYPT; + } } else { - session_iter = sessions_.find(session_id); - } - if (session_iter == sessions_.end()) { - LOGE("CdmEngine::Decrypt: session not found: id=%s, id size=%d", - session_id.c_str(), session_id.size()); - return SESSION_NOT_FOUND_FOR_DECRYPT; + if (!session_map_.FindSession(session_id, &session)) { + LOGE("CdmEngine::Decrypt: session not found: id=%s, id size=%d", + session_id.c_str(), session_id.size()); + return SESSION_NOT_FOUND_FOR_DECRYPT; + } } - return session_iter->second->Decrypt(parameters); + return session->Decrypt(parameters); } CdmResponseType CdmEngine::GenericEncrypt( const std::string& session_id, const std::string& in_buffer, const std::string& key_id, const std::string& iv, CdmEncryptionAlgorithm algorithm, std::string* out_buffer) { - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::GenericEncrypt: session_id not found = %s ", session_id.c_str()); return SESSION_NOT_FOUND_13; } - return iter->second->GenericEncrypt(in_buffer, key_id, iv, - algorithm, out_buffer); + return session->GenericEncrypt(in_buffer, key_id, iv, algorithm, out_buffer); } CdmResponseType CdmEngine::GenericDecrypt( @@ -1353,48 +1379,48 @@ CdmResponseType CdmEngine::GenericDecrypt( const std::string& key_id, const std::string& iv, CdmEncryptionAlgorithm algorithm, std::string* out_buffer) { - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::GenericDecrypt: session_id not found = %s ", session_id.c_str()); return SESSION_NOT_FOUND_14; } - return iter->second->GenericDecrypt(in_buffer, key_id, iv, - algorithm, out_buffer); + return session->GenericDecrypt(in_buffer, key_id, iv, algorithm, out_buffer); } CdmResponseType CdmEngine::GenericSign( const std::string& session_id, const std::string& message, const std::string& key_id, CdmSigningAlgorithm algorithm, std::string* signature) { - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::GenericSign: session_id not found = %s ", session_id.c_str()); return SESSION_NOT_FOUND_15; } - return iter->second->GenericSign(message, key_id, algorithm, signature); + return session->GenericSign(message, key_id, algorithm, signature); } CdmResponseType CdmEngine::GenericVerify( const std::string& session_id, const std::string& message, const std::string& key_id, CdmSigningAlgorithm algorithm, const std::string& signature) { - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter == sessions_.end()) { + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { LOGE("CdmEngine::GenericVerify: session_id not found = %s ", session_id.c_str()); return SESSION_NOT_FOUND_16; } - CdmResponseType sts = iter->second->GenericVerify(message, key_id, - algorithm, signature); - return sts; + return session->GenericVerify(message, key_id, algorithm, signature); } +// TODO(gmorgan) Used? Delete if unused. bool CdmEngine::IsKeyLoaded(const KeyId& key_id) { - for (CdmSessionMap::iterator iter = sessions_.begin(); - iter != sessions_.end(); ++iter) { - if (iter->second->IsKeyLoaded(key_id)) { + CdmSessionList sessions; + session_map_.GetSessionList(sessions); + for (CdmSessionList::iterator iter = sessions.begin(); + iter != sessions.end(); ++iter) { + if ((*iter)->IsKeyLoaded(key_id)) { return true; } } @@ -1408,18 +1434,20 @@ bool CdmEngine::FindSessionForKey(const KeyId& key_id, return false; } - uint32_t session_sharing_id = Properties::GetSessionSharingId(*session_id); - CdmSessionMap::iterator session_iter = sessions_.end(); + CdmSessionList sessions; + session_map_.GetSessionList(sessions); + + CdmSessionList::iterator session_iter = sessions.end(); + int64_t seconds_remaining = 0; - for (CdmSessionMap::iterator iter = sessions_.begin(); - iter != sessions_.end(); ++iter) { - CdmSessionId local_session_id = iter->second->session_id(); - if (Properties::GetSessionSharingId(local_session_id) == - session_sharing_id) { - if (iter->second->IsKeyLoaded(key_id)) { - int64_t duration = iter->second->GetDurationRemaining(); + for (CdmSessionList::iterator iter = sessions.begin(); + iter != sessions.end(); ++iter) { + CdmSessionId id = (*iter)->session_id(); + if (Properties::GetSessionSharingId(id) == session_sharing_id) { + if ((*iter)->IsKeyLoaded(key_id)) { + int64_t duration = (*iter)->GetDurationRemaining(); if (duration > seconds_remaining) { session_iter = iter; seconds_remaining = duration; @@ -1428,8 +1456,8 @@ bool CdmEngine::FindSessionForKey(const KeyId& key_id, } } - if (session_iter != sessions_.end()) { - *session_id = session_iter->second->session_id(); + if (session_iter != sessions.end()) { + *session_id = (*session_iter)->session_id(); return true; } return false; @@ -1437,9 +1465,9 @@ bool CdmEngine::FindSessionForKey(const KeyId& key_id, bool CdmEngine::NotifyResolution(const CdmSessionId& session_id, uint32_t width, uint32_t height) { - CdmSessionMap::iterator iter = sessions_.find(session_id); - if (iter != sessions_.end()) { - iter->second->NotifyResolution(width, height); + std::shared_ptr session; + if (session_map_.FindSession(session_id, &session)) { + session->NotifyResolution(width, height); return true; } return false; @@ -1452,8 +1480,11 @@ bool CdmEngine::ValidateKeySystem(const CdmKeySystem& key_system) { void CdmEngine::OnTimerEvent() { Clock clock; uint64_t current_time = clock.GetCurrentTime(); - bool usage_update_period_expired = false; + CdmSessionList sessions; + session_map_.GetSessionList(sessions); + + bool usage_update_period_expired = false; if (current_time - last_usage_information_update_time_ > kUpdateUsageInformationPeriod) { usage_update_period_expired = true; @@ -1463,51 +1494,48 @@ void CdmEngine::OnTimerEvent() { bool is_initial_usage_update = false; bool is_usage_update_needed = false; - { - AutoLock lock(session_list_lock_); - for (CdmSessionMap::iterator iter = sessions_.begin(); - iter != sessions_.end(); ++iter) { - is_initial_usage_update = - is_initial_usage_update || iter->second->is_initial_usage_update(); - is_usage_update_needed = - is_usage_update_needed || iter->second->is_usage_update_needed(); + while (!sessions.empty()) { + is_initial_usage_update = + is_initial_usage_update || sessions.front()->is_initial_usage_update(); + is_usage_update_needed = + is_usage_update_needed || sessions.front()->is_usage_update_needed(); - iter->second->OnTimerEvent(usage_update_period_expired); - } + sessions.front()->OnTimerEvent(usage_update_period_expired); + sessions.pop_front(); + } - if (is_usage_update_needed && - (usage_update_period_expired || is_initial_usage_update)) { - bool has_usage_been_updated = false; - for (CdmSessionMap::iterator iter = sessions_.begin(); - iter != sessions_.end(); ++iter) { - iter->second->reset_usage_flags(); - if (iter->second->get_usage_support_type() == kUsageEntrySupport) - iter->second->UpdateUsageEntryInformation(); + if (is_usage_update_needed && + (usage_update_period_expired || is_initial_usage_update)) { + bool has_usage_been_updated = false; - if (!has_usage_been_updated) { - // usage is updated for all sessions so this needs to be - // called only once per update usage information period - if (iter->second->get_usage_support_type() == kUsageTableSupport) { - CdmResponseType status = iter->second->UpdateUsageTableInformation(); - if (NO_ERROR != status) { - LOGW("Update usage information failed: %d", status); - } else { - has_usage_been_updated = true; - } - } + // Session list may have changed. Rebuild. + session_map_.GetSessionList(sessions); + + for (CdmSessionList::iterator iter = sessions.begin(); + iter != sessions.end(); ++iter) { + (*iter)->reset_usage_flags(); + if (!has_usage_been_updated) { + // usage is updated for all sessions so this needs to be + // called only once per update usage information period + CdmResponseType status = (*iter)->UpdateUsageInformation(); + if (NO_ERROR != status) { + LOGW("Update usage information failed: %d", status); + } else { + has_usage_been_updated = true; } } } } - CloseExpiredReleaseSessions(); } void CdmEngine::OnKeyReleaseEvent(const CdmKeySetId& key_set_id) { - AutoLock lock(session_list_lock_); - for (CdmSessionMap::iterator iter = sessions_.begin(); - iter != sessions_.end(); ++iter) { - iter->second->OnKeyReleaseEvent(key_set_id); + CdmSessionList sessions; + session_map_.GetSessionList(sessions); + + while (!sessions.empty()) { + sessions.front()->OnKeyReleaseEvent(key_set_id); + sessions.pop_front(); } } @@ -1563,28 +1591,29 @@ void CdmEngine::DeleteAllUsageReportsUponFactoryReset() { if (!file_system_->Exists(device_base_path_level1) && !file_system_->Exists(device_base_path_level3)) { - scoped_ptr crypto_session( - new CryptoSession(metrics_.GetCryptoMetrics())); + scoped_ptr crypto_session(new CryptoSession(&metrics_)); CdmResponseType status; M_TIME( status = crypto_session->Open( cert_provisioning_requested_security_level_), - metrics_.GetCryptoMetrics(), + &metrics_, crypto_session_open_, status, cert_provisioning_requested_security_level_); if (NO_ERROR == status) { - status = crypto_session->DeleteAllUsageReports(); - metrics_.GetCryptoMetrics()->crypto_session_delete_all_usage_reports_ - .Increment(status); + M_TIME( + status = crypto_session->DeleteAllUsageReports(), + &metrics_, + crypto_session_delete_all_usage_reports_, + status); if (NO_ERROR != status) { LOGW( - "CdmEngine::GetProvisioningRequest: " + "CdmEngine::DeleteAllUsageReportsUponFactoryReset: " "Fails to delete usage reports: %d", status); } } else { LOGW( - "CdmEngine::GetProvisioningRequest: " + "CdmEngine::DeleteAllUsageReportsUponFactoryReset: " "Fails to open crypto session: error=%d.\n" "Usage reports are not removed after factory reset.", status); } diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index 7954cfcd..984edddd 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -12,11 +12,11 @@ #include "clock.h" #include "file_store.h" #include "log.h" +#include "metrics_front_end.h" #include "properties.h" #include "string_conversions.h" #include "wv_cdm_constants.h" #include "wv_cdm_event_listener.h" -#include "usage_table_header.h" namespace { const size_t kKeySetIdLength = 14; @@ -24,10 +24,10 @@ const size_t kKeySetIdLength = 14; namespace wvcdm { -CdmSession::CdmSession(FileSystem* file_system, - metrics::SessionMetrics* metrics) : - metrics_(metrics), +CdmSession::CdmSession(FileSystem* file_system) : initialized_(false), + closed_(false), + crypto_session_(new CryptoSession(&metrics_)), file_handle_(new DeviceFiles(file_system)), license_received_(false), is_offline_(false), @@ -39,14 +39,8 @@ CdmSession::CdmSession(FileSystem* file_system, has_decrypted_since_last_report_(false), is_initial_usage_update_(true), is_usage_update_needed_(false), - usage_support_type_(kNonSecureUsageSupport), - usage_table_header_(NULL), - usage_entry_number_(0), mock_license_parser_in_use_(false), mock_policy_engine_in_use_(false) { - assert(metrics_); // metrics_ must not be null. - crypto_metrics_ = metrics_->GetCryptoMetrics(); - crypto_session_.reset(new CryptoSession(crypto_metrics_)); life_span_.Start(); } @@ -57,10 +51,7 @@ CdmSession::~CdmSession() { } Properties::RemoveSessionPropertySet(session_id_); - if (metrics_) { - M_RECORD(metrics_, cdm_session_life_span_, life_span_.AsMs()); - metrics_->SetCompleted(); - } + M_RECORD(&metrics_, cdm_session_life_span_, life_span_.AsMs()); } CdmResponseType CdmSession::Init( @@ -85,28 +76,23 @@ CdmResponseType CdmSession::Init( } CdmResponseType sts; M_TIME( - sts = crypto_session_->Open(requested_security_level_), - crypto_metrics_, + sts = crypto_session_->Open( + requested_security_level_), + &metrics_, crypto_session_open_, sts, requested_security_level_); if (NO_ERROR != sts) return sts; - - security_level_ = crypto_session_->GetSecurityLevel(); - crypto_metrics_->crypto_session_security_level_.Record(security_level_); - + M_TIME( + security_level_ = crypto_session_->GetSecurityLevel(), + &metrics_, + crypto_session_get_security_level_, + security_level_); if (!file_handle_->Init(security_level_)) { LOGE("CdmSession::Init: Unable to initialize file handle"); return SESSION_FILE_HANDLE_INIT_ERROR; } - if (crypto_session_->GetUsageSupportType(&usage_support_type_) == NO_ERROR) { - if (usage_support_type_ == kUsageEntrySupport) - usage_table_header_ = crypto_session_->GetUsageTableHeader(); - } else { - usage_support_type_ = kNonSecureUsageSupport; - } - // Device Provisioning state is not yet known. // If not using certificates, then Keybox is client token for license // requests. @@ -124,9 +110,13 @@ CdmResponseType CdmSession::Init( LOGW("CdmSession::Init: Properties::use_certificates_as_identification() " "is not set - using Keybox for license requests (not recommended)."); - bool get_client_token_sts = crypto_session_->GetClientToken(&client_token); - crypto_metrics_->crypto_session_get_token_.Increment( - get_client_token_sts); + bool get_client_token_sts; + M_TIME( + get_client_token_sts = crypto_session_->GetClientToken( + &client_token), + &metrics_, + crypto_session_get_token_, + get_client_token_sts); if (!get_client_token_sts) { return SESSION_INIT_ERROR_1; } @@ -141,7 +131,7 @@ CdmResponseType CdmSession::Init( M_TIME( load_cert_sts = crypto_session_->LoadCertificatePrivateKey( wrapped_key), - crypto_metrics_, + &metrics_, crypto_session_load_certificate_private_key_, load_cert_sts); if(!load_cert_sts) { @@ -163,7 +153,6 @@ CdmResponseType CdmSession::Init( session_id_ = Properties::AlwaysUseKeySetIds() ? key_set_id_ : GenerateSessionId(); - metrics_->SetSessionId(session_id_); if (session_id_.empty()) { LOGE("CdmSession::Init: empty session ID"); @@ -191,54 +180,33 @@ CdmResponseType CdmSession::Init( CdmResponseType CdmSession::RestoreOfflineSession( const CdmKeySetId& key_set_id, const CdmLicenseType license_type) { - if (!key_set_id_.empty()) { - file_handle_->UnreserveLicenseId(key_set_id_); - } key_set_id_ = key_set_id; DeviceFiles::LicenseState license_state; int64_t playback_start_time; int64_t last_playback_time; int64_t grace_period_end_time; + std::string usage_entry; if (!file_handle_->RetrieveLicense( key_set_id, &license_state, &offline_init_data_, &key_request_, &key_response_, &offline_key_renewal_request_, &offline_key_renewal_response_, &offline_release_server_url_, &playback_start_time, &last_playback_time, &grace_period_end_time, - &app_parameters_, &usage_entry_, &usage_entry_number_)) { - LOGE("CdmSession::RestoreOfflineSession: failed to retrieve license. " - "key set id = %s", key_set_id.c_str()); + &app_parameters_, &usage_entry)) { + LOGE("CdmSession::Init failed to retrieve license. key set id = %s", + key_set_id.c_str()); return GET_LICENSE_ERROR; } // Do not restore a released offline license, unless a release retry if (!(license_type == kLicenseTypeRelease || license_state == DeviceFiles::kLicenseStateActive)) { - LOGE("CdmSession::RestoreOfflineSession: invalid offline license state = " - "%d, type = %d", license_state, license_type); + LOGE("CdmSession::Init invalid offline license state = %d, type = %d", + license_state, license_type); return GET_RELEASED_LICENSE_ERROR; } - std::string provider_session_token; - if (!license_parser_->ExtractProviderSessionToken( - key_response_, &provider_session_token)) { - provider_session_token.clear(); - } - - if (usage_support_type_ == kUsageEntrySupport && - provider_session_token.size() > 0 && - usage_table_header_ != nullptr) { - CdmResponseType sts = usage_table_header_->LoadEntry(crypto_session_.get(), - usage_entry_, - usage_entry_number_); - if (sts != NO_ERROR) { - LOGE("CdmSession::RestoreOfflineSession: failed to load usage entry = %d", - sts); - return sts; - } - } - if (license_type == kLicenseTypeRelease) { if (!license_parser_->RestoreLicenseForRelease(key_request_, key_response_)) { @@ -247,28 +215,11 @@ CdmResponseType CdmSession::RestoreOfflineSession( } else { if (!license_parser_->RestoreOfflineLicense( key_request_, key_response_, offline_key_renewal_response_, - playback_start_time, last_playback_time, grace_period_end_time, - this)) { + playback_start_time, last_playback_time, grace_period_end_time)) { return RESTORE_OFFLINE_LICENSE_ERROR_2; } } - if (usage_support_type_ == kUsageEntrySupport && - provider_session_token.size() > 0 && - usage_table_header_ != nullptr) { - CdmResponseType sts = - usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_); - if (sts != NO_ERROR) { - LOGE("CdmSession::RestoreOfflineSession failed to update usage entry = " - "%d", sts); - return sts; - } - if (!StoreLicense(license_state)) { - LOGW("CdmSession::RestoreUsageSession: unable to save updated usage " - "info"); - } - } - license_received_ = true; is_offline_ = true; is_release_ = license_type == kLicenseTypeRelease; @@ -276,47 +227,14 @@ CdmResponseType CdmSession::RestoreOfflineSession( } CdmResponseType CdmSession::RestoreUsageSession( - const DeviceFiles::CdmUsageData& usage_data) { - if (!key_set_id_.empty()) { - file_handle_->UnreserveLicenseId(key_set_id_); - } - key_set_id_ = usage_data.key_set_id; - key_request_ = usage_data.license_request; - key_response_ = usage_data.license; - usage_entry_ = usage_data.usage_entry; - usage_entry_number_ = usage_data.usage_entry_number; - usage_provider_session_token_ = usage_data.provider_session_token; - - if (usage_support_type_ == kUsageEntrySupport && - usage_table_header_ != nullptr) { - CdmResponseType sts = usage_table_header_->LoadEntry( - crypto_session_.get(), usage_entry_, usage_entry_number_); - if (sts != NO_ERROR) { - LOGE("CdmSession::RestoreUsageSession: failed to load usage entry = %d", - sts); - return sts; - } - } + const CdmKeyMessage& key_request, const CdmKeyResponse& key_response) { + key_request_ = key_request; + key_response_ = key_response; if (!license_parser_->RestoreLicenseForRelease(key_request_, key_response_)) { return RELEASE_LICENSE_ERROR_2; } - if (usage_support_type_ == kUsageEntrySupport && - usage_table_header_ != nullptr) { - CdmResponseType sts = - usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_); - if (sts != NO_ERROR) { - LOGE("CdmSession::RestoreUsageSession: failed to update usage entry: %d", - sts); - return sts; - } - if (!UpdateUsageInfo()) { - LOGW("CdmSession::RestoreUsageSession: unable to save updated usage " - "info"); - } - } - license_received_ = true; is_offline_ = false; is_release_ = true; @@ -442,57 +360,14 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) { } else if (license_received_) { // renewal return RenewKey(key_response); } else { - // If usage table header+entries are supported, preprocess the license - // to see if it has a provider session token. If so a new entry needs - // to be created. - CdmResponseType sts; - std::string provider_session_token; - if (usage_support_type_ == kUsageEntrySupport && - usage_table_header_ != nullptr) { - if (license_parser_->ExtractProviderSessionToken( - key_response, &provider_session_token) && - !provider_session_token.empty()) { - std::string app_id; - GetApplicationId(&app_id); - sts = usage_table_header_->AddEntry( - crypto_session_.get(), is_offline_, key_set_id_, - DeviceFiles::GetUsageInfoFileName(app_id), &usage_entry_number_); - if (sts != NO_ERROR) return sts; - } - } - sts = license_parser_->HandleKeyResponse(key_response); - - // Update or delete entry if usage table header+entries are supported - if (usage_support_type_ == kUsageEntrySupport && - !provider_session_token.empty() && - usage_table_header_ != nullptr) { - if (sts != KEY_ADDED) { - CdmResponseType sts = - usage_table_header_->DeleteEntry(usage_entry_number_, - file_handle_.get(), - crypto_metrics_); - if (sts != NO_ERROR) { - LOGW("CdmSession::AddKey: Delete usage entry failed = %d", sts); - } - } - } + CdmResponseType sts = license_parser_->HandleKeyResponse(key_response); if (sts != KEY_ADDED) return (sts == KEY_ERROR) ? ADD_KEY_ERROR : sts; license_received_ = true; key_response_ = key_response; - if (is_offline_ || has_provider_session_token()) { - if (has_provider_session_token() && - usage_support_type_ == kUsageEntrySupport && - usage_table_header_ != nullptr) { - usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_); - } - - if (!is_offline_) - usage_provider_session_token_ = - license_parser_->provider_session_token(); - + if (is_offline_ || !license_parser_->provider_session_token().empty()) { sts = StoreLicense(); if (sts != NO_ERROR) return sts; } @@ -595,7 +470,8 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParameters& params) { } has_decrypted_since_last_report_ = true; if (!is_usage_update_needed_) { - is_usage_update_needed_ = has_provider_session_token(); + is_usage_update_needed_ = + !license_parser_->provider_session_token().empty(); } } else { Clock clock; @@ -614,7 +490,7 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParameters& params) { CdmResponseType CdmSession::GenerateRenewalRequest( CdmKeyRequest* key_request) { CdmResponseType status = license_parser_->PrepareKeyUpdateRequest( - true, app_parameters_, NULL, &key_request->message, &key_request->url); + true, app_parameters_, &key_request->message, &key_request->url); key_request->type = kKeyRequestTypeRenewal; @@ -644,32 +520,16 @@ CdmResponseType CdmSession::GenerateReleaseRequest( CdmKeyRequest* key_request) { is_release_ = true; CdmResponseType status = license_parser_->PrepareKeyUpdateRequest( - false, app_parameters_, usage_table_header_ == NULL ? NULL : this, - &key_request->message, &key_request->url); + false, app_parameters_, &key_request->message, + &key_request->url); key_request->type = kKeyRequestTypeRelease; if (KEY_MESSAGE != status) return status; - if (has_provider_session_token() && - usage_support_type_ == kUsageEntrySupport) { - status = usage_table_header_->UpdateEntry(crypto_session_.get(), - &usage_entry_); - if (status != NO_ERROR) { - LOGE("CdmSession::GenerateReleaseRequest: Update usage entry failed = " - "%d", status); - return status; - } - } - if (is_offline_) { // Mark license as being released if (!StoreLicense(DeviceFiles::kLicenseStateReleasing)) return RELEASE_KEY_REQUEST_ERROR; - } else if (!usage_provider_session_token_.empty()) { - if (usage_support_type_ == kUsageEntrySupport) { - if (!UpdateUsageInfo()) - return RELEASE_USAGE_INFO_FAILED; - } } return KEY_MESSAGE; } @@ -680,56 +540,12 @@ CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) { license_parser_->HandleKeyUpdateResponse(false, key_response); if (sts != KEY_ADDED) return (sts == KEY_ERROR) ? RELEASE_KEY_ERROR : sts; - if (is_offline_ || has_provider_session_token()) { + if (is_offline_ || !license_parser_->provider_session_token().empty()) { DeleteLicense(); - - if (usage_support_type_ == kUsageEntrySupport && - has_provider_session_token()) { - sts = DeleteUsageEntry(usage_entry_number_); - if (NO_ERROR != sts) return sts; - } } return NO_ERROR; } -CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) { - if (usage_support_type_ != kUsageEntrySupport) { - LOGE("CdmSession::DeleteUsageEntry: Unexpected usage type supported: %d", - usage_support_type_); - return INCORRECT_USAGE_SUPPORT_TYPE_1; - } - - // The usage entry cannot be deleted if it has a crypto session handling - // it, so close and reopen session. - CdmResponseType sts; - crypto_session_->Close(); - crypto_session_.reset(new CryptoSession(crypto_metrics_)); - M_TIME( - sts = crypto_session_->Open(requested_security_level_), - crypto_metrics_, - crypto_session_open_, - sts, - requested_security_level_); - if (sts != NO_ERROR) return sts; - - usage_table_header_ = NULL; - if (crypto_session_->GetUsageSupportType(&usage_support_type_) == NO_ERROR) { - if (usage_support_type_ == kUsageEntrySupport) - usage_table_header_ = crypto_session_->GetUsageTableHeader(); - } else { - usage_support_type_ = kNonSecureUsageSupport; - } - - if (usage_table_header_ == NULL) { - LOGE("CdmSession::DeleteUsageEntry: Usage table header unavailable"); - return INCORRECT_USAGE_SUPPORT_TYPE_1; - } - - return usage_table_header_->DeleteEntry(usage_entry_number, - file_handle_.get(), - crypto_metrics_); -} - bool CdmSession::IsKeyLoaded(const KeyId& key_id) { return license_parser_->IsKeyLoaded(key_id); } @@ -803,11 +619,10 @@ CdmResponseType CdmSession::StoreLicense() { std::string app_id; GetApplicationId(&app_id); + std::string usage_entry; if (!file_handle_->StoreUsageInfo(provider_session_token, key_request_, - key_response_, - DeviceFiles::GetUsageInfoFileName(app_id), - key_set_id_, usage_entry_, - usage_entry_number_)) { + key_response_, app_id, key_set_id_, + usage_entry)) { LOGE("CdmSession::StoreLicense: Unable to store usage info"); return STORE_USAGE_INFO_ERROR; } @@ -815,13 +630,13 @@ CdmResponseType CdmSession::StoreLicense() { } bool CdmSession::StoreLicense(DeviceFiles::LicenseState state) { + std::string usage_entry; return file_handle_->StoreLicense( key_set_id_, state, offline_init_data_, key_request_, key_response_, offline_key_renewal_request_, offline_key_renewal_response_, offline_release_server_url_, policy_engine_->GetPlaybackStartTime(), policy_engine_->GetLastPlaybackTime(), - policy_engine_->GetGracePeriodEndTime(), app_parameters_, usage_entry_, - usage_entry_number_); + policy_engine_->GetGracePeriodEndTime(), app_parameters_, usage_entry); } CdmResponseType CdmSession::ReleaseCrypto() { @@ -830,7 +645,7 @@ CdmResponseType CdmSession::ReleaseCrypto() { } bool CdmSession::DeleteLicense() { - if (!is_offline_ && !has_provider_session_token()) + if (!is_offline_ && license_parser_->provider_session_token().empty()) return false; if (is_offline_) { @@ -839,8 +654,7 @@ bool CdmSession::DeleteLicense() { std::string app_id; GetApplicationId(&app_id); return file_handle_->DeleteUsageInfo( - DeviceFiles::GetUsageInfoFileName(app_id), - license_parser_->provider_session_token()); + app_id, license_parser_->provider_session_token()); } } @@ -873,48 +687,24 @@ void CdmSession::GetApplicationId(std::string* app_id) { CdmResponseType CdmSession::DeleteMultipleUsageInformation( const std::vector& provider_session_tokens) { - CdmResponseType sts = crypto_session_->DeleteMultipleUsageInformation( - provider_session_tokens); - crypto_metrics_->crypto_session_delete_multiple_usage_information_ - .Increment(sts); - return sts; -} - -CdmResponseType CdmSession::UpdateUsageTableInformation() { CdmResponseType sts; M_TIME( - sts = crypto_session_->UpdateUsageInformation(), - crypto_metrics_, - crypto_session_update_usage_information_, + sts = crypto_session_->DeleteMultipleUsageInformation( + provider_session_tokens), + &metrics_, + crypto_session_delete_multiple_usage_information_, sts); return sts; } -CdmResponseType CdmSession::UpdateUsageEntryInformation() { - if (usage_support_type_ != kUsageEntrySupport || - !has_provider_session_token() || - usage_table_header_ == nullptr) { - LOGE("CdmSession::UpdateUsageEntryInformation: Unexpected state, " - "usage support type: %d, PST present: %s, usage table header available" - ": %s", usage_support_type_, - has_provider_session_token() ? "yes" : "no", - usage_table_header_ == nullptr ? "no" : "yes"); - return INCORRECT_USAGE_SUPPORT_TYPE_2; - } - - CdmResponseType sts = usage_table_header_->UpdateEntry(crypto_session_.get(), - &usage_entry_); - - if (sts != NO_ERROR) return sts; - - if (is_offline_) - StoreLicense(is_release_ - ? DeviceFiles::kLicenseStateReleasing - : DeviceFiles::kLicenseStateActive); - else if (!usage_provider_session_token_.empty()) - UpdateUsageInfo(); - - return NO_ERROR; +CdmResponseType CdmSession::UpdateUsageInformation() { + CdmResponseType sts; + M_TIME( + sts = crypto_session_->UpdateUsageInformation(), + &metrics_, + crypto_session_update_usage_information_, + sts); + return sts; } CdmResponseType CdmSession::GenericEncrypt(const std::string& in_buffer, @@ -934,7 +724,7 @@ CdmResponseType CdmSession::GenericEncrypt(const std::string& in_buffer, iv, algorithm, out_buffer), - crypto_metrics_, + &metrics_, crypto_session_generic_encrypt_, sts, metrics::Pow2Bucket(in_buffer.size()), @@ -959,7 +749,7 @@ CdmResponseType CdmSession::GenericDecrypt(const std::string& in_buffer, iv, algorithm, out_buffer), - crypto_metrics_, + &metrics_, crypto_session_generic_decrypt_, sts, metrics::Pow2Bucket(in_buffer.size()), @@ -982,7 +772,7 @@ CdmResponseType CdmSession::GenericSign(const std::string& message, key_id, algorithm, signature), - crypto_metrics_, + &metrics_, crypto_session_generic_sign_, sts, metrics::Pow2Bucket(message.size()), @@ -1001,7 +791,7 @@ CdmResponseType CdmSession::GenericVerify(const std::string& message, key_id, algorithm, signature), - crypto_metrics_, + &metrics_, crypto_session_generic_verify_, sts, metrics::Pow2Bucket(message.size()), @@ -1009,24 +799,6 @@ CdmResponseType CdmSession::GenericVerify(const std::string& message, return sts; } -bool CdmSession::UpdateUsageInfo() { - std::string app_id; - GetApplicationId(&app_id); - - DeviceFiles::CdmUsageData usage_data; - usage_data.provider_session_token = usage_provider_session_token_; - usage_data.license_request = key_request_; - usage_data.license = key_response_; - usage_data.key_set_id = key_set_id_; - usage_data.usage_entry = usage_entry_; - usage_data.usage_entry_number = usage_entry_number_; - - return file_handle_->UpdateUsageInfo( - DeviceFiles::GetUsageInfoFileName(app_id), - usage_provider_session_token_, - usage_data); -} - // For testing only - takes ownership of pointers void CdmSession::set_license_parser(CdmLicense* license_parser) { diff --git a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index bcd5868a..5b0c2de3 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -19,45 +19,71 @@ const std::string kProvisioningServerUrl = "https://www.googleapis.com/" "certificateprovisioning/v1/devicecertificates/create" "?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE"; + +/* + * Provisioning response is a base64-encoded protobuf, optionally within a + * JSON wrapper. If the JSON wrapper is present, extract the embedded response + * message. Then perform the base64 decode and return the result. + * + * If an error occurs during the parse or the decode, return an empty string. + */ +void ExtractAndDecodeSignedMessage(const std::string& provisioning_response, + std::string* result) { + const std::string json_start_substr("\"signedResponse\": \""); + const std::string json_end_substr("\""); + std::string message_string; + + size_t start = provisioning_response.find(json_start_substr); + + if (start == provisioning_response.npos) { + // Message is not properly wrapped - reject it. + LOGE("ExtractAndDecodeSignedMessage: cannot locate start substring"); + result->clear(); + return; + } else { + // Appears to be JSON-wrapped protobuf - find end of protobuf portion. + size_t end = provisioning_response.find(json_end_substr, + start + json_start_substr.length()); + if (end == provisioning_response.npos) { + LOGE("ExtractAndDecodeSignedMessage: cannot locate end substring"); + result->clear(); + return; + } + size_t b64_string_size = end - start - json_start_substr.length(); + message_string.assign(provisioning_response, + start + json_start_substr.length(), b64_string_size); + } + + if (message_string.empty()) { + LOGE("ExtractAndDecodeSignedMessage: CdmProvisioningResponse is empty"); + result->clear(); + return; + } + + // Decode the base64-encoded message. + const std::vector decoded_message = + wvcdm::Base64SafeDecode(message_string); + result->assign(decoded_message.begin(), decoded_message.end()); +} + } namespace wvcdm { // Protobuf generated classes. using video_widevine::ClientIdentification; +using video_widevine::EncryptedClientIdentification; using video_widevine::ProvisioningOptions; using video_widevine::ProvisioningRequest; using video_widevine::ProvisioningResponse; using video_widevine::SignedProvisioningMessage; -/* - * This function converts SignedProvisioningRequest into base64 string. It then - * wraps it in JSON format expected by the frontend. This server requires a - * "web-safe" base 64 encoding, where '+' becomes '-' and '/' becomes '_'. - * - * Returns the JSON formated string in *request. The JSON string will be - * appended as a query parameter, i.e. signedRequest=. All base64 '=' padding chars must be removed. - * - * The JSON formated request takes the following format: - * - * base64 encoded message - */ -void CertificateProvisioning::ComposeJsonRequestAsQueryString( - const std::string& message, CdmProvisioningRequest* request) { - // Performs base64 encoding for message - std::vector message_vector(message.begin(), message.end()); - std::string message_b64 = Base64SafeEncodeNoPad(message_vector); - request->assign(message_b64); -} - /* * Return the ClientIdentification message token type for provisioning request. * NOTE: a DRM Cert should never be presented to the provisioning server. */ bool CertificateProvisioning::GetProvisioningTokenType( ClientIdentification::TokenType* token_type) { - CdmClientTokenType token = crypto_session_.GetPreProvisionTokenType(); - switch (token) { + switch (crypto_session_.GetPreProvisionTokenType()) { case kClientTokenKeybox: *token_type = ClientIdentification::KEYBOX; return true; @@ -67,8 +93,6 @@ bool CertificateProvisioning::GetProvisioningTokenType( case kClientTokenDrmCert: default: // shouldn't happen - LOGE("CertificateProvisioning::GetProvisioningTokenType: unexpected " - "provisioning type: %d", token); return false; } } @@ -83,7 +107,7 @@ bool CertificateProvisioning::SetSpoidParameter( const std::string& origin, const std::string& spoid, ProvisioningRequest* request) { if (!request) { - LOGE("CertificateProvisioning::SetSpoidParameter: No request buffer " + LOGE("CertificateProvisioning::SetSpoidParameter : No request buffer " "passed to method."); return false; } @@ -102,7 +126,8 @@ bool CertificateProvisioning::SetSpoidParameter( // Legacy behavior - Concatenate Unique ID with Origin std::string device_unique_id; if (!crypto_session_.GetInternalDeviceUniqueId(&device_unique_id)) { - LOGE("CryptoSession::GetStableIdField: Failure to get device unique ID"); + LOGE("CertificateProvisioning::SetSpoidParameter: Failure getting " + "device unique ID"); return false; } request->set_stable_id(device_unique_id + origin); @@ -123,9 +148,9 @@ SignedProvisioningMessage::ProtocolVersion } /* - * Composes a device provisioning request and output the request in JSON format - * in *request. It also returns the default url for the provisioning server - * in *default_url. + * Compose a device provisioning request and output *request in a + * JSON-compatible format (web-safe base64). + * Also return *default_url of the provisioning server. * * Returns NO_ERROR for success and CERT_PROVISIONING_REQUEST_ERROR_? if fails. */ @@ -164,6 +189,22 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest( client_id->set_token(token); client_id->set_type(token_type); +#if 0 // TODO(gmorgan) Encrypt ClientIdentification. Pending Design. + if (service_certificate_->has_certificate()) { + EncryptedClientIdentification* encrypted_client_id = + provisioning_request.mutable_encrypted_client_id(); + CdmResponseType status; + status = service_certificate_->EncryptClientId(&crypto_session_, client_id, + encrypted_client_id); + if (status == NO_ERROR) { + provisioning_request.clear_client_id(); + } else { + provisioning_request.clear_encrypted_client_id(); + } + return status; + } +#endif + uint32_t nonce; if (!crypto_session_.GenerateNonce(&nonce)) { LOGE("GetProvisioningRequest: fails to generate a nonce"); @@ -220,43 +261,13 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest( std::string serialized_request; signed_provisioning_msg.SerializeToString(&serialized_request); - // Converts request into JSON string - ComposeJsonRequestAsQueryString(serialized_request, request); + // Return request as web-safe base64 string + std::vector request_vector(serialized_request.begin(), + serialized_request.end()); + request->assign(Base64SafeEncodeNoPad(request_vector)); return NO_ERROR; } -/* - * Parses the input json_str and locates substring using start_substr and - * end_stubstr. The found base64 substring is then decoded and returns - * in *result. - * - * Returns true for success and false if fails. - */ -bool CertificateProvisioning::ParseJsonResponse( - const CdmProvisioningResponse& json_str, const std::string& start_substr, - const std::string& end_substr, std::string* result) { - std::string b64_string; - size_t start = json_str.find(start_substr); - if (start == json_str.npos) { - LOGE("ParseJsonResponse: cannot find start substring"); - return false; - } - size_t end = json_str.find(end_substr, start + start_substr.length()); - if (end == json_str.npos) { - LOGE("ParseJsonResponse cannot locate end substring"); - return false; - } - - size_t b64_string_size = end - start - start_substr.length(); - b64_string.assign(json_str, start + start_substr.length(), b64_string_size); - - // Decodes base64 substring and returns it in *result - std::vector result_vector = Base64SafeDecode(b64_string); - result->assign(result_vector.begin(), result_vector.end()); - - return true; -} - /* * The response message consists of a device certificate and the device RSA key. * The device RSA key is stored in the T.E.E. The device certificate is stored @@ -267,13 +278,15 @@ bool CertificateProvisioning::ParseJsonResponse( CdmResponseType CertificateProvisioning::HandleProvisioningResponse( FileSystem* file_system, const CdmProvisioningResponse& response, std::string* cert, std::string* wrapped_key) { - // Extracts signed response from JSON string, decodes base64 signed response - const std::string kMessageStart = "\"signedResponse\": \""; - const std::string kMessageEnd = "\""; - std::string serialized_signed_response; - if (!ParseJsonResponse(response, kMessageStart, kMessageEnd, - &serialized_signed_response)) { - LOGE("Fails to extract signed serialized response from JSON response"); + + std::string raw_string; + // The response is base64 encoded in a JSON wrapper. + // Extract it and decode it. If errors, return an empty string. + ExtractAndDecodeSignedMessage(response, &raw_string); + + if (raw_string.empty()) { + LOGE("HandleProvisioningResponse: response message is empty or " + "an invalid JSON/base64 string."); return CERT_PROVISIONING_RESPONSE_ERROR_1; } @@ -281,7 +294,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( // the provisioing request's input). Validate provisioning response and // stores private device RSA key and certificate. SignedProvisioningMessage signed_response; - if (!signed_response.ParseFromString(serialized_signed_response)) { + if (!signed_response.ParseFromString(raw_string)) { LOGE("HandleProvisioningResponse: fails to parse signed response"); return CERT_PROVISIONING_RESPONSE_ERROR_2; } @@ -300,6 +313,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( if (error) return CERT_PROVISIONING_RESPONSE_ERROR_3; const std::string& signed_message = signed_response.message(); + const std::string& signature = signed_response.signature(); ProvisioningResponse provisioning_response; if (!provisioning_response.ParseFromString(signed_message)) { @@ -312,17 +326,28 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( return CERT_PROVISIONING_RESPONSE_ERROR_5; } - const std::string& enc_rsa_key = provisioning_response.device_rsa_key(); + // If Provisioning 3.0 (OEM Cert provisioned), verify that the + // message is properly signed. + if (crypto_session_.GetPreProvisionTokenType() == kClientTokenOemCert) { + if (!service_certificate_->VerifySignedMessage(signed_message, signature)) { + LOGE("HandleProvisioningResponse: message not properly signed"); + return CERT_PROVISIONING_RESPONSE_ERROR_6; + } + } + + const std::string& new_private_key = provisioning_response.device_rsa_key(); const std::string& nonce = provisioning_response.nonce(); - const std::string& rsa_key_iv = provisioning_response.device_rsa_key_iv(); + const std::string& iv = provisioning_response.device_rsa_key_iv(); + const std::string& wrapping_key = (provisioning_response.has_wrapping_key()) ? - provisioning_response.wrapping_key() : std::string(); - const std::string& signature = signed_response.signature(); - std::string wrapped_rsa_key; + provisioning_response.wrapping_key() : std::string(); + + std::string wrapped_private_key; + if (!crypto_session_.RewrapCertificate(signed_message, signature, nonce, - enc_rsa_key, rsa_key_iv, wrapping_key, - &wrapped_rsa_key)) { - LOGE("HandleProvisioningResponse: RewrapDeviceRSAKey fails"); + new_private_key, iv, wrapping_key, + &wrapped_private_key)) { + LOGE("HandleProvisioningResponse: RewrapCertificate fails"); return CERT_PROVISIONING_RESPONSE_ERROR_6; } @@ -330,10 +355,13 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( if (cert_type_ == kCertificateX509) { *cert = provisioning_response.device_certificate(); - *wrapped_key = wrapped_rsa_key; + *wrapped_key = wrapped_private_key; return NO_ERROR; } + // This is the entire certificate (SignedDrmDeviceCertificate). + // This will be stored to the device as the final step in the device + // provisioning process. const std::string& device_certificate = provisioning_response.device_certificate(); @@ -342,7 +370,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( LOGE("HandleProvisioningResponse: failed to init DeviceFiles"); return CERT_PROVISIONING_RESPONSE_ERROR_7; } - if (!handle.StoreCertificate(device_certificate, wrapped_rsa_key)) { + if (!handle.StoreCertificate(device_certificate, wrapped_private_key)) { LOGE("HandleProvisioningResponse: failed to save provisioning certificate"); return CERT_PROVISIONING_RESPONSE_ERROR_8; } diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index c442d38d..64d0aba7 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -7,19 +7,16 @@ #include // needed for ntoh() #include -#include #include -#include +#include #include "crypto_key.h" #include "log.h" -#include "openssl/asn1.h" +#include "metrics_front_end.h" #include "openssl/sha.h" -#include "openssl/x509v3.h" #include "properties.h" #include "pst_report.h" #include "string_conversions.h" -#include "usage_table_header.h" #include "wv_cdm_constants.h" namespace { @@ -36,15 +33,6 @@ const uint32_t kRsaSignatureLength = 256; const size_t kMaximumChunkSize = 100 * 1024; // 100 KiB const size_t kEstimatedInitialUsageTableHeader = 40; const size_t kOemCryptoApiVersionSupportsBigUsageTables = 13; - -// Constants and utility objects relating to OEM Certificates -const int kExtensionOidSize = 64; -const char* const kWidevineSystemIdExtensionOid = "1.3.6.1.4.1.11129.4.1.1"; -struct X509StackDeleter { - void operator()(STACK_OF(X509)* stack) { - sk_X509_pop_free(stack, X509_free); - } -}; } namespace wvcdm { @@ -53,21 +41,16 @@ Lock CryptoSession::crypto_lock_; bool CryptoSession::initialized_ = false; int CryptoSession::session_count_ = 0; uint64_t CryptoSession::request_id_index_ = 0; -UsageTableHeader* CryptoSession::usage_table_header_l1_ = NULL; -UsageTableHeader* CryptoSession::usage_table_header_l3_ = NULL; -CryptoSession::CryptoSession(metrics::CryptoMetrics* metrics) +CryptoSession::CryptoSession(metrics::MetricsGroup* metrics) : metrics_(metrics), open_(false), update_usage_table_after_close_session_(false), is_destination_buffer_type_valid_(false), requested_security_level_(kLevelDefault), - is_usage_support_type_valid_(false), - usage_support_type_(kNonSecureUsageSupport), - usage_table_header_(NULL), + usage_support_type_(kUnknownUsageSupport), request_id_base_(0), cipher_mode_(kCipherModeCtr) { - assert(metrics); Init(); life_span_.Start(); } @@ -82,21 +65,23 @@ CryptoSession::~CryptoSession() { bool CryptoSession::GetProvisioningMethod(CdmClientTokenType* token_type) { OEMCrypto_ProvisioningMethod method; + CdmClientTokenType type; switch (method = OEMCrypto_GetProvisioningMethod(requested_security_level_)) { case OEMCrypto_OEMCertificate: - *token_type = kClientTokenOemCert; + type = kClientTokenOemCert; break; case OEMCrypto_Keybox: - *token_type = kClientTokenKeybox; + type = kClientTokenKeybox; break; case OEMCrypto_DrmCertificate: - *token_type = kClientTokenDrmCert; + type = kClientTokenDrmCert; break; case OEMCrypto_ProvisioningError: default: LOGE("OEMCrypto_GetProvisioningMethod failed", method); return false; } + *token_type = type; return true; } @@ -136,16 +121,6 @@ void CryptoSession::Terminate() { if (OEMCrypto_SUCCESS != sts) { LOGE("OEMCrypto_Terminate failed: %d", sts); } - - if (usage_table_header_l1_ != NULL) { - delete usage_table_header_l1_; - usage_table_header_l1_ = NULL; - } - if (usage_table_header_l3_ != NULL) { - delete usage_table_header_l3_; - usage_table_header_l3_ = NULL; - } - initialized_ = false; } @@ -164,7 +139,8 @@ bool CryptoSession::GetTokenFromKeybox(std::string* token) { metrics_, oemcrypto_get_key_data_, status, - metrics::Pow2Bucket(buf_size)); + metrics::Pow2Bucket(buf_size), + requested_security_level_); if (OEMCrypto_SUCCESS == status) { token->swap(temp_buffer); return true; @@ -174,10 +150,6 @@ bool CryptoSession::GetTokenFromKeybox(std::string* token) { } bool CryptoSession::GetTokenFromOemCert(std::string* token) { - if (token == NULL) { - LOGE("CryptoSession::GetTokenFromOemCert: token not provided "); - return false; - } OEMCryptoResult status; if (!oem_token_.empty()) { token->assign(oem_token_); @@ -193,7 +165,7 @@ bool CryptoSession::GetTokenFromOemCert(std::string* token) { if (OEMCrypto_SUCCESS == status) { temp_buffer.resize(buf_size); oem_token_.assign(temp_buffer); - token->assign(temp_buffer); + token->swap(temp_buffer); return true; } if (OEMCrypto_ERROR_SHORT_BUFFER && !retrying) { @@ -245,35 +217,37 @@ bool CryptoSession::GetProvisioningToken(std::string* token) { } CdmSecurityLevel CryptoSession::GetSecurityLevel() { - LOGV("CryptoSession::GetSecurityLevel"); + LOGV("CryptoSession::GetSecurityLevel: Lock"); + AutoLock auto_lock(crypto_lock_); if (!initialized_) { return kSecurityLevelUninitialized; } - std::string security_level = - OEMCrypto_SecurityLevel(requested_security_level_); + std::string security_level; + M_TIME( + security_level = OEMCrypto_SecurityLevel( + requested_security_level_), + metrics_, + oemcrypto_security_level_, + security_level, + requested_security_level_); if ((security_level.size() != 2) || (security_level.at(0) != 'L')) { return kSecurityLevelUnknown; } - CdmSecurityLevel cdm_security_level; switch (security_level.at(1)) { case '1': - cdm_security_level = kSecurityLevelL1; - break; + return kSecurityLevelL1; case '2': - cdm_security_level = kSecurityLevelL2; - break; + return kSecurityLevelL2; case '3': - cdm_security_level = kSecurityLevelL3; - break; + return kSecurityLevelL3; default: - cdm_security_level = kSecurityLevelUnknown; - break; + return kSecurityLevelUnknown; } - return cdm_security_level; + return kSecurityLevelUnknown; } bool CryptoSession::GetInternalDeviceUniqueId(std::string* device_id) { @@ -298,10 +272,16 @@ bool CryptoSession::GetInternalDeviceUniqueId(std::string* device_id) { size_t id_length = 32; id.resize(id_length); - OEMCryptoResult sts = OEMCrypto_GetDeviceID(&id[0], &id_length, - requested_security_level_); - // Increment the count of times this method was called. - metrics_->oemcrypto_get_device_id_.Increment(sts); + OEMCryptoResult sts; + M_TIME( + sts = OEMCrypto_GetDeviceID( + &id[0], + &id_length, + requested_security_level_), + metrics_, + oemcrypto_get_device_id_, + sts, + requested_security_level_); if (OEMCrypto_SUCCESS != sts) { return false; @@ -341,166 +321,55 @@ bool CryptoSession::GetApiVersion(uint32_t* version) { if (!initialized_) { return false; } - - *version = OEMCrypto_APIVersion(requested_security_level_); - // Record the version into the metrics. - metrics_->oemcrypto_api_version_.Record(*version); + M_TIME( + *version = OEMCrypto_APIVersion(requested_security_level_), + metrics_, + oemcrypto_api_version_, + *version, + requested_security_level_); return true; } bool CryptoSession::GetSystemId(uint32_t* system_id) { - // TODO(gmorgan): if Prov 3.0, get system ID from DRM Device Cert. If - // DRM Device Cert is not available (e.g., not yet provisioned), return false. if (!system_id) { - LOGE("CryptoSession::GetSystemId: No buffer passed to method."); + LOGE("CryptoSession::GetSystemId : No buffer passed to method."); return false; } + uint8_t buf[KEYBOX_KEY_DATA_SIZE]; + size_t buf_size = sizeof(buf); + LOGV("CryptoSession::GetSystemId: Lock"); AutoLock auto_lock(crypto_lock_); if (!initialized_) { return false; } + OEMCryptoResult sts; + M_TIME( + sts = OEMCrypto_GetKeyData( + buf, + &buf_size, + requested_security_level_), + metrics_, + oemcrypto_get_key_data_, + sts, + metrics::Pow2Bucket(buf_size), + requested_security_level_); - if (pre_provision_token_type_ == kClientTokenKeybox) { - uint8_t buf[KEYBOX_KEY_DATA_SIZE]; - size_t buf_size = sizeof(buf); - - OEMCryptoResult sts; - M_TIME( - sts = OEMCrypto_GetKeyData( - buf, - &buf_size, - requested_security_level_), - metrics_, - oemcrypto_get_key_data_, - sts, - metrics::Pow2Bucket(buf_size)); - - if (OEMCrypto_SUCCESS != sts) { - LOGE("CryptoSession::GetSystemId: OEMCrypto_GetKeyData failed with %d", - sts); - return false; - } - - // Decode 32-bit int encoded as network-byte-order byte array starting at - // index 4. - uint32_t* id = reinterpret_cast(&buf[4]); - - *system_id = ntohl(*id); - return true; - } else if (pre_provision_token_type_ == kClientTokenOemCert) { - // Get the OEM Cert - std::string oem_cert; - if (GetTokenFromOemCert(&oem_cert)) { - return ExtractSystemIdFromOemCert(oem_cert, system_id); - } else { - return false; - } - } else { - LOGE("CryptoSession::GetSystemId: Unsupported pre-provision token type %d", - pre_provision_token_type_); + if (OEMCrypto_SUCCESS != sts) { return false; } + + // Decode 32-bit int encoded as network-byte-order byte array starting at + // index 4. + uint32_t* id = reinterpret_cast(&buf[4]); + + *system_id = ntohl(*id); + return true; } -bool CryptoSession::ExtractSystemIdFromOemCert(const std::string& oem_cert, - uint32_t* system_id) { - // Parse the OEM Cert chain into an OpenSSL X509 Stack - const std::unique_ptr - x509_stack(sk_X509_new_null()); - if (!x509_stack) { - LOGE("CryptoSession::GetSystemId: Unable to allocate X509 Stack."); - return false; - } - - CBS pkcs7; - CBS_init(&pkcs7, reinterpret_cast(oem_cert.data()), - oem_cert.size()); - if (!PKCS7_get_certificates(x509_stack.get(), &pkcs7)) { - LOGE("CryptoSession::GetSystemId: Error getting certificate chain."); - return false; - } - - // Get the Widevine intermediate cert from the stack - if (sk_X509_num(x509_stack.get()) != 2) { - LOGE("CryptoSession::GetSystemId: Expected 2 certificates in chain, got %d", - sk_X509_num(x509_stack.get())); - return false; - } - - X509* const intermediate_cert = sk_X509_value(x509_stack.get(), 1); - if (!intermediate_cert) { - LOGE("CryptoSession::GetSystemId: Unable to get intermediate cert."); - return false; - } - - // Find the Widevine System ID extension in the intermediate cert - const int extension_count = X509_get_ext_count(intermediate_cert); - for (int i = 0; i < extension_count; ++i) { - X509_EXTENSION* const extension = X509_get_ext(intermediate_cert, i); - if (!extension) { - LOGE("CryptoSession::GetSystemId: Unable to get cert extension %d", i); - continue; - } - - ASN1_OBJECT* const extension_object = X509_EXTENSION_get_object(extension); - if (!extension_object) { - LOGE("CryptoSession::GetSystemId: Unable to get object of cert " - "extension %d", i); - continue; - } - - char extension_name[kExtensionOidSize + 1]; - OBJ_obj2txt(extension_name, kExtensionOidSize, extension_object, 1); - if (strcmp(extension_name, kWidevineSystemIdExtensionOid) != 0) { - // This extension is not the Widevine System ID, so we should move on to - // the next one. - continue; - } - - ASN1_OCTET_STRING* const octet_str = X509_EXTENSION_get_data(extension); - if (!octet_str) { - LOGE("CryptoSession::GetSystemId: Unable to get data of Widevine System " - "ID extension."); - return false; - } - - const unsigned char* data = octet_str->data; - if (!data) { - LOGE("CryptoSession::GetSystemId: Null data in Widevine System ID " - "extension."); - return false; - } - - ASN1_INTEGER* const asn1_integer = - d2i_ASN1_INTEGER(NULL, &data, octet_str->length); - if (!asn1_integer) { - LOGE("CryptoSession::GetSystemId: Unable to decode data in Widevine " - "System ID extension."); - return false; - } - - const long system_id_long = ASN1_INTEGER_get(asn1_integer); - ASN1_INTEGER_free(asn1_integer); - if (system_id_long == -1) { - LOGE("CryptoSession::GetSystemId: Unable to decode ASN integer in " - "Widevine System ID extension."); - return false; - } - - *system_id = static_cast(system_id_long); - return true; - } - - LOGE("CryptoSession::GetSystemId: Widevine System ID extension not found."); - return false; -} - - bool CryptoSession::GetProvisioningId(std::string* provisioning_id) { - // TODO(gmorgan): if Prov 3.0, return false (no "provisioning ID" available). if (!provisioning_id) { LOGE("CryptoSession::GetProvisioningId : No buffer passed to method."); return false; @@ -537,7 +406,8 @@ bool CryptoSession::GetProvisioningId(std::string* provisioning_id) { metrics_, oemcrypto_get_key_data_, sts, - metrics::Pow2Bucket(buf_size)); + metrics::Pow2Bucket(buf_size), + requested_security_level_); if (OEMCrypto_SUCCESS != sts) { return false; } @@ -548,23 +418,34 @@ bool CryptoSession::GetProvisioningId(std::string* provisioning_id) { } uint8_t CryptoSession::GetSecurityPatchLevel() { - uint8_t patch = OEMCrypto_Security_Patch_Level(requested_security_level_); - metrics_->oemcrypto_security_patch_level_.Record(patch); + uint8_t patch; + M_TIME( + patch = OEMCrypto_Security_Patch_Level( + requested_security_level_), + metrics_, + oemcrypto_security_patch_level_, + patch, + requested_security_level_); return patch; } CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) { - LOGD("CryptoSession::Open: Lock: requested_security_level: %s", - requested_security_level == kLevel3 - ? QUERY_VALUE_SECURITY_LEVEL_L3.c_str() - : QUERY_VALUE_SECURITY_LEVEL_DEFAULT.c_str()); + LOGV("CryptoSession::Open: Lock"); AutoLock auto_lock(crypto_lock_); if (!initialized_) return UNKNOWN_ERROR; if (open_) return NO_ERROR; OEMCrypto_SESSION sid; requested_security_level_ = requested_security_level; - OEMCryptoResult sts = OEMCrypto_OpenSession(&sid, requested_security_level); + OEMCryptoResult sts; + M_TIME( + sts = OEMCrypto_OpenSession( + &sid, + requested_security_level), + metrics_, + oemcrypto_open_session_, + sts, + requested_security_level); if (OEMCrypto_SUCCESS == sts) { oec_session_id_ = static_cast(sid); LOGV("OpenSession: id= %ld", (uint32_t)oec_session_id_); @@ -579,63 +460,44 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) { sts, session_count_, (int)initialized_); return UNKNOWN_ERROR; } - OEMCryptoResult random_sts = OEMCrypto_GetRandom( - reinterpret_cast(&request_id_base_), - sizeof(request_id_base_)); - metrics_->oemcrypto_get_random_.Increment(random_sts); + OEMCryptoResult random_sts; + M_TIME( + random_sts = OEMCrypto_GetRandom( + reinterpret_cast(&request_id_base_), + sizeof(request_id_base_)), + metrics_, + oemcrypto_get_random_, + random_sts, + metrics::Pow2Bucket(sizeof(request_id_base_))); ++request_id_index_; - - CdmUsageSupportType usage_support_type; - if (GetUsageSupportType(&usage_support_type) == NO_ERROR) { - if (usage_support_type == kUsageEntrySupport) { - CdmSecurityLevel security_level = GetSecurityLevel(); - if (security_level == kSecurityLevelL1 || - security_level == kSecurityLevelL3) { - UsageTableHeader** header = security_level == kSecurityLevelL1 ? - &usage_table_header_l1_ : &usage_table_header_l3_; - if (*header == NULL) { - *header = new UsageTableHeader(); - // Ignore errors since we do not know when a session is opened, - // if it is intended to be used for offline/usage session related - // or otherwise. - crypto_lock_.Release(); - bool is_usage_table_header_inited = - (*header)->Init(security_level, this); - crypto_lock_.Acquire(); - if (!is_usage_table_header_inited) { - delete *header; - *header = NULL; - usage_table_header_ = NULL; - return NO_ERROR; - } - } - usage_table_header_ = *header; - } - } - } - return NO_ERROR; } void CryptoSession::Close() { LOGV("CloseSession: id=%ld open=%s", (uint32_t)oec_session_id_, open_ ? "true" : "false"); + AutoLock auto_lock(crypto_lock_); + if (!open_) return; OEMCryptoResult close_sts; - bool update_usage_table = false; - { - AutoLock auto_lock(crypto_lock_); - if (!open_) return; - - close_sts = OEMCrypto_CloseSession(oec_session_id_); - metrics_->oemcrypto_close_session_.Increment(close_sts); - if (OEMCrypto_SUCCESS == close_sts) - open_ = false; - update_usage_table = update_usage_table_after_close_session_; - } - if (close_sts == OEMCrypto_SUCCESS && update_usage_table && - usage_support_type_ == kUsageTableSupport) { - UpdateUsageInformation(); + M_TIME( + close_sts = OEMCrypto_CloseSession( + oec_session_id_), + metrics_, + oemcrypto_close_session_, + close_sts); + if (OEMCrypto_SUCCESS == close_sts) { + open_ = false; + if (update_usage_table_after_close_session_) { + OEMCryptoResult update_sts; + M_TIME( + update_sts = OEMCrypto_UpdateUsageTable(), + metrics_, + oemcrypto_update_usage_table_, + update_sts); + if ( update_sts != OEMCrypto_SUCCESS) + LOGW("CryptoSession::Close: OEMCrypto_UpdateUsageTable error=%ld", update_sts); + } } } @@ -807,31 +669,27 @@ CdmResponseType CryptoSession::LoadKeys( metrics_, oemcrypto_load_keys_, sts); - CdmResponseType result = KEY_ADDED; if (OEMCrypto_SUCCESS == sts) { - if (!provider_session_token.empty()) + if (!provider_session_token.empty()) { update_usage_table_after_close_session_ = true; - result = KEY_ADDED; + M_TIME( + sts = OEMCrypto_UpdateUsageTable(), + metrics_, + oemcrypto_update_usage_table_, + sts); + if (sts != OEMCrypto_SUCCESS) { + LOGW("CryptoSession::LoadKeys: OEMCrypto_UpdateUsageTable error=%ld", + sts); + } + } + return KEY_ADDED; } else if (OEMCrypto_ERROR_TOO_MANY_KEYS == sts) { LOGE("CryptoSession::LoadKeys: OEMCrypto_LoadKeys error=%d", sts); - result = INSUFFICIENT_CRYPTO_RESOURCES; - } else if (OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE == sts) { - // Handle vendor specific error - LOGE("CryptoSession::LoadKeys: OEMCrypto_LoadKeys error=%d", sts); - result = NEED_PROVISIONING; + return INSUFFICIENT_CRYPTO_RESOURCES; } else { LOGE("CryptoSession::LoadKeys: OEMCrypto_LoadKeys error=%d", sts); - result = LOAD_KEY_ERROR; + return LOAD_KEY_ERROR; } - - // Leaving critical section - crypto_lock_.Release(); - - if (!provider_session_token.empty() && - usage_support_type_ == kUsageTableSupport) { - UpdateUsageInformation(); - } - return result; } bool CryptoSession::LoadCertificatePrivateKey(std::string& wrapped_key) { @@ -847,6 +705,7 @@ bool CryptoSession::LoadCertificatePrivateKey(std::string& wrapped_key) { OEMCrypto_GetOEMPublicCertificate(oec_session_id_, buf, &buf_size); LOGV("LoadDeviceRSAKey: id=%ld", (uint32_t)oec_session_id_); + M_TIME( sts = OEMCrypto_LoadDeviceRSAKey( oec_session_id_, @@ -855,6 +714,7 @@ bool CryptoSession::LoadCertificatePrivateKey(std::string& wrapped_key) { metrics_, oemcrypto_load_device_rsa_key_, sts); + if (OEMCrypto_SUCCESS != sts) { LOGE("LoadCertificatePrivateKey: OEMCrypto_LoadDeviceRSAKey error=%d", sts); return false; @@ -1153,6 +1013,7 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) { metrics_, oemcrypto_copy_buffer_, sts, + requested_security_level_, metrics::Pow2Bucket(params.encrypt_length)); if (sts == OEMCrypto_ERROR_BUFFER_TOO_LARGE && @@ -1243,19 +1104,18 @@ bool CryptoSession::UsageInformationSupport(bool* has_support) { } CdmResponseType CryptoSession::UpdateUsageInformation() { - LOGV("CryptoSession::UpdateUsageInformation: id=%ld", (uint32_t)oec_session_id_); + LOGV("UpdateUsageInformation: id=%ld", (uint32_t)oec_session_id_); AutoLock auto_lock(crypto_lock_); if (!initialized_) return UNKNOWN_ERROR; - if (usage_table_header_ != NULL) { - LOGV("UpdateUsageInformation: deprecated for OEMCrypto v13+"); - return NO_ERROR; - } - - OEMCryptoResult status = OEMCrypto_UpdateUsageTable(); - metrics_->oemcrypto_update_usage_table_.Increment(status); + OEMCryptoResult status; + M_TIME( + status = OEMCrypto_UpdateUsageTable(), + metrics_, + oemcrypto_update_usage_table_, + status); if (status != OEMCrypto_SUCCESS) { - LOGE("CryptoSession::UpdateUsageInformation: error=%ld", status); + LOGE("CryptoSession::UsageUsageInformation: error=%ld", status); return UNKNOWN_ERROR; } return NO_ERROR; @@ -1270,9 +1130,15 @@ CdmResponseType CryptoSession::DeactivateUsageInformation( const_cast(provider_session_token.data())); // TODO(fredgc or rfrias): make sure oec_session_id_ is valid. - OEMCryptoResult status = OEMCrypto_DeactivateUsageEntry( - (uint32_t)oec_session_id_, pst, provider_session_token.length()); - metrics_->oemcrypto_deactivate_usage_entry_.Increment(status); + OEMCryptoResult status; + M_TIME( + status = OEMCrypto_DeactivateUsageEntry( + (uint32_t)oec_session_id_, + pst, + provider_session_token.length()), + metrics_, + oemcrypto_deactivate_usage_entry_, + status); switch (status) { case OEMCrypto_SUCCESS: @@ -1302,10 +1168,17 @@ CdmResponseType CryptoSession::GenerateUsageReport( const_cast(provider_session_token.data())); size_t usage_length = 0; - OEMCryptoResult status = OEMCrypto_ReportUsage( - oec_session_id_, pst, provider_session_token.length(), - NULL, &usage_length); - metrics_->oemcrypto_report_usage_.Increment(status); + OEMCryptoResult status; + M_TIME( + status = OEMCrypto_ReportUsage( + oec_session_id_, + pst, + provider_session_token.length(), + NULL, + &usage_length), + metrics_, + oemcrypto_report_usage_, + status); if (OEMCrypto_SUCCESS != status) { if (OEMCrypto_ERROR_SHORT_BUFFER != status) { @@ -1317,13 +1190,16 @@ CdmResponseType CryptoSession::GenerateUsageReport( std::vector buffer(usage_length); - status = OEMCrypto_ReportUsage( + M_TIME( + status = OEMCrypto_ReportUsage( oec_session_id_, pst, provider_session_token.length(), &buffer[0], - &usage_length); - metrics_->oemcrypto_report_usage_.Increment(status); + &usage_length), + metrics_, + oemcrypto_report_usage_, + status); if (OEMCrypto_SUCCESS != status) { LOGE("CryptoSession::GenerateUsageReport: Report Usage error=%ld", status); @@ -1386,31 +1262,40 @@ CdmResponseType CryptoSession::ReleaseUsageInformation( const std::string& message, const std::string& signature, const std::string& provider_session_token) { LOGV("ReleaseUsageInformation: id=%ld", (uint32_t)oec_session_id_); - { - AutoLock auto_lock(crypto_lock_); - if (usage_table_header_ != NULL) { - LOGW("ReleaseUsageInformation: deprecated for OEMCrypto v13+"); - return NO_ERROR; - } + AutoLock auto_lock(crypto_lock_); + const uint8_t* msg = reinterpret_cast(message.data()); + const uint8_t* sig = reinterpret_cast(signature.data()); + const uint8_t* pst = msg + GetOffset(message, provider_session_token); - const uint8_t* msg = reinterpret_cast(message.data()); - const uint8_t* sig = reinterpret_cast(signature.data()); - const uint8_t* pst = msg + GetOffset(message, provider_session_token); + OEMCryptoResult status; + M_TIME( + status = OEMCrypto_DeleteUsageEntry( + oec_session_id_, + pst, + provider_session_token.length(), + msg, + message.length(), + sig, + signature.length()), + metrics_, + oemcrypto_delete_usage_entry_, + status); - OEMCryptoResult status = OEMCrypto_DeleteUsageEntry( - oec_session_id_, pst, provider_session_token.length(), - msg, message.length(), sig, signature.length()); - metrics_->oemcrypto_delete_usage_entry_.Increment(status); - - if (OEMCrypto_SUCCESS != status) { - LOGE("CryptoSession::ReleaseUsageInformation: Report Usage error=%ld", - status); - return UNKNOWN_ERROR; - } + if (OEMCrypto_SUCCESS != status) { + LOGE("CryptoSession::ReleaseUsageInformation: Report Usage error=%ld", + status); + return UNKNOWN_ERROR; + } + M_TIME( + status = OEMCrypto_UpdateUsageTable(), + metrics_, + oemcrypto_update_usage_table_, + status); + if (status != OEMCrypto_SUCCESS) { + LOGW("CryptoSession::ReleaseUsageInformation: update table error=%ld", + status); } - if (usage_support_type_ == kUsageTableSupport) - UpdateUsageInformation(); return NO_ERROR; } @@ -1419,20 +1304,28 @@ CdmResponseType CryptoSession::DeleteUsageInformation( CdmResponseType response = NO_ERROR; LOGV("CryptoSession::DeleteUsageInformation"); OEMCryptoResult status; - { - AutoLock auto_lock(crypto_lock_); - status = OEMCrypto_ForceDeleteUsageEntry( - reinterpret_cast(provider_session_token.c_str()), - provider_session_token.length()); - metrics_->oemcrypto_force_delete_usage_entry_.Increment(status); - if (OEMCrypto_SUCCESS != status) { - LOGE("CryptoSession::DeleteUsageInformation: Delete Usage Table error " - "= %ld", status); - response = UNKNOWN_ERROR; - } + M_TIME( + status = OEMCrypto_ForceDeleteUsageEntry( + reinterpret_cast(provider_session_token.c_str()), + provider_session_token.length()), + metrics_, + oemcrypto_force_delete_usage_entry_, + status); + if (OEMCrypto_SUCCESS != status) { + LOGE("CryptoSession::DeleteUsageInformation: Delete Usage Table error =%ld", + status); + response = UNKNOWN_ERROR; + } + M_TIME( + status = OEMCrypto_UpdateUsageTable(), + metrics_, + oemcrypto_update_usage_table_, + status); + if (status != OEMCrypto_SUCCESS) { + LOGE("CryptoSession::DeleteUsageInformation: update table error=%ld", + status); + response = UNKNOWN_ERROR; } - if (usage_support_type_ == kUsageTableSupport) - UpdateUsageInformation(); return response; } @@ -1440,47 +1333,69 @@ CdmResponseType CryptoSession::DeleteMultipleUsageInformation( const std::vector& provider_session_tokens) { LOGV("CryptoSession::DeleteMultipleUsageInformation"); CdmResponseType response = NO_ERROR; - { - AutoLock auto_lock(crypto_lock_); - for (size_t i=0; i < provider_session_tokens.size(); ++i) { - OEMCryptoResult status = OEMCrypto_ForceDeleteUsageEntry( - reinterpret_cast(provider_session_tokens[i].c_str()), - provider_session_tokens[i].length()); - metrics_->oemcrypto_force_delete_usage_entry_.Increment(status); - if (OEMCrypto_SUCCESS != status) { - LOGW("CryptoSession::DeleteMultipleUsageInformation: " - "Delete Usage Table error =%ld", status); - response = UNKNOWN_ERROR; - } + for (size_t i=0; i < provider_session_tokens.size(); ++i) { + OEMCryptoResult status; + M_TIME( + status = OEMCrypto_ForceDeleteUsageEntry( + reinterpret_cast(provider_session_tokens[i].c_str()), + provider_session_tokens[i].length()), + metrics_, + oemcrypto_force_delete_usage_entry_, + status); + if (OEMCrypto_SUCCESS != status) { + LOGW("CryptoSession::DeleteMultipleUsageInformation: " + "Delete Usage Table error =%ld", status); + response = UNKNOWN_ERROR; } } - if (usage_support_type_ == kUsageTableSupport) - UpdateUsageInformation(); + OEMCryptoResult status; + M_TIME( + status = OEMCrypto_UpdateUsageTable(), + metrics_, + oemcrypto_update_usage_table_, + status); + if (status != OEMCrypto_SUCCESS) { + LOGE("CryptoSession::DeleteMultipleUsageInformation: update table error=%ld", + status); + response = UNKNOWN_ERROR; + } return response; } CdmResponseType CryptoSession::DeleteAllUsageReports() { LOGV("DeleteAllUsageReports"); OEMCryptoResult status; - { - AutoLock auto_lock(crypto_lock_); - status = OEMCrypto_DeleteOldUsageTable(); - metrics_->oemcrypto_delete_usage_table_.Increment(status); - if (OEMCrypto_SUCCESS != status) { - LOGE("CryptoSession::DeleteAllUsageReports: Delete Usage Table error " - "=%ld", status); - } + M_TIME( + status = OEMCrypto_DeleteOldUsageTable(), + metrics_, + oemcrypto_delete_usage_table_, + status); + if (OEMCrypto_SUCCESS != status) { + LOGE("CryptoSession::DeleteAllUsageReports: Delete Usage Table error =%ld", + status); } - if (usage_support_type_ == kUsageTableSupport) - UpdateUsageInformation(); + M_TIME( + status = OEMCrypto_UpdateUsageTable(), + metrics_, + oemcrypto_update_usage_table_, + status); + if (status != OEMCrypto_SUCCESS) { + LOGE("CryptoSession::DeletaAllUsageReports: update table error=%ld", + status); + return UNKNOWN_ERROR; + } return NO_ERROR; } bool CryptoSession::IsAntiRollbackHwPresent() { - bool is_present = - OEMCrypto_IsAntiRollbackHwPresent(requested_security_level_); - metrics_->oemcrypto_is_anti_rollback_hw_present_.Record(is_present); + bool is_present; + M_TIME( + is_present = OEMCrypto_IsAntiRollbackHwPresent(requested_security_level_), + metrics_, + oemcrypto_is_anti_rollback_hw_present_, + is_present, + requested_security_level_); return is_present; } @@ -1493,8 +1408,14 @@ bool CryptoSession::GenerateNonce(uint32_t* nonce) { LOGV("CryptoSession::GenerateNonce: Lock"); AutoLock auto_lock(crypto_lock_); - OEMCryptoResult result = OEMCrypto_GenerateNonce(oec_session_id_, nonce); - metrics_->oemcrypto_generate_nonce_.Increment(result); + OEMCryptoResult result; + M_TIME( + result = OEMCrypto_GenerateNonce( + oec_session_id_, + nonce), + metrics_, + oemcrypto_generate_nonce_, + result); return OEMCrypto_SUCCESS == result; } @@ -1663,7 +1584,7 @@ bool CryptoSession::RewrapDeviceRSAKey30(const std::string& message, wrapped_private_key->resize(wrapped_private_key_length); if (OEMCrypto_SUCCESS != status) { - LOGE("OEMCrypto_RewrapDeviceRSAKey30 fails with %d", status); + LOGE("OEMCrypto_RewrapDeviceRSAKey fails with %d", status); return false; } return true; @@ -1677,17 +1598,20 @@ bool CryptoSession::GetHdcpCapabilities(HdcpCapability* current, LOGE("CryptoSession::GetHdcpCapabilities: |current|, |max| cannot be NULL"); return false; } - OEMCryptoResult status = OEMCrypto_GetHDCPCapability( - requested_security_level_, current, max); - + OEMCryptoResult status; + M_TIME( + status = OEMCrypto_GetHDCPCapability( + requested_security_level_, + current, + max), + metrics_, + oemcrypto_get_hdcp_capability_, + status, + requested_security_level_); if (OEMCrypto_SUCCESS != status) { - metrics_->oemcrypto_current_hdcp_capability_.SetError(status); - metrics_->oemcrypto_max_hdcp_capability_.SetError(status); LOGW("OEMCrypto_GetHDCPCapability fails with %d", status); return false; } - metrics_->oemcrypto_current_hdcp_capability_.Record(*current); - metrics_->oemcrypto_max_hdcp_capability_.Record(*max); return true; } @@ -1714,8 +1638,15 @@ bool CryptoSession::GetRandom(size_t data_length, uint8_t* random_data) { LOGE("CryptoSession::GetRandom: random data destination not provided"); return false; } - OEMCryptoResult sts = OEMCrypto_GetRandom(random_data, data_length); - metrics_->oemcrypto_get_random_.Increment(sts); + OEMCryptoResult sts; + M_TIME( + sts = OEMCrypto_GetRandom( + random_data, + data_length), + metrics_, + oemcrypto_get_random_, + sts, + metrics::Pow2Bucket(data_length)); if (sts != OEMCrypto_SUCCESS) { LOGE("OEMCrypto_GetRandom fails with %d", sts); @@ -1734,16 +1665,19 @@ bool CryptoSession::GetNumberOfOpenSessions(size_t* count) { } size_t sessions_count; - OEMCryptoResult status = OEMCrypto_GetNumberOfOpenSessions( - requested_security_level_, &sessions_count); - + OEMCryptoResult status; + M_TIME( + status = OEMCrypto_GetNumberOfOpenSessions( + requested_security_level_, + &sessions_count), + metrics_, + oemcrypto_get_number_of_open_sessions_, + status, + requested_security_level_); if (OEMCrypto_SUCCESS != status) { LOGW("OEMCrypto_GetNumberOfOpenSessions fails with %d", status); - metrics_->oemcrypto_number_of_open_sessions_.SetError(status); return false; } - - metrics_->oemcrypto_number_of_open_sessions_.Record(sessions_count); *count = sessions_count; return true; } @@ -1757,15 +1691,20 @@ bool CryptoSession::GetMaxNumberOfSessions(size_t* max) { } size_t max_sessions; - OEMCryptoResult status = OEMCrypto_GetMaxNumberOfSessions( - requested_security_level_, &max_sessions); + OEMCryptoResult status; + M_TIME( + status = OEMCrypto_GetMaxNumberOfSessions( + requested_security_level_, + &max_sessions), + metrics_, + oemcrypto_get_max_number_of_sessions_, + status, + requested_security_level_); + if (OEMCrypto_SUCCESS != status) { LOGW("OEMCrypto_GetMaxNumberOfSessions fails with %d", status); - metrics_->oemcrypto_max_number_of_sessions_.SetError(status); return false; } - - metrics_->oemcrypto_max_number_of_sessions_.Record(max_sessions); *max = max_sessions; return true; } @@ -1779,15 +1718,11 @@ bool CryptoSession::GetSrmVersion(uint16_t* srm_version) { } OEMCryptoResult status = OEMCrypto_GetCurrentSRMVersion(srm_version); - switch (status) { - case OEMCrypto_SUCCESS: - return true; - case OEMCrypto_ERROR_NOT_IMPLEMENTED: - return false; - default: - LOGW("OEMCrypto_GetCurrentSRMVersion fails with %d", status); - return false; + if (OEMCrypto_SUCCESS != status) { + LOGW("OEMCrypto_GetCurrentSRMVersion fails with %d", status); + return false; } + return true; } bool CryptoSession::IsSrmUpdateSupported() { @@ -2025,7 +1960,7 @@ CdmResponseType CryptoSession::GetUsageSupportType( return INVALID_PARAMETERS_ENG_23; } - if (is_usage_support_type_valid_) { + if (usage_support_type_ != kUnknownUsageSupport) { *usage_support_type = usage_support_type_; return NO_ERROR; } @@ -2038,7 +1973,6 @@ CdmResponseType CryptoSession::GetUsageSupportType( if (!has_support) { *usage_support_type = usage_support_type_ = kNonSecureUsageSupport; - is_usage_support_type_valid_ = true; return NO_ERROR; } @@ -2051,7 +1985,6 @@ CdmResponseType CryptoSession::GetUsageSupportType( *usage_support_type = usage_support_type_ = (api_version >= kOemCryptoApiVersionSupportsBigUsageTables) ? kUsageEntrySupport : kUsageTableSupport; - is_usage_support_type_valid_ = true; return NO_ERROR; } @@ -2082,7 +2015,7 @@ CdmResponseType CryptoSession::CreateUsageTableHeader( } if (result != OEMCrypto_SUCCESS) { - LOGE("CreateUsageTableHeader: usage table header creation failed: %d", + LOGE("CreateUsageTableHeader; usage table header creation failed: %d", result); return CREATE_USAGE_TABLE_ERROR; } @@ -2275,55 +2208,6 @@ CdmResponseType CryptoSession::MoveUsageEntry(uint32_t new_entry_number) { return NO_ERROR; } -bool CryptoSession::CreateOldUsageEntry( - uint64_t time_since_license_received, - uint64_t time_since_first_decrypt, - uint64_t time_since_last_decrypt, - UsageDurationStatus usage_duration_status, - const std::string& server_mac_key, - const std::string& client_mac_key, - const std::string& provider_session_token) { - LOGV("CreateOldUsageEntry: Lock"); - AutoLock auto_lock(crypto_lock_); - - if (server_mac_key.size() < MAC_KEY_SIZE || - client_mac_key.size() < MAC_KEY_SIZE) { - LOGE("CreateOldUsageEntry: Invalid mac key size: server mac key size %d, " - "client mac key size: %d", server_mac_key.size(), - client_mac_key.size()); - return false; - } - - OEMCrypto_Usage_Entry_Status status; - switch (usage_duration_status) { - case kUsageDurationsInvalid: status = kUnused; break; - case kUsageDurationPlaybackNotBegun: status = kInactiveUnused; break; - case kUsageDurationsValid: status = kActive; break; - default: - LOGE("CreateOldUsageEntry: Unrecognized usage entry status: %d", status); - status = kUnused; - return false; - } - - OEMCryptoResult result = - OEMCrypto_CreateOldUsageEntry( - requested_security_level_, time_since_license_received, - time_since_first_decrypt, time_since_last_decrypt, status, - reinterpret_cast( - const_cast(server_mac_key.data())), - reinterpret_cast( - const_cast(client_mac_key.data())), - reinterpret_cast(provider_session_token.data()), - provider_session_token.size()); - - if (result != OEMCrypto_SUCCESS) { - LOGE("CreateOldUsageEntry: OEMCrypto_CreateOldUsageEntry error: %d", - result); - return false; - } - return true; -} - CdmResponseType CryptoSession::CopyOldUsageEntry( const std::string& provider_session_token) { LOGV("CopyOldUsageEntry: id=%ld", (uint32_t)oec_session_id_); @@ -2421,6 +2305,7 @@ OEMCryptoResult CryptoSession::CopyBufferInChunks( metrics_, oemcrypto_copy_buffer_, sts, + requested_security_level_, metrics::Pow2Bucket(chunk_size)); if (sts != OEMCrypto_SUCCESS) { diff --git a/libwvdrmengine/cdm/core/src/device_files.cpp b/libwvdrmengine/cdm/core/src/device_files.cpp index 589f8db3..119faee6 100644 --- a/libwvdrmengine/cdm/core/src/device_files.cpp +++ b/libwvdrmengine/cdm/core/src/device_files.cpp @@ -40,8 +40,6 @@ using video_widevine_client::sdk:: UsageTableInfo_UsageEntryInfo_UsageEntryStorage_LICENSE; using video_widevine_client::sdk:: UsageTableInfo_UsageEntryInfo_UsageEntryStorage_USAGE_INFO; -using video_widevine_client::sdk:: - UsageTableInfo_UsageEntryInfo_UsageEntryStorage_UNKNOWN; namespace { @@ -51,7 +49,7 @@ const char kUsageInfoFileNamePrefix[] = "usage"; const char kUsageInfoFileNameExt[] = ".bin"; const char kLicenseFileNameExt[] = ".lic"; const char kEmptyFileName[] = ""; -const char kUsageTableFileName[] = "usgtable.bin"; +const char kUsageTableFileName[] = "usagetable.bin"; const char kWildcard[] = "*"; bool Hash(const std::string& data, std::string* hash) { @@ -146,7 +144,6 @@ bool DeviceFiles::RetrieveCertificate(std::string* certificate, } DeviceCertificate device_certificate = file.device_certificate(); - *certificate = device_certificate.certificate(); *wrapped_private_key = device_certificate.wrapped_private_key(); return true; @@ -179,8 +176,7 @@ bool DeviceFiles::StoreLicense( const std::string& release_server_url, int64_t playback_start_time, int64_t last_playback_time, int64_t grace_period_end_time, const CdmAppParameterMap& app_parameters, - const CdmUsageEntry& usage_entry, - const uint32_t usage_entry_number) { + const CdmUsageEntry& usage_entry) { if (!initialized_) { LOGW("DeviceFiles::StoreLicense: not initialized"); return false; @@ -222,7 +218,6 @@ bool DeviceFiles::StoreLicense( app_params->set_value(iter->second); } license->set_usage_entry(usage_entry); - license->set_usage_entry_number(usage_entry_number); std::string serialized_file; file.SerializeToString(&serialized_file); @@ -237,8 +232,7 @@ bool DeviceFiles::RetrieveLicense( CdmKeyMessage* license_renewal_request, CdmKeyResponse* license_renewal, std::string* release_server_url, int64_t* playback_start_time, int64_t* last_playback_time, int64_t* grace_period_end_time, - CdmAppParameterMap* app_parameters, CdmUsageEntry* usage_entry, - uint32_t* usage_entry_number) { + CdmAppParameterMap* app_parameters, CdmUsageEntry* usage_entry) { if (!initialized_) { LOGW("DeviceFiles::RetrieveLicense: not initialized"); return false; @@ -293,7 +287,6 @@ bool DeviceFiles::RetrieveLicense( license.app_parameters(i).value(); } *usage_entry = license.usage_entry(); - *usage_entry_number = license.usage_entry_number(); return true; } @@ -354,7 +347,6 @@ bool DeviceFiles::DeleteAllFiles() { // We pass an empty string to RemoveFile to delete the device files base // directory itself. - // TODO[gmorgan]: verify RemoveFile("") should remove all files. return RemoveFile(kEmptyFileName); } @@ -388,21 +380,21 @@ bool DeviceFiles::UnreserveLicenseId(const std::string& key_set_id) { bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token, const CdmKeyMessage& key_request, const CdmKeyResponse& key_response, - const std::string& usage_info_file_name, + const std::string& app_id, const std::string& key_set_id, - const std::string& usage_entry, - uint32_t usage_entry_number) { + const CdmUsageEntry& usage_entry) { if (!initialized_) { LOGW("DeviceFiles::StoreUsageInfo: not initialized"); return false; } video_widevine_client::sdk::File file; - if (!FileExists(usage_info_file_name)) { + std::string file_name = GetUsageInfoFileName(app_id); + if (!FileExists(file_name)) { file.set_type(video_widevine_client::sdk::File::USAGE_INFO); file.set_version(video_widevine_client::sdk::File::VERSION_1); } else { - if (!RetrieveHashedFile(usage_info_file_name, &file)) { + if (!RetrieveHashedFile(file_name, &file)) { LOGW("DeviceFiles::StoreUsageInfo: Unable to parse file"); return false; } @@ -417,21 +409,92 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token, provider_session->set_license(key_response.data(), key_response.size()); provider_session->set_key_set_id(key_set_id.data(), key_set_id.size()); provider_session->set_usage_entry(usage_entry); - provider_session->set_usage_entry_number(usage_entry_number); std::string serialized_file; file.SerializeToString(&serialized_file); - return StoreFileWithHash(usage_info_file_name, serialized_file); + return StoreFileWithHash(file_name, serialized_file); } -bool DeviceFiles::DeleteUsageInfo(const std::string& usage_info_file_name, +bool DeviceFiles::ListUsageRecords(const std::string& app_id, + std::vector* ksids) { + if (!initialized_) { + LOGW("DeviceFiles::ListUsageRecords: not initialized"); + return false; + } + + if (ksids == NULL) { + LOGW("DeviceFiles::ListUsageRecords: return parameter not provided"); + return false; + } + + // Empty or non-existent file == no usage records. + std::string file_name = GetUsageInfoFileName(app_id); + if (!FileExists(file_name) || GetFileSize(file_name) == 0) { + ksids->clear(); + return true; + } + + video_widevine_client::sdk::File file; + if (!RetrieveHashedFile(file_name, &file)) { + LOGW("DeviceFiles::ListUsageRecords: Unable to parse file"); + return false; + } + + ksids->clear(); + + size_t num_records = file.usage_info().sessions_size(); + for (size_t i = 0; i < num_records; ++i) { + if (!file.usage_info().sessions(i).key_set_id().empty()) { + ksids->push_back(file.usage_info().sessions(i).key_set_id()); + } + } + return true; +} + +bool DeviceFiles::GetProviderSessionToken(const std::string& app_id, + const std::string& key_set_id, + std::string* provider_session_token) { + if (!initialized_) { + LOGW("DeviceFiles::GetProviderSessionToken: not initialized"); + return false; + } + + if (provider_session_token == NULL) { + LOGW("DeviceFiles::GetProviderSessionToken: NULL return argument pointer"); + return false; + } + + std::string file_name = GetUsageInfoFileName(app_id); + if (!FileExists(file_name) || GetFileSize(file_name) == 0) { + LOGW("DeviceFiles::GetProviderSessionToken: empty file"); + return false; + } + + video_widevine_client::sdk::File file; + if (!RetrieveHashedFile(file_name, &file)) { + LOGW("DeviceFiles::GetProviderSessionToken: unable to parse file"); + return false; + } + + size_t num_records = file.usage_info().sessions_size(); + for (size_t i = 0; i < num_records; ++i) { + if (file.usage_info().sessions(i).key_set_id() == key_set_id) { + *provider_session_token = file.usage_info().sessions(i).token(); + return true; + } + } + return false; +} + +bool DeviceFiles::DeleteUsageInfo(const std::string& app_id, const std::string& provider_session_token) { if (!initialized_) { LOGW("DeviceFiles::DeleteUsageInfo: not initialized"); return false; } video_widevine_client::sdk::File file; - if (!RetrieveHashedFile(usage_info_file_name, &file)) return false; + std::string file_name = GetUsageInfoFileName(app_id); + if (!RetrieveHashedFile(file_name, &file)) return false; UsageInfo* usage_info = file.mutable_usage_info(); int index = 0; @@ -460,11 +523,11 @@ bool DeviceFiles::DeleteUsageInfo(const std::string& usage_info_file_name, std::string serialized_file; file.SerializeToString(&serialized_file); - return StoreFileWithHash(usage_info_file_name, serialized_file); + return StoreFileWithHash(file_name, serialized_file); } bool DeviceFiles::DeleteAllUsageInfoForApp( - const std::string& usage_info_file_name, + const std::string& app_id, std::vector* provider_session_tokens) { if (!initialized_) { LOGW("DeviceFiles::DeleteAllUsageInfoForApp: not initialized"); @@ -476,21 +539,22 @@ bool DeviceFiles::DeleteAllUsageInfoForApp( } provider_session_tokens->clear(); - if (!FileExists(usage_info_file_name)) return true; + std::string file_name = GetUsageInfoFileName(app_id); + if (!FileExists(file_name)) return true; video_widevine_client::sdk::File file; - if (RetrieveHashedFile(usage_info_file_name, &file)) { + if (RetrieveHashedFile(file_name, &file)) { for (int i = 0; i < file.usage_info().sessions_size(); ++i) { provider_session_tokens->push_back(file.usage_info().sessions(i).token()); } } else { LOGW("DeviceFiles::DeleteAllUsageInfoForApp: Unable to retrieve file"); } - return RemoveFile(usage_info_file_name); + return RemoveFile(file_name); } bool DeviceFiles::RetrieveUsageInfo( - const std::string& usage_info_file_name, + const std::string& app_id, std::vector >* usage_info) { if (!initialized_) { LOGW("DeviceFiles::RetrieveUsageInfo: not initialized"); @@ -504,14 +568,14 @@ bool DeviceFiles::RetrieveUsageInfo( return false; } - if (!FileExists(usage_info_file_name) || - GetFileSize(usage_info_file_name) == 0) { + std::string file_name = GetUsageInfoFileName(app_id); + if (!FileExists(file_name) || GetFileSize(file_name) == 0) { usage_info->resize(0); return true; } video_widevine_client::sdk::File file; - if (!RetrieveHashedFile(usage_info_file_name, &file)) { + if (!RetrieveHashedFile(file_name, &file)) { LOGW("DeviceFiles::RetrieveUsageInfo: Unable to parse file"); return false; } @@ -526,19 +590,19 @@ bool DeviceFiles::RetrieveUsageInfo( return true; } -bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, +bool DeviceFiles::RetrieveUsageInfo(const std::string& app_id, const std::string& provider_session_token, CdmKeyMessage* license_request, CdmKeyResponse* license_response, - std::string* usage_entry, - uint32_t* usage_entry_number) { + CdmUsageEntry* usage_entry) { if (!initialized_) { LOGW("DeviceFiles::RetrieveUsageInfo: not initialized"); return false; } + std::string file_name = GetUsageInfoFileName(app_id); video_widevine_client::sdk::File file; - if (!RetrieveHashedFile(usage_info_file_name, &file)) { + if (!RetrieveHashedFile(file_name, &file)) { return false; } @@ -548,8 +612,6 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, *license_request = file.usage_info().sessions(index).license_request(); *license_response = file.usage_info().sessions(index).license(); *usage_entry = file.usage_info().sessions(index).usage_entry(); - *usage_entry_number = - file.usage_info().sessions(index).usage_entry_number(); return true; } } @@ -558,32 +620,28 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, } bool DeviceFiles::RetrieveUsageInfoByKeySetId( - const std::string& usage_info_file_name, + const std::string& app_id, const std::string& key_set_id, - std::string* provider_session_token, CdmKeyMessage* license_request, CdmKeyResponse* license_response, - std::string* usage_entry, - uint32_t* usage_entry_number) { + CdmUsageEntry* usage_entry) { if (!initialized_) { LOGW("DeviceFiles::RetrieveUsageInfoByKeySetId: not initialized"); return false; } + std::string file_name = GetUsageInfoFileName(app_id); video_widevine_client::sdk::File file; - if (!RetrieveHashedFile(usage_info_file_name, &file)) { + if (!RetrieveHashedFile(file_name, &file)) { return false; } int index = 0; for (; index < file.usage_info().sessions_size(); ++index) { if (file.usage_info().sessions(index).key_set_id() == key_set_id) { - *provider_session_token = file.usage_info().sessions(index).token(); *license_request = file.usage_info().sessions(index).license_request(); *license_response = file.usage_info().sessions(index).license(); *usage_entry = file.usage_info().sessions(index).usage_entry(); - *usage_entry_number = - file.usage_info().sessions(index).usage_entry_number(); return true; } } @@ -591,190 +649,6 @@ bool DeviceFiles::RetrieveUsageInfoByKeySetId( return false; } -bool DeviceFiles::StoreUsageInfo(const std::string& usage_info_file_name, - const std::vector& usage_data) { - if (!initialized_) { - LOGW("DeviceFiles::StoreUsageInfo: not initialized"); - return false; - } - - video_widevine_client::sdk::File file; - file.set_type(video_widevine_client::sdk::File::USAGE_INFO); - file.set_version(video_widevine_client::sdk::File::VERSION_1); - - UsageInfo* usage_info = file.mutable_usage_info(); - for (size_t i = 0; i < usage_data.size(); ++i) { - UsageInfo_ProviderSession* provider_session = usage_info->add_sessions(); - - provider_session->set_token(usage_data[i].provider_session_token.data(), - usage_data[i].provider_session_token.size()); - provider_session->set_license_request(usage_data[i].license_request.data(), - usage_data[i].license_request.size()); - provider_session->set_license(usage_data[i].license.data(), - usage_data[i].license.size()); - provider_session->set_key_set_id(usage_data[i].key_set_id.data(), - usage_data[i].key_set_id.size()); - provider_session->set_usage_entry(usage_data[i].usage_entry); - provider_session->set_usage_entry_number(usage_data[i].usage_entry_number); - } - - std::string serialized_file; - file.SerializeToString(&serialized_file); - return StoreFileWithHash(usage_info_file_name, serialized_file); -} - -bool DeviceFiles::UpdateUsageInfo(const std::string& usage_info_file_name, - const std::string& provider_session_token, - const CdmUsageData& usage_data) { - if (!initialized_) { - LOGW("DeviceFiles::UpdateUsageInfo: not initialized"); - return false; - } - - video_widevine_client::sdk::File file; - if (!FileExists(usage_info_file_name)) { - LOGW("DeviceFiles::UpdateUsageInfo: Usage file does not exist"); - return false; - } - - - if (!RetrieveHashedFile(usage_info_file_name, &file)) { - LOGW("DeviceFiles::UpdateUsageInfo: Unable to parse file"); - return false; - } - - int index = 0; - for (; index < file.usage_info().sessions_size(); ++index) { - if (file.usage_info().sessions(index).token() == provider_session_token) { - UsageInfo* usage_info = file.mutable_usage_info(); - UsageInfo_ProviderSession* provider_session = - usage_info->mutable_sessions(index); - provider_session->set_license_request(usage_data.license_request); - provider_session->set_license(usage_data.license); - provider_session->set_key_set_id(usage_data.key_set_id); - provider_session->set_usage_entry(usage_data.usage_entry); - provider_session->set_usage_entry_number(usage_data.usage_entry_number); - - std::string serialized_file; - file.SerializeToString(&serialized_file); - return StoreFileWithHash(usage_info_file_name, serialized_file); - } - } - - return false; -} - -bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, - std::vector* usage_data) { - if (!initialized_) { - LOGW("DeviceFiles::RetrieveUsageInfo: not initialized"); - return false; - } - - if (usage_data == NULL) { - LOGW("DeviceFiles::RetrieveUsageInfo: usage_data not provided"); - return false; - } - - if (!FileExists(usage_info_file_name) || - GetFileSize(usage_info_file_name) == 0) { - usage_data->resize(0); - return true; - } - - video_widevine_client::sdk::File file; - if (!RetrieveHashedFile(usage_info_file_name, &file)) { - return false; - } - - usage_data->resize(file.usage_info().sessions_size()); - for (int i = 0; i < file.usage_info().sessions_size(); ++i) { - (*usage_data)[i].provider_session_token = - file.usage_info().sessions(i).token(); - (*usage_data)[i].license_request = - file.usage_info().sessions(i).license_request(); - (*usage_data)[i].license = file.usage_info().sessions(i).license(); - (*usage_data)[i].key_set_id = file.usage_info().sessions(i).key_set_id(); - (*usage_data)[i].usage_entry = file.usage_info().sessions(i).usage_entry(); - (*usage_data)[i].usage_entry_number = - file.usage_info().sessions(i).usage_entry_number(); - } - - return true; -} - -bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, - const std::string& provider_session_token, - CdmUsageData* usage_data) { - if (!initialized_) { - LOGW("DeviceFiles::RetrieveUsageInfo: not initialized"); - return false; - } - - if (usage_data == NULL) { - LOGW("DeviceFiles::RetrieveUsageInfo: usage_data not provided"); - return false; - } - - video_widevine_client::sdk::File file; - if (!RetrieveHashedFile(usage_info_file_name, &file)) { - return false; - } - - int index = 0; - for (; index < file.usage_info().sessions_size(); ++index) { - if (file.usage_info().sessions(index).token() == provider_session_token) { - usage_data->provider_session_token = - file.usage_info().sessions(index).token(); - usage_data->license_request = - file.usage_info().sessions(index).license_request(); - usage_data->license = file.usage_info().sessions(index).license(); - usage_data->key_set_id = file.usage_info().sessions(index).key_set_id(); - usage_data->usage_entry = file.usage_info().sessions(index).usage_entry(); - usage_data->usage_entry_number = - file.usage_info().sessions(index).usage_entry_number(); - return true; - } - } - - return false; -} - -bool DeviceFiles::ListUsageInfoFiles( - std::vector* usage_info_file_names) { - if (!initialized_) { - LOGW("DeviceFiles::ListUsageInfoFiles: not initialized"); - return false; - } - - if (usage_info_file_names == NULL) { - LOGW("DeviceFiles::ListUsageInfoFiles: usage_info_file_names not provided"); - return false; - } - - // Get list of filenames - std::vector filenames; - if (!ListFiles(&filenames)) { - return false; - } - - // Scan list of all filenames and return only usage info filenames - usage_info_file_names->clear(); - for (size_t i = 0; i < filenames.size(); i++) { - std::string* name = &filenames[i]; - std::size_t pos_prefix = name->find(kUsageInfoFileNamePrefix); - std::size_t pos_suffix = name->find(kUsageInfoFileNameExt); - if (pos_prefix == std::string::npos || - pos_suffix == std::string::npos) { - // Skip this file - extension does not match - continue; - } - - usage_info_file_names->push_back(*name); - } - return true; -} - bool DeviceFiles::StoreHlsAttributes( const std::string& key_set_id, const CdmHlsMethod method, const std::vector& media_segment_iv) { @@ -874,7 +748,7 @@ bool DeviceFiles::DeleteHlsAttributes(const std::string& key_set_id) { bool DeviceFiles::StoreUsageTableInfo( const CdmUsageTableHeader& usage_table_header, - const std::vector& usage_entry_info) { + const std::vector& usage_entry_info) { if (!initialized_) { LOGW("DeviceFiles::StoreUsageTableHeader: not initialized"); return false; @@ -891,23 +765,23 @@ bool DeviceFiles::StoreUsageTableInfo( for (size_t i = 0; i < usage_entry_info.size(); ++i) { UsageTableInfo_UsageEntryInfo* info = usage_table_info->add_usage_entry_info(); - info->set_key_set_id(usage_entry_info[i].key_set_id); switch (usage_entry_info[i].storage_type) { case kStorageLicense: info->set_storage( UsageTableInfo_UsageEntryInfo_UsageEntryStorage_LICENSE); + info->set_key_set_id(usage_entry_info[i].key_set_id); break; case kStorageUsageInfo: info->set_storage( UsageTableInfo_UsageEntryInfo_UsageEntryStorage_USAGE_INFO); - info->set_usage_info_file_name( - usage_entry_info[i].usage_info_file_name); + info->set_provider_session_token( + usage_entry_info[i].provider_session_token); + info->set_app_id(usage_entry_info[i].app_id); break; - case kStorageUnknown: default: - info->set_storage( - UsageTableInfo_UsageEntryInfo_UsageEntryStorage_UNKNOWN); - break; + LOGW("DeviceFiles::StoreUsageTableHeader: unknown storage type: %d", + usage_entry_info[i].storage_type); + return false; } } @@ -919,7 +793,7 @@ bool DeviceFiles::StoreUsageTableInfo( bool DeviceFiles::RetrieveUsageTableInfo( CdmUsageTableHeader* usage_table_header, - std::vector* usage_entry_info) { + std::vector* usage_entry_info) { if (!initialized_) { LOGW("DeviceFiles::RetrieveUsageTableInfo: not initialized"); return false; @@ -963,20 +837,21 @@ bool DeviceFiles::RetrieveUsageTableInfo( for (int i = 0; i < usage_table_info.usage_entry_info_size(); ++i) { const UsageTableInfo_UsageEntryInfo& info = usage_table_info.usage_entry_info(i); - (*usage_entry_info)[i].key_set_id = info.key_set_id(); switch (info.storage()) { case UsageTableInfo_UsageEntryInfo_UsageEntryStorage_LICENSE: (*usage_entry_info)[i].storage_type = kStorageLicense; + (*usage_entry_info)[i].key_set_id = info.key_set_id(); break; case UsageTableInfo_UsageEntryInfo_UsageEntryStorage_USAGE_INFO: (*usage_entry_info)[i].storage_type = kStorageUsageInfo; - (*usage_entry_info)[i].usage_info_file_name = - info.usage_info_file_name(); + (*usage_entry_info)[i].provider_session_token = + info.provider_session_token(); + (*usage_entry_info)[i].app_id = info.app_id(); break; - case UsageTableInfo_UsageEntryInfo_UsageEntryStorage_UNKNOWN: default: - (*usage_entry_info)[i].storage_type = kStorageUnknown; - break; + LOGW("DeviceFiles::RetrieveUsageTableInfo: Unknown storage type: %d", + info.storage()); + return false; } } diff --git a/libwvdrmengine/cdm/core/src/device_files.proto b/libwvdrmengine/cdm/core/src/device_files.proto index 02b86bdf..1bfb21ce 100644 --- a/libwvdrmengine/cdm/core/src/device_files.proto +++ b/libwvdrmengine/cdm/core/src/device_files.proto @@ -44,7 +44,6 @@ message License { // ignored if there is no grace period. optional int64 grace_period_end_time = 11 [default = 0]; optional bytes usage_entry = 12; - optional int64 usage_entry_number = 13; } message UsageInfo { @@ -54,7 +53,6 @@ message UsageInfo { optional bytes license = 3; optional bytes key_set_id = 4; optional bytes usage_entry = 5; - optional int64 usage_entry_number = 6; } repeated ProviderSession sessions = 1; @@ -74,12 +72,12 @@ message UsageTableInfo { enum UsageEntryStorage { LICENSE = 1; USAGE_INFO = 2; - UNKNOWN = 3; } optional UsageEntryStorage storage = 1; - optional bytes key_set_id = 2; - optional bytes usage_info_file_name = 3; // hash of the app_id + optional bytes key_set_id = 2; // used if storage is LICENSE + optional bytes provider_session_token = 3; // used if storage is USAGE_INFO + optional bytes app_id = 4; // used if storage is USAGE_INFO } optional bytes usage_table_header = 1; diff --git a/libwvdrmengine/cdm/core/src/license.cpp b/libwvdrmengine/cdm/core/src/license.cpp index 771f97ef..07664681 100644 --- a/libwvdrmengine/cdm/core/src/license.cpp +++ b/libwvdrmengine/cdm/core/src/license.cpp @@ -7,7 +7,6 @@ #include #include "clock.h" -#include "cdm_session.h" #include "crypto_key.h" #include "crypto_session.h" #include "device_files.h" @@ -284,8 +283,7 @@ CdmResponseType CdmLicense::PrepareKeyRequest( CdmResponseType CdmLicense::PrepareKeyUpdateRequest( bool is_renewal, const CdmAppParameterMap& app_parameters, - CdmSession* cdm_session, CdmKeyMessage* signed_request, - std::string* server_url) { + CdmKeyMessage* signed_request, std::string* server_url) { if (!initialized_) { LOGE("CdmLicense::PrepareKeyUpdateRequest: not initialized"); return LICENSE_PARSER_NOT_INITIALIZED_1; @@ -343,13 +341,6 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest( if (NO_ERROR != status) return status; } - // TODO(rfrias): Refactor to avoid needing to call CdmSession - if (cdm_session && - cdm_session->get_usage_support_type() == kUsageEntrySupport) { - CdmResponseType status = cdm_session->UpdateUsageEntryInformation(); - if (NO_ERROR != status) return status; - } - std::string usage_report; CdmResponseType status = crypto_session_->GenerateUsageReport( provider_session_token_, &usage_report, &usage_duration_status, @@ -624,8 +615,7 @@ bool CdmLicense::RestoreOfflineLicense( const CdmKeyMessage& license_request, const CdmKeyResponse& license_response, const CdmKeyResponse& license_renewal_response, int64_t playback_start_time, - int64_t last_playback_time, int64_t grace_period_end_time, - CdmSession* cdm_session) { + int64_t last_playback_time, int64_t grace_period_end_time) { if (license_request.empty() || license_response.empty()) { LOGE( "CdmLicense::RestoreOfflineLicense: key_request or response empty: " @@ -667,16 +657,9 @@ bool CdmLicense::RestoreOfflineLicense( } if (!provider_session_token_.empty()) { - if (cdm_session && - cdm_session->get_usage_support_type() == kUsageEntrySupport) { - CdmResponseType status = cdm_session->UpdateUsageEntryInformation(); - if (NO_ERROR != status) return false; - } - std::string usage_report; CryptoSession::UsageDurationStatus usage_duration_status = CryptoSession::kUsageDurationsInvalid; - int64_t seconds_since_started, seconds_since_last_played; sts = crypto_session_->GenerateUsageReport( provider_session_token_, &usage_report, &usage_duration_status, @@ -805,43 +788,6 @@ bool CdmLicense::IsKeyLoaded(const KeyId& key_id) { return loaded_keys_.find(key_id) != loaded_keys_.end(); } -bool CdmLicense::ExtractProviderSessionToken( - const CdmKeyResponse& license_response, - std::string* provider_session_token) { - if (license_response.empty()) { - LOGW("CdmLicense::ExtractProviderSessionToken: empty license response"); - return false; - } - - SignedMessage signed_response; - if (!signed_response.ParseFromString(license_response)) { - LOGW( - "CdmLicense::ExtractProviderSessionToken: unable to parse signed " - "license response"); - return false; - } - - if (signed_response.type() != SignedMessage::LICENSE) { - LOGW("CdmLicense::ExtractProviderSessionToken: unrecognized signed message " - "type: %d", signed_response.type()); - return false; - } - - License license; - if (!license.ParseFromString(signed_response.msg())) { - LOGE("CdmLicense::ExtractProviderSessionToken: unable to parse license " - "response"); - return false; - } - - if (license.id().has_provider_session_token()) { - *provider_session_token = license.id().provider_session_token(); - return true; - } - - return false; -} - CdmResponseType CdmLicense::HandleKeyErrorResponse( const SignedMessage& signed_message) { LicenseError license_error; diff --git a/libwvdrmengine/cdm/core/src/license_key_status.cpp b/libwvdrmengine/cdm/core/src/license_key_status.cpp index 6ee38d11..940fa0a8 100644 --- a/libwvdrmengine/cdm/core/src/license_key_status.cpp +++ b/libwvdrmengine/cdm/core/src/license_key_status.cpp @@ -5,6 +5,7 @@ #include #include "log.h" +#include "wv_cdm_constants.h" namespace { // License protocol aliases @@ -86,17 +87,14 @@ bool LicenseKeys::GetAllowedUsage(const KeyId& key_id, } } -bool LicenseKeys::ApplyStatusChange( - const CdmKeyStatus* new_status, const uint32_t* new_resolution, - const CryptoSession::HdcpCapability* new_hdcp_level, - bool* new_usable_keys) { +bool LicenseKeys::ApplyStatusChange(CdmKeyStatus new_status, + bool* new_usable_keys) { bool keys_changed = false; bool newly_usable = false; *new_usable_keys = false; for (LicenseKeyStatusIterator it = keys_.begin(); it != keys_.end(); ++it) { bool usable; - if (it->second->ApplyStatusChange(new_status, new_resolution, - new_hdcp_level, &usable)) { + if (it->second->ApplyStatusChange(new_status, &usable)) { newly_usable |= usable; keys_changed = true; } @@ -125,6 +123,13 @@ bool LicenseKeys::MeetsConstraints(const KeyId& key_id) { } } +void LicenseKeys::ApplyConstraints( + uint32_t new_resolution, CryptoSession::HdcpCapability new_hdcp_level) { + for (LicenseKeyStatusIterator i = keys_.begin(); i != keys_.end(); ++i) { + i->second->ApplyConstraints(new_resolution, new_hdcp_level); + } +} + void LicenseKeys::SetFromLicense( const video_widevine::License& license) { this->Clear(); @@ -141,9 +146,6 @@ void LicenseKeys::SetFromLicense( LicenseKeyStatus::LicenseKeyStatus(const KeyContainer& key) : is_content_key_(false), key_status_(kKeyStatusInternalError), - resolution_(kNoResolution), - hdcp_level_(HDCP_NONE), - can_check_constraints_(false), meets_constraints_(true), default_hdcp_level_(HDCP_NONE) { @@ -220,55 +222,26 @@ bool LicenseKeyStatus::GetAllowedUsage(CdmKeyAllowedUsage* allowed_usage) { return true; } -bool LicenseKeyStatus::ApplyStatusChange( - const CdmKeyStatus* maybe_new_status, const uint32_t* maybe_new_resolution, - const CryptoSession::HdcpCapability* maybe_new_hdcp_level, - bool* newly_usable) { - *newly_usable = false; +bool LicenseKeyStatus::ApplyStatusChange(CdmKeyStatus new_status, + bool* new_usable_key) { + *new_usable_key = false; if (!is_content_key_) { return false; } - - // Most of this function is various work to calculate an updated value for - // the status. We start at the same value as the current status. - CdmKeyStatus updated_status = key_status_; - - // Account for the new status, if provided. - if (maybe_new_status != NULL) { - const CdmKeyStatus& new_status = *maybe_new_status; - can_check_constraints_ = (new_status == kKeyStatusUsable); - updated_status = new_status; - } - - // Account for the new resolution, if provided. - if (maybe_new_resolution != NULL) { - resolution_ = *maybe_new_resolution; - } - - // Account for the new HDCP level, if provided. - if (maybe_new_hdcp_level != NULL) { - hdcp_level_ = *maybe_new_hdcp_level; - } - - // If we can, check the current state against the constraints and update the - // status if needed. - if (can_check_constraints_) { - ApplyConstraints(); + CdmKeyStatus updated_status = new_status; + if (updated_status == kKeyStatusUsable) { if (!MeetsConstraints()) { updated_status = kKeyStatusOutputNotAllowed; } } - - // Check if any of that work changed the key status. if (key_status_ != updated_status) { key_status_ = updated_status; if (updated_status == kKeyStatusUsable) { - *newly_usable = true; + *new_usable_key = true; } return true; - } else { - return false; } + return false; } // If the key has constraints, find the constraint that applies. @@ -278,16 +251,12 @@ bool LicenseKeyStatus::ApplyStatusChange( // If the key has no constraints, or if the constraint has no HDCP // requirement, use the key's default HDCP setting to check against the // device's current HDCP level. -void LicenseKeyStatus::ApplyConstraints() { - if (resolution_ == kNoResolution) { - // Until a resolution has been detected, the constraints cannot be checked. - meets_constraints_ = true; - return; - } +void LicenseKeyStatus::ApplyConstraints( + uint32_t video_pixels, CryptoSession::HdcpCapability new_hdcp_level) { VideoResolutionConstraint* current_constraint = NULL; - if (HasConstraints()) { - current_constraint = GetConstraintForRes(resolution_, constraints_); + if (HasConstraints() && video_pixels != HDCP_UNSPECIFIED_VIDEO_RESOLUTION) { + current_constraint = GetConstraintForRes(video_pixels, constraints_); if (NULL == current_constraint) { meets_constraints_ = false; return; @@ -302,7 +271,7 @@ void LicenseKeyStatus::ApplyConstraints() { desired_hdcp_level = default_hdcp_level_; } - meets_constraints_ = (hdcp_level_ >= desired_hdcp_level); + meets_constraints_ = (new_hdcp_level >= desired_hdcp_level); } void LicenseKeyStatus::SetConstraints(const ConstraintList& constraints) { diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index f4917127..50d12393 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -29,7 +29,8 @@ #include "level3.h" #include "lock.h" #include "log.h" -#include "metrics_collections.h" +#include "metrics_front_end.h" +#include "metrics_group.h" #include "properties.h" #include "wv_cdm_constants.h" @@ -40,8 +41,6 @@ using wvcdm::kLevel3; namespace { static const size_t kMaxGenericEncryptChunkSize = 100*1024; -const OEMCryptoResult kOemCryptoResultVendorSpecificError1 = - static_cast(10008); typedef struct { const uint8_t* key_id; @@ -376,169 +375,6 @@ void clear_cache_function(void *page, size_t len) { #endif } -// The WatchDog looks after a worker thread that is trying to initialize L3. -// Once in a rare while, the L3 init does not finish and eats up CPU cycles. -// If that happens, the watchdog thread will give up and return an error. -class WatchDog { - public: - // Created by main thread. - WatchDog() { - pthread_mutex_init(&mutex_, NULL); - pthread_cond_init(&condition_, NULL); - status_ = OEMCrypto_SUCCESS; - gave_up_ = false; - } - - // Deleted by either thread. - ~WatchDog() { - pthread_cond_destroy(&condition_); - } - - // Starts worker thread. - void StartThread() { - running_ = true; - if(pthread_create(&thread_, NULL, RunWatchDog, this)) { - LOGE("Could not create watch dog thread."); - status_ = OEMCrypto_ERROR_INIT_FAILED; - running_ = false; - return; - } - } - - // Function called by new worker thread in pthread_create. - static void *RunWatchDog(void *watcher) { - WatchDog* dog = reinterpret_cast(watcher); - dog->DoInit(); - dog->SignalDoneAndCleanUp(); - return NULL; - } - - // Called by worker thread. - void DoInit() { - std::string base_path; - wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL3, - &base_path); - status_ = Level3_Initialize(clear_cache_function, - base_path.c_str()); - } - - std::string FailureFilename() { - std::string path; - if (!wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL3, - &path)) { - LOGW("WatchDog::FailureFilename: Unable to get base path"); - return "/data/l3_failure_file"; - } - path += "l3_failure_file"; - return path; - } - - // Check to see if the failure file was created before that last abort. - void CheckForPreviousFailure(wvcdm::metrics::OemCryptoDynamicAdapterMetrics* metrics) { - wvcdm::FileSystem file_system; - std::string filename = FailureFilename(); - if (!file_system.Exists(filename)) return; - wvcdm::File* file = file_system.Open(filename, file_system.kReadOnly); - if (file) { - uint32_t flag = 0; - ssize_t size = sizeof(flag); - ssize_t size_read = file->Read(reinterpret_cast(&flag), size); - file->Close(); - file_system.Remove(filename); - if (size == size_read && flag) { - LOGE("Previous L3 Init failed."); - if (metrics == nullptr) return; - metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode( - wvcdm::metrics::OEMCrypto_INITIALIZED_L3_INITIALIZATION_FAILED); - } - } - } - - // Save the failure file before we abort. - void SaveFailureInformation() { - wvcdm::FileSystem file_system; - std::string filename = FailureFilename(); - LOGD("failure filename = %s", filename.c_str()); - wvcdm::File* file = file_system.Open( - filename, file_system.kCreate | file_system.kTruncate); - if (!file) { - LOGE("Could not create file %s", filename.c_str()); - return; - } - uint32_t flag = 0x6261640a; // bad - ssize_t size = sizeof(flag); - ssize_t size_written = file->Write(reinterpret_cast(&flag), size); - file->Close(); - if (size != size_written) { - LOGE("Wrote %d bytes, not %d, to file %s", size_written, size, - filename.c_str()); - } else { - LOGE("I wrote %d to %s", size_written, filename.c_str()); - } - } - - // Called by worker thread after DoInit has finshed. - void SignalDoneAndCleanUp() { - pthread_mutex_lock(&mutex_); - running_ = false; - pthread_cond_signal(&condition_); - // If the main thread gave up, it won't delete this, so we must. - bool should_delete = gave_up_; - pthread_mutex_unlock(&mutex_); - // https://isocpp.org/wiki/faq/freestore-mgmt#delete-this - if (should_delete) delete this; - } - - // Called by main thread to wait for worker thread. - OEMCryptoResult WaitForStatusAndCleanUp() { - pthread_mutex_lock(&mutex_); - struct timespec time_to_giveup; - clock_gettime(CLOCK_REALTIME, &time_to_giveup); - time_to_giveup.tv_sec += 120; // wait 2 minutes. - if (running_) { - pthread_cond_timedwait(&condition_, &mutex_, &time_to_giveup); - } - if (running_) { - gave_up_ = true; - status_ = OEMCrypto_ERROR_INIT_FAILED; - LOGE("XXX WATCH DOG ERROR XXX"); - // HACK: this normally just returns an error. However, we are using it - // as a signal to dump debugging information. - Level3_GetOEMPublicCertificate(0, nullptr, nullptr); - SaveFailureInformation(); - // This tells the worker thread to clean up after itself. It is not - // really needed since we are going to abort. However, if somebody - // removes the "abort()" below, then this is needed. - pthread_detach(thread_); - // This is controversial. The argument for an abort here is that if we - // do not abort, we will suck all the life out of the user's battery. By - // saving information to the file system, above, we can still track - // metrics. - abort(); - } - // If we gave up waiting for init thread, we should not delete the mutex - // out from under it. - bool should_delete = !gave_up_; - OEMCryptoResult status = status_; - pthread_mutex_unlock(&mutex_); - if (should_delete) { - pthread_join(thread_, NULL); - delete this; - } - return status; - } - - OEMCryptoResult status() { return status_; } - - private: - OEMCryptoResult status_; - pthread_t thread_; - pthread_mutex_t mutex_; - pthread_cond_t condition_; - bool running_; - bool gave_up_; -}; - struct LevelSession { FunctionPointers* fcn; OEMCrypto_SESSION session; @@ -584,36 +420,44 @@ class Adapter { OEMCryptoResult Initialize() { /* - * To avoid changing the function signature and function contract, use a - * reference to a singleton object for the metrics collected from the - * dynamic adapter. + * To avoid changing the function signature and function contract - declare + * a one-off metrics group to collect detailed information about how + * oemcrypto was intialized. */ - wvcdm::metrics::OemCryptoDynamicAdapterMetrics& metrics = - wvcdm::metrics::GetDynamicAdapterMetricsInstance(); + wvcdm::metrics::MetricsGroup metrics; level1_ = FunctionPointers(); // start with all null pointers. level3_ = FunctionPointers(); // start with all null pointers. LoadLevel3(); - WatchDog *watcher = new WatchDog(); - watcher->CheckForPreviousFailure(&metrics); - watcher->StartThread(); - OEMCryptoResult result = watcher->WaitForStatusAndCleanUp(); + std::string base_path; + wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL3, + &base_path); + OEMCryptoResult result = Level3_Initialize(clear_cache_function, + base_path.c_str()); if (Level3_IsInApp()) { - metrics.SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_IN_APP); return result; } if (force_level3()) { LOGW("Test code. User requested falling back to L3"); - metrics.SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_FORCING_L3); return result; } - LOGI("L3 Initialized. Trying L1."); std::string library_name; if (!wvcdm::Properties::GetOEMCryptoPath(&library_name)) { LOGW("L1 library not specified. Falling back to L3"); - metrics.OemCryptoDynamicAdapterMetrics::SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_NO_L1_LIBRARY_PATH); return result; } @@ -621,11 +465,14 @@ class Adapter { if (level1_library_ == NULL) { LOGW("Could not load %s. Falling back to L3. %s", library_name.c_str(), dlerror()); - metrics.OemCryptoDynamicAdapterMetrics::SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_L1_OPEN_FAILED); return result; } - if (LoadLevel1(&metrics)) { + if (LoadLevel1(metrics)) { LOGD("OEMCrypto_Initialize Level 1 success. I will use level 1."); } else { level1_ = FunctionPointers(); // revert to all null pointers. @@ -636,10 +483,7 @@ class Adapter { return result; } - bool LoadLevel1(wvcdm::metrics::OemCryptoDynamicAdapterMetrics* metrics) { - if (metrics == nullptr) { - return false; - } + bool LoadLevel1(wvcdm::metrics::MetricsGroup& metrics) { level1_valid_ = true; const uint32_t kMinimumVersion = 8; const uint32_t kMaximumVersion = 13; @@ -648,25 +492,37 @@ class Adapter { LOOKUP_ALL(8, APIVersion, OEMCrypto_APIVersion); LOOKUP_ALL(8, Terminate, OEMCrypto_Terminate); if (!level1_valid_) { - metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_INVALID_L1); return false; } OEMCryptoResult st = level1_.Initialize(); if (st != OEMCrypto_SUCCESS) { LOGW("Could not initialize L1. Falling Back to L3."); - metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_COULD_NOT_INITIALIZE_L1); return false; } level1_.version = level1_.APIVersion(); - metrics->SetL1ApiVersion(level1_.version); - metrics->SetL1MinApiVersion(kMinimumVersion); - + M_RECORD( + &metrics, + oemcrypto_l1_api_version_, + NO_TIME, + level1_.version, + kMinimumVersion); if (level1_.version < kMinimumVersion) { LOGW("liboemcrypto.so is version %d, not %d. Falling Back to L3.", level1_.version, kMinimumVersion); - metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_WRONG_L1_VERSION); level1_.Terminate(); return false; @@ -741,7 +597,10 @@ class Adapter { // If we have a valid keybox, initialization is done. We're good. if (OEMCrypto_SUCCESS == level1_.IsKeyboxValid()) { - metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L1_WITH_KEYBOX); return true; } @@ -750,7 +609,10 @@ class Adapter { // will have to be caught in the future when provisioning fails. if (level1_.version > 11 && (level1_.GetProvisioningMethod() == OEMCrypto_OEMCertificate)) { - metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L1_WITH_PROVISIONING_3_0); return true; } @@ -767,10 +629,16 @@ class Adapter { // because we still want to test OEMCrypto in that configuration. LOGE("OEMCrypto uses cert as identification, but cdm does not!"); LOGE("This will not work on a production device."); - metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L1_CERTIFICATE_MIX); } else { - metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L1_WITH_CERTIFICATE); } return true; @@ -780,7 +648,10 @@ class Adapter { if (!wvcdm::Properties::GetFactoryKeyboxPath(&filename)) { LOGW("Bad Level 1 Keybox. Falling Back to L3."); level1_.Terminate(); - metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_BAD_KEYBOX); return false; } @@ -789,7 +660,10 @@ class Adapter { if (size <= 0 || !file) { LOGW("Could not open %s. Falling Back to L3.", filename.c_str()); level1_.Terminate(); - metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_COULD_NOT_OPEN_FACTORY_KEYBOX); return false; } @@ -800,12 +674,18 @@ class Adapter { LOGE("Could NOT install keybox from %s. Falling Back to L3.", filename.c_str()); level1_.Terminate(); - metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_COULD_NOT_INSTALL_KEYBOX); return false; } LOGI("Installed keybox from %s", filename.c_str()); - metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode( + M_RECORD( + &metrics, + oemcrypto_initialization_mode_, + NO_TIME, wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L1_INSTALLED_KEYBOX); return true; } @@ -1276,26 +1156,18 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys( } else { if (pair.fcn->LoadKeys_V9_or_V10 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; - OEMCryptoResult result = pair.fcn->LoadKeys_V9_or_V10( - pair.session, message, message_length, signature, signature_length, - enc_mac_key_iv, enc_mac_key, num_keys, &key_array_v10[0], pst, - pst_length); - // Convert a vendor specific error, to make it actionable - if (result == kOemCryptoResultVendorSpecificError1) - result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE; - return result; + return pair.fcn->LoadKeys_V9_or_V10(pair.session, message, message_length, + signature, signature_length, + enc_mac_key_iv, enc_mac_key, num_keys, + &key_array_v10[0], pst, pst_length); } } else { if (pair.fcn->version < 13) { if (pair.fcn->LoadKeys_V11_or_V12 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; - OEMCryptoResult result = pair.fcn->LoadKeys_V11_or_V12( + return pair.fcn->LoadKeys_V11_or_V12( pair.session, message, message_length, signature, signature_length, enc_mac_key_iv, enc_mac_key, num_keys, key_array, pst, pst_length); - // Convert a vendor specific error, to make it actionable - if (result == kOemCryptoResultVendorSpecificError1) - result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE; - return result; } else { if (pair.fcn->LoadKeys == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; return pair.fcn->LoadKeys(pair.session, message, message_length, diff --git a/libwvdrmengine/cdm/core/src/policy_engine.cpp b/libwvdrmengine/cdm/core/src/policy_engine.cpp index b6f52058..bbee4342 100644 --- a/libwvdrmengine/cdm/core/src/policy_engine.cpp +++ b/libwvdrmengine/cdm/core/src/policy_engine.cpp @@ -14,14 +14,6 @@ using video_widevine::License; -namespace { - -const int kCdmPolicyTimerDurationSeconds = 1; -const int kClockSkewDelta = 5; // seconds -const int64_t kHdcpCheckInterval = 10; - -} // namespace - namespace wvcdm { PolicyEngine::PolicyEngine(CdmSessionId session_id, @@ -36,7 +28,6 @@ PolicyEngine::PolicyEngine(CdmSessionId session_id, last_expiry_time_set_(false), was_expired_on_load_(false), next_renewal_time_(0), - last_recorded_current_time_(0), session_id_(session_id), event_listener_(event_listener), license_keys_(new LicenseKeys), @@ -57,38 +48,36 @@ bool PolicyEngine::CanDecryptContent(const KeyId& key_id) { } void PolicyEngine::InitDevice(CryptoSession* crypto_session) { - current_resolution_ = kNoResolution; + current_resolution_ = HDCP_UNSPECIFIED_VIDEO_RESOLUTION; next_device_check_ = 0; crypto_session_ = crypto_session; } -void PolicyEngine::CheckDevice(int64_t current_time) { - if (current_time < next_device_check_) { - return; - } +void PolicyEngine::SetDeviceResolution(uint32_t width, uint32_t height) { + current_resolution_ = width * height; + CheckDeviceHdcpStatus(); +} - if (!license_keys_->Empty() && current_resolution_ != kNoResolution) { +void PolicyEngine::CheckDeviceHdcpStatusOnTimer(int64_t current_time) { + if (current_time >= next_device_check_) { + CheckDeviceHdcpStatus(); + next_device_check_ = current_time + HDCP_DEVICE_CHECK_INTERVAL; + } +} + +void PolicyEngine::CheckDeviceHdcpStatus() { + if (!license_keys_->Empty()) { CryptoSession::HdcpCapability current_hdcp_level; CryptoSession::HdcpCapability ignored; if (!crypto_session_->GetHdcpCapabilities(¤t_hdcp_level, &ignored)) { current_hdcp_level = HDCP_NONE; } - - bool new_usable_keys = false; - bool keys_changed = - license_keys_->ApplyStatusChange(NULL, // new_status - ¤t_resolution_, - ¤t_hdcp_level, - &new_usable_keys); - NotifyIfKeysChanged(keys_changed, new_usable_keys); - - next_device_check_ = current_time + kHdcpCheckInterval; + license_keys_->ApplyConstraints(current_resolution_, current_hdcp_level); } } void PolicyEngine::OnTimerEvent() { - last_recorded_current_time_ += kCdmPolicyTimerDurationSeconds; - int64_t current_time = GetCurrentTime(); + int64_t current_time = clock_->GetCurrentTime(); // If we have passed the grace period, the expiration will update. if (grace_period_end_time_ == 0 && HasPlaybackStarted(current_time)) { @@ -100,19 +89,21 @@ void PolicyEngine::OnTimerEvent() { if (HasLicenseOrPlaybackDurationExpired(current_time) && license_state_ != kLicenseStateExpired) { license_state_ = kLicenseStateExpired; - UpdateKeyStatus(kKeyStatusExpired); + NotifyKeysChange(kKeyStatusExpired); return; } // Check device conditions that affect playability (HDCP, resolution) - CheckDevice(current_time); + CheckDeviceHdcpStatusOnTimer(current_time); - // Test to determine if renewal should be attempted. bool renewal_needed = false; + // Test to determine if renewal should be attempted. switch (license_state_) { case kLicenseStateCanPlay: { if (HasRenewalDelayExpired(current_time)) renewal_needed = true; + // HDCP may change, so force a check. + NotifyKeysChange(kKeyStatusUsable); break; } @@ -129,7 +120,7 @@ void PolicyEngine::OnTimerEvent() { case kLicenseStatePending: { if (current_time >= license_start_time_) { license_state_ = kLicenseStateCanPlay; - UpdateKeyStatus(kKeyStatusUsable); + NotifyKeysChange(kKeyStatusUsable); } break; } @@ -141,7 +132,7 @@ void PolicyEngine::OnTimerEvent() { default: { license_state_ = kLicenseStateExpired; - UpdateKeyStatus(kKeyStatusInternalError); + NotifyKeysChange(kKeyStatusInternalError); break; } } @@ -166,7 +157,7 @@ void PolicyEngine::SetLicenseForRelease(const License& license) { policy_.Clear(); // Expire any old keys. - UpdateKeyStatus(kKeyStatusExpired); + NotifyKeysChange(kKeyStatusExpired); UpdateLicense(license); } @@ -195,21 +186,21 @@ void PolicyEngine::UpdateLicense(const License& license) { license_start_time_ = license.license_start_time(); next_renewal_time_ = license_start_time_ + policy_.renewal_delay_seconds(); - int64_t current_time = GetCurrentTime(); + int64_t current_time = clock_->GetCurrentTime(); if (!policy_.can_play() || HasLicenseOrPlaybackDurationExpired(current_time)) { license_state_ = kLicenseStateExpired; - UpdateKeyStatus(kKeyStatusExpired); + NotifyKeysChange(kKeyStatusExpired); return; } // Update state if (current_time >= license_start_time_) { license_state_ = kLicenseStateCanPlay; - UpdateKeyStatus(kKeyStatusUsable); + NotifyKeysChange(kKeyStatusUsable); } else { license_state_ = kLicenseStatePending; - UpdateKeyStatus(kKeyStatusPending); + NotifyKeysChange(kKeyStatusPending); } NotifyExpirationUpdate(current_time); } @@ -220,7 +211,7 @@ void PolicyEngine::BeginDecryption() { case kLicenseStateCanPlay: case kLicenseStateNeedRenewal: case kLicenseStateWaitingLicenseUpdate: - playback_start_time_ = GetCurrentTime(); + playback_start_time_ = clock_->GetCurrentTime(); last_playback_time_ = playback_start_time_; if (policy_.play_start_grace_period_seconds() == 0) grace_period_end_time_ = playback_start_time_; @@ -240,7 +231,7 @@ void PolicyEngine::BeginDecryption() { } void PolicyEngine::DecryptionEvent() { - last_playback_time_ = GetCurrentTime(); + last_playback_time_ = clock_->GetCurrentTime(); } void PolicyEngine::NotifyResolution(uint32_t width, uint32_t height) { @@ -249,12 +240,12 @@ void PolicyEngine::NotifyResolution(uint32_t width, uint32_t height) { void PolicyEngine::NotifySessionExpiration() { license_state_ = kLicenseStateExpired; - UpdateKeyStatus(kKeyStatusExpired); + NotifyKeysChange(kKeyStatusExpired); } CdmResponseType PolicyEngine::Query(CdmQueryMap* query_response) { std::stringstream ss; - int64_t current_time = GetCurrentTime(); + int64_t current_time = clock_->GetCurrentTime(); if (license_state_ == kLicenseStateInitial) { query_response->clear(); @@ -295,7 +286,7 @@ CdmResponseType PolicyEngine::QueryKeyAllowedUsage( bool PolicyEngine::GetSecondsSinceStarted(int64_t* seconds_since_started) { if (playback_start_time_ == 0) return false; - *seconds_since_started = GetCurrentTime() - playback_start_time_; + *seconds_since_started = clock_->GetCurrentTime() - playback_start_time_; return (*seconds_since_started >= 0) ? true : false; } @@ -303,12 +294,12 @@ bool PolicyEngine::GetSecondsSinceLastPlayed( int64_t* seconds_since_last_played) { if (last_playback_time_ == 0) return false; - *seconds_since_last_played = GetCurrentTime() - last_playback_time_; + *seconds_since_last_played = clock_->GetCurrentTime() - last_playback_time_; return (*seconds_since_last_played >= 0) ? true : false; } int64_t PolicyEngine::GetLicenseOrPlaybackDurationRemaining() { - const int64_t current_time = GetCurrentTime(); + const int64_t current_time = clock_->GetCurrentTime(); const int64_t expiry_time = GetExpiryTime(current_time, /* ignore_soft_enforce_playback_duration */ false); @@ -332,7 +323,7 @@ void PolicyEngine::RestorePlaybackTimes(int64_t playback_start_time, playback_start_time_ = grace_period_end_time; } - const int64_t current_time = GetCurrentTime(); + const int64_t current_time = clock_->GetCurrentTime(); const int64_t expiry_time = GetExpiryTime(current_time, /* ignore_soft_enforce_playback_duration */ true); @@ -403,8 +394,6 @@ int64_t PolicyEngine::GetLicenseOrRentalDurationRemaining( if (license_expiry_time == NEVER_EXPIRES) return LLONG_MAX; if (license_expiry_time < current_time) return 0; const int64_t policy_license_duration = policy_.license_duration_seconds(); - if (policy_license_duration == NEVER_EXPIRES) - return license_expiry_time - current_time; return std::min(license_expiry_time - current_time, policy_license_duration); } @@ -440,23 +429,19 @@ bool PolicyEngine::HasRenewalRetryIntervalExpired(int64_t current_time) { next_renewal_time_ <= current_time; } -void PolicyEngine::UpdateKeyStatus(CdmKeyStatus new_status) { - bool new_usable_keys = false; - bool keys_changed = - license_keys_->ApplyStatusChange(&new_status, - NULL, // new_resolution - NULL, // new_hdcp_level - &new_usable_keys); - NotifyIfKeysChanged(keys_changed, new_usable_keys); -} - -void PolicyEngine::NotifyIfKeysChanged(bool keys_changed, - bool new_usable_keys) { +void PolicyEngine::NotifyKeysChange(CdmKeyStatus new_status) { + bool keys_changed; + bool has_new_usable_key = false; + if (new_status == kKeyStatusUsable) { + CheckDeviceHdcpStatus(); + } + keys_changed = license_keys_->ApplyStatusChange(new_status, + &has_new_usable_key); if (event_listener_ && keys_changed) { CdmKeyStatusMap content_keys; license_keys_->ExtractKeyStatuses(&content_keys); event_listener_->OnSessionKeysChange(session_id_, content_keys, - new_usable_keys); + has_new_usable_key); } } @@ -472,15 +457,6 @@ void PolicyEngine::NotifyExpirationUpdate(int64_t current_time) { last_expiry_time_set_ = true; } -int64_t PolicyEngine::GetCurrentTime() { - int64_t current_time = clock_->GetCurrentTime(); - if (current_time + kClockSkewDelta < last_recorded_current_time_) - current_time = last_recorded_current_time_; - else - last_recorded_current_time_ = current_time; - return current_time; -} - void PolicyEngine::set_clock(Clock* clock) { clock_.reset(clock); } } // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/src/privacy_crypto_openssl.cpp b/libwvdrmengine/cdm/core/src/privacy_crypto_openssl.cpp index eabf667d..c5f89ebd 100644 --- a/libwvdrmengine/cdm/core/src/privacy_crypto_openssl.cpp +++ b/libwvdrmengine/cdm/core/src/privacy_crypto_openssl.cpp @@ -29,15 +29,14 @@ RSA* GetKey(const std::string& serialized_key) { return NULL; } RSA* key = d2i_RSAPublicKey_bio(bio, NULL); + BIO_free(bio); if (key == NULL) { LOGE("GetKey: RSA key deserialization failure: %s", ERR_error_string(ERR_get_error(), NULL)); - BIO_free(bio); return NULL; } - BIO_free(bio); return key; } @@ -183,7 +182,7 @@ bool RsaPublicKey::Encrypt(const std::string& clear_message, // LogOpenSSLError is a callback from OpenSSL which is called with each error // in the thread's error queue. -static int LogOpenSSLError(const char *msg, size_t /* len */, void */* ctx */) { +static int LogOpenSSLError(const char* msg, size_t /* len */, void* /* ctx */) { LOGE(" %s", msg); return 1; } diff --git a/libwvdrmengine/cdm/core/src/service_certificate.cpp b/libwvdrmengine/cdm/core/src/service_certificate.cpp index 784841b5..73f7586a 100644 --- a/libwvdrmengine/cdm/core/src/service_certificate.cpp +++ b/libwvdrmengine/cdm/core/src/service_certificate.cpp @@ -67,6 +67,40 @@ CdmResponseType ServiceCertificate::Init(const std::string& raw_certificate) { return VerifyAndExtract(raw_certificate); } +CdmResponseType ServiceCertificate::VerifySignedMessage( + const std::string& message, const std::string& signature) { + + if (certificate_.empty()) { + LOGE("ServiceCertificate::VerifySignedMessage: " + "service certificate is not properly initialized"); + return UNKNOWN_ERROR; + } + + DrmDeviceCertificate service_certificate; + if (!service_certificate.ParseFromString(certificate_)) { + LOGE("ServiceCertificate::EncryptClientId: unable to parse retrieved " + "service certificate"); + return PARSE_SERVICE_CERTIFICATE_ERROR; + } + + if (service_certificate.type() != + video_widevine::DrmDeviceCertificate_CertificateType_SERVICE) { + LOGE("ServiceCertificate::EncryptClientId: retrieved certificate not of " + "type service, %d", service_certificate.type()); + return SERVICE_CERTIFICATE_TYPE_ERROR; + } + + // TODO(gm) verify; rework error codes. + RsaPublicKey rsa; + if (!rsa.Init(service_certificate.public_key())) + return CLIENT_ID_RSA_INIT_ERROR; + + if (!rsa.VerifySignature(message, signature)) + return CLIENT_ID_RSA_ENCRYPT_ERROR; + + return NO_ERROR; +} + CdmResponseType ServiceCertificate::EncryptClientId( CryptoSession* crypto_session, const ClientIdentification* clear_client_id, EncryptedClientIdentification* encrypted_client_id) { diff --git a/libwvdrmengine/cdm/core/src/string_conversions.cpp b/libwvdrmengine/cdm/core/src/string_conversions.cpp index 4b825d2a..7d4368f0 100644 --- a/libwvdrmengine/cdm/core/src/string_conversions.cpp +++ b/libwvdrmengine/cdm/core/src/string_conversions.cpp @@ -10,14 +10,28 @@ #include #include -#include -#include - #include "log.h" namespace wvcdm { -static bool CharToDigit(char ch, unsigned char* digit) { +static const char kBase64Codes[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + +// Gets the low |n| bits of |in|. +#define GET_LOW_BITS(in, n) ((in) & ((1 << (n)) - 1)) +// Gets the given (zero-indexed) bits [a, b) of |in|. +#define GET_BITS(in, a, b) GET_LOW_BITS((in) >> (a), (b) - (a)) +// Calculates a/b using round-up division (only works for positive numbers). +#define CEIL_DIVIDE(a, b) ((((a) - 1) / (b)) + 1) + +int DecodeBase64Char(char c) { + const char* it = strchr(kBase64Codes, c); + if (it == NULL) + return -1; + return it - kBase64Codes; +} + +bool DecodeHexChar(char ch, unsigned char* digit) { if (ch >= '0' && ch <= '9') { *digit = ch - '0'; } else { @@ -43,8 +57,8 @@ std::vector a2b_hex(const std::string& byte) { for (unsigned int i = 0; i < count / 2; ++i) { unsigned char msb = 0; // most significant 4 bits unsigned char lsb = 0; // least significant 4 bits - if (!CharToDigit(byte[i * 2], &msb) || - !CharToDigit(byte[i * 2 + 1], &lsb)) { + if (!DecodeHexChar(byte[i * 2], &msb) || + !DecodeHexChar(byte[i * 2 + 1], &lsb)) { LOGE("Invalid hex value %c%c at index %d", byte[i * 2], byte[i * 2 + 1], i); return array; @@ -80,23 +94,50 @@ std::string b2a_hex(const std::string& byte) { } // Encode for standard base64 encoding (RFC4648). +// https://en.wikipedia.org/wiki/Base64 +// Text | M | a | n | +// ASCI | 77 (0x4d) | 97 (0x61) | 110 (0x6e) | +// Bits | 0 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0 | +// Index | 19 | 22 | 5 | 46 | +// Base64 | T | W | F | u | +// | <----------------- 24-bits -----------------> | std::string Base64Encode(const std::vector& bin_input) { if (bin_input.empty()) { return std::string(); } - int in_size = bin_input.size(); - std::string b64_output(modp_b64_encode_len(in_size), 0); + // |temp| stores a 24-bit block that is treated as an array where insertions + // occur from high to low. + uint32_t temp = 0; + size_t out_index = 0; + const size_t out_size = CEIL_DIVIDE(bin_input.size(), 3) * 4; + std::string result(out_size, '\0'); + for (size_t i = 0; i < bin_input.size(); i++) { + // "insert" 8-bits of data + temp |= (bin_input[i] << ((2 - (i % 3)) * 8)); - int out_size = modp_b64_encode( - &b64_output[0], reinterpret_cast(&bin_input[0]), in_size); - if (out_size == -1) { - LOGE("Base64Encode failed"); - return std::string(); + if (i % 3 == 2) { + result[out_index++] = kBase64Codes[GET_BITS(temp, 18, 24)]; + result[out_index++] = kBase64Codes[GET_BITS(temp, 12, 18)]; + result[out_index++] = kBase64Codes[GET_BITS(temp, 6, 12)]; + result[out_index++] = kBase64Codes[GET_BITS(temp, 0, 6)]; + temp = 0; + } } - b64_output.resize(out_size); - return b64_output; + if (bin_input.size() % 3 == 1) { + result[out_index++] = kBase64Codes[GET_BITS(temp, 18, 24)]; + result[out_index++] = kBase64Codes[GET_BITS(temp, 12, 18)]; + result[out_index++] = '='; + result[out_index++] = '='; + } else if (bin_input.size() % 3 == 2) { + result[out_index++] = kBase64Codes[GET_BITS(temp, 18, 24)]; + result[out_index++] = kBase64Codes[GET_BITS(temp, 12, 18)]; + result[out_index++] = kBase64Codes[GET_BITS(temp, 6, 12)]; + result[out_index++] = '='; + } + + return result; } // Filename-friendly base64 encoding (RFC4648), commonly referred to @@ -111,18 +152,14 @@ std::string Base64SafeEncode(const std::vector& bin_input) { return std::string(); } - int in_size = bin_input.size(); - std::string b64_output(modp_b64w_encode_len(in_size), 0); - - int out_size = modp_b64w_encode( - &b64_output[0], reinterpret_cast(&bin_input[0]), in_size); - if (out_size == -1) { - LOGE("Base64SafeEncode failed"); - return std::string(); + std::string ret = Base64Encode(bin_input); + for (size_t i = 0; i < ret.size(); i++) { + if (ret[i] == '+') + ret[i] = '-'; + else if (ret[i] == '/') + ret[i] = '_'; } - - b64_output.resize(out_size); - return b64_output; + return ret; } std::string Base64SafeEncodeNoPad(const std::vector& bin_input) { @@ -138,17 +175,57 @@ std::vector Base64Decode(const std::string& b64_input) { return std::vector(); } - int in_size = b64_input.size(); - std::vector bin_output(modp_b64_decode_len(in_size), 0); - int out_size = modp_b64_decode(reinterpret_cast(&bin_output[0]), - b64_input.data(), in_size); - if (out_size == -1) { - LOGE("Base64Decode failed"); - return std::vector(0); + const size_t out_size_max = CEIL_DIVIDE(b64_input.size() * 3, 4); + std::vector result(out_size_max, '\0'); + + // |temp| stores 24-bits of data that is treated as an array where insertions + // occur from high to low. + uint32_t temp = 0; + size_t out_index = 0; + size_t i; + for (i = 0; i < b64_input.size(); i++) { + if (b64_input[i] == '=') { + // Verify an '=' only appears at the end. We want i to remain at the + // first '=', so we need an inner loop. + for (size_t j = i; j < b64_input.size(); j++) { + if (b64_input[j] != '=') { + LOGE("base64Decode failed"); + return std::vector(); + } + } + break; + } + + const int decoded = DecodeBase64Char(b64_input[i]); + if (decoded < 0) { + LOGE("base64Decode failed"); + return std::vector(); + } + // "insert" 6-bits of data + temp |= (decoded << ((3 - (i % 4)) * 6)); + + if (i % 4 == 3) { + result[out_index++] = GET_BITS(temp, 16, 24); + result[out_index++] = GET_BITS(temp, 8, 16); + result[out_index++] = GET_BITS(temp, 0, 8); + temp = 0; + } } - bin_output.resize(out_size); - return bin_output; + switch (i % 4) { + case 1: + LOGE("base64Decode failed"); + return std::vector(); + case 2: + result[out_index++] = GET_BITS(temp, 16, 24); + break; + case 3: + result[out_index++] = GET_BITS(temp, 16, 24); + result[out_index++] = GET_BITS(temp, 8, 16); + break; + } + result.resize(out_index); + return result; } // Decode for Filename-friendly base64 encoding (RFC4648), commonly referred @@ -158,17 +235,16 @@ std::vector Base64SafeDecode(const std::string& b64_input) { return std::vector(); } - int in_size = b64_input.size(); - std::vector bin_output(modp_b64w_decode_len(in_size), 0); - int out_size = modp_b64w_decode(reinterpret_cast(&bin_output[0]), - b64_input.data(), in_size); - if (out_size == -1) { - LOGE("Base64SafeDecode failed"); - return std::vector(0); + // Make a copy so we can modify it to replace the web-safe special characters + // with the normal ones. + std::string input_copy = b64_input; + for (size_t i = 0; i < input_copy.size(); i++) { + if (input_copy[i] == '-') + input_copy[i] = '+'; + else if (input_copy[i] == '_') + input_copy[i] = '/'; } - - bin_output.resize(out_size); - return bin_output; + return Base64Decode(input_copy); } std::string HexEncode(const uint8_t* in_buffer, unsigned int size) { diff --git a/libwvdrmengine/cdm/core/src/usage_table_header.cpp b/libwvdrmengine/cdm/core/src/usage_table_header.cpp index 0f66ace9..8b5abbe2 100644 --- a/libwvdrmengine/cdm/core/src/usage_table_header.cpp +++ b/libwvdrmengine/cdm/core/src/usage_table_header.cpp @@ -24,7 +24,6 @@ UsageTableHeader::UsageTableHeader() : security_level_(kSecurityLevelUninitialized), requested_security_level_(kLevelDefault), is_inited_(false) { - file_system_.reset(new FileSystem()); file_handle_.reset(new DeviceFiles(file_system_.get())); } @@ -110,7 +109,7 @@ CdmResponseType UsageTableHeader::AddEntry( size_t number_of_entries = usage_entry_info_.size(); usage_entry_info_.resize(*usage_entry_number + 1); for (size_t i = number_of_entries; i < usage_entry_info_.size() - 1; ++i) { - usage_entry_info_[i].storage_type = kStorageUnknown; + usage_entry_info_[i].storage_type = kStorageTypeUnknown; usage_entry_info_[i].key_set_id.clear(); usage_entry_info_[i].usage_info_file_name.clear(); } @@ -183,7 +182,7 @@ CdmResponseType UsageTableHeader::DeleteEntry(uint32_t usage_entry_number, if (status == NO_ERROR) swap_usage_entry_valid = true; break; } - case kStorageUnknown: + case kStorageTypeUnknown: default: break; } @@ -199,7 +198,7 @@ CdmResponseType UsageTableHeader::DeleteEntry(uint32_t usage_entry_number, // If unable to move entry, unset storage type of entry to be deleted and // resize |usage_entry_info_| so that swap usage entry is the last entry. if (status != NO_ERROR) { - usage_entry_info_[usage_entry_number].storage_type = kStorageUnknown; + usage_entry_info_[usage_entry_number].storage_type = kStorageTypeUnknown; usage_entry_info_[usage_entry_number].key_set_id.clear(); if (usage_entry_info_.size() - 1 == swap_entry_number) { file_handle_->StoreUsageTableInfo(usage_table_header_, @@ -286,7 +285,7 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number, &last_playback_time, &grace_period_end_time, &app_parameters, usage_entry, &entry_number)) { LOGE("UsageTableHeader::GetEntry: Failed to retrieve license"); - return USAGE_RETRIEVE_LICENSE_FAILED; + return USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED; } break; } @@ -302,17 +301,17 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number, usage_entry, &entry_number)) { LOGE( "UsageTableHeader::GetEntry: Failed to retrieve usage information"); - return USAGE_RETRIEVE_USAGE_INFO_FAILED; + return USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED; } break; } - case kStorageUnknown: + case kStorageTypeUnknown: default: LOGE( "UsageTableHeader::GetEntry: Attempting to retrieve usage " "information from unknown storage type: %d", usage_entry_info_[usage_entry_number].storage_type); - return USAGE_RETRIEVE_INVALID_STORAGE_TYPE; + return USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE; } if (usage_entry_number != entry_number) { @@ -343,7 +342,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number, &last_playback_time, &grace_period_end_time, &app_parameters, &entry, &entry_number)) { LOGE("UsageTableHeader::StoreEntry: Failed to retrieve license"); - return USAGE_RETRIEVE_LICENSE_FAILED; + return USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED; } if (!handle->StoreLicense( usage_entry_info_[usage_entry_number].key_set_id, license_state, @@ -368,7 +367,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number, LOGE( "UsageTableHeader::StoreEntry: Failed to retrieve usage " "information"); - return USAGE_RETRIEVE_USAGE_INFO_FAILED; + return USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED; } handle->DeleteUsageInfo( usage_entry_info_[usage_entry_number].usage_info_file_name, @@ -383,13 +382,13 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number, } break; } - case kStorageUnknown: + case kStorageTypeUnknown: default: LOGE( "UsageTableHeader::GetUsageEntry: Attempting to retrieve usage " "information from unknown storage type: %d", usage_entry_info_[usage_entry_number].storage_type); - return USAGE_RETRIEVE_INVALID_STORAGE_TYPE; + return USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE; } return NO_ERROR; } diff --git a/libwvdrmengine/cdm/core/test/base64_test.cpp b/libwvdrmengine/cdm/core/test/base64_test.cpp index 44cefac4..1ac883ae 100644 --- a/libwvdrmengine/cdm/core/test/base64_test.cpp +++ b/libwvdrmengine/cdm/core/test/base64_test.cpp @@ -53,6 +53,9 @@ const std::pair kBase64TestVectors[] = make_pair(&kTwoBytesOverData, &kTwoBytesOverB64Data), make_pair(&kTestData, &kB64TestData)}; +const std::string kBase64ErrorVectors[] = {"Foo$sa", "Foo\x99\x23\xfa\02", + "Foo==Foo", "FooBa"}; + std::string ConvertToBase64WebSafe(const std::string &std_base64_string) { std::string str(std_base64_string); for (size_t i = 0; i < str.size(); ++i) { @@ -89,9 +92,19 @@ TEST_P(Base64EncodeDecodeTest, WebSafeEncodeDecodeTest) { EXPECT_STREQ(encoded_string.data(), b64_string.data()); } +class Base64ErrorDecodeTest : public ::testing::TestWithParam {}; + +TEST_P(Base64ErrorDecodeTest, EncoderErrors) { + std::vector result = Base64Decode(GetParam()); + EXPECT_EQ(0u, result.size()); +} + INSTANTIATE_TEST_CASE_P(ExecutesBase64Test, Base64EncodeDecodeTest, ::testing::ValuesIn(kBase64TestVectors)); +INSTANTIATE_TEST_CASE_P(ExecutesBase64Test, Base64ErrorDecodeTest, + ::testing::ValuesIn(kBase64ErrorVectors)); + class HtoNLL64Test : public ::testing::Test {}; TEST_F(HtoNLL64Test, PositiveNumber) { diff --git a/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp b/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp index ea6ef4ae..343065f4 100644 --- a/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp +++ b/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp @@ -52,7 +52,7 @@ class WvCdmEngineTest : public testing::Test { g_client_auth.assign(config.client_auth()); g_key_system.assign(config.key_system()); g_wrong_key_id.assign(config.wrong_key_id()); - g_license_server.assign(config.license_server_url()); + g_license_server.assign(config.license_server()); g_key_id_pssh.assign(a2bs_hex(config.key_id())); // Extract the key ID from the PSSH box. diff --git a/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp b/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp index 2eafe3a9..bd064e14 100644 --- a/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp @@ -99,8 +99,7 @@ class MockDeviceFiles : public DeviceFiles { class MockCryptoSession : public CryptoSession { public: - MockCryptoSession(metrics::CryptoMetrics* crypto_metrics) - : CryptoSession(crypto_metrics) { } + MockCryptoSession() : CryptoSession(NULL) { } MOCK_METHOD1(GetClientToken, bool(std::string*)); MOCK_METHOD1(GetProvisioningToken, bool(std::string*)); MOCK_METHOD0(GetPreProvisionTokenType, CdmClientTokenType()); @@ -142,11 +141,11 @@ class CdmSessionTest : public ::testing::Test { protected: virtual void SetUp() { service_cert_ = new ServiceCertificate; - cdm_session_.reset(new CdmSession(NULL, &metrics_)); + cdm_session_.reset(new CdmSession(NULL)); // Inject testing mocks. license_parser_ = new MockCdmLicense(cdm_session_->session_id()); cdm_session_->set_license_parser(license_parser_); - crypto_session_ = new MockCryptoSession(&crypto_metrics_); + crypto_session_ = new MockCryptoSession(); cdm_session_->set_crypto_session(crypto_session_); policy_engine_ = new MockPolicyEngine(); cdm_session_->set_policy_engine(policy_engine_); @@ -154,16 +153,8 @@ class CdmSessionTest : public ::testing::Test { cdm_session_->set_file_handle(file_handle_); } - virtual void TearDown() { - // Force the cdm_session_ to be deleted. This enforces a requirement that - // the CDM session metrics exist at least as long as the CDM session. - cdm_session_.reset(); - } - - metrics::SessionMetrics metrics_; scoped_ptr cdm_session_; MockCdmLicense* license_parser_; - metrics::CryptoMetrics crypto_metrics_; MockCryptoSession* crypto_session_; MockPolicyEngine* policy_engine_; MockDeviceFiles* file_handle_; diff --git a/libwvdrmengine/cdm/core/test/config_test_env.cpp b/libwvdrmengine/cdm/core/test/config_test_env.cpp index e05c4fb4..cc435211 100644 --- a/libwvdrmengine/cdm/core/test/config_test_env.cpp +++ b/libwvdrmengine/cdm/core/test/config_test_env.cpp @@ -2,21 +2,23 @@ #include "config_test_env.h" -#include "string_conversions.h" - namespace wvcdm { namespace { const std::string kWidevineKeySystem = "com.widevine.alpha"; +// QA/Test server +const std::string kQALicenseServerUrl = + "http://0.widevine-qa-wls.licenseserver.widevine-license-qa.lf.borg.google.com/"; +const std::string kQAServiceCertificate = ""; +const std::string kQAProvisioningServerUrl = "http://www-googleapis-test.sandbox.google.com/certificateprovisioning/v1/devicecertificates/create" + "?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE"; + + // Content Protection license server (UAT) data const std::string kCpUatLicenseServer = "http://widevine-proxy.appspot.com/proxy"; -const std::string kUatProvisioningServerUrl = - "https://staging-www.sandbox.googleapis.com/" - "certificateprovisioning/v1/devicecertificates/create" - "?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE"; const std::string kCpClientAuth = ""; const std::string kCpKeyId = "00000042" // blob size @@ -26,7 +28,7 @@ const std::string kCpKeyId = "00000022" // pssh data size // pssh data: "08011a0d7769646576696e655f746573" - "74220f73747265616d696e675f636c69" // "streaming_clip1" + "74220f73747265616d696e675f636c69" "7031"; const std::string kCpOfflineKeyId = "00000040" // blob size @@ -36,26 +38,7 @@ const std::string kCpOfflineKeyId = "00000020" // pssh data size // pssh data: "08011a0d7769646576696e655f746573" - "74220d6f66666c696e655f636c697032"; // "offline_clip2" -const CdmInitData kCpStagingSrmOuputProtectionRequired = - "0000003d" // blob size - "70737368" // "pssh" - "00000000" // flags - "edef8ba979d64acea3c827dcd51d21ed" // Widevine system id - "0000001d" // pssh data size - // pssh data: - "08011a0d7769646576696e655f746573" - "74220a74656172735f73726d32"; // "tears_srm2" -const CdmInitData kCpStagingSrmOuputProtectionRequested = - "0000003d" // blob size - "70737368" // "pssh" - "00000000" // flags - "edef8ba979d64acea3c827dcd51d21ed" // Widevine system id - "0000001d" // pssh data size - // pssh data: - "08011a0d7769646576696e655f746573" - "74220a74656172735f73726d32"; // "tears_srm1" -const CdmInitData kEmptyData; + "74220d6f66666c696e655f636c697032"; const std::string kCpUatServiceCertificate = "0ABF020803121028703454C008F63618ADE7443DB6C4C8188BE7F99005228E023082010A02" "82010100B52112B8D05D023FCC5D95E2C251C1C649B4177CD8D2BEEF355BB06743DE661E3D" @@ -78,46 +61,9 @@ const std::string kCpUatServiceCertificate = "7C0011E0F5B38E4E298ED2CB301EB4564965F55C5D79757A250A4EB9C84AB3E6539F6B6FDF" "56899EA29914"; -const std::string kCpProductionLicenseServer = - "https://widevine-proxy.appspot.com/proxy"; -const std::string kProductionProvisioningServerUrl = - "https://www.googleapis.com/" - "certificateprovisioning/v1/devicecertificates/create" - "?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE"; -// NOTE: Provider ID = staging.google.com -const std::string kCpProductionServiceCertificate = - "0ABF020803121028703454C008F63618ADE7443DB6C4C8188BE7F9900522" - "8E023082010A0282010100B52112B8D05D023FCC5D95E2C251C1C649B417" - "7CD8D2BEEF355BB06743DE661E3D2ABC3182B79946D55FDC08DFE9540781" - "5E9A6274B322A2C7F5E067BB5F0AC07A89D45AEA94B2516F075B66EF811D" - "0D26E1B9A6B894F2B9857962AA171C4F66630D3E4C602718897F5E1EF9B6" - "AAF5AD4DBA2A7E14176DF134A1D3185B5A218AC05A4C41F081EFFF80A3A0" - "40C50B09BBC740EEDCD8F14D675A91980F92CA7DDC646A06ADAD5101F74A" - "0E498CC01F00532BAC217850BD905E90923656B7DFEFEF42486767F33EF6" - "283D4F4254AB72589390BEE55808F1D668080D45D893C2BCA2F74D60A0C0" - "D0A0993CEF01604703334C3638139486BC9DAF24FD67A07F9AD943020301" - "00013A1273746167696E672E676F6F676C652E636F6D128003983E303526" - "75F40BA715FC249BDAE5D4AC7249A2666521E43655739529721FF880E0AA" - "EFC5E27BC980DAEADABF3FC386D084A02C82537848CC753FF497B011A7DA" - "97788A00E2AA6B84CD7D71C07A48EBF61602CCA5A3F32030A7295C30DA91" - "5B91DC18B9BC9593B8DE8BB50F0DEDC12938B8E9E039CDDE18FA82E81BB0" - "32630FE955D85A566CE154300BF6D4C1BD126966356B287D657B18CE63D0" - "EFD45FC5269E97EAB11CB563E55643B26FF49F109C2101AFCAF35B832F28" - "8F0D9D45960E259E85FB5D24DBD2CF82764C5DD9BF727EFBE9C861F86932" - "1F6ADE18905F4D92F9A6DA6536DB8475871D168E870BB2303CF70C6E9784" - "C93D2DE845AD8262BE7E0D4E2E4A0759CEF82D109D2592C72429F8C01742" - "BAE2B3DECADBC33C3E5F4BAF5E16ECB74EADBAFCB7C6705F7A9E3B6F3940" - "383F9C5116D202A20C9229EE969C2519718303B50D0130C3352E06B014D8" - "38540F8A0C227C0011E0F5B38E4E298ED2CB301EB4564965F55C5D79757A" - "250A4EB9C84AB3E6539F6B6FDF56899EA29914"; - // Content Protection license server (staging) data const std::string kCpStagingLicenseServer = - "https://proxy.staging.widevine.com/proxy"; -const std::string kStagingProvisioningServerUrl = - "https://staging-www.sandbox.googleapis.com/" - "certificateprovisioning/v1/devicecertificates/create" - "?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE"; + "http://wv-staging-proxy.appspot.com/proxy"; const std::string kCpStagingServiceCertificate = "0AC102080312101705B917CC1204868B06333A2F772A8C1882B4829205228E023082010A02" "8201010099ED5B3B327DAB5E24EFC3B62A95B598520AD5BCCB37503E0645B814D876B8DF40" @@ -178,17 +124,21 @@ const std::string kWrongKeyId = "0901121094889920e8d6520098577df8" "f2dd5546"; +// URL of provisioning server (returned by GetProvisioningRequest()) +const std::string kProductionProvisioningServerUrl = + "https://www.googleapis.com/" + "certificateprovisioning/v1/devicecertificates/create" + "?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE"; + const ConfigTestEnv::LicenseServerConfiguration license_servers[] = { - {kGooglePlayServer, kGpLicenseServer, "", kGpClientAuth, kGpKeyId, - kGpOfflineKeyId, kProductionProvisioningServerUrl}, - {kContentProtectionProductionServer, kCpProductionLicenseServer, - kCpProductionServiceCertificate, kCpClientAuth, kCpKeyId, kCpOfflineKeyId, - kProductionProvisioningServerUrl}, - {kContentProtectionUatServer, kCpUatLicenseServer, kCpUatServiceCertificate, - kCpClientAuth, kCpKeyId, kCpOfflineKeyId, kUatProvisioningServerUrl}, + {kGooglePlayServer, kGpLicenseServer, kGpClientAuth, kGpKeyId, + kGpOfflineKeyId, ""}, + {kContentProtectionUatServer, kCpUatLicenseServer, kCpClientAuth, + kCpKeyId, kCpOfflineKeyId, kCpUatServiceCertificate}, {kContentProtectionStagingServer, kCpStagingLicenseServer, - kCpStagingServiceCertificate, kCpClientAuth, kCpKeyId, kCpOfflineKeyId, - kStagingProvisioningServerUrl}, + kCpClientAuth, kCpKeyId, kCpOfflineKeyId, kCpStagingServiceCertificate}, + {kContentProtectionTestQAServer, kQALicenseServerUrl, + kCpClientAuth, kCpKeyId, kCpOfflineKeyId, kQAServiceCertificate}, }; } // namespace @@ -219,45 +169,13 @@ ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id, bool streaming, } void ConfigTestEnv::Init(LicenseServerId server_id) { - server_id_ = server_id; client_auth_ = license_servers[server_id].client_tag; key_id_ = license_servers[server_id].key_id; key_system_ = kWidevineKeySystem; - license_server_url_ = license_servers[server_id].license_server_url; - provisioning_server_url_ = license_servers[server_id].provisioning_server_url; - service_certificate_ = license_servers[server_id].license_service_certificate; + license_server_ = license_servers[server_id].url; + provisioning_server_url_ = kProductionProvisioningServerUrl; + service_certificate_ = license_servers[server_id].service_certificate; wrong_key_id_ = kWrongKeyId; } -const CdmInitData ConfigTestEnv::GetInitData(ContentId content_id) { - switch (content_id) { - case kContentIdStreaming: - return wvcdm::a2bs_hex(kCpKeyId); - case kContentIdOffline: - return wvcdm::a2bs_hex(kCpOfflineKeyId); - case kContentIdStagingSrmOuputProtectionRequested: - return wvcdm::a2bs_hex(kCpStagingSrmOuputProtectionRequested); - case kContentIdStagingSrmOuputProtectionRequired: - return wvcdm::a2bs_hex(kCpStagingSrmOuputProtectionRequired); - default: - return kEmptyData; - } -} - -const std::string& ConfigTestEnv::GetLicenseServerUrl( - LicenseServerId license_server_id) { - switch (license_server_id) { - case kGooglePlayServer: - return kGpLicenseServer; - case kContentProtectionUatServer: - return kCpUatLicenseServer; - case kContentProtectionStagingServer: - return kCpStagingLicenseServer; - case kContentProtectionProductionServer: - return kCpProductionLicenseServer; - default: - return kEmptyData; - } -} - } // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/test/config_test_env.h b/libwvdrmengine/cdm/core/test/config_test_env.h index 7f218da5..71ee7629 100644 --- a/libwvdrmengine/cdm/core/test/config_test_env.h +++ b/libwvdrmengine/cdm/core/test/config_test_env.h @@ -11,30 +11,19 @@ typedef enum { kGooglePlayServer, kContentProtectionUatServer, kContentProtectionStagingServer, - kContentProtectionProductionServer, + kContentProtectionTestQAServer, } LicenseServerId; -// Identifies content used in tests. Specify Prod/Uat/Staging if content -// has been registered across license services. -enum ContentId { - kContentIdStreaming, - kContentIdOffline, - kContentIdStagingSrmOuputProtectionRequested, - kContentIdStagingSrmOuputProtectionRequired, -}; - // Configures default test environment. class ConfigTestEnv { public: - typedef struct { LicenseServerId id; - std::string license_server_url; - std::string license_service_certificate; + std::string url; std::string client_tag; std::string key_id; std::string offline_key_id; - std::string provisioning_server_url; + std::string service_certificate; } LicenseServerConfiguration; explicit ConfigTestEnv(LicenseServerId server_id); @@ -46,7 +35,7 @@ class ConfigTestEnv { const std::string& client_auth() const { return client_auth_; } const KeyId& key_id() const { return key_id_; } const CdmKeySystem& key_system() const { return key_system_; } - const std::string& license_server_url() const { return license_server_url_; } + const std::string& license_server() const { return license_server_; } const std::string& provisioning_server_url() const { return provisioning_server_url_; } @@ -55,19 +44,12 @@ class ConfigTestEnv { } const KeyId& wrong_key_id() const { return wrong_key_id_; } - static const CdmInitData GetInitData(ContentId content_id); - static const std::string& GetLicenseServerUrl( - LicenseServerId license_server_id); - void set_key_id(KeyId& key_id) { key_id_.assign(key_id); } void set_key_system(CdmKeySystem& key_system) { key_system_.assign(key_system); } void set_license_server(std::string& license_server) { - license_server_url_.assign(license_server); - } - void set_provisioning_server(std::string& provisioning_server) { - provisioning_server_url_.assign(provisioning_server); + license_server_.assign(license_server); } private: @@ -76,11 +58,10 @@ class ConfigTestEnv { std::string client_auth_; KeyId key_id_; CdmKeySystem key_system_; - std::string license_server_url_; + std::string license_server_; std::string provisioning_server_url_; std::string service_certificate_; KeyId wrong_key_id_; - LicenseServerId server_id_; CORE_DISALLOW_COPY_AND_ASSIGN(ConfigTestEnv); }; diff --git a/libwvdrmengine/cdm/core/test/device_files_unittest.cpp b/libwvdrmengine/cdm/core/test/device_files_unittest.cpp index 09eaec42..7d4a05e4 100644 --- a/libwvdrmengine/cdm/core/test/device_files_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/device_files_unittest.cpp @@ -17,7 +17,12 @@ namespace { const uint32_t kCertificateLen = 700; const uint32_t kWrappedKeyLen = 500; -const uint32_t kProtobufEstimatedOverhead = 200; +const uint32_t kProtobufEstimatedOverhead = 75; +const uint32_t kLicenseRequestLen = 300; +const uint32_t kLicenseLen = 500; +const uint32_t kProviderSessionTokenLen = 128; +const uint32_t kKeySetIdLen = 20; +const uint32_t kUsageEntryLen = 50; const std::string kEmptyString; @@ -119,7 +124,6 @@ struct LicenseInfo { int64_t grace_period_end_time; std::string app_parameters; std::string usage_entry; - uint32_t usage_entry_number; std::string file_data; }; @@ -226,9 +230,9 @@ LicenseInfo license_test_data[] = { "0112001A16200342120A106B63746C0000000000ECDCBE0000000020DBDF" "A68F051A20182F029E35047A3841FA176C74E5B387350E8D58DEA6878FF0" "BEA6CABACA1C2C"), - "https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "", "", 0, + "https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "", "", a2bs_hex( - "0AAE150802100122A7150801121408011210303132333435363738394142434445461" + "0AAC150802100122A5150801121408011210303132333435363738394142434445461" "A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0" "7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302" "5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B" @@ -307,9 +311,8 @@ LicenseInfo license_test_data[] = { "106B63746C0000000000ECDCBE0000000020DBDFA68F051A20182F029E35047A3841F" "A176C74E5B387350E8D58DEA6878FF0BEA6CABACA1C2C3A2E68747470733A2F2F7465" "73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7" - "365400048005800620068001220785CE1756656A049E77F28C8449AB2DD115B6C43B2" - "FF232D23F98B72F1DCE96A" - )}, + "3654000480058006200122039CB77169260F923E5D4BA5BBF6A7611117483253F2869" + "9DF3D9D14C3718E309")}, // license 1 {"ksidC8EAA2579A282EB0", DeviceFiles::kLicenseStateReleasing, @@ -412,9 +415,8 @@ LicenseInfo license_test_data[] = { a2bs_hex( "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021" "22232425262728292a2b2c2d2e2f"), - 5, a2bs_hex( - "0AF7150802100122F0150802121408011210303132333435363738394142434445461" + "0AF5150802100122EE150802121408011210303132333435363738394142434445461" "A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0" "7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302" "5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B" @@ -495,8 +497,8 @@ LicenseInfo license_test_data[] = { "73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7" "36540F8ACD1910148E58ED29101520F0A054E616D6531120656616C75653158006230" "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212" - "2232425262728292A2B2C2D2E2F6805122010DB816A045F2AA5865B17FE2F20DA2114" - "17B2F8B2D7511C9DE89A87CB5208AB")}, + "2232425262728292A2B2C2D2E2F1220312487214ACA5A9AF5ED9D45F209DC77E03CA1" + "DBFFDF86C44A35A1351CE968B9")}, // license 2 {"ksidE8C37662C88DC673", DeviceFiles::kLicenseStateReleasing, @@ -599,9 +601,8 @@ LicenseInfo license_test_data[] = { a2bs_hex( "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021" "22232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"), - 12, a2bs_hex( - "0AAD160802100122A6160802121408011210303132333435363738394142434445461" + "0AAB160802100122A4160802121408011210303132333435363738394142434445461" "A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0" "7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302" "5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B" @@ -683,9 +684,8 @@ LicenseInfo license_test_data[] = { "36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910152150A054E616D6531120C5661" "6C756531204E616D653252160A0C4E616D653220506172616D321206506172616D325" "8006240000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E" - "1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F680" - "C12206AA0237760D1F06E5CB78F5AFC3D124BBF7C26921CB3CC2EA44766801E25D34" - "F")}}; + "1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F122" + "07CEAAE401B81E635808AC830A0F3F43308A38FAB16069E542F994B6EC1325280")}}; // Sample license data and related data for storage and use for offline // playback. The license data and URLs in this test are not real. @@ -792,9 +792,8 @@ LicenseInfo license_update_test_data[] = { a2bs_hex( "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021" "22232425262728292a2b2c2d2e2f"), - 15, a2bs_hex( - "0AEE150802100122E7150801121408011210303132333435363738394142434445461" + "0AEC150802100122E5150801121408011210303132333435363738394142434445461" "A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0" "7A7D5076189EDFB68F05228E023082010A0282010100CC1715C81AD3F6F279C686F82" "6E6D7C8961EB13318367D06B4061BBC57E3C616A226A10F042CAD54D44C6484C725CD" @@ -875,14 +874,14 @@ LicenseInfo license_update_test_data[] = { "73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7" "36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910158006230000102030405060708" "090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2" - "B2C2D2E2F680F122009B8588A8E9926339289BA373DB8479A71F7AA1164083D90613F" - "766D60B07CBC")}, + "B2C2D2E2F1220A33C179B7718632337DFDC32D3711FD543336EBE838979DFDEB3A168" + "BC9AFB27")}, // license being released. all fields are identical except for license // state and hashed file data {"", DeviceFiles::kLicenseStateReleasing, "", "", "", "", "", "", 0, 0, 0, - "", "", 15, + "", "", a2bs_hex( - "0AEE150802100122E7150802121408011210303132333435363738394142434445461" + "0AEC150802100122E5150802121408011210303132333435363738394142434445461" "A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0" "7A7D5076189EDFB68F05228E023082010A0282010100CC1715C81AD3F6F279C686F82" "6E6D7C8961EB13318367D06B4061BBC57E3C616A226A10F042CAD54D44C6484C725CD" @@ -963,8 +962,8 @@ LicenseInfo license_update_test_data[] = { "73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7" "36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910158006230000102030405060708" "090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2" - "B2C2D2E2F680F12202F5B77A3168AC2A81832231A435D0587F6D1DF3B905A7058C5E8" - "565C81B96CA6")}}; + "B2C2D2E2F1220394BA01DFB519C1A7311115F8B2A0AC3141F981FFEA09FCD48A8EFA3" + "A045AAE6")}}; // Application parameters were added to the License message. This data // is used to verify that a License saved without application parameters can @@ -1066,7 +1065,7 @@ LicenseInfo license_app_parameters_backwards_compatibility_test_data = { "0112001A16200342120A106B63746C0000000000ECDCBE0000000020DBDF" "A68F051A20182F029E35047A3841FA176C74E5B387350E8D58DEA6878FF0" "BEA6CABACA1C2C"), - "https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "", "", 0, + "https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "", "", a2bs_hex( "0AA8150802100122A1150801121408011210303132333435363738394142434445461" "A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0" @@ -1150,702 +1149,295 @@ LicenseInfo license_app_parameters_backwards_compatibility_test_data = { "365400048001220CD0599C2B85D9F2D573AC7893CE77CB5A10B326828BA8C89047505" "A8C9B606AC")}; -struct DeviceFilesTestListUsageInfoData { - std::string file_name; - bool is_usage_info_file; -}; - -DeviceFilesTestListUsageInfoData kTestListUsageInfoData[] = { - {"ksid056fe6e9c.lic", false}, {"usage.bin", true}, - {"cert.bin", false}, {"usage345agdf==.bin", true}, - {"usageyd6e.lic", false}, {"usgtable.bin", false}, - {"usaget3ED.bin", true}, -}; - struct UsageInfo { - std::string app_id; - DeviceFiles::CdmUsageData usage_data; + std::string provider_session_token; + std::string license_request; + std::string license; + std::string usage_entry; std::string file_data; }; -std::string kEmptyUsageInfoFileData = a2bs_hex( - "0A06080310012A001220468A9A97B23D0E17147416276CB133175F0A18534155C6FFEF024A" - "D80371D7C4"); - UsageInfo kUsageInfoTestData[] = { - // test vector 0, app id: "", usage entry 0 - {"", - { - a2bs_hex("b8e7f26b6b8b59babf05b5a1f8927b412a85bc8551a928f00856329814ae" - "5a82"), - a2bs_hex("4463dc57079c27e34ae115c6f65b08f6311c4ea604a6512c42470b6f692a" - "76ea769d60d0b6bcf8d565ef31eb925f38e2095039c9f2f113ecee020f11" - "26eb30165372d538b551ebd7bae5cf0bbeebb3cdb6f180d42868051aab8f" - "f4947460dd96f0f8259fc6001059c998d2eb6902c064f9ae08e6cd3c7807" - "e50379507b41620d15dd76c0b1e7ed9417efd6825959b5077f464e6429a4" - "dee467a1ba2b05d38049912d5539f1ee9f5d8a569aa1c384384f847ed64f" - "6ffc101036da70e69c06e4916493e82e9fe3f65d85254c8c14f6ca0579bf" - "b3eaa86b2d7bb5ff572eccfd70f2ea4695f326beadf241ae4311e428c7c1" - "2a0d4d1915cd0537ff0f62cf13eb2fa2"), - a2bs_hex( - "bbe6b4b60da9d9bc34dcc8502fb81d8fd5fdbc8fa89605c86205f2b8c6530ff64" - "c8c31f579bd8eca603dfd5e397ac35e48931fd330351d01361bb31caaa7dbf816" - "a6144a12b6c22d1dceba20669ed635a40831066abd8071342119d7da11c43696b" - "2898d3df3b36beb8da013d9dc145343494b19d6da085f4a41e421d3def2ad8b72" - "dffffb6e79bbceaf8594045d16a62eed16904a3569860c531a32eaa5abb868b1d" - "d6a0b03d69c1a3f8336af80eb80badbbc7b80ca5943bd5b374302147052201fae" - "d30e9ffa99fc00b47f7eeb469512a413e873f91d959cccacccd3585b7f00ed8d4" - "685022101713c3adc439f27512a45926c1d2473477662c4bace72f380d105ddc9" - "f7be49ed71991b3d9e29a2038201373f98a845a57624a692f44ebd316d26c48fe" - "e82b655583317eca4aaa4dac841524a2dca111749629637ef29fa7e72645a8759" - "57fb3d98a5e6c8065b1349cfa23011cd6349d911c535475fed50be9eacb6a1ff3" - "ea7458823f0229f2fa90b7a7099e8ec349d3d0fe0277cba5157ca62c8fbaa893f" - "37b8c8cea2a0d2d2912caccf92d31aa17439479711b4a5b77445cc02c18bfe019" - "5ce8f1fe59e317214005cee5e25904c9fb0af7e2b6b4dccdf78e61e179a9f9399" - "6ec3c76f6da9b5a291bf08a73032b37edcbbbdd20cff94088a489167c56e5e75b" - "376874e9750212fe94d7656d9cd835db3b771ba5b58d2b255"), - "ksid854c8a60a5a547e122c24fca", - a2bs_hex("7d2b905e5eafd4b28aeeb7633283579e48add21a68eb26cc8c3b2e344579" - "003b12a38554336305525fa6ab70f024a18c73631bb1531eca3f0782c72d" - "ba017311b3f1e98c739632e305e4bc0b2561ae2b"), - 5, - }, + {"", "", "", "", // 0 usage info records + a2bs_hex("0A06080210012A00122095053501C5FA405B7EF01DA94685C6B20CB36493" + "A9CF1653B720E2BEA3B77929")}, + {// 1 usage info record a2bs_hex( - "0AA407080310012A9D070A9A070A20B8E7F26B6B8B59BABF05B5A1F8927B412A85BC8" - "551A928F00856329814AE5A821280024463DC57079C27E34AE115C6F65B08F6311C4E" - "A604A6512C42470B6F692A76EA769D60D0B6BCF8D565EF31EB925F38E2095039C9F2F" - "113ECEE020F1126EB30165372D538B551EBD7BAE5CF0BBEEBB3CDB6F180D42868051A" - "AB8FF4947460DD96F0F8259FC6001059C998D2EB6902C064F9AE08E6CD3C7807E5037" - "9507B41620D15DD76C0B1E7ED9417EFD6825959B5077F464E6429A4DEE467A1BA2B05" - "D38049912D5539F1EE9F5D8A569AA1C384384F847ED64F6FFC101036DA70E69C06E49" - "16493E82E9FE3F65D85254C8C14F6CA0579BFB3EAA86B2D7BB5FF572ECCFD70F2EA46" - "95F326BEADF241AE4311E428C7C12A0D4D1915CD0537FF0F62CF13EB2FA21A8004BBE" - "6B4B60DA9D9BC34DCC8502FB81D8FD5FDBC8FA89605C86205F2B8C6530FF64C8C31F5" - "79BD8ECA603DFD5E397AC35E48931FD330351D01361BB31CAAA7DBF816A6144A12B6C" - "22D1DCEBA20669ED635A40831066ABD8071342119D7DA11C43696B2898D3DF3B36BEB" - "8DA013D9DC145343494B19D6DA085F4A41E421D3DEF2AD8B72DFFFFB6E79BBCEAF859" - "4045D16A62EED16904A3569860C531A32EAA5ABB868B1DD6A0B03D69C1A3F8336AF80" - "EB80BADBBC7B80CA5943BD5B374302147052201FAED30E9FFA99FC00B47F7EEB46951" - "2A413E873F91D959CCCACCCD3585B7F00ED8D4685022101713C3ADC439F27512A4592" - "6C1D2473477662C4BACE72F380D105DDC9F7BE49ED71991B3D9E29A2038201373F98A" - "845A57624A692F44EBD316D26C48FEE82B655583317ECA4AAA4DAC841524A2DCA1117" - "49629637EF29FA7E72645A875957FB3D98A5E6C8065B1349CFA23011CD6349D911C53" - "5475FED50BE9EACB6A1FF3EA7458823F0229F2FA90B7A7099E8EC349D3D0FE0277CBA" - "5157CA62C8FBAA893F37B8C8CEA2A0D2D2912CACCF92D31AA17439479711B4A5B7744" - "5CC02C18BFE0195CE8F1FE59E317214005CEE5E25904C9FB0AF7E2B6B4DCCDF78E61E" - "179A9F93996EC3C76F6DA9B5A291BF08A73032B37EDCBBBDD20CFF94088A489167C56" - "E5E75B376874E9750212FE94D7656D9CD835DB3B771BA5B58D2B255221C6B73696438" - "35346338613630613561353437653132326332346663612A507D2B905E5EAFD4B28AE" - "EB7633283579E48ADD21A68EB26CC8C3B2E344579003B12A38554336305525FA6AB70" - "F024A18C73631BB1531ECA3F0782C72DBA017311B3F1E98C739632E305E4BC0B2561A" - "E2B30051220BCA71B49A97A2CFD5A3C4619807FE9EFCB68F9C69C4D63254FF10B22F1" - "13FA82")}, - // test vector 1, app id: "", usage entry 1 - {"", - { - a2bs_hex("5d637be37a9722aa35c23d346470851aca7d2edcd1a27edf124ea6"), - a2bs_hex("bc96d6878e3086c33624821f1f3ece23f27e58222c2bb8d1615476a11792" - "63b58f6427e92911d961fc7a3afd947aed8c9aead1f08457925d2ce4e0f6" - "18b21942baa60b231eae864048f94f74ffa700e5777f812adb6f0cb6ba6f" - "0d145e3951191eb217140c32f2c7565053222131ff823bc36d80b24b561c" - "cbea9d397fe00942e7ff73b8152cdc083b63a9f9c4a77056a0d79f44f267" - "da0ed629d9c902f7e838957ea41aa442221c3aa9410db58302b468c6d7f2" - "113663809f0dcf187c108ced"), - a2bs_hex("f6fb3693413cc1d7d5e3459b856e4156c78f8d85d548939fd00474c8cded" - "c46835cc981758500fe61cc79383b4d9f87c3e33d19c2d25d7d15dd0f3d2" - "b1af4583b71e90c59886d297e78e929c2f3840c82c626914a4eb537b3a51" - "61d963472b6592c0fa1e415556bc009c2da22bcf743ac434e22f8a33b432" - "10dfd8aa09fe86105610f366e6fb7da18996cf7c7db425a9bb50e4a13190" - "a680b9f82d37d09658585abe3bf9f009a5c1ce38a7cefe17f71fb402768b" - "2d66b4ca523ed06729349695d7864d7cf7a1cc11d0da2b8a43db834d10b4" - "7d9579ec9e46986a133277b92c636cb2a6a823afe73317266c9c0601ddba" - "db76e1d254d6183b93a1ea91a7e6c567331b3ee3a5ab1484af91fd0f8dac" - "5fd980a67d8f33cc1d6cf20ee4c24582d03967ed48b6f28e7514e4d18f38" - "c8cb1e54fba59af7d6a79c6c5a7ab06baac964c7958d201910adca018022" - "fbeb8535b64f5ce83d3c"), - "ksid2f2e85ce8a677f60047d7024e07b5ae6", - a2bs_hex("b74880fbddc5bb9db82f09bc7de3ffd95a0a671b979d4c1f0564eaf63eb6" - "b5a8c3f16d9f964afbd011e2326f9c27afbe74536f3f0601a71d9c1c422f" - "335611bf3bf1a1c89e2dea27c17a9d9a58a74121e840b002e8a6fb590072" - "45be786c1f64"), - 9, - }, + "924B035FBDA56AE5EF0ED05A08DE7AECC8ABE1835E0C4A548F7803937F4C3B4520EB7" + "F3334FFCDFA00DE56408F09D5019FCE87072D0DC6789817468974B2EA51EE3944B8D7" + "E0A88E4F16EBB80F03BD845231A01E6146841CBAEF0134DCD9300DB2D92732992C0F2" + "310D8E386FB31C67B9477010DEF9D99C4272589572A26A17E"), a2bs_hex( - "0AE80C080310012AE10C0A9A070A20B8E7F26B6B8B59BABF05B5A1F8927B412A85BC8" - "551A928F00856329814AE5A821280024463DC57079C27E34AE115C6F65B08F6311C4E" - "A604A6512C42470B6F692A76EA769D60D0B6BCF8D565EF31EB925F38E2095039C9F2F" - "113ECEE020F1126EB30165372D538B551EBD7BAE5CF0BBEEBB3CDB6F180D42868051A" - "AB8FF4947460DD96F0F8259FC6001059C998D2EB6902C064F9AE08E6CD3C7807E5037" - "9507B41620D15DD76C0B1E7ED9417EFD6825959B5077F464E6429A4DEE467A1BA2B05" - "D38049912D5539F1EE9F5D8A569AA1C384384F847ED64F6FFC101036DA70E69C06E49" - "16493E82E9FE3F65D85254C8C14F6CA0579BFB3EAA86B2D7BB5FF572ECCFD70F2EA46" - "95F326BEADF241AE4311E428C7C12A0D4D1915CD0537FF0F62CF13EB2FA21A8004BBE" - "6B4B60DA9D9BC34DCC8502FB81D8FD5FDBC8FA89605C86205F2B8C6530FF64C8C31F5" - "79BD8ECA603DFD5E397AC35E48931FD330351D01361BB31CAAA7DBF816A6144A12B6C" - "22D1DCEBA20669ED635A40831066ABD8071342119D7DA11C43696B2898D3DF3B36BEB" - "8DA013D9DC145343494B19D6DA085F4A41E421D3DEF2AD8B72DFFFFB6E79BBCEAF859" - "4045D16A62EED16904A3569860C531A32EAA5ABB868B1DD6A0B03D69C1A3F8336AF80" - "EB80BADBBC7B80CA5943BD5B374302147052201FAED30E9FFA99FC00B47F7EEB46951" - "2A413E873F91D959CCCACCCD3585B7F00ED8D4685022101713C3ADC439F27512A4592" - "6C1D2473477662C4BACE72F380D105DDC9F7BE49ED71991B3D9E29A2038201373F98A" - "845A57624A692F44EBD316D26C48FEE82B655583317ECA4AAA4DAC841524A2DCA1117" - "49629637EF29FA7E72645A875957FB3D98A5E6C8065B1349CFA23011CD6349D911C53" - "5475FED50BE9EACB6A1FF3EA7458823F0229F2FA90B7A7099E8EC349D3D0FE0277CBA" - "5157CA62C8FBAA893F37B8C8CEA2A0D2D2912CACCF92D31AA17439479711B4A5B7744" - "5CC02C18BFE0195CE8F1FE59E317214005CEE5E25904C9FB0AF7E2B6B4DCCDF78E61E" - "179A9F93996EC3C76F6DA9B5A291BF08A73032B37EDCBBBDD20CFF94088A489167C56" - "E5E75B376874E9750212FE94D7656D9CD835DB3B771BA5B58D2B255221C6B73696438" - "35346338613630613561353437653132326332346663612A507D2B905E5EAFD4B28AE" - "EB7633283579E48ADD21A68EB26CC8C3B2E344579003B12A38554336305525FA6AB70" - "F024A18C73631BB1531ECA3F0782C72DBA017311B3F1E98C739632E305E4BC0B2561A" - "E2B30050AC1050A1B5D637BE37A9722AA35C23D346470851ACA7D2EDCD1A27EDF124E" - "A612C001BC96D6878E3086C33624821F1F3ECE23F27E58222C2BB8D1615476A117926" - "3B58F6427E92911D961FC7A3AFD947AED8C9AEAD1F08457925D2CE4E0F618B21942BA" - "A60B231EAE864048F94F74FFA700E5777F812ADB6F0CB6BA6F0D145E3951191EB2171" - "40C32F2C7565053222131FF823BC36D80B24B561CCBEA9D397FE00942E7FF73B8152C" - "DC083B63A9F9C4A77056A0D79F44F267DA0ED629D9C902F7E838957EA41AA442221C3" - "AA9410DB58302B468C6D7F2113663809F0DCF187C108CED1AD402F6FB3693413CC1D7" - "D5E3459B856E4156C78F8D85D548939FD00474C8CDEDC46835CC981758500FE61CC79" - "383B4D9F87C3E33D19C2D25D7D15DD0F3D2B1AF4583B71E90C59886D297E78E929C2F" - "3840C82C626914A4EB537B3A5161D963472B6592C0FA1E415556BC009C2DA22BCF743" - "AC434E22F8A33B43210DFD8AA09FE86105610F366E6FB7DA18996CF7C7DB425A9BB50" - "E4A13190A680B9F82D37D09658585ABE3BF9F009A5C1CE38A7CEFE17F71FB402768B2" - "D66B4CA523ED06729349695D7864D7CF7A1CC11D0DA2B8A43DB834D10B47D9579EC9E" - "46986A133277B92C636CB2A6A823AFE73317266C9C0601DDBADB76E1D254D6183B93A" - "1EA91A7E6C567331B3EE3A5AB1484AF91FD0F8DAC5FD980A67D8F33CC1D6CF20EE4C2" - "4582D03967ED48B6F28E7514E4D18F38C8CB1E54FBA59AF7D6A79C6C5A7AB06BAAC96" - "4C7958D201910ADCA018022FBEB8535B64F5CE83D3C22246B73696432663265383563" - "653861363737663630303437643730323465303762356165362A60B74880FBDDC5BB9" - "DB82F09BC7DE3FFD95A0A671B979D4C1F0564EAF63EB6B5A8C3F16D9F964AFBD011E2" - "326F9C27AFBE74536F3F0601A71D9C1C422F335611BF3BF1A1C89E2DEA27C17A9D9A5" - "8A74121E840B002E8A6FB59007245BE786C1F6430091220B9626315C7601BC2BD1E1C" - "88F752C956261CE7509669B2AEAA1E7F1304017941")}, - // test vector 2, app id: "app_1", usage entry 0 - {"app_1", - { - a2bs_hex("bb3370ccd3c3c49573d6b74386d1886d9888bd81fe3241bcd2bac9407d1a" - "834e"), - a2bs_hex("dc0e51cfa5863f6c0b32a4ad7fa40625dadcc2dcde9e7fa3983b8804d996" - "6803181682fc8ae831472e0b2fc26276242fbce624d286eedecce5555804" - "913b4f8f86c5ae86160b8434b109169a63da04c5265102d772c1180543ef" - "226d2140357aca6cf87da3f7e370dfc08ca92a1f7c7d314eab36292a9170" - "8f6c6ad84b37ee1c7dfafb99289206cb752d063f330efd85885f4b72ba1c" - "a5823eed865a461345e3d6417872bf3b0608b3d9e1004c11e7326d3ed406" - "192e13455d0ec4e1f558a147"), - a2bs_hex("f42a68ca3a14fb68f5992e4519f57970c3dae73f8da1d5b0b1da3eff7a95" - "4012a0dc634357f3f5477a820e182182f24ae8e835ab10c18386cc8a0727" - "d3f38b628639bfbd69a94d4053eab1c31e075e014cc578b226cfe24d6b42" - "db242972def8f23a4aae88451307c2abaf54c1803ae54e3f1149aa6e6d42" - "88cc7d474e876be07954e8b2deff4ade4bf30229fb6c92df4d66cd463f68" - "6b4754b940210eb59f1581d658ddf8de8389e0e2d123e2cae3c2be6eb194" - "8ccc896dd4cdf45f9090c96dfb925795cfb4ccda83e3eb4f745577b17fc1" - "66bf5f4103c9085134cad7863a41b04f32ef20201e54b55f1817ce589619" - "b096c254fd2c2fa4a06f4de35ccfd23e"), - "kside11109bf20cde544083ef4ee", - a2bs_hex("ea106c124476b753d39368a5966972a2729bb8bbea734a2b3e812b705eac" - "e016c8a03c9a406094d80059ef4ca26f1928fa2daa5de9a6f22372e5c7a9" - "41e610d1efb56ed7ce2228a70e2e150afb66edc2da066d463aa90ba0caff" - "078fbfec05c8"), - 0, - }, - a2bs_hex("0AF404080310012AED040AEA040A20BB3370CCD3C3C49573D6B74386D1886D98" - "88BD81FE3241BCD2BAC9407D1A834E12C001DC0E51CFA5863F6C0B32A4AD7FA4" - "0625DADCC2DCDE9E7FA3983B8804D9966803181682FC8AE831472E0B2FC26276" - "242FBCE624D286EEDECCE5555804913B4F8F86C5AE86160B8434B109169A63DA" - "04C5265102D772C1180543EF226D2140357ACA6CF87DA3F7E370DFC08CA92A1F" - "7C7D314EAB36292A91708F6C6AD84B37EE1C7DFAFB99289206CB752D063F330E" - "FD85885F4B72BA1CA5823EED865A461345E3D6417872BF3B0608B3D9E1004C11" - "E7326D3ED406192E13455D0EC4E1F558A1471A8002F42A68CA3A14FB68F5992E" - "4519F57970C3DAE73F8DA1D5B0B1DA3EFF7A954012A0DC634357F3F5477A820E" - "182182F24AE8E835AB10C18386CC8A0727D3F38B628639BFBD69A94D4053EAB1" - "C31E075E014CC578B226CFE24D6B42DB242972DEF8F23A4AAE88451307C2ABAF" - "54C1803AE54E3F1149AA6E6D4288CC7D474E876BE07954E8B2DEFF4ADE4BF302" - "29FB6C92DF4D66CD463F686B4754B940210EB59F1581D658DDF8DE8389E0E2D1" - "23E2CAE3C2BE6EB1948CCC896DD4CDF45F9090C96DFB925795CFB4CCDA83E3EB" - "4F745577B17FC166BF5F4103C9085134CAD7863A41B04F32EF20201E54B55F18" - "17CE589619B096C254FD2C2FA4A06F4DE35CCFD23E221C6B7369646531313130" - "396266323063646535343430383365663465652A60EA106C124476B753D39368" - "A5966972A2729BB8BBEA734A2B3E812B705EACE016C8A03C9A406094D80059EF" - "4CA26F1928FA2DAA5DE9A6F22372E5C7A941E610D1EFB56ED7CE2228A70E2E15" - "0AFB66EDC2DA066D463AA90BA0CAFF078FBFEC05C8300012203384AAAFD3A883" - "17E6ED20BB88B0B3C01388AB1DF721547AE6FCB586659BC437")}, - // test vector 3, app id: "app_2", usage entry 0 - {"app_2", - { - a2bs_hex( - "9212a6926f21c6727c1ee89d5607047a1636f206f70e21fda86e01b6a4b5"), - a2bs_hex("ef947abed64078edf5b21fe6d3fb65384595d63a6d03e4d1d397c5019dee" - "b6890d3ef8773002b91e255af0820fb594069df55d8abf96498e493f5c70" - "f6b85f50e12a1ed3c039ad0cd838fe44d3fa9e2bbddeb2919041203111ed" - "7778701b04d6b15f41d0bde799e20a38b27bf96fdbe844f10364baeb5935" - "96220993c608ac793de76c237ca350931a7e216538074dbd83ddf262d9f1" - "8acd91e1ea5372f7e773c5b64333"), - a2bs_hex("7709721b3aa48597e88c99e82eaf7dff07e87e0318d9d7cec29096ec5918" - "26aa7a359316d6de1d1329b408543e237de84c986987ead1bb6a0c38817e" - "93013e5c989d366f49590b834453ec64b7433bf0b3335b9e222bad4caf55" - "4d69575c58595283166fea42e89645fc7e2d3ac9e0c1399b096cf3fed1e5" - "deb1bc4e0ee894f0ae3f929dd7dba4530e5655edbbf6041df430482eb2e8" - "91b6a93af84d3c16dbad92733ffd34e8f4ce24506bead578d20cd3e291c2" - "fc2f811db875f49abc21a24277d2ba474fe6af6c14021cfead5513e0999e" - "094020ce08209bbc08f13fe2b96d7ba8213c8e9c85b6a623788d34da794e" - "17e4cd3bd65680b97fb30bad64ddc42b1bcfb0b83e5dda3501a5902ca609" - "f41837a0d5cd096e0659b67c"), - "ksid62d88ed7b292217b0238be", - a2bs_hex("5422463fd2e4dd47626e97dd6b4ee0b89523aaebe8d11e7e7be703ef01e4" - "9b17eaf020cede0a9e0e7b5d91e4db7abdce445936cb2deecdefefdb14b7" - "8f67b7ca5c733c9e88446fd814584584b86becbf6eb2b0e3d5603e8b"), - 25, - }, + "1E6FFBE66FC6153E7749906EC8F684E819467E16CAF317F315DB32B6D3FDD1A8E8A09" + "4174D92D063B88E4835EAB78BD09541EA7FE72F132EB7364E154BC1548FC40EC70927" + "75531508C95F9ED5D76F36BC0C198C3A33A1F9415B343905D6BE37645E6800F053B1D" + "A9A20286EFCBBC320424ADF7FB6E3D5D8E86C35E576A1A2A37D344A419C0F0034A1B5" + "F767D3C61D90DCA1119E5024C34EDE8FA7DD128696D8C435410F218E52A853AD214FD" + "05D0F8B3CB4832CFCD97FE159E6DEE64CE82CDAEC0321AE71B3BCBAE42DF9EA65E42E" + "151827086EADE71C138B972CC3992CF9ADA944C063816352ED8658D3FA07BE0F32239" + "E74A65932B069AAC4E8386DB59154AF9AEF71448128C66E510445294F44E511BD9B1A" + "F19D4D67E99363093BE888D4B2AB841CAFF252CAD13EDF8E"), a2bs_hex( - "0AE604080310012ADF040ADC040A1E9212A6926F21C6727C1EE89D5607047A1636F20" - "6F70E21FDA86E01B6A4B512A401EF947ABED64078EDF5B21FE6D3FB65384595D63A6D" - "03E4D1D397C5019DEEB6890D3EF8773002B91E255AF0820FB594069DF55D8ABF96498" - "E493F5C70F6B85F50E12A1ED3C039AD0CD838FE44D3FA9E2BBDDEB2919041203111ED" - "7778701B04D6B15F41D0BDE799E20A38B27BF96FDBE844F10364BAEB593596220993C" - "608AC793DE76C237CA350931A7E216538074DBD83DDF262D9F18ACD91E1EA5372F7E7" - "73C5B643331A9A027709721B3AA48597E88C99E82EAF7DFF07E87E0318D9D7CEC2909" - "6EC591826AA7A359316D6DE1D1329B408543E237DE84C986987EAD1BB6A0C38817E93" - "013E5C989D366F49590B834453EC64B7433BF0B3335B9E222BAD4CAF554D69575C585" - "95283166FEA42E89645FC7E2D3AC9E0C1399B096CF3FED1E5DEB1BC4E0EE894F0AE3F" - "929DD7DBA4530E5655EDBBF6041DF430482EB2E891B6A93AF84D3C16DBAD92733FFD3" - "4E8F4CE24506BEAD578D20CD3E291C2FC2F811DB875F49ABC21A24277D2BA474FE6AF" - "6C14021CFEAD5513E0999E094020CE08209BBC08F13FE2B96D7BA8213C8E9C85B6A62" - "3788D34DA794E17E4CD3BD65680B97FB30BAD64DDC42B1BCFB0B83E5DDA3501A5902C" - "A609F41837A0D5CD096E0659B67C221A6B73696436326438386564376232393232313" - "7623032333862652A585422463FD2E4DD47626E97DD6B4EE0B89523AAEBE8D11E7E7B" - "E703EF01E49B17EAF020CEDE0A9E0E7B5D91E4DB7ABDCE445936CB2DEECDEFEFDB14B" - "78F67B7CA5C733C9E88446FD814584584B86BECBF6EB2B0E3D5603E8B30191220E964" - "7EB0AC28F0CB11C85111D69B5FA74E80015F4A07FB5C144E6CFE0E8E3709")}, - // test vector 4, app id: "app_2", usage entry 1 - {"app_2", - { - a2bs_hex("831fad51e52a403524539eab6a1b201e46674ca3b9167b1c1b53f5e5e3"), - a2bs_hex("36d83acbc5e4ed027ed583e3b2169d98f4abedda15b781408e68efa14fef" - "a9f3f0309bcb5a9fff6580636ebe3548e5acb43b76cfeb29a9c86324e62a" - "eb40556005c6686e718f9bf61b0681d43b5b1e88084b3aea27a6b0e844e5" - "500b6fcfacf2ee44d6af7f64154ab3fd4fbd0b8056cf63971076a1eb3642" - "b78d5e76b84f4ed9f6220089863f8a4911691e79feffc9f804c4c36c7f85" - "e45b1d276c85875875267eb65da70fd2d5e9176d6914"), - a2bs_hex("317bd7063bfb9fae1b2e46f4cf15b7bc8c92517ff5c32cbb52ae4b67afc5" - "d569cb66a462def7a18a7d0acebf9f6e8a604356ade2c81450c5466a4728" - "90b03eefcf65388f060e24551c67b7d46ae5d4d841d5cc63d137fd543fae" - "2c771756590b90e480ca0126f1fc0090ace62499e47569fc52196c788f80" - "139755bdf12a7acb29fd6e23a46a4c036f04ff1ed6cd714094253bf1c587" - "62c93f0ddf8a73c4be927ffec2723a16d8ffe5128851f58537461275f6aa" - "1976e3b399b7243919207e040ec16c5328e8ab082278fce0e5d3df5c5f92" - "dba51fa6613587d4ece31f2c001b49bfaed434f9512e895c2e09c88ddbf1" - "84bfafe4d82e5d05a26ac06cde29faf6ab05b96685649c923779ce5ef7f3" - "16531ada8e74e45ab1dc1d75648aa2de052674728867e87639ff9b782a3" - "3"), - "kside1d30b33b55f2deb4716", - a2bs_hex("d44a9d70a7c582559f089b1c0fdfcbdaf5e26b672fca5d58e889b407a0ba" - "8599079cde11fadfab23aa1b97622839f3b7e1a96f8332bec5fbcbc9eb64" - "fd5ed05887b8fa3bfd6ecc7bc91e621342732062d2f4411b763e20328af6" - "f8ef5030e2f8027aef9e"), - 6, - }, + "40FC62339728520E6C0C09907C26F3FB78287231661952A8B699E47AE241B999C029F" + "D2067836DC4BC64F66998A3ECD197DAE36F808A2E5A4C5BF25DD580E52B1C39A8B037" + "72BF82D58929766F2DA04F0E616F92B3A0EB75661B8FF5DE1EB807C990F9E6BA991C8" + "BAD5EB63B37E8663A4E22AA9DB2015D3DF8BED1C8313F85F13B9483C7A39C592436C8" + "B13C23F78F55CE812795335059F7F527CA580306A0AEE5A6D957A91F498F64AA2EFC6" + "780716400E17C7EEA30B2E6523B902986995E003C2D919A7DC7C0122CE9410037A660" + "2B59A63B5C89473D4E02DE35C1F01B12ADB48A3D94D43693F08268FECCC78DAF6F4C3" + "5FA32C538CD73FBF3CEA274B01179C02473486311956E5A0C78E44C59B2F34FF24B06" + "53A6379A2F5F6F51467CAE26D55CC5BBDCFC9BCFA7B8C5CBF82EBE7BD340C3DAE6374" + "D0692052C529AA33D7A6799C8F1F59C78575E51F707013026CC4F83F6B3328EE6FB1A" + "C91929A4491338E93D10EE6193014A73BA241A9A833EA835217894EB4FD4BDB8904A5" + "999928325D0AC31B6D58609EDD9D85E88F74B5BD6FA7BDD83C51EEB91633ED267ACA2" + "E103904BBE4C031A6483858FBAD74DACD01711F7B882749FFFBA0DB6C7D7109D82989" + "C7D4DB5A0F1E7506AC24C89CECAF231EFF99F96AD76E57DABDD3C2DFBA7BAA869A771" + "F561B165987E552824B0C914E708E425C3"), a2bs_hex( - "0AE809080310012AE1090ADC040A1E9212A6926F21C6727C1EE89D5607047A1636F20" - "6F70E21FDA86E01B6A4B512A401EF947ABED64078EDF5B21FE6D3FB65384595D63A6D" - "03E4D1D397C5019DEEB6890D3EF8773002B91E255AF0820FB594069DF55D8ABF96498" - "E493F5C70F6B85F50E12A1ED3C039AD0CD838FE44D3FA9E2BBDDEB2919041203111ED" - "7778701B04D6B15F41D0BDE799E20A38B27BF96FDBE844F10364BAEB593596220993C" - "608AC793DE76C237CA350931A7E216538074DBD83DDF262D9F18ACD91E1EA5372F7E7" - "73C5B643331A9A027709721B3AA48597E88C99E82EAF7DFF07E87E0318D9D7CEC2909" - "6EC591826AA7A359316D6DE1D1329B408543E237DE84C986987EAD1BB6A0C38817E93" - "013E5C989D366F49590B834453EC64B7433BF0B3335B9E222BAD4CAF554D69575C585" - "95283166FEA42E89645FC7E2D3AC9E0C1399B096CF3FED1E5DEB1BC4E0EE894F0AE3F" - "929DD7DBA4530E5655EDBBF6041DF430482EB2E891B6A93AF84D3C16DBAD92733FFD3" - "4E8F4CE24506BEAD578D20CD3E291C2FC2F811DB875F49ABC21A24277D2BA474FE6AF" - "6C14021CFEAD5513E0999E094020CE08209BBC08F13FE2B96D7BA8213C8E9C85B6A62" - "3788D34DA794E17E4CD3BD65680B97FB30BAD64DDC42B1BCFB0B83E5DDA3501A5902C" - "A609F41837A0D5CD096E0659B67C221A6B73696436326438386564376232393232313" - "7623032333862652A585422463FD2E4DD47626E97DD6B4EE0B89523AAEBE8D11E7E7B" - "E703EF01E49B17EAF020CEDE0A9E0E7B5D91E4DB7ABDCE445936CB2DEECDEFEFDB14B" - "78F67B7CA5C733C9E88446FD814584584B86BECBF6EB2B0E3D5603E8B30190AFF040A" - "1D831FAD51E52A403524539EAB6A1B201E46674CA3B9167B1C1B53F5E5E312AC0136D" - "83ACBC5E4ED027ED583E3B2169D98F4ABEDDA15B781408E68EFA14FEFA9F3F0309BCB" - "5A9FFF6580636EBE3548E5ACB43B76CFEB29A9C86324E62AEB40556005C6686E718F9" - "BF61B0681D43B5B1E88084B3AEA27A6B0E844E5500B6FCFACF2EE44D6AF7F64154AB3" - "FD4FBD0B8056CF63971076A1EB3642B78D5E76B84F4ED9F6220089863F8A4911691E7" - "9FEFFC9F804C4C36C7F85E45B1D276C85875875267EB65DA70FD2D5E9176D69141AAC" - "02317BD7063BFB9FAE1B2E46F4CF15B7BC8C92517FF5C32CBB52AE4B67AFC5D569CB6" - "6A462DEF7A18A7D0ACEBF9F6E8A604356ADE2C81450C5466A472890B03EEFCF65388F" - "060E24551C67B7D46AE5D4D841D5CC63D137FD543FAE2C771756590B90E480CA0126F" - "1FC0090ACE62499E47569FC52196C788F80139755BDF12A7ACB29FD6E23A46A4C036F" - "04FF1ED6CD714094253BF1C58762C93F0DDF8A73C4BE927FFEC2723A16D8FFE512885" - "1F58537461275F6AA1976E3B399B7243919207E040EC16C5328E8AB082278FCE0E5D3" - "DF5C5F92DBA51FA6613587D4ECE31F2C001B49BFAED434F9512E895C2E09C88DDBF18" - "4BFAFE4D82E5D05A26AC06CDE29FAF6AB05B96685649C923779CE5EF7F316531ADA8E" - "74E45AB1DC1D75648AA2DE052674728867E87639FF9B782A3322186B7369646531643" - "3306233336235356632646562343731362A64D44A9D70A7C582559F089B1C0FDFCBDA" - "F5E26B672FCA5D58E889B407A0BA8599079CDE11FADFAB23AA1B97622839F3B7E1A96" - "F8332BEC5FBCBC9EB64FD5ED05887B8FA3BFD6ECC7BC91E621342732062D2F4411B76" - "3E20328AF6F8EF5030E2F8027AEF9E300612203F1EEC1DDC56EE480AC744C1D72379E" - "AFFD4675FF15A7D53BD56AC9736D62FC1")}, - // test vector 5, app id: "app_1", usage entry 1 - {"app_1", - { - a2bs_hex("eace80e30bfda213f1ce4dbcfd9d4d24b8e2ae00054d167d9d7ae9954706" - "2b9113"), - a2bs_hex("68a7665a21348fc0590328608dc520be40f5b749328568fe383ef69c1a58" - "7ab2446cf9c41d821373d0856a883b316519a42218f80e7bd5764d16bac9" - "a9b427a7278f5940e563fcf6dee0ff3aadbb702ebf2c54ec354ae7acc84e" - "e6a54bca1f30e38ef71c44a81d0009b1484feaf4f1a56f58c35bb2372c80" - "c6dfb389e6de60bdd3d46c03975715260f6fdbe42facb64c22eda9635c04" - "da79434e1c41fbd2fdbbab6598283226c0278e8e0a96d780d3436523efd" - "1"), - a2bs_hex("ff6fecf7157828812a2d6dcb15383a6d9af4519ef804c6053a10c436002d" - "e3a4efcc017755f4ad1101bdc813e2d211732418dee529cbb413c48aa588" - "4c76a5c6f556a715055560d4247f5bf310956949a3a171a4aa608a484468" - "84e7676d558ff64d392b84e617805693d90f1e9b7b540c383d384d7f7ce0" - "6c23618681bd838ceb1a514047f1c562c43159cc5e21588fbfce8a354111" - "160f1a1e2bd3d798a000579bdfdb977252809ee1502df8045972fe8aac84" - "0211c2f8d9e4d5be18509c327c647d654c4b6cc430b98f1ff37c96fab087" - "fb561b8cc18480f877c873594d3148ff74b0e3c6327c27ca876dae742239" - "8fc5e85269cba49ad099"), - "ksid8e80350cbef6463a0025e6cc", - a2bs_hex("7ccc7ce96055e16a52fa192ea2cf3c9df3e89b9133a52286f71e6c6d82d0" - "435f6b2155dfde590b347d8c86f62d7dfbaae640c237256f609e5da9cc6c" - "103465fe3441612bbdfdf4d1c24b2147feb8565cef4993e439c9d564a39a" - "4ac5bb1da69acb44da06e4522c9a93d310cdda5dac1e1e0b91abff41e4e2" - "edda4001"), - 7, - }, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021" + "22232425262728292a2b2c2d2e2f"), a2bs_hex( - "0AEC09080310012AE5090AEA040A20BB3370CCD3C3C49573D6B74386D1886D9888BD8" - "1FE3241BCD2BAC9407D1A834E12C001DC0E51CFA5863F6C0B32A4AD7FA40625DADCC2" - "DCDE9E7FA3983B8804D9966803181682FC8AE831472E0B2FC26276242FBCE624D286E" - "EDECCE5555804913B4F8F86C5AE86160B8434B109169A63DA04C5265102D772C11805" - "43EF226D2140357ACA6CF87DA3F7E370DFC08CA92A1F7C7D314EAB36292A91708F6C6" - "AD84B37EE1C7DFAFB99289206CB752D063F330EFD85885F4B72BA1CA5823EED865A46" - "1345E3D6417872BF3B0608B3D9E1004C11E7326D3ED406192E13455D0EC4E1F558A14" - "71A8002F42A68CA3A14FB68F5992E4519F57970C3DAE73F8DA1D5B0B1DA3EFF7A9540" - "12A0DC634357F3F5477A820E182182F24AE8E835AB10C18386CC8A0727D3F38B62863" - "9BFBD69A94D4053EAB1C31E075E014CC578B226CFE24D6B42DB242972DEF8F23A4AAE" - "88451307C2ABAF54C1803AE54E3F1149AA6E6D4288CC7D474E876BE07954E8B2DEFF4" - "ADE4BF30229FB6C92DF4D66CD463F686B4754B940210EB59F1581D658DDF8DE8389E0" - "E2D123E2CAE3C2BE6EB1948CCC896DD4CDF45F9090C96DFB925795CFB4CCDA83E3EB4" - "F745577B17FC166BF5F4103C9085134CAD7863A41B04F32EF20201E54B55F1817CE58" - "9619B096C254FD2C2FA4A06F4DE35CCFD23E221C6B736964653131313039626632306" - "3646535343430383365663465652A60EA106C124476B753D39368A5966972A2729BB8" - "BBEA734A2B3E812B705EACE016C8A03C9A406094D80059EF4CA26F1928FA2DAA5DE9A" - "6F22372E5C7A941E610D1EFB56ED7CE2228A70E2E150AFB66EDC2DA066D463AA90BA0" - "CAFF078FBFEC05C830000AF5040A21EACE80E30BFDA213F1CE4DBCFD9D4D24B8E2AE0" - "0054D167D9D7AE99547062B911312B40168A7665A21348FC0590328608DC520BE40F5" - "B749328568FE383EF69C1A587AB2446CF9C41D821373D0856A883B316519A42218F80" - "E7BD5764D16BAC9A9B427A7278F5940E563FCF6DEE0FF3AADBB702EBF2C54EC354AE7" - "ACC84EE6A54BCA1F30E38EF71C44A81D0009B1484FEAF4F1A56F58C35BB2372C80C6D" - "FB389E6DE60BDD3D46C03975715260F6FDBE42FACB64C22EDA9635C04DA79434E1C41" - "FBD2FDBBAB6598283226C0278E8E0A96D780D3436523EFD11AFA01FF6FECF71578288" - "12A2D6DCB15383A6D9AF4519EF804C6053A10C436002DE3A4EFCC017755F4AD1101BD" - "C813E2D211732418DEE529CBB413C48AA5884C76A5C6F556A715055560D4247F5BF31" - "0956949A3A171A4AA608A48446884E7676D558FF64D392B84E617805693D90F1E9B7B" - "540C383D384D7F7CE06C23618681BD838CEB1A514047F1C562C43159CC5E21588FBFC" - "E8A354111160F1A1E2BD3D798A000579BDFDB977252809EE1502DF8045972FE8AAC84" - "0211C2F8D9E4D5BE18509C327C647D654C4B6CC430B98F1FF37C96FAB087FB561B8CC" - "18480F877C873594D3148FF74B0E3C6327C27CA876DAE7422398FC5E85269CBA49AD0" - "99221C6B7369643865383033353063626566363436336130303235653663632A7C7CC" - "C7CE96055E16A52FA192EA2CF3C9DF3E89B9133A52286F71E6C6D82D0435F6B2155DF" - "DE590B347D8C86F62D7DFBAAE640C237256F609E5DA9CC6C103465FE3441612BBDFDF" - "4D1C24B2147FEB8565CEF4993E439C9D564A39A4AC5BB1DA69ACB44DA06E4522C9A93" - "D310CDDA5DAC1E1E0B91ABFF41E4E2EDDA40013007122062B0F22E176F77881114844" - "DABC6F0EB0F80381D8A06ECDF09913A5CF8E85B3F")}, - // test vector 6, app id: "", usage entry 2 - {"", - { - a2bs_hex("1fbf0a1d2432805a0f8292ff627a9a7c60b733a51b365892c832261d71"), - a2bs_hex("1ad116a26f423c7019fa8dca226c2d2bdeec91beb1fd38d6890e32745a4d" - "bb9409b65fe834c2522d92621b265a9d526b4fcadcacf4c4deb364661118" - "494fd1561621392bf4450e6833be290d49e59e665a031375ee56ad1f3392" - "436ba213abc5ac10a199e73123f84f7644282137da24cbde30c10a6eb847" - "ca72b8b311ad329d2c9cb0909c2ecbe3fbaf88e81bb5aeaa6480fff67e87" - "77fa00c783aa160f1e211cb9bf3835fa8f82923c05895c359cf306f5cb90" - "a73b8ce2ce9ed210485e1c57"), - a2bs_hex("0bf120627d01690d14321fa967d81997b959b35ed7745dee9e885dd402df" - "83c3b8f52999b16c2d1d47bf4724a9ced984175eb8a032d613294c148020" - "74154c34fd40fe6ea74fa830fdcb9cc7e0799a75aadaf41ddda3d0038896" - "da966b1a67ff4e6c7403debfdbe7d1d48f1a3304124f04c974bfa0eff4d0" - "b1733a84aa6f89ec74c89dad2168da4706f6dfcfd980502b573d0f7b3791" - "252cc918394e8b3a3e1ef37ce48b7fd6a2040db5915f55809f284ce4ec24" - "4149f53038b432964705e26c3bb6535461b7fff27ac8eff679dce8e5bfe1" - "d000b69a22d9efc1f310ba2f0115c96b00bc15888fbb3edd230834458491" - "eede2440550dd59c613dc8433efe979c71e9"), - "ksida5d27d7b0ccd433203e157", - a2bs_hex("1be7cd47cefdef69576348ef9a143be2311041a5f80259938fa886139679" - "4eabcc985a695be2ef4a8361d86979859c490922d92d3ed0484e1666270a" - "a96388bf6be3c4f4f0b7e2f59efc6b8e965d8fadd5ab86b2bb816d2573ec" - "36eb42b571297681be152d40639d"), - 0, - }, + "0AB307080210012AAC070AA9070A8001924B035FBDA56AE5EF0ED05A08DE7AECC8ABE" + "1835E0C4A548F7803937F4C3B4520EB7F3334FFCDFA00DE56408F09D5019FCE87072D" + "0DC6789817468974B2EA51EE3944B8D7E0A88E4F16EBB80F03BD845231A01E6146841" + "CBAEF0134DCD9300DB2D92732992C0F2310D8E386FB31C67B9477010DEF9D99C42725" + "89572A26A17E12AC021E6FFBE66FC6153E7749906EC8F684E819467E16CAF317F315D" + "B32B6D3FDD1A8E8A094174D92D063B88E4835EAB78BD09541EA7FE72F132EB7364E15" + "4BC1548FC40EC7092775531508C95F9ED5D76F36BC0C198C3A33A1F9415B343905D6B" + "E37645E6800F053B1DA9A20286EFCBBC320424ADF7FB6E3D5D8E86C35E576A1A2A37D" + "344A419C0F0034A1B5F767D3C61D90DCA1119E5024C34EDE8FA7DD128696D8C435410" + "F218E52A853AD214FD05D0F8B3CB4832CFCD97FE159E6DEE64CE82CDAEC0321AE71B3" + "BCBAE42DF9EA65E42E151827086EADE71C138B972CC3992CF9ADA944C063816352ED8" + "658D3FA07BE0F32239E74A65932B069AAC4E8386DB59154AF9AEF71448128C66E5104" + "45294F44E511BD9B1AF19D4D67E99363093BE888D4B2AB841CAFF252CAD13EDF8E1AF" + "40340FC62339728520E6C0C09907C26F3FB78287231661952A8B699E47AE241B999C0" + "29FD2067836DC4BC64F66998A3ECD197DAE36F808A2E5A4C5BF25DD580E52B1C39A8B" + "03772BF82D58929766F2DA04F0E616F92B3A0EB75661B8FF5DE1EB807C990F9E6BA99" + "1C8BAD5EB63B37E8663A4E22AA9DB2015D3DF8BED1C8313F85F13B9483C7A39C59243" + "6C8B13C23F78F55CE812795335059F7F527CA580306A0AEE5A6D957A91F498F64AA2E" + "FC6780716400E17C7EEA30B2E6523B902986995E003C2D919A7DC7C0122CE9410037A" + "6602B59A63B5C89473D4E02DE35C1F01B12ADB48A3D94D43693F08268FECCC78DAF6F" + "4C35FA32C538CD73FBF3CEA274B01179C02473486311956E5A0C78E44C59B2F34FF24" + "B0653A6379A2F5F6F51467CAE26D55CC5BBDCFC9BCFA7B8C5CBF82EBE7BD340C3DAE6" + "374D0692052C529AA33D7A6799C8F1F59C78575E51F707013026CC4F83F6B3328EE6F" + "B1AC91929A4491338E93D10EE6193014A73BA241A9A833EA835217894EB4FD4BDB890" + "4A5999928325D0AC31B6D58609EDD9D85E88F74B5BD6FA7BDD83C51EEB91633ED267A" + "CA2E103904BBE4C031A6483858FBAD74DACD01711F7B882749FFFBA0DB6C7D7109D82" + "989C7D4DB5A0F1E7506AC24C89CECAF231EFF99F96AD76E57DABDD3C2DFBA7BAA869A" + "771F561B165987E552824B0C914E708E425C3122051C8F84C5713500997DC5B325BAE" + "D208B224DFAEB2B034E58046A62F503FED6E")}, + {// 2 usage info records a2bs_hex( - "0ADA11080310012AD3110A9A070A20B8E7F26B6B8B59BABF05B5A1F8927B412A85BC8" - "551A928F00856329814AE5A821280024463DC57079C27E34AE115C6F65B08F6311C4E" - "A604A6512C42470B6F692A76EA769D60D0B6BCF8D565EF31EB925F38E2095039C9F2F" - "113ECEE020F1126EB30165372D538B551EBD7BAE5CF0BBEEBB3CDB6F180D42868051A" - "AB8FF4947460DD96F0F8259FC6001059C998D2EB6902C064F9AE08E6CD3C7807E5037" - "9507B41620D15DD76C0B1E7ED9417EFD6825959B5077F464E6429A4DEE467A1BA2B05" - "D38049912D5539F1EE9F5D8A569AA1C384384F847ED64F6FFC101036DA70E69C06E49" - "16493E82E9FE3F65D85254C8C14F6CA0579BFB3EAA86B2D7BB5FF572ECCFD70F2EA46" - "95F326BEADF241AE4311E428C7C12A0D4D1915CD0537FF0F62CF13EB2FA21A8004BBE" - "6B4B60DA9D9BC34DCC8502FB81D8FD5FDBC8FA89605C86205F2B8C6530FF64C8C31F5" - "79BD8ECA603DFD5E397AC35E48931FD330351D01361BB31CAAA7DBF816A6144A12B6C" - "22D1DCEBA20669ED635A40831066ABD8071342119D7DA11C43696B2898D3DF3B36BEB" - "8DA013D9DC145343494B19D6DA085F4A41E421D3DEF2AD8B72DFFFFB6E79BBCEAF859" - "4045D16A62EED16904A3569860C531A32EAA5ABB868B1DD6A0B03D69C1A3F8336AF80" - "EB80BADBBC7B80CA5943BD5B374302147052201FAED30E9FFA99FC00B47F7EEB46951" - "2A413E873F91D959CCCACCCD3585B7F00ED8D4685022101713C3ADC439F27512A4592" - "6C1D2473477662C4BACE72F380D105DDC9F7BE49ED71991B3D9E29A2038201373F98A" - "845A57624A692F44EBD316D26C48FEE82B655583317ECA4AAA4DAC841524A2DCA1117" - "49629637EF29FA7E72645A875957FB3D98A5E6C8065B1349CFA23011CD6349D911C53" - "5475FED50BE9EACB6A1FF3EA7458823F0229F2FA90B7A7099E8EC349D3D0FE0277CBA" - "5157CA62C8FBAA893F37B8C8CEA2A0D2D2912CACCF92D31AA17439479711B4A5B7744" - "5CC02C18BFE0195CE8F1FE59E317214005CEE5E25904C9FB0AF7E2B6B4DCCDF78E61E" - "179A9F93996EC3C76F6DA9B5A291BF08A73032B37EDCBBBDD20CFF94088A489167C56" - "E5E75B376874E9750212FE94D7656D9CD835DB3B771BA5B58D2B255221C6B73696438" - "35346338613630613561353437653132326332346663612A507D2B905E5EAFD4B28AE" - "EB7633283579E48ADD21A68EB26CC8C3B2E344579003B12A38554336305525FA6AB70" - "F024A18C73631BB1531ECA3F0782C72DBA017311B3F1E98C739632E305E4BC0B2561A" - "E2B30050AC1050A1B5D637BE37A9722AA35C23D346470851ACA7D2EDCD1A27EDF124E" - "A612C001BC96D6878E3086C33624821F1F3ECE23F27E58222C2BB8D1615476A117926" - "3B58F6427E92911D961FC7A3AFD947AED8C9AEAD1F08457925D2CE4E0F618B21942BA" - "A60B231EAE864048F94F74FFA700E5777F812ADB6F0CB6BA6F0D145E3951191EB2171" - "40C32F2C7565053222131FF823BC36D80B24B561CCBEA9D397FE00942E7FF73B8152C" - "DC083B63A9F9C4A77056A0D79F44F267DA0ED629D9C902F7E838957EA41AA442221C3" - "AA9410DB58302B468C6D7F2113663809F0DCF187C108CED1AD402F6FB3693413CC1D7" - "D5E3459B856E4156C78F8D85D548939FD00474C8CDEDC46835CC981758500FE61CC79" - "383B4D9F87C3E33D19C2D25D7D15DD0F3D2B1AF4583B71E90C59886D297E78E929C2F" - "3840C82C626914A4EB537B3A5161D963472B6592C0FA1E415556BC009C2DA22BCF743" - "AC434E22F8A33B43210DFD8AA09FE86105610F366E6FB7DA18996CF7C7DB425A9BB50" - "E4A13190A680B9F82D37D09658585ABE3BF9F009A5C1CE38A7CEFE17F71FB402768B2" - "D66B4CA523ED06729349695D7864D7CF7A1CC11D0DA2B8A43DB834D10B47D9579EC9E" - "46986A133277B92C636CB2A6A823AFE73317266C9C0601DDBADB76E1D254D6183B93A" - "1EA91A7E6C567331B3EE3A5AB1484AF91FD0F8DAC5FD980A67D8F33CC1D6CF20EE4C2" - "4582D03967ED48B6F28E7514E4D18F38C8CB1E54FBA59AF7D6A79C6C5A7AB06BAAC96" - "4C7958D201910ADCA018022FBEB8535B64F5CE83D3C22246B73696432663265383563" - "653861363737663630303437643730323465303762356165362A60B74880FBDDC5BB9" - "DB82F09BC7DE3FFD95A0A671B979D4C1F0564EAF63EB6B5A8C3F16D9F964AFBD011E2" - "326F9C27AFBE74536F3F0601A71D9C1C422F335611BF3BF1A1C89E2DEA27C17A9D9A5" - "8A74121E840B002E8A6FB59007245BE786C1F6430090AEF040A1D1FBF0A1D2432805A" - "0F8292FF627A9A7C60B733A51B365892C832261D7112C0011AD116A26F423C7019FA8" - "DCA226C2D2BDEEC91BEB1FD38D6890E32745A4DBB9409B65FE834C2522D92621B265A" - "9D526B4FCADCACF4C4DEB364661118494FD1561621392BF4450E6833BE290D49E59E6" - "65A031375EE56AD1F3392436BA213ABC5AC10A199E73123F84F7644282137DA24CBDE" - "30C10A6EB847CA72B8B311AD329D2C9CB0909C2ECBE3FBAF88E81BB5AEAA6480FFF67" - "E8777FA00C783AA160F1E211CB9BF3835FA8F82923C05895C359CF306F5CB90A73B8C" - "E2CE9ED210485E1C571A82020BF120627D01690D14321FA967D81997B959B35ED7745" - "DEE9E885DD402DF83C3B8F52999B16C2D1D47BF4724A9CED984175EB8A032D613294C" - "14802074154C34FD40FE6EA74FA830FDCB9CC7E0799A75AADAF41DDDA3D0038896DA9" - "66B1A67FF4E6C7403DEBFDBE7D1D48F1A3304124F04C974BFA0EFF4D0B1733A84AA6F" - "89EC74C89DAD2168DA4706F6DFCFD980502B573D0F7B3791252CC918394E8B3A3E1EF" - "37CE48B7FD6A2040DB5915F55809F284CE4EC244149F53038B432964705E26C3BB653" - "5461B7FFF27AC8EFF679DCE8E5BFE1D000B69A22D9EFC1F310BA2F0115C96B00BC158" - "88FBB3EDD230834458491EEDE2440550DD59C613DC8433EFE979C71E9221A6B736964" - "613564323764376230636364343333323033653135372A681BE7CD47CEFDEF6957634" - "8EF9A143BE2311041A5F80259938FA8861396794EABCC985A695BE2EF4A8361D86979" - "859C490922D92D3ED0484E1666270AA96388BF6BE3C4F4F0B7E2F59EFC6B8E965D8FA" - "DD5AB86B2BB816D2573EC36EB42B571297681BE152D40639D3000122076CFC9DBA6CD" - "93FFC6BB74D61C1B644CC32121553C50817A9F6F00633575E659")}, - // test vector 7, app id: "app_2", usage entry 2 - {"app_2", - { - a2bs_hex("8f922e955b269458ed1345bde9a24516520a536817e8e8612154a1"), - a2bs_hex("d4acc596a52055cee710e1fec44796dbf3ae6b017ab156d9bff7bfdb8f1e" - "6352bfbe453034968f940c36ac18800e22bb2ff71268053702ef3fce3fb2" - "d607a078e0d1449fcc9d0675d41b1a65f78e3c02370d18112aae1e2577ff" - "9087825a45125db5dee8e27bd14ea8666b4e8e6aba6811c40b585aabb9c9" - "185209a48d11130ff690316916961f28286c71c3e985d7dc3352166e414b" - "89da2c17cc5b69fc9c00990697f5"), - a2bs_hex("169d3c432f9c2f8b99e11632bd7d6a63f3d57679c567bedcb2e596ace105" - "0453732040cb468e9c43f6009b430ca4a4046d017e67a4badd5b71c0c9fc" - "e2274817f0bcda311a4f8703e6dc32aedf30e6f9abd40e249fc8b0a5045c" - "c1e47e60a60b4893ef92602f5584e1162f4ff3ee6d906228f97b442ace1f" - "b175d113b671bdbe4ceffdd98f2bb094c0dfac03b79541a44d8affdc987f" - "4268706b5a554e998907eb7126e8c6bc07c837d8aeebea3249e37b4b7dd7" - "327300fe7e62c15981cf73a13e806d065bcadc2c747256907a5493592b07" - "a0c07f9cd805fcdc0d30f70e4c4b2959a0f52385c6bd3e6eeb4e3d81fdc1" - "a9dc3c76faf1bfed913d58567fa9b296d27dff5217c583e7c134a642601f" - "8237"), - "kside684918d6c39bfa652a40ad936", - a2bs_hex("703f69807c8f4d140168874b924a625132eb3b896a381d617b8fb83c7314" - "a6b634d840925f711ae330599f0e0863800902b05d201a8a87b88a4bc170" - "65a1a8a556c34bf86b53afcc9951be15bea9ab55"), - 27, - }, + "7290396E183156BDF830B7BF31BA762CB2675528C9004FD24A61DAFB587ABCF1D36F8" + "7795EE0B3DA0B425616A66C82349B2E3BB8841C1335536865F919ED2AE671487B608B" + "21A362D888E0AB4F7AB7175B82F108617C3503F175435788AECAF7FFBFE76995D93CD" + "79424A843A247A8D8A6054A5B5404C9C057AACAD91A203229"), a2bs_hex( - "0AB60E080310012AAF0E0ADC040A1E9212A6926F21C6727C1EE89D5607047A1636F20" - "6F70E21FDA86E01B6A4B512A401EF947ABED64078EDF5B21FE6D3FB65384595D63A6D" - "03E4D1D397C5019DEEB6890D3EF8773002B91E255AF0820FB594069DF55D8ABF96498" - "E493F5C70F6B85F50E12A1ED3C039AD0CD838FE44D3FA9E2BBDDEB2919041203111ED" - "7778701B04D6B15F41D0BDE799E20A38B27BF96FDBE844F10364BAEB593596220993C" - "608AC793DE76C237CA350931A7E216538074DBD83DDF262D9F18ACD91E1EA5372F7E7" - "73C5B643331A9A027709721B3AA48597E88C99E82EAF7DFF07E87E0318D9D7CEC2909" - "6EC591826AA7A359316D6DE1D1329B408543E237DE84C986987EAD1BB6A0C38817E93" - "013E5C989D366F49590B834453EC64B7433BF0B3335B9E222BAD4CAF554D69575C585" - "95283166FEA42E89645FC7E2D3AC9E0C1399B096CF3FED1E5DEB1BC4E0EE894F0AE3F" - "929DD7DBA4530E5655EDBBF6041DF430482EB2E891B6A93AF84D3C16DBAD92733FFD3" - "4E8F4CE24506BEAD578D20CD3E291C2FC2F811DB875F49ABC21A24277D2BA474FE6AF" - "6C14021CFEAD5513E0999E094020CE08209BBC08F13FE2B96D7BA8213C8E9C85B6A62" - "3788D34DA794E17E4CD3BD65680B97FB30BAD64DDC42B1BCFB0B83E5DDA3501A5902C" - "A609F41837A0D5CD096E0659B67C221A6B73696436326438386564376232393232313" - "7623032333862652A585422463FD2E4DD47626E97DD6B4EE0B89523AAEBE8D11E7E7B" - "E703EF01E49B17EAF020CEDE0A9E0E7B5D91E4DB7ABDCE445936CB2DEECDEFEFDB14B" - "78F67B7CA5C733C9E88446FD814584584B86BECBF6EB2B0E3D5603E8B30190AFF040A" - "1D831FAD51E52A403524539EAB6A1B201E46674CA3B9167B1C1B53F5E5E312AC0136D" - "83ACBC5E4ED027ED583E3B2169D98F4ABEDDA15B781408E68EFA14FEFA9F3F0309BCB" - "5A9FFF6580636EBE3548E5ACB43B76CFEB29A9C86324E62AEB40556005C6686E718F9" - "BF61B0681D43B5B1E88084B3AEA27A6B0E844E5500B6FCFACF2EE44D6AF7F64154AB3" - "FD4FBD0B8056CF63971076A1EB3642B78D5E76B84F4ED9F6220089863F8A4911691E7" - "9FEFFC9F804C4C36C7F85E45B1D276C85875875267EB65DA70FD2D5E9176D69141AAC" - "02317BD7063BFB9FAE1B2E46F4CF15B7BC8C92517FF5C32CBB52AE4B67AFC5D569CB6" - "6A462DEF7A18A7D0ACEBF9F6E8A604356ADE2C81450C5466A472890B03EEFCF65388F" - "060E24551C67B7D46AE5D4D841D5CC63D137FD543FAE2C771756590B90E480CA0126F" - "1FC0090ACE62499E47569FC52196C788F80139755BDF12A7ACB29FD6E23A46A4C036F" - "04FF1ED6CD714094253BF1C58762C93F0DDF8A73C4BE927FFEC2723A16D8FFE512885" - "1F58537461275F6AA1976E3B399B7243919207E040EC16C5328E8AB082278FCE0E5D3" - "DF5C5F92DBA51FA6613587D4ECE31F2C001B49BFAED434F9512E895C2E09C88DDBF18" - "4BFAFE4D82E5D05A26AC06CDE29FAF6AB05B96685649C923779CE5EF7F316531ADA8E" - "74E45AB1DC1D75648AA2DE052674728867E87639FF9B782A3322186B7369646531643" - "3306233336235356632646562343731362A64D44A9D70A7C582559F089B1C0FDFCBDA" - "F5E26B672FCA5D58E889B407A0BA8599079CDE11FADFAB23AA1B97622839F3B7E1A96" - "F8332BEC5FBCBC9EB64FD5ED05887B8FA3BFD6ECC7BC91E621342732062D2F4411B76" - "3E20328AF6F8EF5030E2F8027AEF9E30060ACB040A1B8F922E955B269458ED1345BDE" - "9A24516520A536817E8E8612154A112A401D4ACC596A52055CEE710E1FEC44796DBF3" - "AE6B017AB156D9BFF7BFDB8F1E6352BFBE453034968F940C36AC18800E22BB2FF7126" - "8053702EF3FCE3FB2D607A078E0D1449FCC9D0675D41B1A65F78E3C02370D18112AAE" - "1E2577FF9087825A45125DB5DEE8E27BD14EA8666B4E8E6ABA6811C40B585AABB9C91" - "85209A48D11130FF690316916961F28286C71C3E985D7DC3352166E414B89DA2C17CC" - "5B69FC9C00990697F51A9002169D3C432F9C2F8B99E11632BD7D6A63F3D57679C567B" - "EDCB2E596ACE1050453732040CB468E9C43F6009B430CA4A4046D017E67A4BADD5B71" - "C0C9FCE2274817F0BCDA311A4F8703E6DC32AEDF30E6F9ABD40E249FC8B0A5045CC1E" - "47E60A60B4893EF92602F5584E1162F4FF3EE6D906228F97B442ACE1FB175D113B671" - "BDBE4CEFFDD98F2BB094C0DFAC03B79541A44D8AFFDC987F4268706B5A554E998907E" - "B7126E8C6BC07C837D8AEEBEA3249E37B4B7DD7327300FE7E62C15981CF73A13E806D" - "065BCADC2C747256907A5493592B07A0C07F9CD805FCDC0D30F70E4C4B2959A0F5238" - "5C6BD3E6EEB4E3D81FDC1A9DC3C76FAF1BFED913D58567FA9B296D27DFF5217C583E7" - "C134A642601F8237221E6B73696465363834393138643663333962666136353261343" - "061643933362A50703F69807C8F4D140168874B924A625132EB3B896A381D617B8FB8" - "3C7314A6B634D840925F711AE330599F0E0863800902B05D201A8A87B88A4BC17065A" - "1A8A556C34BF86B53AFCC9951BE15BEA9AB55301B122002206F46D9D05740AD34B99F" - "10C21A2FA23B8E45DCB00713E32D5CECF239D0A8")}, - // test vector 8, app id: "app_1", usage entry 2 - {"app_1", - { - a2bs_hex("d0b9a07ad7ffeec13784bd60da011be3589f3e450227fd36b1a3f6786cdb" - "fe8f"), - a2bs_hex("a419c5687a592099dc67da8bc4f5ef238c80fe4ce3e2fcb025392efb1438" - "4b581b595a0e8fa95de637fb2184719eb36ad6539ee9df0f67697f91d018" - "6e04552e811196029cf4e256518ddf3215af8ec61442c17d6753b93f9d3a" - "9240bae39bacf5563659cf47d3a611ce20ed3ebbf86cddad60cc2847c459" - "5dcfd934d012ce205960052158461d7c5d480de2e597876e64e8f8de6928" - "29a3"), - a2bs_hex("f7c19357e50fc474437c1a635c5bae8f6f51afa20750766db19457dff7ae" - "f2cae78848a225cc6a088bbcffead5be6aab6fc8af091bf459c3bd9bcfa1" - "8de53ef76db1b4826cf0b8ff7b2d7c44bbadb3cd7aedd8f639d1f38c52a5" - "8611a9782aeace72be69a73d2e091a1120dc63f7ba6f1cb6cddd69e9a236" - "232ed8c14cee665756ba51f1d2e2530ab3662ce1b6efba91c5f10c53abc8" - "86d6f25b5dc40417e54270843f3b454c8c047fc366249e30379b0fbe0174" - "fcab8b8405ae7f20f6f2b81f11082ff0e270b75f1e1aa7ed5806f4e65b46" - "b872dbcb703d7bf20b9ecaa481425a5218d85a49595f3ed268d61f1be8e3" - "8e6126eb075fa6b7ae80431c8521c4bc2ce701e45d33bfca9a5b0b66b550" - "aab21eae41f84cadfd2517dee9a2c139ad475c387d25"), - "ksid321bb636f8a3f5cd5d54a236", - a2bs_hex("c3cb027611397b5d70cc0b08e0f5249cd19996da674e33722902173d45d7" - "09914a3d7e898d93170317bfcff34861c0d687048cc93542a75a2c99b232" - "3fafea1ee0c3e3d24edf2633"), - 7, - }, + "3478A2D76DEB90BE713B03A11037EA7C305D1AF65099E3F2B92C4D4443A8F481C1177" + "DEF0A3CB49BA5F1448A10AF1207AD2D361B4A1F961B4B1F215B76A9A5005B414EF45E" + "AFBCF2636ABFC01413B27DD11871103579F8C041A799E22888D9ADB798E92A5E29BC4" + "6DECBC90991C65FE151C49F18068C1B65D0E90A9ECDA9248B87C120D5FD8EC81D4D36" + "B529FB2DAD39E0D39578B13B158E2B07C752D86F1A9D8160C93930C1F4F9E1D0D8E2C" + "5AB308732EB27722A6BF8BE852624C2BE3E4FE85819B89BEBA6535FCFBE85FA63A57B" + "D0FBAF284C64FFD97A146B76B3F37B576FC091C03E2222FBD24C2211344B7E2417EFC" + "36C4A54DCCC460CF810E7EA8AC6386D6AB567C819FED88A22CE55EF9BBE62C2CBC7AE" + "EDE5E5A69FF3472418CE2F4514496C59D26E72F3BFE0131F"), a2bs_hex( - "0ABD0E080310012AB60E0AEA040A20BB3370CCD3C3C49573D6B74386D1886D9888BD8" - "1FE3241BCD2BAC9407D1A834E12C001DC0E51CFA5863F6C0B32A4AD7FA40625DADCC2" - "DCDE9E7FA3983B8804D9966803181682FC8AE831472E0B2FC26276242FBCE624D286E" - "EDECCE5555804913B4F8F86C5AE86160B8434B109169A63DA04C5265102D772C11805" - "43EF226D2140357ACA6CF87DA3F7E370DFC08CA92A1F7C7D314EAB36292A91708F6C6" - "AD84B37EE1C7DFAFB99289206CB752D063F330EFD85885F4B72BA1CA5823EED865A46" - "1345E3D6417872BF3B0608B3D9E1004C11E7326D3ED406192E13455D0EC4E1F558A14" - "71A8002F42A68CA3A14FB68F5992E4519F57970C3DAE73F8DA1D5B0B1DA3EFF7A9540" - "12A0DC634357F3F5477A820E182182F24AE8E835AB10C18386CC8A0727D3F38B62863" - "9BFBD69A94D4053EAB1C31E075E014CC578B226CFE24D6B42DB242972DEF8F23A4AAE" - "88451307C2ABAF54C1803AE54E3F1149AA6E6D4288CC7D474E876BE07954E8B2DEFF4" - "ADE4BF30229FB6C92DF4D66CD463F686B4754B940210EB59F1581D658DDF8DE8389E0" - "E2D123E2CAE3C2BE6EB1948CCC896DD4CDF45F9090C96DFB925795CFB4CCDA83E3EB4" - "F745577B17FC166BF5F4103C9085134CAD7863A41B04F32EF20201E54B55F1817CE58" - "9619B096C254FD2C2FA4A06F4DE35CCFD23E221C6B736964653131313039626632306" - "3646535343430383365663465652A60EA106C124476B753D39368A5966972A2729BB8" - "BBEA734A2B3E812B705EACE016C8A03C9A406094D80059EF4CA26F1928FA2DAA5DE9A" - "6F22372E5C7A941E610D1EFB56ED7CE2228A70E2E150AFB66EDC2DA066D463AA90BA0" - "CAFF078FBFEC05C830000AF5040A21EACE80E30BFDA213F1CE4DBCFD9D4D24B8E2AE0" - "0054D167D9D7AE99547062B911312B40168A7665A21348FC0590328608DC520BE40F5" - "B749328568FE383EF69C1A587AB2446CF9C41D821373D0856A883B316519A42218F80" - "E7BD5764D16BAC9A9B427A7278F5940E563FCF6DEE0FF3AADBB702EBF2C54EC354AE7" - "ACC84EE6A54BCA1F30E38EF71C44A81D0009B1484FEAF4F1A56F58C35BB2372C80C6D" - "FB389E6DE60BDD3D46C03975715260F6FDBE42FACB64C22EDA9635C04DA79434E1C41" - "FBD2FDBBAB6598283226C0278E8E0A96D780D3436523EFD11AFA01FF6FECF71578288" - "12A2D6DCB15383A6D9AF4519EF804C6053A10C436002DE3A4EFCC017755F4AD1101BD" - "C813E2D211732418DEE529CBB413C48AA5884C76A5C6F556A715055560D4247F5BF31" - "0956949A3A171A4AA608A48446884E7676D558FF64D392B84E617805693D90F1E9B7B" - "540C383D384D7F7CE06C23618681BD838CEB1A514047F1C562C43159CC5E21588FBFC" - "E8A354111160F1A1E2BD3D798A000579BDFDB977252809EE1502DF8045972FE8AAC84" - "0211C2F8D9E4D5BE18509C327C647D654C4B6CC430B98F1FF37C96FAB087FB561B8CC" - "18480F877C873594D3148FF74B0E3C6327C27CA876DAE7422398FC5E85269CBA49AD0" - "99221C6B7369643865383033353063626566363436336130303235653663632A7C7CC" - "C7CE96055E16A52FA192EA2CF3C9DF3E89B9133A52286F71E6C6D82D0435F6B2155DF" - "DE590B347D8C86F62D7DFBAAE640C237256F609E5DA9CC6C103465FE3441612BBDFDF" - "4D1C24B2147FEB8565CEF4993E439C9D564A39A4AC5BB1DA69ACB44DA06E4522C9A93" - "D310CDDA5DAC1E1E0B91ABFF41E4E2EDDA400130070ACE040A20D0B9A07AD7FFEEC13" - "784BD60DA011BE3589F3E450227FD36B1A3F6786CDBFE8F129801A419C5687A592099" - "DC67DA8BC4F5EF238C80FE4CE3E2FCB025392EFB14384B581B595A0E8FA95DE637FB2" - "184719EB36AD6539EE9DF0F67697F91D0186E04552E811196029CF4E256518DDF3215" - "AF8EC61442C17D6753B93F9D3A9240BAE39BACF5563659CF47D3A611CE20ED3EBBF86" - "CDDAD60CC2847C4595DCFD934D012CE205960052158461D7C5D480DE2E597876E64E8" - "F8DE692829A31AA402F7C19357E50FC474437C1A635C5BAE8F6F51AFA20750766DB19" - "457DFF7AEF2CAE78848A225CC6A088BBCFFEAD5BE6AAB6FC8AF091BF459C3BD9BCFA1" - "8DE53EF76DB1B4826CF0B8FF7B2D7C44BBADB3CD7AEDD8F639D1F38C52A58611A9782" - "AEACE72BE69A73D2E091A1120DC63F7BA6F1CB6CDDD69E9A236232ED8C14CEE665756" - "BA51F1D2E2530AB3662CE1B6EFBA91C5F10C53ABC886D6F25B5DC40417E54270843F3" - "B454C8C047FC366249E30379B0FBE0174FCAB8B8405AE7F20F6F2B81F11082FF0E270" - "B75F1E1AA7ED5806F4E65B46B872DBCB703D7BF20B9ECAA481425A5218D85A49595F3" - "ED268D61F1BE8E38E6126EB075FA6B7AE80431C8521C4BC2CE701E45D33BFCA9A5B0B" - "66B550AAB21EAE41F84CADFD2517DEE9A2C139AD475C387D25221C6B7369643332316" - "262363336663861336635636435643534613233362A48C3CB027611397B5D70CC0B08" - "E0F5249CD19996DA674E33722902173D45D709914A3D7E898D93170317BFCFF34861C" - "0D687048CC93542A75A2C99B2323FAFEA1EE0C3E3D24EDF263330071220B174821B32" - "5B0A6A900AD8C660C755D3B0273CA6E81D70E2C548CDEC07BE53FA")}, -}; - -DeviceFiles::CdmUsageData kUsageInfoUpdateTestData = { - a2bs_hex("b8e7f26b6b83d6b74386d1886d9888bd81fe3241bca928f09407329814ae" - "5a82"), - a2bs_hex("4463dc57079c27e34ae115c6f65b08f6311c4ea604a6512c42470b6f692a" - "6803181682fc8ae831472e0b2fc26276242fbce624d286eedecce5555804" - "913b4f8f86c5ae86160b8434b109169a63da04c5265102d772c1180543ef" - "226d2140357aca6cf87da3f7e370dfc08ca92a1f7c7d314eab36292a9170" - "26eb30165372d538b551ebd7bae5cf0bbeebb3cdb6f180d42868051aab8f" - "e50379507b41620d15dd76c0b1e7ed9417efd6825959b5077f464e6429a4" - "6ffc101036da70e69c06e4916493e82e9fe3f65d85254c8c14f6ca0579bf" - "2a0d4d1915cd0537ff0f62cf13eb2fa2"), - a2bs_hex("bbe6b4b60da9d9bc34dcc8502fb81d8fd5fdbc8fa89605c86205f2b8c6530ff64" - "c84012a0dc634357f3f5477a820e182182f24ae8e835ab10c18386cc8a0727816" - "a6144a12b6c22d1dceba20669ed635a40831066abd8071342119d7da11c43696b" - "289d3f38b628639bfbd69a94d4053eab1c31e075e014cc578b226cfe24d6b4272" - "dffffb6e79bbceaf8594045d16a62eed16904a3569860c531a32eaa5abb868b1d" - "d6adb242972def8f23a4aae88451307c2abaf54c1803ae54e3f1149aa6e6d42ae" - "d30e9ffa99fc00b47f7eeb469512a413e873f91d959cccacccd3585b7f00ed8d4" - "685022101713c3adc439f27512a45926c1d2473477662c4bace72f380d105ddc9" - "f88cc7d474e876be07954e8b2deff4ade4bf30229fb6c92df4d66cd463f6848fe" - "e82b655583317eca4aaa4dac841524a2dca111749629637ef29fa7e72645a8759" - "57fb6b4754b940210eb59f1581d658ddf8de8389e0e2d123e2cae3c2be6eb1943" - "ea7458823f0229f2fa90b7a7099e8ec349d3d0fe0277cba5157ca62c8fbaa893f" - "37b8c8cea2a0d2d2912caccf92d31aa17439479711b4a5b77445cc02c18bfe019" - "5ce8ccc896dd4cdf45f9090c96dfb925795cfb4ccda83e3eb4f745577b17fc199" - "6ec66bf5f4103c9085134cad7863a41b04f32ef20201e54b55f1817ce5896195b" - "376874e9750212fe94d7656d9cd835db3b771ba5b58d2b255"), - "ksid854c89bf20cde54122c24fca", - a2bs_hex("7d2b905e368a5966972a2729bb8bbea734a2b21a68eb26cc8c3b2e344579" - "003b12a3855016c8a03c9a406094d80059ef4ca26f1928fa2a3f0782c72d" - "ba0e2228a70e2e150afb66e305e4bc0b2561ae2b"), - 6, -}; + "C45FDCB3296A0EBE24FF381E027E6E2EF1AC289C67D3B858330669A81E8131583D2F1" + "40FD64615BDED0ED8316ABFD9C7E887433E1CAA6EA8E0C4F87ADB2A7FC3CF6FF87A7F" + "02AFF03BF5DB640AD8DDB572C41532E673618DCD8C33EF2BFE4E25EE821DF7D742B09" + "90398543B16EFCDBB03C6327B79D3664CED442E894020F4410ECC178C92AAEDFE39DC" + "563AC226FE9E0EF22E1C896C4F2835CDFDCD50B6C4DBA2B27A3B65DE3963D0A5F6E44" + "2A3C32008AB9D1ACBE4F366990EB43F8EE213B71E98DA090282680ABDD649BECA8970" + "0764561379F1DD23490CE967632ECA349AF8E1CBFA1F3A4F39F453614C8FFB5A17975" + "6243CB1FDB515834229BC64917C47A2F2E1116FAAC13368015312C31FD41215106469" + "BEE77D0EF2FE10CF645B3E82902EAF53A676933D0EC433949C1833BE52E76602CC3E4" + "E784C002E20624BCE0F38F9CBC478439899DA7F15554D0ACADEC140C00C8FA8FC9886" + "2D9933938781B30CB9C76899B3A48DBF170DDA0A18ED37D77F048ABBC85CB19469638" + "C2A32AA3180CF3943BD6B8C5CB26F2EA70868F18B0707C882054141086997A1AE5B70" + "9D4D0AA2B358990F244BA76C8E40791D29A0C63C9EF620B97FDFFA9B671E5A65AFCC1" + "C94CAACE0443E9D91F14028935BEA3988831BEBBFD3EB7C3A5AC9605B3534712A0912" + "4345ACB09665E357E58946871BC140D365"), + a2bs_hex( + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021" + "22232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"), + a2bs_hex( + "0ADF0E080210012AD80E0AA9070A8001924B035FBDA56AE5EF0ED05A08DE7AECC8ABE" + "1835E0C4A548F7803937F4C3B4520EB7F3334FFCDFA00DE56408F09D5019FCE87072D" + "0DC6789817468974B2EA51EE3944B8D7E0A88E4F16EBB80F03BD845231A01E6146841" + "CBAEF0134DCD9300DB2D92732992C0F2310D8E386FB31C67B9477010DEF9D99C42725" + "89572A26A17E12AC021E6FFBE66FC6153E7749906EC8F684E819467E16CAF317F315D" + "B32B6D3FDD1A8E8A094174D92D063B88E4835EAB78BD09541EA7FE72F132EB7364E15" + "4BC1548FC40EC7092775531508C95F9ED5D76F36BC0C198C3A33A1F9415B343905D6B" + "E37645E6800F053B1DA9A20286EFCBBC320424ADF7FB6E3D5D8E86C35E576A1A2A37D" + "344A419C0F0034A1B5F767D3C61D90DCA1119E5024C34EDE8FA7DD128696D8C435410" + "F218E52A853AD214FD05D0F8B3CB4832CFCD97FE159E6DEE64CE82CDAEC0321AE71B3" + "BCBAE42DF9EA65E42E151827086EADE71C138B972CC3992CF9ADA944C063816352ED8" + "658D3FA07BE0F32239E74A65932B069AAC4E8386DB59154AF9AEF71448128C66E5104" + "45294F44E511BD9B1AF19D4D67E99363093BE888D4B2AB841CAFF252CAD13EDF8E1AF" + "40340FC62339728520E6C0C09907C26F3FB78287231661952A8B699E47AE241B999C0" + "29FD2067836DC4BC64F66998A3ECD197DAE36F808A2E5A4C5BF25DD580E52B1C39A8B" + "03772BF82D58929766F2DA04F0E616F92B3A0EB75661B8FF5DE1EB807C990F9E6BA99" + "1C8BAD5EB63B37E8663A4E22AA9DB2015D3DF8BED1C8313F85F13B9483C7A39C59243" + "6C8B13C23F78F55CE812795335059F7F527CA580306A0AEE5A6D957A91F498F64AA2E" + "FC6780716400E17C7EEA30B2E6523B902986995E003C2D919A7DC7C0122CE9410037A" + "6602B59A63B5C89473D4E02DE35C1F01B12ADB48A3D94D43693F08268FECCC78DAF6F" + "4C35FA32C538CD73FBF3CEA274B01179C02473486311956E5A0C78E44C59B2F34FF24" + "B0653A6379A2F5F6F51467CAE26D55CC5BBDCFC9BCFA7B8C5CBF82EBE7BD340C3DAE6" + "374D0692052C529AA33D7A6799C8F1F59C78575E51F707013026CC4F83F6B3328EE6F" + "B1AC91929A4491338E93D10EE6193014A73BA241A9A833EA835217894EB4FD4BDB890" + "4A5999928325D0AC31B6D58609EDD9D85E88F74B5BD6FA7BDD83C51EEB91633ED267A" + "CA2E103904BBE4C031A6483858FBAD74DACD01711F7B882749FFFBA0DB6C7D7109D82" + "989C7D4DB5A0F1E7506AC24C89CECAF231EFF99F96AD76E57DABDD3C2DFBA7BAA869A" + "771F561B165987E552824B0C914E708E425C30AA9070A80017290396E183156BDF830" + "B7BF31BA762CB2675528C9004FD24A61DAFB587ABCF1D36F87795EE0B3DA0B425616A" + "66C82349B2E3BB8841C1335536865F919ED2AE671487B608B21A362D888E0AB4F7AB7" + "175B82F108617C3503F175435788AECAF7FFBFE76995D93CD79424A843A247A8D8A60" + "54A5B5404C9C057AACAD91A20322912AC023478A2D76DEB90BE713B03A11037EA7C30" + "5D1AF65099E3F2B92C4D4443A8F481C1177DEF0A3CB49BA5F1448A10AF1207AD2D361" + "B4A1F961B4B1F215B76A9A5005B414EF45EAFBCF2636ABFC01413B27DD11871103579" + "F8C041A799E22888D9ADB798E92A5E29BC46DECBC90991C65FE151C49F18068C1B65D" + "0E90A9ECDA9248B87C120D5FD8EC81D4D36B529FB2DAD39E0D39578B13B158E2B07C7" + "52D86F1A9D8160C93930C1F4F9E1D0D8E2C5AB308732EB27722A6BF8BE852624C2BE3" + "E4FE85819B89BEBA6535FCFBE85FA63A57BD0FBAF284C64FFD97A146B76B3F37B576F" + "C091C03E2222FBD24C2211344B7E2417EFC36C4A54DCCC460CF810E7EA8AC6386D6AB" + "567C819FED88A22CE55EF9BBE62C2CBC7AEEDE5E5A69FF3472418CE2F4514496C59D2" + "6E72F3BFE0131F1AF403C45FDCB3296A0EBE24FF381E027E6E2EF1AC289C67D3B8583" + "30669A81E8131583D2F140FD64615BDED0ED8316ABFD9C7E887433E1CAA6EA8E0C4F8" + "7ADB2A7FC3CF6FF87A7F02AFF03BF5DB640AD8DDB572C41532E673618DCD8C33EF2BF" + "E4E25EE821DF7D742B0990398543B16EFCDBB03C6327B79D3664CED442E894020F441" + "0ECC178C92AAEDFE39DC563AC226FE9E0EF22E1C896C4F2835CDFDCD50B6C4DBA2B27" + "A3B65DE3963D0A5F6E442A3C32008AB9D1ACBE4F366990EB43F8EE213B71E98DA0902" + "82680ABDD649BECA89700764561379F1DD23490CE967632ECA349AF8E1CBFA1F3A4F3" + "9F453614C8FFB5A179756243CB1FDB515834229BC64917C47A2F2E1116FAAC1336801" + "5312C31FD41215106469BEE77D0EF2FE10CF645B3E82902EAF53A676933D0EC433949" + "C1833BE52E76602CC3E4E784C002E20624BCE0F38F9CBC478439899DA7F15554D0ACA" + "DEC140C00C8FA8FC98862D9933938781B30CB9C76899B3A48DBF170DDA0A18ED37D77" + "F048ABBC85CB19469638C2A32AA3180CF3943BD6B8C5CB26F2EA70868F18B0707C882" + "054141086997A1AE5B709D4D0AA2B358990F244BA76C8E40791D29A0C63C9EF620B97" + "FDFFA9B671E5A65AFCC1C94CAACE0443E9D91F14028935BEA3988831BEBBFD3EB7C3A" + "5AC9605B3534712A09124345ACB09665E357E58946871BC140D3651220464E4A1BB23" + "1A5B0287888B34CA0A8CF5396EB2B8313377DC5ED5C41A9B389A9")}, + {// 3 usage info records + a2bs_hex( + "983358221FB8DBF892047F00AA661F217EEC4E7A1626E8F98E025509E4D65A685E7D9" + "B169B98B16934F6E43E0E0E854A3FA9EB8E9A9D08E9D9B3A6C766AA44F7C655879BA2" + "DF5F38732FB7EDCA66D8C13A855B15E32CC9389B7DD119BA1F2417825FF1F52970F8E" + "985D34DD353D2AC8B24267353E5B8406C098427C4559A90CC"), + a2bs_hex( + "483EAC68243092009D06FAB41DB594ACB22E068C9524810758ECFF8BAB7E1B1ACA988" + "C3987023F01EFEC11529C7326279742E805E755A08EBBD9AA322F305805BE1166AB45" + "CB156FB0A9E6734371F4028707EE01CF2FB08465707E7E5613DD90D74B0D02536E26C" + "F1261CDDA8713943F3620ECC54095C76F8CD3CE31948C3CC0C9EB5582A4D087A54B39" + "1B4CDCBC98E35830B5932F6CF8D16427EF115CFF0A99499513702DD54C758E53248BB" + "5D195F2A2DD1DB18F97562F1F9034E223CEDB1E09ED1B0FE26089C20ED43B5D87B51F" + "6FC6C9F86255FBF70DF233F2665D604355BF9740A3B755521102E0B485C5CCCA607A9" + "A1BEB757BEDEF12327C637D17D6401E3756719F99BBE69B9CE4C8E47C2AC771F35A8E" + "E3FC4D58B2B2269CF85728E4DA7231BC8F0FD7C50E2A1EE9"), + a2bs_hex( + "5826D3A95F78879292612BCE06D845D64285CD45A7EAA6C87A9DBC3290B0B6AC95315" + "809F8CC7938768F9BD342C62CD4CE055866394489D955247CB0535001D50EFF4FEDF0" + "9501C58569B1EB9AA2305A113A5F4D4524AD34148A2DC48D2F522937F44A57FC76F57" + "EB1D4819C438EA42C7F8974FC7D2FE61CAAB3E1F27172FE6B8675DF4CCF1329A6EFB3" + "1F686FB0DC0F8B552D78970708D50C82ADBE333B585F6DE5A0D01D106F8232EB9ED45" + "42A2DC5AA031CC44652E8A42EDCA5AB08B0B5CA61A922E69A119E556F6014642522EA" + "1550F6D6E63EB25ACC03A4DD3F22F4686ED525F994FABA87629AF5939C16BA68C0F09" + "3EFE033CD319180BF69FCB72AC5123EBCB9DCF1AF00F0A68E31FF5B18FA8CFF3DFBB7" + "DA45413799105D67FA78217710D2F6C33394DD4088100013295FF43CF0598E6FE5C05" + "F03417CCD031F01CF63BECD444C750DF198345F155AB2B2AB94394A3C0C0AE05E386D" + "E6CC565AE82398BD0E377D6ABE103B9D5E84582C3772584B759891FC4B121A113370E" + "2DF5372DD81FB6358C64B0F6EB8F26193CA119E4D9D3D38036FA450EE2047CB2CE265" + "0FF37DF85BE23D58C17379FEC08DC0648236A107AE66178EEBF78F05F3B898424FA02" + "668B51F838AFA90D367B5CB425372D8CC3790BEA8AFB8795251FA09340D85A7F0B003" + "134C838F08BB1054D18404C3F69130700E"), + a2bs_hex( + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021" + "22232425262728292a2b2c2d2e2f"), + a2bs_hex( + "0A8B16080210012A84160AA9070A8001924B035FBDA56AE5EF0ED05A08DE7AECC8ABE" + "1835E0C4A548F7803937F4C3B4520EB7F3334FFCDFA00DE56408F09D5019FCE87072D" + "0DC6789817468974B2EA51EE3944B8D7E0A88E4F16EBB80F03BD845231A01E6146841" + "CBAEF0134DCD9300DB2D92732992C0F2310D8E386FB31C67B9477010DEF9D99C42725" + "89572A26A17E12AC021E6FFBE66FC6153E7749906EC8F684E819467E16CAF317F315D" + "B32B6D3FDD1A8E8A094174D92D063B88E4835EAB78BD09541EA7FE72F132EB7364E15" + "4BC1548FC40EC7092775531508C95F9ED5D76F36BC0C198C3A33A1F9415B343905D6B" + "E37645E6800F053B1DA9A20286EFCBBC320424ADF7FB6E3D5D8E86C35E576A1A2A37D" + "344A419C0F0034A1B5F767D3C61D90DCA1119E5024C34EDE8FA7DD128696D8C435410" + "F218E52A853AD214FD05D0F8B3CB4832CFCD97FE159E6DEE64CE82CDAEC0321AE71B3" + "BCBAE42DF9EA65E42E151827086EADE71C138B972CC3992CF9ADA944C063816352ED8" + "658D3FA07BE0F32239E74A65932B069AAC4E8386DB59154AF9AEF71448128C66E5104" + "45294F44E511BD9B1AF19D4D67E99363093BE888D4B2AB841CAFF252CAD13EDF8E1AF" + "40340FC62339728520E6C0C09907C26F3FB78287231661952A8B699E47AE241B999C0" + "29FD2067836DC4BC64F66998A3ECD197DAE36F808A2E5A4C5BF25DD580E52B1C39A8B" + "03772BF82D58929766F2DA04F0E616F92B3A0EB75661B8FF5DE1EB807C990F9E6BA99" + "1C8BAD5EB63B37E8663A4E22AA9DB2015D3DF8BED1C8313F85F13B9483C7A39C59243" + "6C8B13C23F78F55CE812795335059F7F527CA580306A0AEE5A6D957A91F498F64AA2E" + "FC6780716400E17C7EEA30B2E6523B902986995E003C2D919A7DC7C0122CE9410037A" + "6602B59A63B5C89473D4E02DE35C1F01B12ADB48A3D94D43693F08268FECCC78DAF6F" + "4C35FA32C538CD73FBF3CEA274B01179C02473486311956E5A0C78E44C59B2F34FF24" + "B0653A6379A2F5F6F51467CAE26D55CC5BBDCFC9BCFA7B8C5CBF82EBE7BD340C3DAE6" + "374D0692052C529AA33D7A6799C8F1F59C78575E51F707013026CC4F83F6B3328EE6F" + "B1AC91929A4491338E93D10EE6193014A73BA241A9A833EA835217894EB4FD4BDB890" + "4A5999928325D0AC31B6D58609EDD9D85E88F74B5BD6FA7BDD83C51EEB91633ED267A" + "CA2E103904BBE4C031A6483858FBAD74DACD01711F7B882749FFFBA0DB6C7D7109D82" + "989C7D4DB5A0F1E7506AC24C89CECAF231EFF99F96AD76E57DABDD3C2DFBA7BAA869A" + "771F561B165987E552824B0C914E708E425C30AA9070A80017290396E183156BDF830" + "B7BF31BA762CB2675528C9004FD24A61DAFB587ABCF1D36F87795EE0B3DA0B425616A" + "66C82349B2E3BB8841C1335536865F919ED2AE671487B608B21A362D888E0AB4F7AB7" + "175B82F108617C3503F175435788AECAF7FFBFE76995D93CD79424A843A247A8D8A60" + "54A5B5404C9C057AACAD91A20322912AC023478A2D76DEB90BE713B03A11037EA7C30" + "5D1AF65099E3F2B92C4D4443A8F481C1177DEF0A3CB49BA5F1448A10AF1207AD2D361" + "B4A1F961B4B1F215B76A9A5005B414EF45EAFBCF2636ABFC01413B27DD11871103579" + "F8C041A799E22888D9ADB798E92A5E29BC46DECBC90991C65FE151C49F18068C1B65D" + "0E90A9ECDA9248B87C120D5FD8EC81D4D36B529FB2DAD39E0D39578B13B158E2B07C7" + "52D86F1A9D8160C93930C1F4F9E1D0D8E2C5AB308732EB27722A6BF8BE852624C2BE3" + "E4FE85819B89BEBA6535FCFBE85FA63A57BD0FBAF284C64FFD97A146B76B3F37B576F" + "C091C03E2222FBD24C2211344B7E2417EFC36C4A54DCCC460CF810E7EA8AC6386D6AB" + "567C819FED88A22CE55EF9BBE62C2CBC7AEEDE5E5A69FF3472418CE2F4514496C59D2" + "6E72F3BFE0131F1AF403C45FDCB3296A0EBE24FF381E027E6E2EF1AC289C67D3B8583" + "30669A81E8131583D2F140FD64615BDED0ED8316ABFD9C7E887433E1CAA6EA8E0C4F8" + "7ADB2A7FC3CF6FF87A7F02AFF03BF5DB640AD8DDB572C41532E673618DCD8C33EF2BF" + "E4E25EE821DF7D742B0990398543B16EFCDBB03C6327B79D3664CED442E894020F441" + "0ECC178C92AAEDFE39DC563AC226FE9E0EF22E1C896C4F2835CDFDCD50B6C4DBA2B27" + "A3B65DE3963D0A5F6E442A3C32008AB9D1ACBE4F366990EB43F8EE213B71E98DA0902" + "82680ABDD649BECA89700764561379F1DD23490CE967632ECA349AF8E1CBFA1F3A4F3" + "9F453614C8FFB5A179756243CB1FDB515834229BC64917C47A2F2E1116FAAC1336801" + "5312C31FD41215106469BEE77D0EF2FE10CF645B3E82902EAF53A676933D0EC433949" + "C1833BE52E76602CC3E4E784C002E20624BCE0F38F9CBC478439899DA7F15554D0ACA" + "DEC140C00C8FA8FC98862D9933938781B30CB9C76899B3A48DBF170DDA0A18ED37D77" + "F048ABBC85CB19469638C2A32AA3180CF3943BD6B8C5CB26F2EA70868F18B0707C882" + "054141086997A1AE5B709D4D0AA2B358990F244BA76C8E40791D29A0C63C9EF620B97" + "FDFFA9B671E5A65AFCC1C94CAACE0443E9D91F14028935BEA3988831BEBBFD3EB7C3A" + "5AC9605B3534712A09124345ACB09665E357E58946871BC140D3650AA9070A8001983" + "358221FB8DBF892047F00AA661F217EEC4E7A1626E8F98E025509E4D65A685E7D9B16" + "9B98B16934F6E43E0E0E854A3FA9EB8E9A9D08E9D9B3A6C766AA44F7C655879BA2DF5" + "F38732FB7EDCA66D8C13A855B15E32CC9389B7DD119BA1F2417825FF1F52970F8E985" + "D34DD353D2AC8B24267353E5B8406C098427C4559A90CC12AC02483EAC68243092009" + "D06FAB41DB594ACB22E068C9524810758ECFF8BAB7E1B1ACA988C3987023F01EFEC11" + "529C7326279742E805E755A08EBBD9AA322F305805BE1166AB45CB156FB0A9E673437" + "1F4028707EE01CF2FB08465707E7E5613DD90D74B0D02536E26CF1261CDDA8713943F" + "3620ECC54095C76F8CD3CE31948C3CC0C9EB5582A4D087A54B391B4CDCBC98E35830B" + "5932F6CF8D16427EF115CFF0A99499513702DD54C758E53248BB5D195F2A2DD1DB18F" + "97562F1F9034E223CEDB1E09ED1B0FE26089C20ED43B5D87B51F6FC6C9F86255FBF70" + "DF233F2665D604355BF9740A3B755521102E0B485C5CCCA607A9A1BEB757BEDEF1232" + "7C637D17D6401E3756719F99BBE69B9CE4C8E47C2AC771F35A8EE3FC4D58B2B2269CF" + "85728E4DA7231BC8F0FD7C50E2A1EE91AF4035826D3A95F78879292612BCE06D845D6" + "4285CD45A7EAA6C87A9DBC3290B0B6AC95315809F8CC7938768F9BD342C62CD4CE055" + "866394489D955247CB0535001D50EFF4FEDF09501C58569B1EB9AA2305A113A5F4D45" + "24AD34148A2DC48D2F522937F44A57FC76F57EB1D4819C438EA42C7F8974FC7D2FE61" + "CAAB3E1F27172FE6B8675DF4CCF1329A6EFB31F686FB0DC0F8B552D78970708D50C82" + "ADBE333B585F6DE5A0D01D106F8232EB9ED4542A2DC5AA031CC44652E8A42EDCA5AB0" + "8B0B5CA61A922E69A119E556F6014642522EA1550F6D6E63EB25ACC03A4DD3F22F468" + "6ED525F994FABA87629AF5939C16BA68C0F093EFE033CD319180BF69FCB72AC5123EB" + "CB9DCF1AF00F0A68E31FF5B18FA8CFF3DFBB7DA45413799105D67FA78217710D2F6C3" + "3394DD4088100013295FF43CF0598E6FE5C05F03417CCD031F01CF63BECD444C750DF" + "198345F155AB2B2AB94394A3C0C0AE05E386DE6CC565AE82398BD0E377D6ABE103B9D" + "5E84582C3772584B759891FC4B121A113370E2DF5372DD81FB6358C64B0F6EB8F2619" + "3CA119E4D9D3D38036FA450EE2047CB2CE2650FF37DF85BE23D58C17379FEC08DC064" + "8236A107AE66178EEBF78F05F3B898424FA02668B51F838AFA90D367B5CB425372D8C" + "C3790BEA8AFB8795251FA09340D85A7F0B003134C838F08BB1054D18404C3F6913070" + "0E12202FF1FBA9926A24A1F79970EC427DDF87B4421488F7952499BC33CEB282D9E48" + "A")}}; struct HlsAttributesInfo { std::string key_set_id; @@ -1873,82 +1465,88 @@ HlsAttributesInfo kHlsAttributesTestData[] = { // Usage Table and Entry Test Data // Note: Make sure the number of entries in kUsageEntriesTestData and // kUsageTableInfoTestData are equal. -CdmUsageEntryInfo kUsageEntriesTestData[] = { +DeviceFiles::UsageEntryInfo kUsageEntriesTestData[] = { // usage entry 0 { - kStorageLicense, "ksid0", "", + DeviceFiles::kStorageLicense, "ksid0", "", "", }, // usage entry 1 { - kStorageLicense, "ksid1", "", + DeviceFiles::kStorageLicense, "ksid1", "", "", }, // usage entry 2 { - kStorageUsageInfo, "", "app_id_2", + DeviceFiles::kStorageUsageInfo, "", "provider_session_token_2", + "app_id_2", }, // usage entry 3 { - kStorageUsageInfo, "", "app_id_3", + DeviceFiles::kStorageUsageInfo, "", "provider_session_token_3", + "app_id_3", }, // usage entry 4 { - kStorageLicense, "ksid4", "", + DeviceFiles::kStorageLicense, "ksid4", "", "", }, // usage entry 5 { - kStorageUsageInfo, "", "app_id_5", + DeviceFiles::kStorageUsageInfo, "", "provider_session_token_5", + "app_id_5", }, }; struct UsageTableTestInfo { - CdmUsageTableHeader usage_table_header; + std::string usage_table_header; std::string file_data; }; UsageTableTestInfo kUsageTableInfoTestData[] = { // usage table 0 - {a2bs_hex("5574517CCC"), a2bs_hex("0A18080510013A120A055574517CCC1209080112056B73696430122018268E3F" "384F28D04BEE00304089C000463C22E987532855390915FD02C36B5C")}, // usage table 1 {a2bs_hex("CA870203010001288001"), - a2bs_hex("0A2C080510013A260A0ACA870203010001288001120B080112056B736964301A" - "00120B080112056B736964311A00122049A8F3481444A5B64B6C4F05FBCC2EF8" - "CB67444A08654763F2F5B80F658D7B38")}, + a2bs_hex("0A28080510013A220A0ACA8702030100012880011209080112056B7369643012" + "09080112056B7369643112202D3638164ADC3B4276734A8EDE96C40BFE14DDB2" + "8013337A3A1A9DFC09F34923")}, // usage table 2 {a2bs_hex("7A7D507618A5D3A68F05228E023082010A028201"), - a2bs_hex("0A46080510013A400A147A7D507618A5D3A68F05228E023082010A028201120B" - "080112056B736964301A00120B080112056B736964311A00120E080212001A08" - "6170705F69645F321220783E93A02223BDB94E743856C0F69C35B213ACCDDE91" - "93E48E9186AA83B80584")}, + a2bs_hex("0A5A080510013A540A147A7D507618A5D3A68F05228E023082010A0282011209" + "080112056B736964301209080112056B73696431122608021A1870726F766964" + "65725F73657373696F6E5F746F6B656E5F3222086170705F69645F321220CB07" + "CA08A1E76C61A5F45067176B960A9DB40D169025AF245CF1AFC66C979F47")}, // usage table 3 {a2bs_hex("E83A4902772DAFD2740B7748E9C3B1752D6F12859CED07E82969B4EC"), - a2bs_hex("0A5E080510013A580A1CE83A4902772DAFD2740B7748E9C3B1752D6F12859CED" - "07E82969B4EC120B080112056B736964301A00120B080112056B736964311A00" - "120E080212001A086170705F69645F32120E080212001A086170705F69645F33" - "122084E67F1338727291BC3D92E28442DC8B0F44CB5AF7B98A799313B7EB7F55" - "ED18")}, + a2bs_hex("0A8B01080510013A84010A1CE83A4902772DAFD2740B7748E9C3B1752D6F1285" + "9CED07E82969B4EC1209080112056B736964301209080112056B736964311226" + "08021A1870726F76696465725F73657373696F6E5F746F6B656E5F3222086170" + "705F69645F32122608021A1870726F76696465725F73657373696F6E5F746F6B" + "656E5F3322086170705F69645F331220C4157F80E81C923A9F0885CE6B928D15" + "7E1648384C3E44F04A966815EB09B260")}, // usage table 4 {a2bs_hex("CA870203010001288001300112800250D1F8B1ECF849B60FF93E37C4DEEF" "52F1CCFC047EF42300131F9C4758F4"), - a2bs_hex("0A7C080510013A760A2DCA870203010001288001300112800250D1F8B1ECF849" - "B60FF93E37C4DEEF52F1CCFC047EF42300131F9C4758F4120B080112056B7369" - "64301A00120B080112056B736964311A00120E080212001A086170705F69645F" - "32120E080212001A086170705F69645F33120B080112056B736964341A001220" - "1CDFCFED5E58A1DF77E1B335305424E1F0260340F9CC15985684C43A4207652" - "1")}, + a2bs_hex("0AA701080510013AA0010A2DCA870203010001288001300112800250D1F8B1EC" + "F849B60FF93E37C4DEEF52F1CCFC047EF42300131F9C4758F41209080112056B" + "736964301209080112056B73696431122608021A1870726F76696465725F7365" + "7373696F6E5F746F6B656E5F3222086170705F69645F32122608021A1870726F" + "76696465725F73657373696F6E5F746F6B656E5F3322086170705F69645F3312" + "09080112056B7369643412203F75C53693E7A3DC9BA5BF3E23D7EFCF3C05687A" + "A6082E3AB78F563525981999")}, // usage table 5 {a2bs_hex("EC83A4902772DAFD2740B7748E9C3B1752D6F12859CED07E8882969B433E" "C29AC6FDBE79230B0FAED5D94CF6B829A420BBE3270323941776EE60DD6B"), - a2bs_hex("0A9C01080510013A95010A3CEC83A4902772DAFD2740B7748E9C3B1752D6F128" + a2bs_hex("0ADE01080510013AD7010A3CEC83A4902772DAFD2740B7748E9C3B1752D6F128" "59CED07E8882969B433EC29AC6FDBE79230B0FAED5D94CF6B829A420BBE32703" - "23941776EE60DD6B120B080112056B736964301A00120B080112056B73696431" - "1A00120E080212001A086170705F69645F32120E080212001A086170705F6964" - "5F33120B080112056B736964341A00120E080212001A086170705F69645F3512" - "20305C7A27A918268119E1996FC182C153DF805034A387F90C3585749E764731" - "32")}, + "23941776EE60DD6B1209080112056B736964301209080112056B736964311226" + "08021A1870726F76696465725F73657373696F6E5F746F6B656E5F3222086170" + "705F69645F32122608021A1870726F76696465725F73657373696F6E5F746F6B" + "656E5F3322086170705F69645F331209080112056B73696434122608021A1870" + "726F76696465725F73657373696F6E5F746F6B656E5F3522086170705F69645F" + "3512203B35BD5C615BBA79008A7A1DA29AFA69F5CD529DFDE794A0544E423B72" + "1CB8E8")}, }; class MockFile : public File { @@ -2053,10 +1651,6 @@ class DeviceFilesSecurityLevelTest : public DeviceFilesTest, public ::testing::WithParamInterface {}; -class DeviceFilesUsageInfoListTest - : public DeviceFilesTest, - public ::testing::WithParamInterface {}; - class DeviceFilesUsageInfoTest : public DeviceFilesTest, public ::testing::WithParamInterface {}; @@ -2291,8 +1885,7 @@ TEST_P(DeviceFilesStoreTest, StoreLicense) { license_test_data[license_num].playback_start_time, license_test_data[license_num].last_playback_time, license_test_data[license_num].grace_period_end_time, app_parameters, - license_test_data[license_num].usage_entry, - license_test_data[license_num].usage_entry_number)); + license_test_data[license_num].usage_entry)); } INSTANTIATE_TEST_CASE_P(StoreLicense, DeviceFilesStoreTest, ::testing::Bool()); @@ -2342,8 +1935,7 @@ TEST_F(DeviceFilesTest, StoreLicenses) { license_test_data[i].playback_start_time, license_test_data[i].last_playback_time, license_test_data[i].grace_period_end_time, app_parameters, - license_test_data[i].usage_entry, - license_test_data[i].usage_entry_number)); + license_test_data[i].usage_entry)); } } @@ -2385,7 +1977,6 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) { std::string release_server_url; CdmAppParameterMap app_parameters; std::string usage_entry; - uint32_t usage_entry_number; for (size_t i = 0; i < kNumberOfLicenses; i++) { DeviceFiles::LicenseState license_state; @@ -2394,7 +1985,7 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) { &key_request, &key_response, &key_renewal_request, &key_renewal_response, &release_server_url, &playback_start_time, &last_playback_time, &grace_period_end_time, &app_parameters, - &usage_entry, &usage_entry_number)); + &usage_entry)); EXPECT_EQ(license_test_data[i].license_state, license_state); EXPECT_EQ(license_test_data[i].pssh_data, pssh_data); EXPECT_EQ(license_test_data[i].key_request, key_request); @@ -2406,7 +1997,6 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) { EXPECT_EQ(license_test_data[i].grace_period_end_time, grace_period_end_time); EXPECT_EQ(license_test_data[i].usage_entry, usage_entry); - EXPECT_EQ(license_test_data[i].usage_entry_number, usage_entry_number); std::map::iterator itr; for (itr = app_parameters.begin(); itr != app_parameters.end(); ++itr) { @@ -2455,14 +2045,12 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) { std::string release_server_url; CdmAppParameterMap app_parameters; std::string usage_entry; - uint32_t usage_entry_number; EXPECT_TRUE(device_files.RetrieveLicense( test_data->key_set_id, &license_state, &pssh_data, &key_request, &key_response, &key_renewal_request, &key_renewal_response, &release_server_url, &playback_start_time, &last_playback_time, - &grace_period_end_time, &app_parameters, &usage_entry, - &usage_entry_number)); + &grace_period_end_time, &app_parameters, &usage_entry)); EXPECT_EQ(test_data->license_state, license_state); EXPECT_EQ(test_data->pssh_data, pssh_data); EXPECT_EQ(test_data->key_request, key_request); @@ -2474,7 +2062,6 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) { EXPECT_EQ(test_data->grace_period_end_time, grace_period_end_time); EXPECT_EQ(0u, app_parameters.size()); EXPECT_EQ(test_data->usage_entry, usage_entry); - EXPECT_EQ(test_data->usage_entry_number, usage_entry_number); } TEST_F(DeviceFilesTest, UpdateLicenseState) { @@ -2511,8 +2098,7 @@ TEST_F(DeviceFilesTest, UpdateLicenseState) { license_update_test_data[0].last_playback_time, license_update_test_data[0].grace_period_end_time, GetAppParameters(license_test_data[0].app_parameters), - license_update_test_data[0].usage_entry, - license_update_test_data[0].usage_entry_number)); + license_update_test_data[0].usage_entry)); EXPECT_TRUE(device_files.StoreLicense( license_update_test_data[0].key_set_id, @@ -2527,8 +2113,7 @@ TEST_F(DeviceFilesTest, UpdateLicenseState) { license_update_test_data[0].last_playback_time, license_update_test_data[0].grace_period_end_time, GetAppParameters(license_test_data[0].app_parameters), - license_update_test_data[0].usage_entry, - license_update_test_data[0].usage_entry_number)); + license_update_test_data[0].usage_entry)); } TEST_F(DeviceFilesTest, DeleteLicense) { @@ -2569,14 +2154,12 @@ TEST_F(DeviceFilesTest, DeleteLicense) { int64_t playback_start_time, last_playback_time, grace_period_end_time; CdmAppParameterMap app_parameters; std::string usage_entry; - uint32_t usage_entry_number; EXPECT_TRUE(device_files.RetrieveLicense( license_test_data[0].key_set_id, &license_state, &pssh_data, &key_request, &key_response, &key_renewal_request, &key_renewal_response, &release_server_url, &playback_start_time, &last_playback_time, - &grace_period_end_time, &app_parameters, &usage_entry, - &usage_entry_number)); + &grace_period_end_time, &app_parameters, &usage_entry)); EXPECT_EQ(license_test_data[0].license_state, license_state); EXPECT_EQ(license_test_data[0].pssh_data, pssh_data); EXPECT_EQ(license_test_data[0].key_request, key_request); @@ -2594,7 +2177,6 @@ TEST_F(DeviceFilesTest, DeleteLicense) { std::string::npos); } EXPECT_EQ(license_test_data[0].usage_entry, usage_entry); - EXPECT_EQ(license_test_data[0].usage_entry_number, usage_entry_number); EXPECT_TRUE(device_files.DeleteLicense(license_test_data[0].key_set_id)); EXPECT_FALSE(device_files.LicenseExists(license_test_data[0].key_set_id)); @@ -2616,304 +2198,204 @@ TEST_F(DeviceFilesTest, ReserveLicenseIdsDoesNotUseFileSystem) { } } -TEST_F(DeviceFilesUsageInfoTest, ListNullParam) { - MockFileSystem file_system; - MockFile file; - - DeviceFiles device_files(&file_system); - EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); - EXPECT_FALSE(device_files.ListUsageInfoFiles(NULL)); -} - -TEST_P(DeviceFilesUsageInfoListTest, UsageInfoList) { +TEST_P(DeviceFilesUsageInfoTest, Read) { MockFileSystem file_system; MockFile file; + std::string app_id; // TODO(fredgc): add tests with multiple app_ids. + std::string path = + device_base_path_ + DeviceFiles::GetUsageInfoFileName(app_id); int index = GetParam(); - std::vector file_list; - std::vector expected_usage_file_list; - for (int i = 0; i <= index; ++i) { - file_list.push_back(kTestListUsageInfoData[i].file_name); - if (kTestListUsageInfoData[i].is_usage_info_file) - expected_usage_file_list.push_back(kTestListUsageInfoData[i].file_name); + std::string data; + if (index >= 0) { + data = kUsageInfoTestData[index].file_data; + } + if (index >= 0) { + EXPECT_CALL(file_system, Exists(StrEq(path))).WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, FileSize(StrEq(path))) + .WillRepeatedly(Return(data.size())); + EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file)); + EXPECT_CALL(file, Read(NotNull(), Eq(data.size()))) + .WillOnce(DoAll(SetArrayArgument<0>(data.begin(), data.end()), + Return(data.size()))); + EXPECT_CALL(file, Close()).Times(1); + } else { + EXPECT_CALL(file_system, Exists(StrEq(path))).WillRepeatedly(Return(false)); + EXPECT_CALL(file_system, FileSize(_)).Times(0); + EXPECT_CALL(file_system, Open(_, _)).Times(0); } - EXPECT_CALL(file_system, List(StrEq(device_base_path_), NotNull())) - .WillOnce(DoAll(SetArgPointee<1>(file_list), Return(true))); + EXPECT_CALL(file, Write(_, _)).Times(0); DeviceFiles device_files(&file_system); EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); - std::vector usage_info_file_names; - EXPECT_TRUE(device_files.ListUsageInfoFiles(&usage_info_file_names)); - EXPECT_EQ(expected_usage_file_list.size(), usage_info_file_names.size()); - EXPECT_THAT(usage_info_file_names, - ::testing::UnorderedElementsAreArray(expected_usage_file_list)); + std::vector > license_info; + ASSERT_TRUE(device_files.RetrieveUsageInfo(app_id, &license_info)); + if (index >= 0) { + EXPECT_EQ(static_cast(index), license_info.size()); + for (size_t i = 0; i < license_info.size(); ++i) { + bool found = false; + for (size_t j = 0; j <= static_cast(index); ++j) { + if ((license_info[i].first.compare( + kUsageInfoTestData[j].license_request) == 0) && + (license_info[i].second.compare(kUsageInfoTestData[j].license) == + 0)) { + found = true; + } + } + EXPECT_TRUE(found); + } + } else { + EXPECT_EQ(0u, license_info.size()); + } } -INSTANTIATE_TEST_CASE_P(UsageInfo, DeviceFilesUsageInfoListTest, - ::testing::Range(0, 7)); - TEST_P(DeviceFilesUsageInfoTest, Store) { MockFileSystem file_system; - MockFile file; + std::string app_id; // TODO(fredgc): multiple app ids. + std::string pst(GenerateRandomData(kProviderSessionTokenLen)); + std::string license_request(GenerateRandomData(kLicenseRequestLen)); + std::string license(GenerateRandomData(kLicenseLen)); + std::string key_set_id(GenerateRandomData(kKeySetIdLen)); + std::string usage_entry(GenerateRandomData(kUsageEntryLen)); + std::string path = + device_base_path_ + DeviceFiles::GetUsageInfoFileName(app_id); int index = GetParam(); - - std::string app_id; - if (index >= 0) app_id = kUsageInfoTestData[index].app_id; - std::string file_name = DeviceFiles::GetUsageInfoFileName(app_id); - std::string path = device_base_path_ + file_name; - - size_t usage_data_fields_length = 0; - std::vector usage_data_fields; - std::vector usage_data_list; - - for (int i = 0; i <= index; ++i) { - if (kUsageInfoTestData[i].app_id == app_id) { - usage_data_list.push_back(kUsageInfoTestData[i].usage_data); - usage_data_fields.push_back( - kUsageInfoTestData[i].usage_data.provider_session_token); - usage_data_fields.push_back( - kUsageInfoTestData[i].usage_data.license_request); - usage_data_fields.push_back(kUsageInfoTestData[i].usage_data.license); - usage_data_fields.push_back(kUsageInfoTestData[i].usage_data.key_set_id); - usage_data_fields.push_back(kUsageInfoTestData[i].usage_data.usage_entry); - usage_data_fields_length += - kUsageInfoTestData[i].usage_data.provider_session_token.size() + - kUsageInfoTestData[i].usage_data.license_request.size() + - kUsageInfoTestData[i].usage_data.license.size() + - kUsageInfoTestData[i].usage_data.key_set_id.size() + - kUsageInfoTestData[i].usage_data.usage_entry.size(); - } - } - - EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file)); - EXPECT_CALL(file, Write(ContainsAllElementsInVector(usage_data_fields), - Gt(usage_data_fields_length))) - .WillOnce(ReturnArg<1>()); - EXPECT_CALL(file, Close()); - - DeviceFiles device_files(&file_system); - EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); - - EXPECT_TRUE(device_files.StoreUsageInfo(file_name, usage_data_list)); -} - -TEST_P(DeviceFilesUsageInfoTest, Retrieve) { - MockFileSystem file_system; - MockFile file; - - int index = GetParam(); - - std::string app_id; - if (index >= 0) app_id = kUsageInfoTestData[index].app_id; - - std::string file_name = DeviceFiles::GetUsageInfoFileName(app_id); - std::string path = device_base_path_ + file_name; - std::string file_data = (index < 0) ? kEmptyUsageInfoFileData - : kUsageInfoTestData[index].file_data; + std::string data; if (index >= 0) { - EXPECT_CALL(file_system, Exists(StrEq(path))) - .Times(2) - .WillRepeatedly(Return(true)); - EXPECT_CALL(file_system, FileSize(StrEq(path))) - .Times(2) - .WillRepeatedly(Return(kUsageInfoTestData[index].file_data.size())); - EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file)); - EXPECT_CALL(file, - Read(NotNull(), Eq(kUsageInfoTestData[index].file_data.size()))) - .WillOnce(DoAll(SetArrayArgument<0>(file_data.begin(), file_data.end()), - Return(file_data.size()))); - EXPECT_CALL(file, Close()); - } - else { - EXPECT_CALL(file_system, Exists(StrEq(path))) - .WillOnce(Return(false)); + data = kUsageInfoTestData[index].file_data; } - std::vector usage_data_list; - DeviceFiles device_files(&file_system); - EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); - - EXPECT_TRUE(device_files.RetrieveUsageInfo(file_name, &usage_data_list)); - - for (size_t i = 0; i < usage_data_list.size(); ++i) { - bool found = false; - int j = 0; - while (!found && j <= index) { - if (app_id == kUsageInfoTestData[j].app_id && - usage_data_list[i].provider_session_token == - kUsageInfoTestData[j].usage_data.provider_session_token) { - EXPECT_EQ(kUsageInfoTestData[j].usage_data.license_request, - usage_data_list[i].license_request); - EXPECT_EQ(kUsageInfoTestData[j].usage_data.license, - usage_data_list[i].license); - EXPECT_EQ(kUsageInfoTestData[j].usage_data.key_set_id, - usage_data_list[i].key_set_id); - EXPECT_EQ(kUsageInfoTestData[j].usage_data.usage_entry, - usage_data_list[i].usage_entry); - EXPECT_EQ(kUsageInfoTestData[j].usage_data.usage_entry_number, - usage_data_list[i].usage_entry_number); - found = true; - } - ++j; - } - EXPECT_TRUE(found); - } -} - -TEST_P(DeviceFilesUsageInfoTest, RetrieveByProviderSessionToken) { - MockFileSystem file_system; MockFile file; - - int index = GetParam(); - - std::string app_id; - if (index >= 0) app_id = kUsageInfoTestData[index].app_id; - - std::string file_name = DeviceFiles::GetUsageInfoFileName(app_id); - std::string path = device_base_path_ + file_name; - - size_t max_index_by_app_id = 0; - for (size_t i = 0; i <= sizeof(kUsageInfoTestData) / sizeof(UsageInfo); ++i) { - if (app_id == kUsageInfoTestData[i].app_id) max_index_by_app_id = i; - } - std::string file_data = - (index < 0) ? kEmptyUsageInfoFileData - : kUsageInfoTestData[max_index_by_app_id].file_data; - std::string provider_session_token = kUsageInfoTestData[index < 0 ? 0 : index] - .usage_data.provider_session_token; - - EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(true)); - EXPECT_CALL(file_system, FileSize(StrEq(path))) - .WillOnce(Return(file_data.size())); - EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file)); - EXPECT_CALL(file, Read(NotNull(), Eq(file_data.size()))) - .WillOnce(DoAll(SetArrayArgument<0>(file_data.begin(), file_data.end()), - Return(file_data.size()))); - EXPECT_CALL(file, Close()); - - DeviceFiles device_files(&file_system); - EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); - - DeviceFiles::CdmUsageData usage_data; - - if (index < 0) { - EXPECT_FALSE(device_files.RetrieveUsageInfo( - file_name, provider_session_token, &usage_data)); - } else { - EXPECT_TRUE(device_files.RetrieveUsageInfo( - file_name, provider_session_token, &usage_data)); - - EXPECT_EQ(kUsageInfoTestData[index].usage_data.provider_session_token, - usage_data.provider_session_token); - EXPECT_EQ(kUsageInfoTestData[index].usage_data.license_request, - usage_data.license_request); - EXPECT_EQ(kUsageInfoTestData[index].usage_data.license, usage_data.license); - EXPECT_EQ(kUsageInfoTestData[index].usage_data.key_set_id, - usage_data.key_set_id); - EXPECT_EQ(kUsageInfoTestData[index].usage_data.usage_entry, - usage_data.usage_entry); - EXPECT_EQ(kUsageInfoTestData[index].usage_data.usage_entry_number, - usage_data.usage_entry_number); - } -} - -TEST_P(DeviceFilesUsageInfoTest, UpdateUsageInfo) { - MockFileSystem file_system; - MockFile file; - - int index = GetParam(); - - std::string app_id; - if (index >= 0) app_id = kUsageInfoTestData[index].app_id; - - std::string file_name = DeviceFiles::GetUsageInfoFileName(app_id); - std::string path = device_base_path_ + file_name; - - size_t usage_data_fields_length = 0; - std::vector usage_data_fields; - - size_t max_index_by_app_id = 0; - for (size_t i = 0; i <= sizeof(kUsageInfoTestData) / sizeof(UsageInfo); ++i) { - if (app_id == kUsageInfoTestData[i].app_id) { - max_index_by_app_id = i; - - if ((int)i != index) { - usage_data_fields.push_back( - kUsageInfoTestData[i].usage_data.provider_session_token); - usage_data_fields.push_back( - kUsageInfoTestData[i].usage_data.license_request); - usage_data_fields.push_back(kUsageInfoTestData[i].usage_data.license); - usage_data_fields.push_back( - kUsageInfoTestData[i].usage_data.key_set_id); - usage_data_fields.push_back( - kUsageInfoTestData[i].usage_data.usage_entry); - usage_data_fields_length += - kUsageInfoTestData[i].usage_data.provider_session_token.size() + - kUsageInfoTestData[i].usage_data.license_request.size() + - kUsageInfoTestData[i].usage_data.license.size() + - kUsageInfoTestData[i].usage_data.key_set_id.size() + - kUsageInfoTestData[i].usage_data.usage_entry.size(); - } - } - } - - if (index >= 0) { - usage_data_fields.push_back( - kUsageInfoTestData[index].usage_data.provider_session_token); - usage_data_fields.push_back(kUsageInfoUpdateTestData.license_request); - usage_data_fields.push_back(kUsageInfoUpdateTestData.license); - usage_data_fields.push_back(kUsageInfoUpdateTestData.key_set_id); - usage_data_fields.push_back(kUsageInfoUpdateTestData.usage_entry); - usage_data_fields_length += - kUsageInfoTestData[index].usage_data.provider_session_token.size() + - kUsageInfoUpdateTestData.license_request.size() + - kUsageInfoUpdateTestData.license.size() + - kUsageInfoUpdateTestData.key_set_id.size() + - kUsageInfoUpdateTestData.usage_entry.size(); - } - - std::string file_data = - (index < 0) ? kEmptyUsageInfoFileData - : kUsageInfoTestData[max_index_by_app_id].file_data; - std::string provider_session_token = kUsageInfoTestData[index < 0 ? 0 : index] - .usage_data.provider_session_token; - EXPECT_CALL(file_system, Exists(StrEq(path))) - .Times(2) - .WillRepeatedly(Return(true)); - EXPECT_CALL(file_system, FileSize(StrEq(path))) - .WillOnce(Return(file_data.size())); - EXPECT_CALL(file, Read(NotNull(), Eq(file_data.size()))) - .WillOnce(DoAll(SetArrayArgument<0>(file_data.begin(), file_data.end()), - Return(file_data.size()))); - - if (index < 0) { - EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file)); - EXPECT_CALL(file, Close()); - } else { + .WillRepeatedly(Return(index >= 0)); + if (index >= 0) { + EXPECT_CALL(file_system, FileSize(StrEq(path))) + .WillOnce(Return(data.size())); EXPECT_CALL(file_system, Open(StrEq(path), _)) .Times(2) .WillRepeatedly(Return(&file)); - EXPECT_CALL(file, Write(ContainsAllElementsInVector(usage_data_fields), - Gt(usage_data_fields_length))) + EXPECT_CALL(file, Read(NotNull(), Eq(data.size()))) + .WillOnce(DoAll(SetArrayArgument<0>(data.begin(), data.end()), + Return(data.size()))); + EXPECT_CALL(file, Close()).Times(2); + } else { + EXPECT_CALL(file_system, FileSize(_)).Times(0); + EXPECT_CALL(file_system, Open(_, _)).Times(1).WillOnce(Return(&file)); + EXPECT_CALL(file, Close()); + } + + EXPECT_CALL(file, Write(Contains(pst, license_request, license, key_set_id, + usage_entry, data.size()), + Gt(pst.size() + license_request.size() + + license.size() + key_set_id.size()))) + .WillOnce(ReturnArg<1>()); + + DeviceFiles device_files(&file_system); + EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); + + ASSERT_TRUE(device_files.StoreUsageInfo(pst, license_request, license, app_id, + key_set_id, usage_entry)); +} + +TEST_P(DeviceFilesUsageInfoTest, Delete) { + MockFileSystem file_system; + MockFile file; + std::string app_id; // TODO(fredgc): expand tests. + std::string path = + device_base_path_ + DeviceFiles::GetUsageInfoFileName(app_id); + + int index = GetParam(); + if (index < 0) return; + + std::string data, pst, prev_data, prev_pst, prev_license; + if (index >= 0) { + data = kUsageInfoTestData[index].file_data; + if (index >= 1) { + pst = kUsageInfoTestData[index].provider_session_token; + prev_data = kUsageInfoTestData[index - 1].file_data; + prev_pst = kUsageInfoTestData[index - 1].provider_session_token; + prev_license = kUsageInfoTestData[index - 1].license; + } + } + + EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(index >= 0)); + + EXPECT_CALL(file_system, FileSize(StrEq(path))).WillOnce(Return(data.size())); + if (index >= 1) { + EXPECT_CALL(file_system, Open(StrEq(path), _)) + .Times(2) + .WillRepeatedly(Return(&file)); + EXPECT_CALL(file, Write(Contains(prev_pst, prev_license, prev_data.size()), + Gt(prev_pst.size() + prev_license.size()))) .WillOnce(ReturnArg<1>()); EXPECT_CALL(file, Close()).Times(2); + } else { + EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file)); + EXPECT_CALL(file, Write(_, _)).Times(0); + EXPECT_CALL(file, Close()).Times(1); + } + EXPECT_CALL(file, Read(NotNull(), Eq(data.size()))) + .WillOnce(DoAll(SetArrayArgument<0>(data.begin(), data.end()), + Return(data.size()))); + + DeviceFiles device_files(&file_system); + EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); + + if (index >= 1) { + ASSERT_TRUE(device_files.DeleteUsageInfo(app_id, pst)); + } else { + ASSERT_FALSE(device_files.DeleteUsageInfo(app_id, pst)); + } +} + +TEST_P(DeviceFilesUsageInfoTest, DeleteAll) { + MockFileSystem file_system; + MockFile file; + std::string app_id; // TODO(fredgc): expand tests. + std::string path = + device_base_path_ + DeviceFiles::GetUsageInfoFileName(app_id); + + int index = GetParam(); + EXPECT_CALL(file, Write(_, _)).Times(0); + + std::string data; + if (index < 0) { + EXPECT_CALL(file_system, Exists(StrEq(path))).WillOnce(Return(false)); + } else { + data = kUsageInfoTestData[index].file_data; + EXPECT_CALL(file_system, Exists(StrEq(path))).WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, FileSize(StrEq(path))) + .WillOnce(Return(data.size())); + EXPECT_CALL(file_system, Open(StrEq(path), _)).WillOnce(Return(&file)); + EXPECT_CALL(file, Read(NotNull(), Eq(data.size()))) + .WillOnce(DoAll(SetArrayArgument<0>(data.begin(), data.end()), + Return(data.size()))); + EXPECT_CALL(file, Close()).Times(1); + EXPECT_CALL(file_system, Remove(StrEq(path))).WillOnce(Return(true)); } DeviceFiles device_files(&file_system); EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); - bool expected_result = index >= 0; - EXPECT_EQ(expected_result, - device_files.UpdateUsageInfo(file_name, provider_session_token, - kUsageInfoUpdateTestData)); + std::vector psts; + ASSERT_TRUE(device_files.DeleteAllUsageInfoForApp(app_id, &psts)); + if (index < 0) { + EXPECT_EQ(0u, psts.size()); + } else { + // DeleteAllUsageInfoForApp returns a list of all psts that + // should be deleted by oemcrypto. + EXPECT_EQ(static_cast(index), psts.size()); + for (int i = 0; i < index; i++) { + EXPECT_EQ(kUsageInfoTestData[i + 1].provider_session_token, psts[i]); + } + } } INSTANTIATE_TEST_CASE_P(UsageInfo, DeviceFilesUsageInfoTest, - ::testing::Range(-1, 9)); + ::testing::Range(-1, 4)); TEST_P(DeviceFilesHlsAttributesTest, Read) { MockFileSystem file_system; @@ -2993,14 +2475,20 @@ TEST_P(DeviceFilesUsageTableTest, Store) { size_t entry_data_length = 0; std::vector entry_data; - std::vector usage_entry_info; + std::vector usage_entry_info; usage_entry_info.resize(index + 1); for (int i = 0; i <= index; ++i) { usage_entry_info[i] = kUsageEntriesTestData[i]; - entry_data.push_back(kUsageEntriesTestData[i].key_set_id); - entry_data.push_back(kUsageEntriesTestData[i].usage_info_file_name); - entry_data_length += kUsageEntriesTestData[i].key_set_id.size() + - kUsageEntriesTestData[i].usage_info_file_name.size(); + if (kUsageEntriesTestData[i].storage_type == DeviceFiles::kStorageLicense) { + entry_data.push_back(kUsageEntriesTestData[i].key_set_id); + entry_data_length += kUsageEntriesTestData[i].key_set_id.size(); + } else { + entry_data.push_back(kUsageEntriesTestData[i].provider_session_token); + entry_data.push_back(kUsageEntriesTestData[i].app_id); + entry_data_length += + kUsageEntriesTestData[i].provider_session_token.size() + + kUsageEntriesTestData[i].app_id.size(); + } } entry_data.push_back(kUsageTableInfoTestData[index].usage_table_header); entry_data_length += kUsageTableInfoTestData[index].usage_table_header.size(); @@ -3024,7 +2512,7 @@ TEST_P(DeviceFilesUsageTableTest, Store) { TEST_P(DeviceFilesUsageTableTest, Read) { MockFileSystem file_system; MockFile file; - size_t index = GetParam(); + int index = GetParam(); std::string path = device_base_path_ + DeviceFiles::GetUsageTableFileName(); @@ -3043,22 +2531,28 @@ TEST_P(DeviceFilesUsageTableTest, Read) { DeviceFiles device_files(&file_system); EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); - std::vector usage_entry_info; - CdmUsageTableHeader usage_table_header; + std::vector usage_entry_info; + std::string usage_table_header; ASSERT_TRUE(device_files.RetrieveUsageTableInfo(&usage_table_header, &usage_entry_info)); EXPECT_EQ(kUsageTableInfoTestData[index].usage_table_header, usage_table_header); - EXPECT_EQ(index + 1, usage_entry_info.size()); + EXPECT_EQ(index + 1u, usage_entry_info.size()); - for (size_t i = 0; i <= index; ++i) { + for (int i = 0; i <= index; ++i) { EXPECT_EQ(kUsageEntriesTestData[i].storage_type, usage_entry_info[i].storage_type); - EXPECT_EQ(kUsageEntriesTestData[i].key_set_id, - usage_entry_info[i].key_set_id); - EXPECT_EQ( - kUsageEntriesTestData[i].usage_info_file_name, - usage_entry_info[i].usage_info_file_name); + if (usage_entry_info[i].storage_type == DeviceFiles::kStorageLicense) { + EXPECT_EQ(kUsageEntriesTestData[i].key_set_id, + usage_entry_info[i].key_set_id); + EXPECT_EQ(kEmptyString, usage_entry_info[i].provider_session_token); + EXPECT_EQ(kEmptyString, usage_entry_info[i].app_id); + } else { + EXPECT_EQ(kEmptyString, usage_entry_info[i].key_set_id); + EXPECT_EQ(kUsageEntriesTestData[i].provider_session_token, + usage_entry_info[i].provider_session_token); + EXPECT_EQ(kUsageEntriesTestData[i].app_id, usage_entry_info[i].app_id); + } } } diff --git a/libwvdrmengine/cdm/core/test/generic_crypto_unittest.cpp b/libwvdrmengine/cdm/core/test/generic_crypto_unittest.cpp index b1a57a12..3dae2a30 100644 --- a/libwvdrmengine/cdm/core/test/generic_crypto_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/generic_crypto_unittest.cpp @@ -36,6 +36,8 @@ class WvGenericOperationsTest : public testing::Test { virtual void SetUp() { ::testing::Test::SetUp(); + cdm_engine_ = NULL; + // TODO(fredgc or gmorgan): This should be updated for provisioning 3.0 // Load test keybox. This keybox will be used by any CryptoSession // created by the CDM under test. @@ -68,7 +70,9 @@ class WvGenericOperationsTest : public testing::Test { virtual void TearDown() { oec_util_session_.close(); - cdm_engine_->CloseSession(session_id_); + if (cdm_engine_ != NULL) { + cdm_engine_->CloseSession(session_id_); + } // OEMCrypto_Terminate() will be performed during the test class's // destruction (specifically by the CryptoSession destructor) } diff --git a/libwvdrmengine/cdm/core/test/license_keys_unittest.cpp b/libwvdrmengine/cdm/core/test/license_keys_unittest.cpp index f8557a83..dc645883 100644 --- a/libwvdrmengine/cdm/core/test/license_keys_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/license_keys_unittest.cpp @@ -392,16 +392,14 @@ TEST_F(LicenseKeysTest, CanDecrypt) { EXPECT_FALSE(license_keys_.CanDecryptContent(os_key)); bool new_usable_keys = false; bool any_change = false; - CdmKeyStatus status = kKeyStatusUsable; - any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL, + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_TRUE(new_usable_keys); EXPECT_TRUE(license_keys_.CanDecryptContent(c_key)); EXPECT_FALSE(license_keys_.CanDecryptContent(os_key)); - status = kKeyStatusExpired; - any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL, + any_change = license_keys_.ApplyStatusChange(kKeyStatusExpired, &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_FALSE(new_usable_keys); @@ -507,7 +505,6 @@ TEST_F(LicenseKeysTest, ExtractKeyStatuses) { TEST_F(LicenseKeysTest, KeyStatusChanges) { bool new_usable_keys = false; bool any_change = false; - CdmKeyStatus status; CdmKeyStatusMap key_status_map; StageOperatorSessionKeys(); StageContentKeys(); @@ -517,8 +514,7 @@ TEST_F(LicenseKeysTest, KeyStatusChanges) { ExpectKeyStatusesEqual(key_status_map, kKeyStatusInternalError); // change to pending - status = kKeyStatusPending; - any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL, + any_change = license_keys_.ApplyStatusChange(kKeyStatusPending, &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_FALSE(new_usable_keys); @@ -530,8 +526,7 @@ TEST_F(LicenseKeysTest, KeyStatusChanges) { ExpectKeyStatusesEqual(key_status_map, kKeyStatusPending); // change to pending (again) - status = kKeyStatusPending; - any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL, + any_change = license_keys_.ApplyStatusChange(kKeyStatusPending, &new_usable_keys); EXPECT_FALSE(any_change); EXPECT_FALSE(new_usable_keys); @@ -543,8 +538,7 @@ TEST_F(LicenseKeysTest, KeyStatusChanges) { ExpectKeyStatusesEqual(key_status_map, kKeyStatusPending); // change to usable - status = kKeyStatusUsable; - any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL, + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_TRUE(new_usable_keys); @@ -556,8 +550,7 @@ TEST_F(LicenseKeysTest, KeyStatusChanges) { ExpectKeyStatusesEqual(key_status_map, kKeyStatusUsable); // change to usable (again) - status = kKeyStatusUsable; - any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL, + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, &new_usable_keys); EXPECT_FALSE(any_change); EXPECT_FALSE(new_usable_keys); @@ -569,8 +562,7 @@ TEST_F(LicenseKeysTest, KeyStatusChanges) { ExpectKeyStatusesEqual(key_status_map, kKeyStatusUsable); // change to expired - status = kKeyStatusExpired; - any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL, + any_change = license_keys_.ApplyStatusChange(kKeyStatusExpired, &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_FALSE(new_usable_keys); @@ -585,14 +577,10 @@ TEST_F(LicenseKeysTest, KeyStatusChanges) { TEST_F(LicenseKeysTest, HdcpChanges) { bool new_usable_keys = false; bool any_change = false; - CdmKeyStatus status; - uint32_t resolution; - CryptoSession::HdcpCapability hdcp_level; CdmKeyStatusMap key_status_map; StageHdcpKeys(); - status = kKeyStatusUsable; - any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL, + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_TRUE(new_usable_keys); @@ -610,11 +598,9 @@ TEST_F(LicenseKeysTest, HdcpChanges) { EXPECT_TRUE(license_keys_.MeetsConstraints(ck_sw_crypto_HDCP_NO_OUTPUT)); EXPECT_TRUE(license_keys_.MeetsConstraints(ck_hw_secure_HDCP_NO_OUTPUT)); - status = kKeyStatusUsable; - resolution = 100; - hdcp_level = HDCP_NONE; - any_change = license_keys_.ApplyStatusChange(&status, &resolution, - &hdcp_level, &new_usable_keys); + license_keys_.ApplyConstraints(100, HDCP_NONE); + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, + &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_FALSE(new_usable_keys); @@ -637,11 +623,9 @@ TEST_F(LicenseKeysTest, HdcpChanges) { ExpectKeyStatusEqual(key_status_map, ck_hw_secure_HDCP_V2_1, kKeyStatusOutputNotAllowed); - status = kKeyStatusUsable; - resolution = 100; - hdcp_level = HDCP_V1; - any_change = license_keys_.ApplyStatusChange(&status, &resolution, - &hdcp_level, &new_usable_keys); + license_keys_.ApplyConstraints(100, HDCP_V1); + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, + &new_usable_keys); EXPECT_FALSE(any_change); EXPECT_FALSE(new_usable_keys); @@ -664,11 +648,9 @@ TEST_F(LicenseKeysTest, HdcpChanges) { ExpectKeyStatusEqual(key_status_map, ck_sw_crypto_HDCP_V2_1, kKeyStatusOutputNotAllowed); - status = kKeyStatusUsable; - resolution = 100; - hdcp_level = HDCP_V2_2; - any_change = license_keys_.ApplyStatusChange(&status, &resolution, - &hdcp_level, &new_usable_keys); + license_keys_.ApplyConstraints(100, HDCP_V2_2); + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, + &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_TRUE(new_usable_keys); @@ -692,11 +674,9 @@ TEST_F(LicenseKeysTest, HdcpChanges) { ExpectKeyStatusEqual(key_status_map, ck_sw_crypto_HDCP_NO_OUTPUT, kKeyStatusOutputNotAllowed); - status = kKeyStatusUsable; - resolution = 100; - hdcp_level = HDCP_NO_DIGITAL_OUTPUT; - any_change = license_keys_.ApplyStatusChange(&status, &resolution, - &hdcp_level, &new_usable_keys); + license_keys_.ApplyConstraints(100, HDCP_NO_DIGITAL_OUTPUT); + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, + &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_TRUE(new_usable_keys); @@ -720,11 +700,9 @@ TEST_F(LicenseKeysTest, HdcpChanges) { ExpectKeyStatusEqual(key_status_map, ck_hw_secure_HDCP_NO_OUTPUT, kKeyStatusUsable); - status = kKeyStatusUsable; - resolution = 100; - hdcp_level = HDCP_NONE; - any_change = license_keys_.ApplyStatusChange(&status, &resolution, - &hdcp_level, &new_usable_keys); + license_keys_.ApplyConstraints(100, HDCP_NONE); + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, + &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_FALSE(new_usable_keys); @@ -752,15 +730,11 @@ TEST_F(LicenseKeysTest, HdcpChanges) { TEST_F(LicenseKeysTest, ConstraintChanges) { bool new_usable_keys = false; bool any_change = false; - CdmKeyStatus status; - uint32_t resolution; - CryptoSession::HdcpCapability hdcp_level; CdmKeyStatusMap key_status_map; StageConstraintKeys(); // No constraints set by device - status = kKeyStatusUsable; - any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL, + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_TRUE(new_usable_keys); @@ -775,11 +749,9 @@ TEST_F(LicenseKeysTest, ConstraintChanges) { EXPECT_TRUE(license_keys_.MeetsConstraints(ck_NO_HDCP_dual_res)); // Low-res device, no HDCP support - status = kKeyStatusUsable; - resolution = dev_lo_res; - hdcp_level = HDCP_NONE; - any_change = license_keys_.ApplyStatusChange(&status, &resolution, - &hdcp_level, &new_usable_keys); + license_keys_.ApplyConstraints(dev_lo_res, HDCP_NONE); + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, + &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_FALSE(new_usable_keys); @@ -799,11 +771,9 @@ TEST_F(LicenseKeysTest, ConstraintChanges) { kKeyStatusOutputNotAllowed); // Hi-res device, HDCP_V1 support - status = kKeyStatusUsable; - resolution = dev_hi_res; - hdcp_level = HDCP_V1; - any_change = license_keys_.ApplyStatusChange(&status, &resolution, - &hdcp_level, &new_usable_keys); + license_keys_.ApplyConstraints(dev_hi_res, HDCP_V1); + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, + &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_TRUE(new_usable_keys); @@ -823,11 +793,9 @@ TEST_F(LicenseKeysTest, ConstraintChanges) { kKeyStatusOutputNotAllowed); // Lo-res device, HDCP V2.2 support - status = kKeyStatusUsable; - resolution = dev_lo_res; - hdcp_level = HDCP_V2_2; - any_change = license_keys_.ApplyStatusChange(&status, &resolution, - &hdcp_level, &new_usable_keys); + license_keys_.ApplyConstraints(dev_lo_res, HDCP_V2_2); + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, + &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_TRUE(new_usable_keys); @@ -848,11 +816,9 @@ TEST_F(LicenseKeysTest, ConstraintChanges) { kKeyStatusOutputNotAllowed); // Hi-res device, Maximal HDCP support - status = kKeyStatusUsable; - resolution = dev_hi_res; - hdcp_level = HDCP_NO_DIGITAL_OUTPUT; - any_change = license_keys_.ApplyStatusChange(&status, &resolution, - &hdcp_level, &new_usable_keys); + license_keys_.ApplyConstraints(dev_hi_res, HDCP_NO_DIGITAL_OUTPUT); + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, + &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_TRUE(new_usable_keys); @@ -873,11 +839,9 @@ TEST_F(LicenseKeysTest, ConstraintChanges) { kKeyStatusUsable); // Lo-res device, no HDCP support - status = kKeyStatusUsable; - resolution = dev_lo_res; - hdcp_level = HDCP_NONE; - any_change = license_keys_.ApplyStatusChange(&status, &resolution, - &hdcp_level, &new_usable_keys); + license_keys_.ApplyConstraints(dev_lo_res, HDCP_NONE); + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, + &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_TRUE(new_usable_keys); @@ -898,11 +862,9 @@ TEST_F(LicenseKeysTest, ConstraintChanges) { kKeyStatusOutputNotAllowed); // Too-high-res -- all keys rejected - status = kKeyStatusUsable; - resolution = dev_top_res; - hdcp_level = HDCP_NONE; - any_change = license_keys_.ApplyStatusChange(&status, &resolution, - &hdcp_level, &new_usable_keys); + license_keys_.ApplyConstraints(dev_top_res, HDCP_NONE); + any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable, + &new_usable_keys); EXPECT_TRUE(any_change); EXPECT_FALSE(new_usable_keys); diff --git a/libwvdrmengine/cdm/core/test/license_unittest.cpp b/libwvdrmengine/cdm/core/test/license_unittest.cpp index 158d1a93..c1a233d2 100644 --- a/libwvdrmengine/cdm/core/test/license_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/license_unittest.cpp @@ -81,8 +81,7 @@ const std::string kLicenseRequestSignature = a2bs_hex( class MockCryptoSession : public CryptoSession { public: - MockCryptoSession(metrics::CryptoMetrics* crypto_metrics) - : CryptoSession(crypto_metrics) { } + MockCryptoSession() : CryptoSession(NULL) { } MOCK_METHOD0(IsOpen, bool()); MOCK_METHOD1(GenerateRequestId, bool(std::string*)); MOCK_METHOD1(UsageInformationSupport, bool(bool*)); @@ -132,7 +131,7 @@ class CdmLicenseTest : public ::testing::Test { protected: virtual void SetUp() { clock_ = new MockClock(); - crypto_session_ = new MockCryptoSession(&crypto_metrics_); + crypto_session_ = new MockCryptoSession(); init_data_ = new MockInitializationData(CENC_INIT_DATA_FORMAT, kCencInitDataHdr + kCencPssh); policy_engine_ = new MockPolicyEngine(crypto_session_); @@ -153,7 +152,6 @@ class CdmLicenseTest : public ::testing::Test { CdmLicense* cdm_license_; MockClock* clock_; - metrics::CryptoMetrics crypto_metrics_; MockCryptoSession* crypto_session_; MockInitializationData* init_data_; MockPolicyEngine* policy_engine_; @@ -193,7 +191,7 @@ TEST_F(CdmLicenseTest, InitWithNullServiceCert) { CreateCdmLicense(); EXPECT_TRUE(cdm_license_->Init(NULL, kToken, kClientTokenDrmCert, - crypto_session_, policy_engine_)); + crypto_session_, policy_engine_)); } TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) { diff --git a/libwvdrmengine/cdm/core/test/policy_engine_constraints_unittest.cpp b/libwvdrmengine/cdm/core/test/policy_engine_constraints_unittest.cpp index 99dd6419..a3b7dd95 100644 --- a/libwvdrmengine/cdm/core/test/policy_engine_constraints_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/policy_engine_constraints_unittest.cpp @@ -1,10 +1,8 @@ // Copyright 2016 Google Inc. All Rights Reserved. -#include -#include - #include #include + #include "crypto_session.h" #include "license.h" #include "policy_engine.h" @@ -16,8 +14,6 @@ // protobuf generated classes. using video_widevine::License; using video_widevine::License_Policy; -using video_widevine::LicenseType; -using video_widevine::OFFLINE; using video_widevine::STREAMING; namespace wvcdm { @@ -80,47 +76,14 @@ class MockCdmEventListener : public WvCdmEventListener { int64_t new_expiry_time_seconds)); }; -struct LicenseTypeParam { - std::string name; - LicenseType license_type; - bool can_persist; -}; - -const LicenseTypeParam kStreamingParam{"Streaming", STREAMING, false}; -const LicenseTypeParam kOfflineParam{"Offline", OFFLINE, true}; - -void PrintTo(const LicenseTypeParam& param, std::ostream* os) { - *os << param.name; -} - -struct LicenseRenewalParam { - std::string name; - bool can_renew; - int64_t renewal_delay_seconds; -}; - -const LicenseRenewalParam kNoRenewalParam{"Cannot Renew", false, 0}; -const LicenseRenewalParam kShortRenewalParam{"Short Renewal Delay", true, 1}; -const LicenseRenewalParam kLongRenewalParam{"Long Renewal Delay", true, 60}; - -void PrintTo(const LicenseRenewalParam& param, std::ostream* os) { - *os << param.name; -} - } // namespace -class PolicyEngineConstraintsTest - : public TestWithParam> { +class PolicyEngineConstraintsTest : public Test { protected: virtual void SetUp() { mock_clock_ = new NiceMock(); current_time_ = 0; - // mock_event_listener_ is a StrictMock, but we don't care about renewal - // calls for these tests and want to ignore them. - EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_)) - .Times(AtLeast(0)); - policy_engine_.reset(new PolicyEngine(kSessionId, &mock_event_listener_, &crypto_session_)); InjectMockClock(); @@ -146,25 +109,19 @@ class PolicyEngineConstraintsTest } void SetupLicense() { - LicenseTypeParam typeParam; - LicenseRenewalParam renewalParam; - std::tie(typeParam, renewalParam) = GetParam(); - license_.set_license_start_time(current_time_); LicenseIdentification* id = license_.mutable_id(); id->set_version(1); - id->set_type(typeParam.license_type); + id->set_type(STREAMING); License_Policy* policy = license_.mutable_policy(); policy = license_.mutable_policy(); policy->set_can_play(true); - policy->set_can_persist(typeParam.can_persist); - policy->set_can_renew(renewalParam.can_renew); + policy->set_can_persist(false); policy->set_rental_duration_seconds(kRentalDuration); policy->set_playback_duration_seconds(kPlaybackDuration); policy->set_license_duration_seconds(kStreamingLicenseDuration); - policy->set_renewal_delay_seconds(renewalParam.renewal_delay_seconds); KeyList* keys = license_.mutable_key(); @@ -255,23 +212,35 @@ class PolicyEngineConstraintsTest License license_; }; -TEST_P(PolicyEngineConstraintsTest, IsPermissiveWithoutAResolution) { +TEST_F(PolicyEngineConstraintsTest, IsPermissiveWithoutAResolution) { EXPECT_CALL(*mock_clock_, GetCurrentTime()).Times(2); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(kSessionId, _)); - ExpectSessionKeysChange(kKeyStatusUsable, true); + + { + Sequence key_change; + ExpectSessionKeysChanges(kKeyId1, kKeyStatusUsable, + kKeyId2, kKeyStatusOutputNotAllowed, + kKeyId3, kKeyStatusUsable, + kKeyId4, kKeyStatusOutputNotAllowed, true); + } + + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); policy_engine_->SetLicense(license_); policy_engine_->OnTimerEvent(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId1)); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId2)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId2)); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId3)); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId4)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId4)); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId5)); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId6)); } -TEST_P(PolicyEngineConstraintsTest, HandlesResolutionsBasedOnConstraints) { +TEST_F(PolicyEngineConstraintsTest, HandlesResolutionsBasedOnConstraints) { { Sequence time; for (int i=0; i<4; ++i) { @@ -293,7 +262,6 @@ TEST_P(PolicyEngineConstraintsTest, HandlesResolutionsBasedOnConstraints) { DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), Return(true))); - policy_engine_->SetLicense(license_); policy_engine_->NotifyResolution(1, kTargetRes1); policy_engine_->OnTimerEvent(); @@ -323,7 +291,7 @@ TEST_P(PolicyEngineConstraintsTest, HandlesResolutionsBasedOnConstraints) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId6)); } -TEST_P(PolicyEngineConstraintsTest, +TEST_F(PolicyEngineConstraintsTest, RequestsHdcpImmediatelyAndOnlyAfterInterval) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(0)) @@ -331,17 +299,34 @@ TEST_P(PolicyEngineConstraintsTest, EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(kSessionId, _)); ExpectSessionKeysChange(kKeyStatusUsable, true); + { + Sequence key_change; + ExpectSessionKeysChanges(kKeyId1, kKeyStatusUsable, + kKeyId2, kKeyStatusOutputNotAllowed, + kKeyId3, kKeyStatusUsable, + kKeyId4, kKeyStatusOutputNotAllowed, true); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillOnce( + DoAll(SetArgPointee<0>(HDCP_V2_2), + Return(false))) + .WillOnce( + DoAll(SetArgPointee<0>(HDCP_V2_2), + Return(false))); + } int64_t start_time = current_time_ + 5; { InSequence calls; EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) .WillOnce( DoAll(SetArgPointee<0>(HDCP_V2_2), - Return(true))); + Return(false))); EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(start_time + kHdcpInterval / 2)) .WillOnce(Return(start_time + kHdcpInterval)); EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillOnce( + DoAll(SetArgPointee<0>(HDCP_V2_2), + Return(false))) .WillOnce( DoAll(SetArgPointee<0>(HDCP_V2_2), Return(true))); @@ -354,7 +339,7 @@ TEST_P(PolicyEngineConstraintsTest, policy_engine_->OnTimerEvent(); } -TEST_P(PolicyEngineConstraintsTest, DoesNotRequestHdcpWithoutALicense) { +TEST_F(PolicyEngineConstraintsTest, DoesNotRequestHdcpWithoutALicense) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(0)); EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)).Times(0); @@ -362,7 +347,7 @@ TEST_P(PolicyEngineConstraintsTest, DoesNotRequestHdcpWithoutALicense) { policy_engine_->OnTimerEvent(); } -TEST_P(PolicyEngineConstraintsTest, HandlesConstraintOverridingHdcp) { +TEST_F(PolicyEngineConstraintsTest, HandlesConstraintOverridingHdcp) { { Sequence time; for (int i=0; i<3; ++i) { @@ -404,7 +389,7 @@ TEST_P(PolicyEngineConstraintsTest, HandlesConstraintOverridingHdcp) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId6)); } -TEST_P(PolicyEngineConstraintsTest, HandlesNoHdcp) { +TEST_F(PolicyEngineConstraintsTest, HandlesNoHdcp) { { Sequence time; for (int i=0; i<3; ++i) { @@ -417,14 +402,13 @@ TEST_P(PolicyEngineConstraintsTest, HandlesNoHdcp) { ExpectSessionKeysChanges(kKeyId1, kKeyStatusUsable, kKeyId2, kKeyStatusOutputNotAllowed, kKeyId3, kKeyStatusUsable, - kKeyId4, kKeyStatusOutputNotAllowed, false); + kKeyId4, kKeyStatusOutputNotAllowed, true); ExpectSessionKeysChanges(kKeyId1, kKeyStatusUsable, kKeyId2, kKeyStatusOutputNotAllowed, kKeyId3, kKeyStatusOutputNotAllowed, kKeyId4, kKeyStatusOutputNotAllowed, false); } EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(kSessionId, _)); - ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) .WillRepeatedly( DoAll(SetArgPointee<0>(HDCP_NONE), @@ -451,7 +435,7 @@ TEST_P(PolicyEngineConstraintsTest, HandlesNoHdcp) { EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId6)); } -TEST_P(PolicyEngineConstraintsTest, IgnoresHdcpWithoutAResolution) { +TEST_F(PolicyEngineConstraintsTest, UsesDefaultHdcpWhenResolutionNotSet) { { Sequence time; for (int i=0; i<2; ++i) { @@ -459,23 +443,30 @@ TEST_P(PolicyEngineConstraintsTest, IgnoresHdcpWithoutAResolution) { .WillOnce(Return(i * 10)); } } - ExpectSessionKeysChange(kKeyStatusUsable, true); + + { + Sequence key_change; + ExpectSessionKeysChanges(kKeyId1, kKeyStatusUsable, + kKeyId2, kKeyStatusOutputNotAllowed, + kKeyId3, kKeyStatusUsable, + kKeyId4, kKeyStatusOutputNotAllowed, true); + } + EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(kSessionId, _)); - EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)).Times(0); + + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); policy_engine_->SetLicense(license_); policy_engine_->OnTimerEvent(); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId1)); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId2)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId2)); EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId3)); - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId4)); + EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId4)); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId5)); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId6)); } -INSTANTIATE_TEST_CASE_P(Default, PolicyEngineConstraintsTest, - Combine( - Values(kStreamingParam, kOfflineParam), - Values(kNoRenewalParam, kShortRenewalParam, kLongRenewalParam))); - } // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp b/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp index 41523a85..91302e7e 100644 --- a/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp @@ -18,6 +18,8 @@ namespace wvcdm { +using namespace testing; + namespace { const int64_t kDurationUnlimited = 0; const int64_t kLicenseStartTime = 1413517500; // ~ 01/01/2013 @@ -52,6 +54,14 @@ int64_t ParseInt(const std::string& str) { return ret; } +class HdcpOnlyMockCryptoSession : public CryptoSession { + public: + HdcpOnlyMockCryptoSession() : + CryptoSession(NULL) {} + + MOCK_METHOD2(GetHdcpCapabilities, bool(HdcpCapability*, HdcpCapability*)); +}; + class MockCdmEventListener : public WvCdmEventListener { public: MOCK_METHOD1(OnSessionRenewalNeeded, void(const CdmSessionId& session_id)); @@ -85,7 +95,8 @@ class PolicyEngineTest : public ::testing::Test { protected: virtual void SetUp() { policy_engine_.reset( - new PolicyEngine(kSessionId, &mock_event_listener_, NULL)); + new PolicyEngine(kSessionId, &mock_event_listener_, + &crypto_session_)); InjectMockClock(); license_.set_license_start_time(kLicenseStartTime); @@ -141,6 +152,7 @@ class PolicyEngineTest : public ::testing::Test { expected_has_new_usable_key)); } + StrictMock crypto_session_; StrictMock mock_event_listener_; MockClock* mock_clock_; scoped_ptr policy_engine_; @@ -164,6 +176,11 @@ TEST_F(PolicyEngineTest, PlaybackSuccess_OfflineLicense) { EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(true))); + policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); policy_engine_->OnTimerEvent(); @@ -185,6 +202,11 @@ TEST_F(PolicyEngineTest, PlaybackSuccess_StreamingLicense) { EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kLicenseStartTime + kLowDuration)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); policy_engine_->OnTimerEvent(); @@ -203,6 +225,11 @@ TEST_F(PolicyEngineTest, PlaybackFailed_CanPlayFalse) { ExpectSessionKeysChange(kKeyStatusExpired, false); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); @@ -223,6 +250,11 @@ TEST_F(PolicyEngineTest, LicenseExpired_RentalDurationExpiredWithoutPlayback) { .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) .WillOnce(Return(kLicenseStartTime + kLowDuration)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -253,6 +285,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_RentalDurationPassedWithPlayback) { .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) .WillOnce(Return(kLicenseStartTime + kLowDuration + 1)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -283,6 +320,11 @@ TEST_F(PolicyEngineTest, PlaybackFails_PlaybackDurationExpired) { .WillOnce(Return(playback_start_time + kPlaybackDuration - 2)) .WillOnce(Return(playback_start_time + kPlaybackDuration + 2)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -315,6 +357,11 @@ TEST_F(PolicyEngineTest, LicenseExpired_LicenseDurationExpiredWithoutPlayback) { .WillOnce(Return(kLicenseStartTime + kLowDuration - 1)) .WillOnce(Return(kLicenseStartTime + kLowDuration)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -346,6 +393,11 @@ TEST_F(PolicyEngineTest, PlaybackFails_ExpiryBeforeRenewalDelay_Offline) { .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 1)) .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 1)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -381,6 +433,11 @@ TEST_F(PolicyEngineTest, PlaybackFails_ExpiryBeforeRenewalDelay_Streaming) { .WillOnce(Return(kLicenseStartTime + kLicenseDuration - 1)) .WillOnce(Return(kLicenseStartTime + kLicenseDuration + 1)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -411,6 +468,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_RentalDuration0) { .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)) .WillOnce(Return(kLicenseStartTime + kLicenseDuration + 1)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -443,6 +505,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_PlaybackDuration0) { .WillOnce(Return(kLicenseStartTime + kLicenseDuration - 2)) .WillOnce(Return(kLicenseStartTime + kLicenseDuration + 2)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -477,6 +544,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_LicenseDuration0) { .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 1)) .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 1)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -514,65 +586,10 @@ TEST_F(PolicyEngineTest, PlaybackOk_PlaybackAndRental0) { EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration)); - policy_engine_->SetLicense(license_); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_PlaybackAndLicense0_WithoutPlayback) { - License_Policy* policy = license_.mutable_policy(); - policy->clear_license_duration_seconds(); - policy->clear_playback_duration_seconds(); - // Only |rental_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration - 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)); - - ExpectSessionKeysChange(kKeyStatusExpired, false); - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); - - policy_engine_->SetLicense(license_); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_PlaybackAndLicense0_WithPlayback) { - License_Policy* policy = license_.mutable_policy(); - policy->clear_license_duration_seconds(); - policy->clear_playback_duration_seconds(); - // Only |rental_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)); - - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, 0)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); @@ -580,68 +597,6 @@ TEST_F(PolicyEngineTest, PlaybackOk_PlaybackAndLicense0_WithPlayback) { EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_RentalAndLicense0_WithoutPlayback) { - License_Policy* policy = license_.mutable_policy(); - policy->clear_license_duration_seconds(); - policy->clear_rental_duration_seconds(); - // Only |playback_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration + 10)); - - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0)); - - policy_engine_->SetLicense(license_); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); -} - -TEST_F(PolicyEngineTest, PlaybackOk_RentalAndLicense0_WithPlayback) { - License_Policy* policy = license_.mutable_policy(); - policy->clear_license_duration_seconds(); - policy->clear_rental_duration_seconds(); - // Only |playback_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 10)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10)); - - ExpectSessionKeysChange(kKeyStatusExpired, false); - ExpectSessionKeysChange(kKeyStatusUsable, true); - EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, 0)); - EXPECT_CALL(mock_event_listener_, - OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); - - policy_engine_->SetLicense(license_); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); } TEST_F(PolicyEngineTest, PlaybackOk_Durations0) { @@ -659,6 +614,16 @@ TEST_F(PolicyEngineTest, PlaybackOk_Durations0) { ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, NEVER_EXPIRES)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); @@ -677,6 +642,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_LicenseWithFutureStartTime) { .WillOnce(Return(kLicenseStartTime)) .WillOnce(Return(kPlaybackStartTime)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusPending, false); EXPECT_CALL(mock_event_listener_, @@ -711,6 +681,11 @@ TEST_F(PolicyEngineTest, PlaybackFailed_CanRenewFalse) { .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 10)) .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 1)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -752,6 +727,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccess) { .WillOnce(Return(kLicenseStartTime + license_renewal_delay + kLicenseRenewalRetryInterval + 10)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -804,6 +784,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccess_WithFutureStartTime) { .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 30)) .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 60)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -856,6 +841,11 @@ TEST_F(PolicyEngineTest, LicenseExpired_RenewFailedVersionNotUpdated) { .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 40)) .WillOnce(Return(kLicenseStartTime + kLowDuration + 10)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -914,6 +904,11 @@ TEST_F(PolicyEngineTest, PlaybackFailed_RepeatedRenewFailures) { .WillOnce(Return(kLicenseStartTime + kLicenseDuration - 15)) .WillOnce(Return(kLicenseStartTime + kLicenseDuration)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -970,6 +965,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccessAfterExpiry) { .WillOnce(Return(new_license_start_time)) .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 20)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -1040,6 +1040,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewSuccessAfterFailures) { .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 67)) .WillOnce(Return(kLicenseStartTime + license_renewal_delay + 200)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -1094,6 +1099,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_RenewedWithUsage) { .WillOnce(Return(kLicenseStartTime + 20)) .WillOnce(Return(kLicenseStartTime + 40)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence s; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -1152,6 +1162,11 @@ TEST_F(PolicyEngineTest, MultipleKeysInLicense) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(kLicenseStartTime + 1)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + ExpectSessionKeysChange(kKeyStatusUsable, kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, _)); @@ -1174,6 +1189,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_SoftEnforcePlaybackDuration) { .WillOnce(Return(kLicenseStartTime + kLicenseDuration - 5)) .WillOnce(Return(kLicenseStartTime + kLicenseDuration + 5)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence seq; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -1207,6 +1227,11 @@ TEST_F(PolicyEngineTest, LicenseExpired_SoftEnforceLoadBeforeExpire) { .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 5)) .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence seq; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -1231,6 +1256,11 @@ TEST_F(PolicyEngineTest, LicenseExpired_SoftEnforceLoadAfterExpire) { .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 5)) .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence seq; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -1260,6 +1290,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_GracePeriod) { .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 5)) .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 5)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence seq; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -1299,6 +1334,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_GracePeriodWithLoad) { .WillOnce(Return(kNewPlaybackStartTime + kPlaybackDuration - 5)) .WillOnce(Return(kNewPlaybackStartTime + kPlaybackDuration + 5)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence seq; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -1337,6 +1377,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_GracePeriodWithExpiredLoad) { .WillOnce(Return(kNewPlaybackStartTime)) .WillOnce(Return(kNewPlaybackStartTime)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence seq; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -1364,6 +1409,11 @@ TEST_F(PolicyEngineTest, PlaybackOk_CanStoreGracePeriod) { .WillOnce(Return(kPlaybackStartTime + 50)) .WillOnce(Return(kPlaybackStartTime + kGracePeriod + 2)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + InSequence seq; ExpectSessionKeysChange(kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, @@ -1505,6 +1555,11 @@ TEST_F(PolicyEngineKeyAllowedUsageTest, AllowedUsageBasic) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(kLicenseStartTime + 1)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + ExpectSessionKeysChange(kKeyStatusUsable, kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, _)); @@ -1560,6 +1615,11 @@ TEST_F(PolicyEngineKeyAllowedUsageTest, AllowedUsageGeneric) { EXPECT_CALL(*mock_clock_, GetCurrentTime()) .WillOnce(Return(kLicenseStartTime + 1)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + ExpectSessionKeysChange(kKeyStatusUsable, kKeyStatusUsable, true); EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, _)); @@ -1585,7 +1645,7 @@ class PolicyEngineQueryTest : public PolicyEngineTest { protected: virtual void SetUp() { PolicyEngineTest::SetUp(); - policy_engine_.reset(new PolicyEngine(kSessionId, NULL, NULL)); + policy_engine_.reset(new PolicyEngine(kSessionId, NULL, &crypto_session_)); InjectMockClock(); // Use a STREAMING license policy. @@ -1623,6 +1683,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess) { .WillOnce(Return(kLicenseStartTime + 1)) .WillOnce(Return(kLicenseStartTime + 100)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); CdmQueryMap query_info; @@ -1645,6 +1710,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackNotBegun) { .WillOnce(Return(kLicenseStartTime + 100)) .WillOnce(Return(kLicenseStartTime + 200)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); CdmQueryMap query_info; @@ -1681,6 +1751,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackBegun) { .WillOnce(Return(kLicenseStartTime + 150)) .WillOnce(Return(kLicenseStartTime + 200)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(true))); + policy_engine_->SetLicense(license_); CdmQueryMap query_info; @@ -1730,6 +1805,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_Offline) { .WillOnce(Return(kLicenseStartTime + 200)) .WillOnce(Return(kLicenseStartTime + 300)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->OnTimerEvent(); @@ -1812,6 +1892,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_CanPlayFalse) { .WillOnce(Return(kLicenseStartTime + 5)) .WillOnce(Return(kLicenseStartTime + 100)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); @@ -1847,6 +1932,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDurationExpired) { .WillOnce(Return(kLicenseStartTime + kLowDuration)) .WillOnce(Return(kLicenseStartTime + kLowDuration + 5)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); @@ -1885,6 +1975,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDurationExpired) { .WillOnce(Return(playback_start_time + 2 + kLowDuration)) .WillOnce(Return(playback_start_time + 5 + kLowDuration)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); @@ -1919,6 +2014,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseDurationExpired) { .WillOnce(Return(kLicenseStartTime + kLowDuration)) .WillOnce(Return(kLicenseStartTime + kLowDuration + 5)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); @@ -1957,6 +2057,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalDuration0) { .WillOnce(Return(kLicenseStartTime + kLowDuration)) .WillOnce(Return(kLicenseStartTime + kLowDuration + 5)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); @@ -1998,6 +2103,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackDuration0) { .WillOnce(Return(kLicenseStartTime + kHighDuration + 2)) .WillOnce(Return(kLicenseStartTime + kHighDuration + 5)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); @@ -2050,6 +2160,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseDuration0) { .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration)) .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 5)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); @@ -2073,303 +2188,6 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseDuration0) { EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); } -TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackAndRental0) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(kDurationUnlimited); - policy->set_playback_duration_seconds(kDurationUnlimited); - policy->set_license_duration_seconds(kLowDuration); - // Only |license_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + kLowDuration - 10)) - .WillOnce(Return(kLicenseStartTime + kLowDuration + 10)) - .WillOnce(Return(kLicenseStartTime + kLowDuration + 10)); - - policy_engine_->SetLicense(license_); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(10, ParseInt(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - ParseInt(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, ParseInt(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - ParseInt(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackAndLicense0_WithoutPlayback) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(kRentalDuration); - policy->set_playback_duration_seconds(kDurationUnlimited); - policy->set_license_duration_seconds(kDurationUnlimited); - // Only |rental_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration - 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration - 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)); - - policy_engine_->SetLicense(license_); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(10, ParseInt(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - ParseInt(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, ParseInt(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - ParseInt(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_PlaybackAndLicense0_WithPlayback) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(kRentalDuration); - policy->set_playback_duration_seconds(kDurationUnlimited); - policy->set_license_duration_seconds(kDurationUnlimited); - // Only |rental_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration - 10)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration - 10)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration + 10)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration + 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)) - .WillOnce(Return(kLicenseStartTime + kRentalDuration + 10)); - - policy_engine_->SetLicense(license_); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(kRentalDuration - kPlaybackDuration + 10, - ParseInt(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - ParseInt(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(kRentalDuration - kPlaybackDuration - 10, - ParseInt(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - ParseInt(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, ParseInt(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(LLONG_MAX, - ParseInt(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalAndLicense0_WithoutPlayback) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(kDurationUnlimited); - policy->set_playback_duration_seconds(kPlaybackDuration); - policy->set_license_duration_seconds(kDurationUnlimited); - // Only |playback_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + 10)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration + 10)) - .WillOnce(Return(kLicenseStartTime + kPlaybackDuration + 10)); - - policy_engine_->SetLicense(license_); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(LLONG_MAX, - ParseInt(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration, - ParseInt(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(LLONG_MAX, - ParseInt(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration, - ParseInt(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - -TEST_F(PolicyEngineQueryTest, QuerySuccess_RentalAndLicense0_WithPlayback) { - License_Policy* policy = license_.mutable_policy(); - policy->set_rental_duration_seconds(kDurationUnlimited); - policy->set_playback_duration_seconds(kPlaybackDuration); - policy->set_license_duration_seconds(kDurationUnlimited); - // Only |playback_duration_seconds| set. - - EXPECT_CALL(*mock_clock_, GetCurrentTime()) - .WillOnce(Return(kLicenseStartTime + 1)) - .WillOnce(Return(kPlaybackStartTime)) - .WillOnce(Return(kPlaybackStartTime + 10)) - .WillOnce(Return(kPlaybackStartTime + 10)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 10)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 10)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10)) - .WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 10)); - - policy_engine_->SetLicense(license_); - policy_engine_->BeginDecryption(); - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - CdmQueryMap query_info; - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(LLONG_MAX, - ParseInt(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(kPlaybackDuration - 10, - ParseInt(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(LLONG_MAX, - ParseInt(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(10, - ParseInt(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); - - policy_engine_->OnTimerEvent(); - - EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId)); - EXPECT_FALSE(policy_engine_->CanDecryptContent(kSomeRandomKeyId)); - - EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(QUERY_VALUE_STREAMING, query_info[QUERY_KEY_LICENSE_TYPE]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_PLAY_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_FALSE, query_info[QUERY_KEY_PERSIST_ALLOWED]); - EXPECT_EQ(QUERY_VALUE_TRUE, query_info[QUERY_KEY_RENEW_ALLOWED]); - - EXPECT_EQ(0, - ParseInt(query_info[QUERY_KEY_LICENSE_DURATION_REMAINING])); - EXPECT_EQ(0, - ParseInt(query_info[QUERY_KEY_PLAYBACK_DURATION_REMAINING])); - EXPECT_EQ(kRenewalServerUrl, query_info[QUERY_KEY_RENEWAL_SERVER_URL]); -} - TEST_F(PolicyEngineQueryTest, QuerySuccess_Durations0) { License_Policy* policy = license_.mutable_policy(); policy->set_rental_duration_seconds(kDurationUnlimited); @@ -2384,6 +2202,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_Durations0) { .WillOnce(Return(kLicenseStartTime + kHighDuration + 9)) .WillOnce(Return(kLicenseStartTime + kHighDuration + 15)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); @@ -2417,6 +2240,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_LicenseWithFutureStartTime) { .WillOnce(Return(kLicenseStartTime + 10)) .WillOnce(Return(kLicenseStartTime + 25)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->OnTimerEvent(); @@ -2468,6 +2296,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_Renew) { .WillOnce(Return(kLicenseStartTime + license_renewal_delay + kLicenseRenewalRetryInterval + 15)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); @@ -2521,6 +2354,11 @@ TEST_F(PolicyEngineQueryTest, QuerySuccess_RenewWithFutureStartTime) { .WillOnce(Return(kLicenseStartTime + license_renewal_delay + kLicenseRenewalRetryInterval + 40)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); @@ -2596,6 +2434,11 @@ TEST_F(PolicyEngineTest, SetLicenseForReleaseAfterSetLicense) { EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration)); + EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)) + .WillRepeatedly( + DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT), + Return(false))); + policy_engine_->SetLicense(license_); policy_engine_->BeginDecryption(); policy_engine_->OnTimerEvent(); diff --git a/libwvdrmengine/cdm/core/test/service_certificate_unittest.cpp b/libwvdrmengine/cdm/core/test/service_certificate_unittest.cpp index f6de7718..2a1684de 100644 --- a/libwvdrmengine/cdm/core/test/service_certificate_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/service_certificate_unittest.cpp @@ -44,16 +44,13 @@ const std::string kTestSignedCertificate = a2bs_hex( class MockCryptoSession : public CryptoSession { public: - MockCryptoSession(metrics::CryptoMetrics* crypto_metrics) - : CryptoSession(crypto_metrics) { } + MockCryptoSession() : CryptoSession(NULL) { } MOCK_METHOD2(GetRandom, bool(size_t, uint8_t*)); }; class ServiceCertificateTest : public ::testing::Test { protected: - virtual void SetUp() { - crypto_session_ = new MockCryptoSession(&crypto_metrics_); - } + virtual void SetUp() { crypto_session_ = new MockCryptoSession(); } virtual void TearDown() { if (crypto_session_) delete crypto_session_; @@ -64,7 +61,6 @@ class ServiceCertificateTest : public ::testing::Test { } ServiceCertificate* service_certificate_; - metrics::CryptoMetrics crypto_metrics_; MockCryptoSession* crypto_session_; }; @@ -111,7 +107,7 @@ class StubCdmClientPropertySet : public CdmClientPropertySet { }; TEST_F(ServiceCertificateTest, InitSuccess) { - MockCryptoSession crypto_session(&crypto_metrics_); + MockCryptoSession crypto_session; CreateServiceCertificate(); service_certificate_->Init(kTestSessionId1); @@ -119,7 +115,6 @@ TEST_F(ServiceCertificateTest, InitSuccess) { } TEST_F(ServiceCertificateTest, InitPrivacyModeRequired) { - MockCryptoSession crypto_session(&crypto_metrics_); StubCdmClientPropertySet property_set; property_set.enable_privacy_mode(); @@ -133,7 +128,6 @@ TEST_F(ServiceCertificateTest, InitPrivacyModeRequired) { } TEST_F(ServiceCertificateTest, InitServiceCertificatePresent) { - MockCryptoSession crypto_session(&crypto_metrics_); StubCdmClientPropertySet property_set; property_set.enable_privacy_mode(); @@ -143,16 +137,15 @@ TEST_F(ServiceCertificateTest, InitServiceCertificatePresent) { Properties::AddSessionPropertySet(kTestSessionId1, &property_set); CreateServiceCertificate(); - std::string raw_service_certificate; + std::string service_certificate; EXPECT_TRUE(Properties::GetServiceCertificate(kTestSessionId1, - &raw_service_certificate)); + &service_certificate)); EXPECT_EQ(NO_ERROR, - service_certificate_->Init(raw_service_certificate)); + service_certificate_->Init(service_certificate)); EXPECT_TRUE(service_certificate_->HasCertificate()); } TEST_F(ServiceCertificateTest, SetServiceCertificate) { - MockCryptoSession crypto_session(&crypto_metrics_); StubCdmClientPropertySet property_set; property_set.enable_privacy_mode(); diff --git a/libwvdrmengine/cdm/core/test/test_printers.cpp b/libwvdrmengine/cdm/core/test/test_printers.cpp index 8bd5d165..3d81fb68 100644 --- a/libwvdrmengine/cdm/core/test/test_printers.cpp +++ b/libwvdrmengine/cdm/core/test/test_printers.cpp @@ -249,6 +249,12 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { case RELEASE_ALL_USAGE_INFO_ERROR_2: *os << "RELEASE_ALL_USAGE_INFO_ERROR_2"; break; + case RELEASE_ALL_USAGE_INFO_ERROR_3: + *os << "RELEASE_ALL_USAGE_INFO_ERROR_3"; + break; + case RELEASE_ALL_USAGE_INFO_ERROR_4: + *os << "RELEASE_ALL_USAGE_INFO_ERROR_4"; + break; case RELEASE_KEY_ERROR: *os << "RELEASE_KEY_ERROR"; break; case RELEASE_KEY_REQUEST_ERROR: *os << "RELEASE_KEY_REQUEST_ERROR"; @@ -302,8 +308,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { break; case STORE_LICENSE_ERROR_2: *os << "STORE_LICENSE_ERROR_2"; break; - case STORE_LICENSE_ERROR_4: *os << "STORE_LICENSE_ERROR_4"; - break; case STORE_USAGE_INFO_ERROR: *os << "STORE_USAGE_INFO_ERROR"; break; case UNPROVISION_ERROR_1: *os << "UNPROVISION_ERROR_1"; @@ -450,6 +454,8 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { break; case INVALID_PARAMETERS_ENG_17: *os << "INVALID_PARAMETERS_ENG_17"; break; + case INVALID_PARAMETERS_ENG_18: *os << "INVALID_PARAMETERS_ENG_18"; + break; case CERT_PROVISIONING_CLIENT_TOKEN_ERROR_1: *os << "CERT_PROVISIONING_CLIENT_TOKEN_ERROR_1"; break; @@ -478,8 +484,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { case LOAD_USAGE_HEADER_UNKNOWN_ERROR: *os << "LOAD_USAGE_HEADER_UNKNOWN_ERROR"; break; - case INVALID_PARAMETERS_ENG_18: *os << "INVALID_PARAMETERS_ENG_18"; - break; case INSUFFICIENT_CRYPTO_RESOURCES_3: *os << "INSUFFICIENT_CRYPTO_RESOURCES_3"; break; @@ -515,8 +519,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { case COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR: *os << "COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR"; break; - case LIST_LICENSES_ERROR: *os << "LIST_LICENSES_ERROR"; - break; case INVALID_PARAMETERS_ENG_23: *os << "INVALID_PARAMETERS_ENG_23"; break; @@ -552,15 +554,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { break; case USAGE_INVALID_LOAD_ENTRY: *os << "USAGE_INVALID_LOAD_ENTRY"; break; - case RELEASE_ALL_USAGE_INFO_ERROR_4: - *os << "RELEASE_ALL_USAGE_INFO_ERROR_4"; - break; - case RELEASE_ALL_USAGE_INFO_ERROR_5: - *os << "RELEASE_ALL_USAGE_INFO_ERROR_5"; - break; - case RELEASE_ALL_USAGE_INFO_ERROR_6: - *os << "RELEASE_ALL_USAGE_INFO_ERROR_6"; - break; case RELEASE_USAGE_INFO_FAILED: *os << "RELEASE_USAGE_INFO_FAILED"; break; case INCORRECT_USAGE_SUPPORT_TYPE_1: @@ -575,8 +568,11 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { case KEY_NOT_FOUND_IN_SESSION: *os << "KEY_NOT_FOUND_IN_SESSION"; break; - case NO_USAGE_ENTRIES: - *os << "NO_USAGE_ENTRIES"; + case NO_USAGE_ENTRIES: *os << "NO_USAGE_ENTRIES"; + break; + case LIST_LICENSE_ERROR_1: *os << "LIST_LICENSE_ERROR_1"; + break; + case LIST_LICENSE_ERROR_2: *os << "LIST_LICENSE_ERROR_2"; break; case LIST_USAGE_ERROR_1: *os << "LIST_USAGE_ERROR_1"; break; @@ -588,24 +584,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { break; case DELETE_USAGE_ERROR_3: *os << "DELETE_USAGE_ERROR_3"; break; - case PRIVACY_MODE_ERROR_1: *os << "PRIVACY_MODE_ERROR_1"; - break; - case PRIVACY_MODE_ERROR_2: *os << "PRIVACY_MODE_ERROR_2"; - break; - case PRIVACY_MODE_ERROR_3: *os << "PRIVACY_MODE_ERROR_3"; - break; - case EMPTY_RESPONSE_ERROR_1: *os << "EMPTY_RESPONSE_ERROR_1"; - break; - case INVALID_PARAMETERS_ENG_24: *os << "INVALID_PARAMETERS_ENG_24"; - break; - case PARSE_RESPONSE_ERROR_1: *os << "PARSE_RESPONSE_ERROR_1"; - break; - case PARSE_RESPONSE_ERROR_2: *os << "PARSE_RESPONSE_ERROR_2"; - break; - case PARSE_RESPONSE_ERROR_3: *os << "PARSE_RESPONSE_ERROR_3"; - break; - case PARSE_RESPONSE_ERROR_4: *os << "PARSE_RESPONSE_ERROR_4"; - break; default: *os << "Unknown CdmResponseType"; diff --git a/libwvdrmengine/cdm/core/test/url_request.cpp b/libwvdrmengine/cdm/core/test/url_request.cpp index 6e862a01..3db0fddf 100644 --- a/libwvdrmengine/cdm/core/test/url_request.cpp +++ b/libwvdrmengine/cdm/core/test/url_request.cpp @@ -167,9 +167,9 @@ bool UrlRequest::PostRequest(const std::string& data) { bool UrlRequest::PostCertRequestInQueryString(const std::string& data) { std::string path = socket_.resource_path(); - path.append("&signedRequest="); + path.append((path.find('?') == std::string::npos) ? "?" : "&"); + path.append("signedRequest="); path.append(data); - return PostRequestWithPath(path, ""); } diff --git a/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp b/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp index fcb870de..5be41123 100644 --- a/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp @@ -47,7 +47,7 @@ const CdmUsageEntryInfo kUsageEntryInfoSecureStop3 = { .key_set_id = "secure_stop_key_set_3", .usage_info_file_name = "usage_info_file_3"}; const CdmUsageEntryInfo kUsageEntryInfoStorageTypeUnknown = { - .storage_type = kStorageUnknown, + .storage_type = kStorageTypeUnknown, .key_set_id = "", .usage_info_file_name = ""}; const std::vector kEmptyLicenseList; @@ -140,8 +140,7 @@ class MockDeviceFiles : public DeviceFiles { class MockCryptoSession : public CryptoSession { public: - MockCryptoSession(metrics::CryptoMetrics* metrics) - : CryptoSession(metrics) {} + MockCryptoSession() : CryptoSession(NULL) {} MOCK_METHOD1(Open, CdmResponseType(SecurityLevel)); MOCK_METHOD1(LoadUsageTableHeader, CdmResponseType(const CdmUsageTableHeader&)); @@ -171,7 +170,7 @@ class UsageTableHeaderTest : public ::testing::Test { virtual void SetUp() { // UsageTableHeader will take ownership of the pointer device_files_ = new MockDeviceFiles(); - crypto_session_ = new MockCryptoSession(&crypto_metrics_); + crypto_session_ = new MockCryptoSession(); usage_table_header_ = new UsageTableHeader(); // usage_table_header_ object takes ownership of these objects @@ -197,7 +196,6 @@ class UsageTableHeaderTest : public ::testing::Test { } MockDeviceFiles* device_files_; - metrics::CryptoMetrics crypto_metrics_; MockCryptoSession* crypto_session_; UsageTableHeader* usage_table_header_; }; @@ -252,6 +250,8 @@ TEST_P(UsageTableHeaderInitializationTest, Upgrade_UnableToRetrieveLicenses) { EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(NotNull())) .WillOnce( DoAll(SetArgPointee<0>(kEmptyUsageTableHeader), Return(NO_ERROR))); + // TODO: Why not being called? + //EXPECT_CALL(*device_files_, DeleteAllLicenses()).WillOnce(Return(true)); EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader, kEmptyUsageEntryInfoVector)) .Times(2) diff --git a/libwvdrmengine/cdm/include/ami_adapter.h b/libwvdrmengine/cdm/include/ami_adapter.h index 42bc4b1f..75999233 100644 --- a/libwvdrmengine/cdm/include/ami_adapter.h +++ b/libwvdrmengine/cdm/include/ami_adapter.h @@ -4,19 +4,22 @@ #define CDM_AMI_ADAPTER_H_ #include -#include #include +#include "report.h" + namespace wvcdm { -class AmiAdapter { +class AmiAdapter : public metrics::Report { public: AmiAdapter(); AmiAdapter(int64_t parent); ~AmiAdapter(); + metrics::Report* NewReport() const; + void UpdateString(const std::string& metric_id, const std::string& value); void UpdateInt32(const std::string& metric_id, int32_t value); void UpdateInt64(const std::string& metric_id, int64_t value); diff --git a/libwvdrmengine/cdm/include/cdm_identifier.h b/libwvdrmengine/cdm/include/cdm_identifier.h index 618c4e5b..e99b9d71 100644 --- a/libwvdrmengine/cdm/include/cdm_identifier.h +++ b/libwvdrmengine/cdm/include/cdm_identifier.h @@ -25,17 +25,11 @@ struct CdmIdentifier { // The origin. May be blank if the app does not set an origin, which is // the likely behavior of most non-web-browser apps. std::string origin; - - // The application package name provided by the application. This is used to - // provide a friendly name of the application package for the purposes of - // logging and metrics. - std::string app_package_name; }; // Provide comparison operators inline bool operator==(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { - return lhs.spoid == rhs.spoid && lhs.origin == rhs.origin - && lhs.app_package_name == rhs.app_package_name; + return lhs.spoid == rhs.spoid && lhs.origin == rhs.origin; } inline bool operator!=(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { @@ -43,11 +37,8 @@ inline bool operator!=(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { } inline bool operator<(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { - return (lhs.spoid < rhs.spoid) - || ((lhs.spoid == rhs.spoid) - && (lhs.origin < rhs.origin - || (lhs.origin == rhs.origin - && lhs.app_package_name < rhs.app_package_name))); + return (lhs.spoid < rhs.spoid) || + ((lhs.spoid == rhs.spoid) && lhs.origin < rhs.origin); } inline bool operator>(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { @@ -65,8 +56,7 @@ inline bool operator>=(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { // Provide default static const CdmIdentifier kDefaultCdmIdentifier = { EMPTY_SPOID, - EMPTY_ORIGIN, - EMPTY_APP_PACKAGE_NAME + EMPTY_ORIGIN }; } // namespace wvcdm diff --git a/libwvdrmengine/cdm/include/wv_content_decryption_module.h b/libwvdrmengine/cdm/include/wv_content_decryption_module.h index 1d9b59d5..8d0b5d27 100644 --- a/libwvdrmengine/cdm/include/wv_content_decryption_module.h +++ b/libwvdrmengine/cdm/include/wv_content_decryption_module.h @@ -11,7 +11,7 @@ #include "cdm_identifier.h" #include "file_store.h" #include "lock.h" -#include "metrics.pb.h" +#include "metrics_front_end.h" #include "timer.h" #include "wv_cdm_types.h" @@ -99,17 +99,13 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler { // Secure stop related methods virtual CdmResponseType GetUsageInfo(const std::string& app_id, - const CdmIdentifier& identifier, CdmUsageInfo* usage_info); virtual CdmResponseType GetUsageInfo(const std::string& app_id, const CdmSecureStopId& ssid, - const CdmIdentifier& identifier, CdmUsageInfo* usage_info); - virtual CdmResponseType ReleaseAllUsageInfo(const std::string& app_id, - const CdmIdentifier& identifier); + virtual CdmResponseType ReleaseAllUsageInfo(const std::string& app_id); virtual CdmResponseType ReleaseUsageInfo( - const CdmUsageInfoReleaseMessage& message, - const CdmIdentifier& identifier); + const CdmUsageInfoReleaseMessage& message); // Accept encrypted buffer and decrypt data. // Decryption parameters that need to be specified are @@ -126,10 +122,6 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler { // Validate a passed-in service certificate virtual bool IsValidServiceCertificate(const std::string& certificate); - // Retrieve the serialized metrics from CdmEngine and CdmSession instances - // that have been closed. - virtual void GetSerializedMetrics(std::string* serialized_metrics); - private: struct CdmInfo { CdmInfo(); @@ -144,10 +136,6 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler { // Finds the CdmEngine instance for the given session id, returning NULL if // not found. CdmEngine* GetCdmForSessionId(const std::string& session_id); - // Closes CdmEngine instances that don't have any open sessions. Also stores - // metrics data for closed CdmEngine instances. - // Callers must acquire the cdms_lock_ before calling this method. - void CloseCdmsWithoutSessions(); uint32_t GenerateSessionSharingId(); @@ -168,8 +156,8 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler { // This contains weak pointers to the CDM instances contained in |cdms_|. std::map cdm_by_session_id_; - // The metrics for cdm engines and sessions that have been closed. - drm_metrics::MetricsGroup metrics_; + metrics::Report* report_root_; + metrics::MetricsFrontEnd* front_end_; CORE_DISALLOW_COPY_AND_ASSIGN(WvContentDecryptionModule); }; diff --git a/libwvdrmengine/cdm/metrics/include/event_metric.h b/libwvdrmengine/cdm/metrics/include/event_metric.h index dcfd5223..f9179b64 100644 --- a/libwvdrmengine/cdm/metrics/include/event_metric.h +++ b/libwvdrmengine/cdm/metrics/include/event_metric.h @@ -6,14 +6,19 @@ #define WVCDM_METRICS_EVENT_METRIC_H_ #include +#include #include +#include +#include +#include +#include #include #include -#include "distribution.h" -#include "field_tuples.h" #include "lock.h" -#include "metric_serialization.h" + +#include "distribution.h" +#include "metric_publisher.h" namespace wvcdm { namespace metrics { @@ -22,11 +27,11 @@ class EventMetricTest; // This base class provides the common defintion used by all templated // instances of EventMetric. -class BaseEventMetric : public MetricSerializable { +class BaseEventMetric : public MetricPublisher { public: - // Send metric values to the MetricSerializer. |serializer| must + // Publish metric values to the MetricNotification. |subscriber| must // not be null and is owned by the caller. - virtual void Serialize(MetricSerializer* serializer); + virtual void Publish(MetricNotification* subscriber); protected: // Instantiates a BaseEventMetric. @@ -55,6 +60,14 @@ class BaseEventMetric : public MetricSerializable { Lock internal_lock_; }; +// This is a placeholder type for unused type parameters. +struct Unused { + // Required for compilation. Should never be used. + inline friend std::ostream& operator<< (std::ostream& out, const Unused&) + { return out; } +}; + + // This class converts the size_t value into the highest power of two // below the value. E.g. for 7, the value is 4. For 11, the value is 8. // This class is intended to simplify the use of EventMetric Fields that may @@ -100,7 +113,7 @@ class Pow2Bucket { // on certain "field" values. For example, if a particular operation can run in // one of two modes, it's useful to track the latency of the operation in each // mode separately. You can use Fields to define how to breakdown the -// statistics. Each Field is a separate dimension. The statistics for each +// statistics. Each Field is a separate dimention. The statistics for each // combination of field values are tracked independently. // // Example usage: @@ -110,22 +123,19 @@ class Pow2Bucket { // // my_metric.Record(1, 7, 23); // (latency value, request type, error code). // -// The EventMetric supports serialization. A call to Serialize will -// serialize all values to the provided MetricsSerializer instance. +// A MetricNotification may be used to allow the EventMetric instance to +// notify that an update occurred and provide the updated value. // -// example: -// -// class MyMetricSerializer : public MetricSerializer { +// class MyMetricNotification : public MetricNotification { // // Add implementation here. // } // -// MyMetricSerializer serializer; -// my_metric.Serialize(&serializer); -// -template +// MyMetricNotification notification; +// my_metric.Publish(notification); +template class EventMetric : public BaseEventMetric { public: // Create an EventMetric instance with the name |metric_name|. @@ -152,33 +162,96 @@ class EventMetric : public BaseEventMetric { // Record will update the statistics of the EventMetric broken down by the // given field values. void Record(double value, - F1 field1 = util::Unused(), - F2 field2 = util::Unused(), - F3 field3 = util::Unused(), - F4 field4 = util::Unused()); + F1 field1 = Unused(), + F2 field2 = Unused(), + F3 field3 = Unused(), + F4 field4 = Unused()); private: friend class EventMetricTest; std::vector field_names_; }; +// This is an internal namespace for helper functions only. +namespace impl { + +// This method formats the collection of field name/value pairs. +// The format of the string is: +// +// [{field:value[&field:value]*}] +// +// If there are no pairs, returns a blank string. +// +// TODO(blueeyes): Add a check for the count of field_names and the count +// of field values (check that the fields are not type Unused). +template +std::string MakeFieldNameString(const std::vector& field_names, + const F1 field1, const F2 field2, + const F3 field3, const F4 field4) { + std::stringstream field_name_and_values; + std::vector::const_iterator field_name_iterator = + field_names.begin(); + if (field_name_iterator == field_names.end()) { + return field_name_and_values.str(); + } + // There is at least one name/value pair. prepend open brace. + field_name_and_values << "{"; + field_name_and_values << *field_name_iterator << ':' << field1; + if (++field_name_iterator == field_names.end()) { + field_name_and_values << "}"; + return field_name_and_values.str(); + } + field_name_and_values << '&' << *field_name_iterator << ':' << field2; + if (++field_name_iterator == field_names.end()) { + field_name_and_values << "}"; + return field_name_and_values.str(); + } + field_name_and_values << '&' << *field_name_iterator << ':' << field3; + if (++field_name_iterator == field_names.end()) { + field_name_and_values << "}"; + return field_name_and_values.str(); + } + field_name_and_values << '&' << *field_name_iterator << ':' << field4; + field_name_and_values << "}"; + return field_name_and_values.str(); +} + +// This specialization of the helper method is a shortcut for EventMetric +// instances with no fields. +template<> +inline std::string MakeFieldNameString( + const std::vector& /* field_names */, + const Unused /* unused1 */, const Unused /* unused2 */, + const Unused /* unused3 */, const Unused /* unused4 */) { + return ""; +} + +// This helper function appends the field names to a vector of strings. +inline void AppendFieldNames(std::vector* field_name_vector, + int field_count, ...) { + va_list field_names; + + va_start(field_names, field_count); + for (int x = 0; x < field_count; x++) { + field_name_vector->push_back(va_arg(field_names, const char*)); + } + va_end(field_names); +} + +} // namespace impl + // Overloaded template constructor implementations for EventMetric. template EventMetric::EventMetric( const std::string& metric_name) - : BaseEventMetric(metric_name) { - ASSERT_METRIC_UNUSED_START_FROM(1); -} + : BaseEventMetric(metric_name) {} template EventMetric::EventMetric( const std::string& metric_name, const char* field_name) : BaseEventMetric(metric_name) { - ASSERT_METRIC_UNUSED_START_FROM(2); - util::AppendFieldNames(&field_names_, - util::FirstUnusedType::value - 1, - field_name); + impl::AppendFieldNames(&field_names_, 1, field_name); } template EventMetric::EventMetric( @@ -186,10 +259,7 @@ EventMetric::EventMetric( const char* field_name1, const char* field_name2) : BaseEventMetric(metric_name) { - ASSERT_METRIC_UNUSED_START_FROM(3); - util::AppendFieldNames(&field_names_, - util::FirstUnusedType::value - 1, - field_name1, field_name2); + impl::AppendFieldNames(&field_names_, 2, field_name1, field_name2); } template EventMetric::EventMetric( @@ -198,10 +268,8 @@ EventMetric::EventMetric( const char* field_name2, const char* field_name3) : BaseEventMetric(metric_name) { - ASSERT_METRIC_UNUSED_START_FROM(4); - util::AppendFieldNames(&field_names_, - util::FirstUnusedType::value - 1, - field_name1, field_name2, field_name3); + impl::AppendFieldNames(&field_names_, + 3, field_name1, field_name2, field_name3); } template EventMetric::EventMetric( @@ -211,10 +279,8 @@ EventMetric::EventMetric( const char* field_name3, const char* field_name4) : BaseEventMetric(metric_name) { - ASSERT_METRIC_UNUSED_START_FROM(5); - util::AppendFieldNames(&field_names_, - util::FirstUnusedType::value - 1, - field_name1, field_name2, + impl::AppendFieldNames(&field_names_, + 4, field_name1, field_name2, field_name3, field_name4); } @@ -222,7 +288,7 @@ template void EventMetric::Record( double value, F1 field1, F2 field2, F3 field3, F4 field4) { std::string field_name_values = - util::MakeFieldNameString(field_names_, field1, field2, field3, field4); + impl::MakeFieldNameString(field_names_, field1, field2, field3, field4); BaseEventMetric::Record(field_name_values, value); } diff --git a/libwvdrmengine/cdm/metrics/include/field_tuples.h b/libwvdrmengine/cdm/metrics/include/field_tuples.h index 495ccefe..40d964c0 100644 --- a/libwvdrmengine/cdm/metrics/include/field_tuples.h +++ b/libwvdrmengine/cdm/metrics/include/field_tuples.h @@ -17,6 +17,9 @@ namespace wvcdm { namespace metrics { namespace util { +// TODO(blueeyes): Change to use C++ 11 support for variadic template args. +// The C++ 03 pattern is no longer needed since we require C++11. b/68766426. + // This is a placeholder type for unused type parameters. It aids in supporting // templated classes with "variable" type arguments. struct Unused { diff --git a/libwvdrmengine/cdm/metrics/include/metrics_collections.h b/libwvdrmengine/cdm/metrics/include/metrics_collections.h index 15e25133..be161e2c 100644 --- a/libwvdrmengine/cdm/metrics/include/metrics_collections.h +++ b/libwvdrmengine/cdm/metrics/include/metrics_collections.h @@ -10,11 +10,9 @@ #include #include -#include "counter_metric.h" #include "event_metric.h" #include "metrics.pb.h" #include "OEMCryptoCENC.h" -#include "value_metric.h" #include "wv_cdm_types.h" // This definition indicates that a given metric does not need timing @@ -88,64 +86,70 @@ class CryptoMetrics { void Serialize(drm_metrics::MetricsGroup* metrics); /* CRYPTO SESSION */ - // TODO(blueeyes): Convert this to crypto_session_default_security_level_. - ValueMetric crypto_session_security_level_; - CounterMetric crypto_session_delete_all_usage_reports_; - CounterMetric crypto_session_delete_multiple_usage_information_; + EventMetric crypto_session_delete_all_usage_reports_; + EventMetric crypto_session_delete_multiple_usage_information_; EventMetric crypto_session_generic_decrypt_; EventMetric crypto_session_generic_encrypt_; EventMetric crypto_session_generic_sign_; EventMetric crypto_session_generic_verify_; - CounterMetric crypto_session_get_device_unique_id_; - CounterMetric crypto_session_get_token_; - ValueMetric crypto_session_life_span_; + EventMetric crypto_session_get_device_unique_id_; + EventMetric crypto_session_get_security_level_; + EventMetric crypto_session_get_system_id_; + EventMetric crypto_session_get_token_; + EventMetric<> crypto_session_life_span_; EventMetric crypto_session_load_certificate_private_key_; - EventMetric crypto_session_open_; // This is the requested security level. - ValueMetric crypto_session_system_id_; + EventMetric crypto_session_open_; EventMetric crypto_session_update_usage_information_; - ValueMetric crypto_session_usage_information_support_; + EventMetric crypto_session_usage_information_support_; /* OEMCRYPTO */ - ValueMetric oemcrypto_api_version_; - CounterMetric oemcrypto_close_session_; - EventMetric oemcrypto_copy_buffer_; - ValueMetric oemcrypto_current_hdcp_capability_; - CounterMetric oemcrypto_deactivate_usage_entry_; + EventMetric oemcrypto_api_version_; + EventMetric oemcrypto_close_session_; + EventMetric oemcrypto_copy_buffer_; + EventMetric oemcrypto_deactivate_usage_entry_; EventMetric oemcrypto_decrypt_cenc_; - CounterMetric oemcrypto_delete_usage_entry_; - CounterMetric oemcrypto_delete_usage_table_; + EventMetric oemcrypto_delete_usage_entry_; + EventMetric oemcrypto_delete_usage_table_; EventMetric oemcrypto_derive_keys_from_session_key_; - CounterMetric oemcrypto_force_delete_usage_entry_; + EventMetric oemcrypto_force_delete_usage_entry_; EventMetric oemcrypto_generate_derived_keys_; - CounterMetric oemcrypto_generate_nonce_; + EventMetric oemcrypto_generate_nonce_; EventMetric oemcrypto_generate_rsa_signature_; EventMetric oemcrypto_generate_signature_; EventMetric oemcrypto_generic_decrypt_; EventMetric oemcrypto_generic_encrypt_; EventMetric oemcrypto_generic_sign_; EventMetric oemcrypto_generic_verify_; - CounterMetric oemcrypto_get_device_id_; - EventMetric oemcrypto_get_key_data_; - CounterMetric oemcrypto_get_oem_public_certificate_; - CounterMetric oemcrypto_get_random_; + EventMetric oemcrypto_get_device_id_; + EventMetric oemcrypto_get_hdcp_capability_; + EventMetric oemcrypto_get_key_data_; + EventMetric oemcrypto_get_max_number_of_sessions_; + EventMetric oemcrypto_get_number_of_open_sessions_; + EventMetric oemcrypto_get_oem_public_certificate_; + EventMetric oemcrypto_get_provisioning_method_; + EventMetric oemcrypto_get_random_; EventMetric oemcrypto_initialize_; - EventMetric oemcrypto_install_keybox_; - ValueMetric oemcrypto_is_anti_rollback_hw_present_; - ValueMetric oemcrypto_is_keybox_valid_; + EventMetric oemcrypto_install_keybox_; + EventMetric oemcrypto_is_anti_rollback_hw_present_; + EventMetric oemcrypto_is_keybox_valid_; EventMetric oemcrypto_load_device_rsa_key_; EventMetric oemcrypto_load_keys_; - ValueMetric oemcrypto_max_hdcp_capability_; - ValueMetric oemcrypto_max_number_of_sessions_; - ValueMetric oemcrypto_number_of_open_sessions_; - ValueMetric oemcrypto_provisioning_method_; + EventMetric oemcrypto_load_test_keybox_; + EventMetric oemcrypto_load_test_rsa_key_; + EventMetric oemcrypto_open_session_; EventMetric oemcrypto_refresh_keys_; - CounterMetric oemcrypto_report_usage_; + EventMetric oemcrypto_report_usage_; EventMetric oemcrypto_rewrap_device_rsa_key_; EventMetric oemcrypto_rewrap_device_rsa_key_30_; - ValueMetric oemcrypto_security_patch_level_; + EventMetric oemcrypto_security_level_; + EventMetric oemcrypto_security_patch_level_; EventMetric oemcrypto_select_key_; - ValueMetric oemcrypto_supports_usage_table_; - CounterMetric oemcrypto_update_usage_table_; + EventMetric oemcrypto_supports_usage_table_; + EventMetric oemcrypto_update_usage_table_; EventMetric oemcrypto_wrap_keybox_; + + /* Internal OEMCrypto Metrics */ + EventMetric oemcrypto_initialization_mode_; + EventMetric oemcrypto_l1_api_version_; }; // This class contains session-scoped metrics. All properties and @@ -174,16 +178,16 @@ class SessionMetrics { // This instance retains ownership of the object. CryptoMetrics* GetCryptoMetrics() { return &crypto_metrics_; } + // Metrics collected at the session level. + EventMetric<> cdm_session_life_span_; + EventMetric cdm_session_renew_key_; + EventMetric cdm_session_restore_offline_session_; + EventMetric 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); - // Metrics collected at the session level. - ValueMetric cdm_session_life_span_; // Milliseconds. - EventMetric cdm_session_renew_key_; - CounterMetric cdm_session_restore_offline_session_; - CounterMetric cdm_session_restore_usage_session_; - private: void SerializeSessionMetrics(drm_metrics::MetricsGroup* metric_group); CdmSessionId session_id_; @@ -191,45 +195,6 @@ class SessionMetrics { CryptoMetrics crypto_metrics_; }; -// This class contains metrics for the OEMCrypto Dynamic Adapter. They are -// separated from other metrics because they need to be encapsulated in a -// singleton object. This is because the dynamic adapter uses the OEMCrypto -// function signatures and contract and cannot be extended to inject -// dependencies. -// -// Operations for this metrics class are serialized since these particular -// metrics may be accessed by a separate thread during intialize even as -// the metric may be serialized. -class OemCryptoDynamicAdapterMetrics { - public: - explicit OemCryptoDynamicAdapterMetrics(); - - // Set methods for OEMCrypto metrics. - void SetInitializationMode(OEMCryptoInitializationMode mode); - void SetL1ApiVersion(uint32_t version); - void SetL1MinApiVersion(uint32_t version); - - // 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); - - // Clears the existing metric values. - void Clear(); - - private: - Lock adapter_lock_; - ValueMetric oemcrypto_initialization_mode_; - ValueMetric oemcrypto_l1_api_version_; - ValueMetric oemcrypto_l1_min_api_version_; -}; - -// This will fetch the singleton instance for dynamic adapter metrics. -// This method is safe only if we use C++ 11. In C++ 11, static function-local -// initialization is guaranteed to be threadsafe. We return the reference to -// avoid non-guaranteed destructor order problems. Effectively, the destructor -// is never run for the created instance. -OemCryptoDynamicAdapterMetrics& GetDynamicAdapterMetricsInstance(); - // 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. @@ -263,34 +228,29 @@ class EngineMetrics { void Serialize(drm_metrics::MetricsGroup* metric_group, bool completed_only, bool clear_serialized_sessions); - void SetAppPackageName(const std::string& app_package_name); - // Metrics recorded at the engine level. EventMetric cdm_engine_add_key_; - ValueMetric cdm_engine_cdm_version_; - CounterMetric cdm_engine_close_session_; - ValueMetric cdm_engine_creation_time_millis_; - EventMetric cdm_engine_decrypt_; - CounterMetric cdm_engine_find_session_for_key_; + EventMetric cdm_engine_close_session_; + EventMetric cdm_engine_decrypt_; + EventMetric cdm_engine_find_session_for_key_; EventMetric cdm_engine_generate_key_request_; EventMetric cdm_engine_get_provisioning_request_; EventMetric cdm_engine_get_usage_info_; EventMetric cdm_engine_handle_provisioning_response_; - ValueMetric cdm_engine_life_span_; // Milliseconds - CounterMetric cdm_engine_open_key_set_session_; - CounterMetric cdm_engine_open_session_; + EventMetric<> cdm_engine_life_span_; + EventMetric cdm_engine_open_key_set_session_; + EventMetric cdm_engine_open_session_; EventMetric cdm_engine_query_key_status_; - CounterMetric cdm_engine_release_all_usage_info_; - CounterMetric cdm_engine_release_usage_info_; - CounterMetric cdm_engine_remove_keys_; + EventMetric cdm_engine_release_all_usage_info_; + EventMetric cdm_engine_release_usage_info_; + EventMetric cdm_engine_remove_keys_; EventMetric cdm_engine_restore_key_; - CounterMetric cdm_engine_unprovision_; + EventMetric cdm_engine_unprovision_; private: Lock session_metrics_lock_; std::vector session_metrics_list_; CryptoMetrics crypto_metrics_; - std::string app_package_name_; void SerializeEngineMetrics(drm_metrics::MetricsGroup* out); }; diff --git a/libwvdrmengine/cdm/metrics/include/value_metric.h b/libwvdrmengine/cdm/metrics/include/value_metric.h index 5c0704ef..6de010ee 100644 --- a/libwvdrmengine/cdm/metrics/include/value_metric.h +++ b/libwvdrmengine/cdm/metrics/include/value_metric.h @@ -86,12 +86,6 @@ class ValueMetric : public MetricSerializable { // Get the current value of the metric. const T& GetValue() { return value_; } - // Clears the indicators that the metric or error was set. - void Clear() { - has_value_ = false; - has_error_ = false; - } - private: std::string metric_name_; T value_; diff --git a/libwvdrmengine/cdm/metrics/src/event_metric.cpp b/libwvdrmengine/cdm/metrics/src/event_metric.cpp index 06e2ac51..1f9bba5d 100644 --- a/libwvdrmengine/cdm/metrics/src/event_metric.cpp +++ b/libwvdrmengine/cdm/metrics/src/event_metric.cpp @@ -32,29 +32,26 @@ void BaseEventMetric::Record(const std::string& field_names_values, distribution->Record(value); } -void BaseEventMetric::Serialize(MetricSerializer* serializer) { +void BaseEventMetric::Publish(MetricNotification* notification) { AutoLock lock(internal_lock_); for (std::map::iterator it = value_map_.begin(); it != value_map_.end(); it++) { - serializer->SetInt64( + notification->UpdateInt64( metric_name_ + "/count" + it->first, it->second->Count()); - serializer->SetDouble( + notification->UpdateDouble( metric_name_ + "/mean" + it->first, it->second->Mean()); - // Only publish additional information if there was more than one sample. - if (it->second->Count() > 1) { - serializer->SetDouble( - metric_name_ + "/variance" + it->first, - it->second->Variance()); - serializer->SetDouble( - metric_name_ + "/min" + it->first, - it->second->Min()); - serializer->SetDouble( - metric_name_ + "/max" + it->first, - it->second->Max()); - } + notification->UpdateDouble( + metric_name_ + "/variance" + it->first, + it->second->Variance()); + notification->UpdateDouble( + metric_name_ + "/min" + it->first, + it->second->Min()); + notification->UpdateDouble( + metric_name_ + "/max" + it->first, + it->second->Max()); } } diff --git a/libwvdrmengine/cdm/metrics/src/metrics.proto b/libwvdrmengine/cdm/metrics/src/metrics.proto index 02c5af24..4df1fe53 100644 --- a/libwvdrmengine/cdm/metrics/src/metrics.proto +++ b/libwvdrmengine/cdm/metrics/src/metrics.proto @@ -33,7 +33,4 @@ message MetricsGroup { // Allow multiple sub groups of metrics. repeated MetricsGroup metric_sub_group = 2; - - // Name of the application package associated with the metrics. - optional string app_package_name = 3; } diff --git a/libwvdrmengine/cdm/metrics/src/metrics_collections.cpp b/libwvdrmengine/cdm/metrics/src/metrics_collections.cpp index 2e81d5dd..34b9722c 100644 --- a/libwvdrmengine/cdm/metrics/src/metrics_collections.cpp +++ b/libwvdrmengine/cdm/metrics/src/metrics_collections.cpp @@ -63,13 +63,11 @@ namespace wvcdm { namespace metrics { CryptoMetrics::CryptoMetrics() : - crypto_session_security_level_( - "/drm/widevine/crypto_session/security_level"), crypto_session_delete_all_usage_reports_( - "/drm/widevine/crypto_session/delete_all_usage_reports", + "/drm/widevine/crypto_session/delete_all_usage_reports/time", "error"), crypto_session_delete_multiple_usage_information_( - "/drm/widevine/crypto_session/delete_multiple_usage_information", + "/drm/widevine/crypto_session/delete_multiple_usage_information/time", "error"), crypto_session_generic_decrypt_( "/drm/widevine/crypto_session/generic_decrypt/time", @@ -92,13 +90,20 @@ CryptoMetrics::CryptoMetrics() : "length", "signing_algorithm"), crypto_session_get_device_unique_id_( - "/drm/widevine/crypto_session/get_device_unique_id", + "/drm/widevine/crypto_session/get_device_unique_id/time", "success"), + crypto_session_get_security_level_( + "/drm/widevine/crypto_session/get_security_level/time", + "security_level"), + crypto_session_get_system_id_( + "/drm/widevine/crypto_session/get_system_id/time", + "success", + "system_id"), crypto_session_get_token_( - "/drm/widevine/crypto_session/get_token", + "/drm/widevine/crypto_session/get_token/time", "success"), crypto_session_life_span_( - "/drm/widevine/crypto_session/life_span"), + "/drm/widevine/crypto_session/life_span/time"), crypto_session_load_certificate_private_key_( "/drm/widevine/crypto_session/load_certificate_private_key/time", "success"), @@ -106,48 +111,48 @@ CryptoMetrics::CryptoMetrics() : "/drm/widevine/crypto_session/open/time", "error", "requested_security_level"), - crypto_session_system_id_( - "/drm/widevine/crypto_session/system_id"), crypto_session_update_usage_information_( "/drm/widevine/crypto_session/update_usage_information/time", "error"), crypto_session_usage_information_support_( - "/drm/widevine/crypto_session/usage_information_support"), + "/drm/widevine/crypto_session/usage_information_support/time", + "success"), oemcrypto_api_version_( - "/drm/widevine/oemcrypto/api_version"), + "/drm/widevine/oemcrypto/api_version/time", + "version", + "requested_security_level"), oemcrypto_close_session_( - "/drm/widevine/oemcrypto/close_session", + "/drm/widevine/oemcrypto/close_session/time", "oemcrypto_error"), oemcrypto_copy_buffer_( "/drm/widevine/oemcrypto/copy_buffer/time", "oemcrypto_error", + "requested_security_level", "length"), - oemcrypto_current_hdcp_capability_( - "/drm/widevine/oemcrypto/current_hdcp_capability"), oemcrypto_deactivate_usage_entry_( - "/drm/widevine/oemcrypto/deactivate_usage_entry", + "/drm/widevine/oemcrypto/deactivate_usage_entry/time", "oemcrypto_error"), oemcrypto_decrypt_cenc_( "/drm/widevine/oemcrypto/decrypt_cenc/time", "oemcrypto_error", "length"), oemcrypto_delete_usage_entry_( - "/drm/widevine/oemcrypto/delete_usage_entry", + "/drm/widevine/oemcrypto/delete_usage_entry/time", "oemcrypto_error"), oemcrypto_delete_usage_table_( - "/drm/widevine/oemcrypto/delete_usage_table", + "/drm/widevine/oemcrypto/delete_usage_table/time", "oemcrypto_error"), oemcrypto_derive_keys_from_session_key_( "/drm/widevine/oemcrypto/derive_keys_from_session_key/time", "oemcrypto_error"), oemcrypto_force_delete_usage_entry_( - "/drm/widevine/oemcrypto/force_delete_usage_entry", + "/drm/widevine/oemcrypto/force_delete_usage_entry/time", "oemcrypto_error"), oemcrypto_generate_derived_keys_( "/drm/widevine/oemcrypto/generate_derived_keys/time", "oemcrypto_error"), oemcrypto_generate_nonce_( - "/drm/widevine/oemcrypto/generate_nonce", + "/drm/widevine/oemcrypto/generate_nonce/time", "oemcrypto_error"), oemcrypto_generate_rsa_signature_( "/drm/widevine/oemcrypto/generate_rsa_signature/time", @@ -174,47 +179,73 @@ CryptoMetrics::CryptoMetrics() : "oemcrypto_error", "length"), oemcrypto_get_device_id_( - "/drm/widevine/oemcrypto/get_device_id", - "oemcrypto_error"), + "/drm/widevine/oemcrypto/get_device_id/time", + "oemcrypto_error", + "requested_security_level"), + oemcrypto_get_hdcp_capability_( + "/drm/widevine/oemcrypto/get_hdcp_capability/time", + "oemcrypto_error", + "requested_security_level"), oemcrypto_get_key_data_( "/drm/widevine/oemcrypto/get_key_data/time", "oemcrypto_error", - "length"), + "length", + "requested_security_level"), + oemcrypto_get_max_number_of_sessions_( + "/drm/widevine/oemcrypto/get_max_number_of_sessions/time", + "oemcrypto_error", + "requested_security_level"), + oemcrypto_get_number_of_open_sessions_( + "/drm/widevine/oemcrypto/get_number_of_open_sessions/time", + "oemcrypto_error", + "requested_security_level"), oemcrypto_get_oem_public_certificate_( - "/drm/widevine/oemcrypto/get_oem_public_certificate", + "/drm/widevine/oemcrypto/get_oem_public_certificate/time", "oemcrypto_error"), + oemcrypto_get_provisioning_method_( + "/drm/widevine/oemcrypto/get_provisioning_method/time", + "method", + "requested_security_level"), oemcrypto_get_random_( - "/drm/widevine/oemcrypto/get_random", - "oemcrypto_error"), + "/drm/widevine/oemcrypto/get_random/time", + "oemcrypto_error", + "length"), oemcrypto_initialize_( "/drm/widevine/oemcrypto/initialize/time", "oemcrypto_error"), oemcrypto_install_keybox_( "/drm/widevine/oemcrypto/install_keybox/time", - "oemcrypto_error"), + "oemcrypto_error", + "requested_security_level"), oemcrypto_is_anti_rollback_hw_present_( - "/drm/widevine/oemcrypto/is_anti_rollback_hw_present"), + "/drm/widevine/oemcrypto/is_anti_rollback_hw_present/time", + "success", + "requested_security_level"), oemcrypto_is_keybox_valid_( - "/drm/widevine/oemcrypto/is_keybox_valid"), + "/drm/widevine/oemcrypto/is_keybox_valid/time", + "oemcrypto_error", + "requested_security_level"), oemcrypto_load_device_rsa_key_( "/drm/widevine/oemcrypto/load_device_rsa_key/time", "oemcrypto_error"), oemcrypto_load_keys_( "/drm/widevine/oemcrypto/load_keys/time", "oemcrypto_error"), - oemcrypto_max_hdcp_capability_( - "/drm/widevine/oemcrypto/max_hdcp_capability"), - oemcrypto_max_number_of_sessions_( - "/drm/widevine/oemcrypto/max_number_of_sessions"), - oemcrypto_number_of_open_sessions_( - "/drm/widevine/oemcrypto/number_of_open_sessions"), - oemcrypto_provisioning_method_( - "/drm/widevine/oemcrypto/provisioning_method"), + oemcrypto_load_test_keybox_( + "/drm/widevine/oemcrypto/load_test_keybox/time", + "oemcrypto_error"), + oemcrypto_load_test_rsa_key_( + "/drm/widevine/oemcrypto/load_test_rsa_key/time", + "oemcrypto_error"), + oemcrypto_open_session_( + "/drm/widevine/oemcrypto/open_session/time", + "oemcrypto_error", + "requested_security_level"), oemcrypto_refresh_keys_( "/drm/widevine/oemcrypto/refresh_keys/time", "oemcrypto_error"), oemcrypto_report_usage_( - "/drm/widevine/oemcrypto/report_usage", + "/drm/widevine/oemcrypto/report_usage/time", "oemcrypto_error"), oemcrypto_rewrap_device_rsa_key_( "/drm/widevine/oemcrypto/rewrap_device_rsa_key/time", @@ -222,25 +253,38 @@ CryptoMetrics::CryptoMetrics() : oemcrypto_rewrap_device_rsa_key_30_( "/drm/widevine/oemcrypto/rewrap_device_rsa_key_30/time", "oemcrypto_error"), + oemcrypto_security_level_( + "/drm/widevine/oemcrypto/security_level/time", + "security_level", + "requested_security_level"), oemcrypto_security_patch_level_( - "/drm/widevine/oemcrypto/security_patch_level"), + "/drm/widevine/oemcrypto/security_patch_level/time", + "patch", + "requested_security_level"), oemcrypto_select_key_( "/drm/widevine/oemcrypto/select_key/time", "oemcrypto_error"), oemcrypto_supports_usage_table_( - "/drm/widevine/oemcrypto/supports_usage_table"), + "/drm/widevine/oemcrypto/supports_usage_table/time", + "oemcrypto_error", + "requested_security_level"), oemcrypto_update_usage_table_( - "/drm/widevine/oemcrypto/update_usage_table", + "/drm/widevine/oemcrypto/update_usage_table/time", "oemcrypto_error"), oemcrypto_wrap_keybox_( "/drm/widevine/oemcrypto/wrap_keybox/time", - "oemcrypto_error") { -} + "oemcrypto_error"), + oemcrypto_initialization_mode_( + "/drm/widevine/oemcrypto/initialization_mode", + "initialization_mode"), + oemcrypto_l1_api_version_( + "/drm/widevine/oemcrypto/l1_api_version", + "version", + "min_version") {} void CryptoMetrics::Serialize(MetricsGroup* metrics) { ProtoMetricSerializer serializer(metrics); /* CRYPTO SESSION */ - crypto_session_security_level_.Serialize(&serializer); crypto_session_delete_all_usage_reports_.Serialize(&serializer); crypto_session_delete_multiple_usage_information_.Serialize(&serializer); crypto_session_generic_decrypt_.Serialize(&serializer); @@ -248,11 +292,12 @@ void CryptoMetrics::Serialize(MetricsGroup* metrics) { crypto_session_generic_sign_.Serialize(&serializer); crypto_session_generic_verify_.Serialize(&serializer); crypto_session_get_device_unique_id_.Serialize(&serializer); + crypto_session_get_security_level_.Serialize(&serializer); + crypto_session_get_system_id_.Serialize(&serializer); crypto_session_get_token_.Serialize(&serializer); crypto_session_life_span_.Serialize(&serializer); crypto_session_load_certificate_private_key_.Serialize(&serializer); crypto_session_open_.Serialize(&serializer); - crypto_session_system_id_.Serialize(&serializer); crypto_session_update_usage_information_.Serialize(&serializer); crypto_session_usage_information_support_.Serialize(&serializer); @@ -260,7 +305,6 @@ void CryptoMetrics::Serialize(MetricsGroup* metrics) { oemcrypto_api_version_.Serialize(&serializer); oemcrypto_close_session_.Serialize(&serializer); oemcrypto_copy_buffer_.Serialize(&serializer); - oemcrypto_current_hdcp_capability_.Serialize(&serializer); oemcrypto_deactivate_usage_entry_.Serialize(&serializer); oemcrypto_decrypt_cenc_.Serialize(&serializer); oemcrypto_delete_usage_entry_.Serialize(&serializer); @@ -276,8 +320,12 @@ void CryptoMetrics::Serialize(MetricsGroup* metrics) { oemcrypto_generic_sign_.Serialize(&serializer); oemcrypto_generic_verify_.Serialize(&serializer); oemcrypto_get_device_id_.Serialize(&serializer); + oemcrypto_get_hdcp_capability_.Serialize(&serializer); oemcrypto_get_key_data_.Serialize(&serializer); + oemcrypto_get_max_number_of_sessions_.Serialize(&serializer); + oemcrypto_get_number_of_open_sessions_.Serialize(&serializer); oemcrypto_get_oem_public_certificate_.Serialize(&serializer); + oemcrypto_get_provisioning_method_.Serialize(&serializer); oemcrypto_get_random_.Serialize(&serializer); oemcrypto_initialize_.Serialize(&serializer); oemcrypto_install_keybox_.Serialize(&serializer); @@ -285,32 +333,36 @@ void CryptoMetrics::Serialize(MetricsGroup* metrics) { oemcrypto_is_keybox_valid_.Serialize(&serializer); oemcrypto_load_device_rsa_key_.Serialize(&serializer); oemcrypto_load_keys_.Serialize(&serializer); - oemcrypto_max_hdcp_capability_.Serialize(&serializer); - oemcrypto_max_number_of_sessions_.Serialize(&serializer); - oemcrypto_number_of_open_sessions_.Serialize(&serializer); - oemcrypto_provisioning_method_.Serialize(&serializer); + oemcrypto_load_test_keybox_.Serialize(&serializer); + oemcrypto_load_test_rsa_key_.Serialize(&serializer); + oemcrypto_open_session_.Serialize(&serializer); oemcrypto_refresh_keys_.Serialize(&serializer); oemcrypto_report_usage_.Serialize(&serializer); oemcrypto_rewrap_device_rsa_key_.Serialize(&serializer); oemcrypto_rewrap_device_rsa_key_30_.Serialize(&serializer); + oemcrypto_security_level_.Serialize(&serializer); oemcrypto_security_patch_level_.Serialize(&serializer); oemcrypto_select_key_.Serialize(&serializer); oemcrypto_supports_usage_table_.Serialize(&serializer); oemcrypto_update_usage_table_.Serialize(&serializer); oemcrypto_wrap_keybox_.Serialize(&serializer); + + /* Internal OEMCrypto Metrics */ + oemcrypto_initialization_mode_.Serialize(&serializer); + oemcrypto_l1_api_version_.Serialize(&serializer); } SessionMetrics::SessionMetrics() : cdm_session_life_span_( - "/drm/widevine/cdm_session/life_span"), + "/drm/widevine/cdm_session/life_span/time"), cdm_session_renew_key_( "/drm/widevine/cdm_session/renew_key/time", "error"), cdm_session_restore_offline_session_( - "/drm/widevine/cdm_session/restore_offline_session", + "/drm/widevine/cdm_session/restore_offline_session/time", "error"), cdm_session_restore_usage_session_( - "/drm/widevine/cdm_session/restore_usage_session", + "/drm/widevine/cdm_session/restore_usage_session/time", "error"), completed_(false) { } @@ -330,77 +382,18 @@ void SessionMetrics::SerializeSessionMetrics(MetricsGroup* metric_group) { cdm_session_restore_usage_session_.Serialize(&serializer); } - -OemCryptoDynamicAdapterMetrics::OemCryptoDynamicAdapterMetrics() : - oemcrypto_initialization_mode_( - "/drm/widevine/oemcrypto/initialization_mode"), - oemcrypto_l1_api_version_( - "/drm/widevine/oemcrypto/l1_api_version"), - oemcrypto_l1_min_api_version_( - "/drm/widevine/oemcrypto/l1_min_api_version") { -} - -void OemCryptoDynamicAdapterMetrics::SetInitializationMode( - OEMCryptoInitializationMode mode) { - AutoLock lock(adapter_lock_); - oemcrypto_initialization_mode_.Record(mode); -} - -void OemCryptoDynamicAdapterMetrics::SetL1ApiVersion(uint32_t version) { - AutoLock lock(adapter_lock_); - oemcrypto_l1_api_version_.Record(version); -} - -void OemCryptoDynamicAdapterMetrics::SetL1MinApiVersion(uint32_t version) { - AutoLock lock(adapter_lock_); - oemcrypto_l1_min_api_version_.Record(version); -} - -void OemCryptoDynamicAdapterMetrics::Serialize( - drm_metrics::MetricsGroup* metric_group) { - AutoLock lock(adapter_lock_); - ProtoMetricSerializer serializer(metric_group); - - oemcrypto_initialization_mode_.Serialize(&serializer); - oemcrypto_l1_api_version_.Serialize(&serializer); - oemcrypto_l1_min_api_version_.Serialize(&serializer); -} - -void OemCryptoDynamicAdapterMetrics::Clear() { - AutoLock lock(adapter_lock_); - - oemcrypto_initialization_mode_.Clear(); - oemcrypto_l1_api_version_.Clear(); - oemcrypto_l1_min_api_version_.Clear(); -} - -// This method returns a reference. This means that the destructor is never -// executed for the returned object. -OemCryptoDynamicAdapterMetrics& GetDynamicAdapterMetricsInstance() { - // This is safe in C++ 11 since the initialization is guaranteed to run - // only once regardless of multi-threaded access. - static OemCryptoDynamicAdapterMetrics* adapter_metrics = - new OemCryptoDynamicAdapterMetrics(); - return *adapter_metrics; -} - EngineMetrics::EngineMetrics() : cdm_engine_add_key_( "/drm/widevine/cdm_engine/add_key/time", "error"), - cdm_engine_cdm_version_( - "/drm/widevine/cdm_engine/version"), cdm_engine_close_session_( - "/drm/widevine/cdm_engine/close_session", + "/drm/widevine/cdm_engine/close_session/time", "error"), - cdm_engine_creation_time_millis_( - "/drm/widevine/cdm_engine/creation_time_millis"), cdm_engine_decrypt_( "/drm/widevine/cdm_engine/decrypt/time", - "error", - "length"), + "error"), cdm_engine_find_session_for_key_( - "/drm/widevine/cdm_engine/find_session_for_key", + "/drm/widevine/cdm_engine/find_session_for_key/time", "success"), cdm_engine_generate_key_request_( "/drm/widevine/cdm_engine/generate_key_request/time", @@ -415,37 +408,36 @@ EngineMetrics::EngineMetrics() : "/drm/widevine/cdm_engine/handle_provisioning_response/time", "error"), cdm_engine_life_span_( - "/drm/widevine/cdm_engine/life_span"), + "/drm/widevine/cdm_engine/life_span/time"), cdm_engine_open_key_set_session_( - "/drm/widevine/cdm_engine/open_key_set_session", + "/drm/widevine/cdm_engine/open_key_set_session/time", "error"), cdm_engine_open_session_( - "/drm/widevine/cdm_engine/open_session", + "/drm/widevine/cdm_engine/open_session/time", "error"), cdm_engine_query_key_status_( "/drm/widevine/cdm_engine/query_key_status/time", "error"), cdm_engine_release_all_usage_info_( - "/drm/widevine/cdm_engine/release_all_usage_info", + "/drm/widevine/cdm_engine/release_all_usage_info/time", "error"), cdm_engine_release_usage_info_( - "/drm/widevine/cdm_engine/release_usage_info", + "/drm/widevine/cdm_engine/release_usage_info/time", "error"), cdm_engine_remove_keys_( - "/drm/widevine/cdm_engine/remove_keys", + "/drm/widevine/cdm_engine/remove_keys/time", "error"), cdm_engine_restore_key_( "/drm/widevine/cdm_engine/restore_key/time", "error"), cdm_engine_unprovision_( - "/drm/widevine/cdm_engine/unprovision", + "/drm/widevine/cdm_engine/unprovision/time", "error", - "security_level"), - app_package_name_("") { + "security_level") { } EngineMetrics::~EngineMetrics() { - AutoLock lock(session_metrics_lock_); + AutoLock kock(session_metrics_lock_); std::vector::iterator i; if (!session_metrics_list_.empty()) { LOGV("EngineMetrics::~EngineMetrics. Session count: %d", @@ -479,24 +471,13 @@ void EngineMetrics::Serialize(drm_metrics::MetricsGroup* metric_group, bool clear_serialized_sessions) { AutoLock lock(session_metrics_lock_); - // Serialize the most recent metrics from the OemCyrpto dynamic adapter. - OemCryptoDynamicAdapterMetrics& adapter_metrics = - GetDynamicAdapterMetricsInstance(); - adapter_metrics.Serialize(metric_group); - if (!app_package_name_.empty()) { - metric_group->set_app_package_name(app_package_name_); - } SerializeEngineMetrics(metric_group); std::vector::iterator i; for (i = session_metrics_list_.begin(); i != session_metrics_list_.end(); /* no increment */) { bool serialized = false; if (!completed_only || (*i)->IsCompleted()) { - MetricsGroup* metric_sub_group = metric_group->add_metric_sub_group(); - if (!app_package_name_.empty()) { - metric_sub_group->set_app_package_name(app_package_name_); - } - (*i)->Serialize(metric_sub_group); + (*i)->Serialize(metric_group->add_metric_sub_group()); serialized = true; } @@ -509,16 +490,10 @@ void EngineMetrics::Serialize(drm_metrics::MetricsGroup* metric_group, } } -void EngineMetrics::SetAppPackageName(const std::string& app_package_name) { - app_package_name_ = app_package_name; -} - void EngineMetrics::SerializeEngineMetrics(MetricsGroup* metric_group) { ProtoMetricSerializer serializer(metric_group); cdm_engine_add_key_.Serialize(&serializer); - cdm_engine_cdm_version_.Serialize(&serializer); cdm_engine_close_session_.Serialize(&serializer); - cdm_engine_creation_time_millis_.Serialize(&serializer); cdm_engine_decrypt_.Serialize(&serializer); cdm_engine_find_session_for_key_.Serialize(&serializer); cdm_engine_generate_key_request_.Serialize(&serializer); diff --git a/libwvdrmengine/cdm/metrics/test/metrics_collections_unittest.cpp b/libwvdrmengine/cdm/metrics/test/metrics_collections_unittest.cpp index ae51fade..ee644414 100644 --- a/libwvdrmengine/cdm/metrics/test/metrics_collections_unittest.cpp +++ b/libwvdrmengine/cdm/metrics/test/metrics_collections_unittest.cpp @@ -58,7 +58,7 @@ TEST_F(EngineMetricsTest, AllEngineMetrics) { // Spot check some metrics. EXPECT_EQ("/drm/widevine/cdm_engine/add_key/time/count{error:2}", actual_metrics.metric(0).name()); - EXPECT_EQ("/drm/widevine/cdm_engine/close_session/count{error:0}", + EXPECT_EQ("/drm/widevine/cdm_engine/close_session/time/mean{error:0}", actual_metrics.metric(3).name()); EXPECT_EQ("/drm/widevine/cdm_engine/decrypt/time/mean{error:0}", actual_metrics.metric(5).name()); @@ -95,7 +95,7 @@ TEST_F(EngineMetricsTest, EngineAndCryptoMetrics) { "{error:0&length:1024&encryption_algorithm:1}", actual_metrics.metric(4).name()); EXPECT_EQ( - "/drm/widevine/crypto_session/get_device_unique_id/count{success:0}", + "/drm/widevine/crypto_session/get_device_unique_id/time/mean{success:0}", actual_metrics.metric(7).name()); EXPECT_EQ(4.0, actual_metrics.metric(7).value().double_value()); } @@ -266,7 +266,7 @@ TEST_F(SessionMetricsTest, AllSessionMetrics) { // Spot check some metrics. EXPECT_EQ("/drm/widevine/cdm_session/session_id", actual_metrics.metric(0).name()); - EXPECT_EQ("/drm/widevine/cdm_session/life_span", + EXPECT_EQ("/drm/widevine/cdm_session/life_span/time/count", actual_metrics.metric(1).name()); EXPECT_EQ("/drm/widevine/cdm_session/renew_key/time/mean{error:0}", actual_metrics.metric(4).name()); @@ -428,7 +428,7 @@ TEST_F(CryptoMetricsTest, AllCryptoMetrics) { // Spot check some metrics. EXPECT_EQ( - "/drm/widevine/crypto_session/delete_all_usage_reports/count" + "/drm/widevine/crypto_session/delete_all_usage_reports/time/count" "{error:0}", actual_metrics.metric(0).name()); EXPECT_EQ(1, actual_metrics.metric(0).value().int_value()); diff --git a/libwvdrmengine/cdm/src/ami_adapter.cpp b/libwvdrmengine/cdm/src/ami_adapter.cpp index 4c7cfc29..73dd4ee9 100644 --- a/libwvdrmengine/cdm/src/ami_adapter.cpp +++ b/libwvdrmengine/cdm/src/ami_adapter.cpp @@ -22,6 +22,10 @@ AmiAdapter::~AmiAdapter() { analytics_item_.selfrecord(); } +metrics::Report* AmiAdapter::NewReport() const { + return new AmiAdapter(analytics_item_.getSessionID()); +} + void AmiAdapter::UpdateString(const std::string& metric_id, const std::string& value) { analytics_item_.setCString(metric_id.c_str(), value.c_str()); diff --git a/libwvdrmengine/cdm/src/file_utils.cpp b/libwvdrmengine/cdm/src/file_utils.cpp index fa00760c..05fd7782 100644 --- a/libwvdrmengine/cdm/src/file_utils.cpp +++ b/libwvdrmengine/cdm/src/file_utils.cpp @@ -15,6 +15,14 @@ #include "log.h" #include "properties.h" +namespace { +const char* kSecurityLevelPathCompatibilityExclusionList[] = { + "ay64.dat", "ay64.dat2", "ay64.dat3"}; +size_t kSecurityLevelPathCompatibilityExclusionListSize = + sizeof(kSecurityLevelPathCompatibilityExclusionList) / + sizeof(*kSecurityLevelPathCompatibilityExclusionList); +} // namespace + namespace wvcdm { bool IsCurrentOrParentDirectory(char* dir) { @@ -250,6 +258,15 @@ void FileUtils::SecurityLevelPathBackwardCompatibility( for (size_t i = 0; i < files.size(); ++i) { std::string from = from_dir + files[i]; + bool exclude = false; + for (size_t j = 0; j < kSecurityLevelPathCompatibilityExclusionListSize; + ++j) { + if (files[i] == kSecurityLevelPathCompatibilityExclusionList[j]) { + exclude = true; + break; + } + } + if (exclude) continue; if (!FileUtils::IsRegularFile(from)) continue; for (size_t j = 0; j < security_dirs.size(); ++j) { diff --git a/libwvdrmengine/cdm/src/log.cpp b/libwvdrmengine/cdm/src/log.cpp index e1a930b5..8c012036 100644 --- a/libwvdrmengine/cdm/src/log.cpp +++ b/libwvdrmengine/cdm/src/log.cpp @@ -22,9 +22,6 @@ #include "log.h" #include -#include -#include - /* * Uncomment the line below if you want to have the LOGV messages to print * IMPORTANT : this will affect all of CDM diff --git a/libwvdrmengine/cdm/src/properties_android.cpp b/libwvdrmengine/cdm/src/properties_android.cpp index fe456c7f..58c83b9e 100644 --- a/libwvdrmengine/cdm/src/properties_android.cpp +++ b/libwvdrmengine/cdm/src/properties_android.cpp @@ -19,7 +19,7 @@ const char kL2Dir[] = "/L2/"; const char kL3Dir[] = "/L3/"; const char kFactoryKeyboxPath[] = "/factory/wv.keys"; -const char kWVCdmVersion[] = "v5.1.0-android"; +const char kWVCdmVersion[] = "v5.0.0-android"; bool GetAndroidProperty(const char* key, std::string* value) { char val[PROPERTY_VALUE_MAX]; diff --git a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp index 982b71b0..0c3be8ff 100644 --- a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp +++ b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp @@ -7,6 +7,7 @@ #include "initialization_data.h" #include "license.h" #include "log.h" +#include "metrics_front_end.h" #include "properties.h" #include "service_certificate.h" #include "wv_cdm_constants.h" @@ -20,10 +21,22 @@ namespace wvcdm { Lock WvContentDecryptionModule::session_sharing_id_generation_lock_; -WvContentDecryptionModule::WvContentDecryptionModule() {} +WvContentDecryptionModule::WvContentDecryptionModule() { + // TODO (b/36497276) + // replace call to new AmiAdapter() and remove ami_apdater.* + report_root_ = NULL; // new AmiAdapter(); + front_end_ = new metrics::MetricsFrontEnd(report_root_); + metrics::MetricsFrontEnd::OverrideInstance(front_end_); +} WvContentDecryptionModule::~WvContentDecryptionModule() { - DisablePolicyTimer(true /* Force. */); + DisablePolicyTimer(true); + + metrics::MetricsFrontEnd::OverrideInstance(NULL); + delete front_end_; + delete report_root_; + front_end_ = NULL; + report_root_ = NULL; } bool WvContentDecryptionModule::IsSupported(const std::string& init_data_type) { @@ -53,9 +66,16 @@ CdmResponseType WvContentDecryptionModule::OpenSession( } CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); - CdmResponseType sts = cdm_engine->OpenSession(key_system, property_set, - event_listener, session_id); - cdm_engine->GetMetrics()->cdm_engine_open_session_.Increment(sts); + CdmResponseType sts; + M_TIME( + sts = cdm_engine->OpenSession( + key_system, + property_set, + event_listener, + session_id), + cdm_engine->GetMetrics(), + cdm_engine_open_session_, + sts); if (sts == NO_ERROR) { cdm_by_session_id_[*session_id] = cdm_engine; } @@ -64,18 +84,20 @@ CdmResponseType WvContentDecryptionModule::OpenSession( CdmResponseType WvContentDecryptionModule::CloseSession( const CdmSessionId& session_id) { - LOGV("WvContentDecryptionModule::CloseSession. id: %s", session_id.c_str()); CdmEngine* cdm_engine = GetCdmForSessionId(session_id); // TODO(rfrias): Avoid reusing the error codes from CdmEngine. if (!cdm_engine) return SESSION_NOT_FOUND_1; - CdmResponseType sts = cdm_engine->CloseSession(session_id); - cdm_engine->GetMetrics()->cdm_engine_close_session_.Increment(sts); + CdmResponseType sts; + M_TIME( + sts = cdm_engine->CloseSession( + session_id), + cdm_engine->GetMetrics(), + cdm_engine_close_session_, + sts); if (sts == NO_ERROR) { cdm_by_session_id_.erase(session_id); } - - DisablePolicyTimer(false /* Do not force. */); - + DisablePolicyTimer(false); return sts; } @@ -93,8 +115,14 @@ CdmResponseType WvContentDecryptionModule::GenerateKeyRequest( CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); CdmResponseType sts; if (license_type == kLicenseTypeRelease) { - sts = cdm_engine->OpenKeySetSession(key_set_id, property_set, NULL); - cdm_engine->GetMetrics()->cdm_engine_open_key_set_session_.Increment(sts); + M_TIME( + sts = cdm_engine->OpenKeySetSession( + key_set_id, + property_set, + NULL), + cdm_engine->GetMetrics(), + cdm_engine_open_key_set_session_, + sts); if (sts != NO_ERROR) return sts; cdm_by_session_id_[key_set_id] = cdm_engine; } @@ -132,11 +160,6 @@ CdmResponseType WvContentDecryptionModule::AddKey( CdmEngine* cdm_engine = session_id.empty() ? GetCdmForSessionId(*key_set_id) : GetCdmForSessionId(session_id); if (!cdm_engine) return SESSION_NOT_FOUND_3; - // Save key_set_id, as CDM will return an empty key_set_id on release - CdmKeySetId release_key_set_id; - if (session_id.empty() && key_set_id != NULL) { - release_key_set_id = *key_set_id; - } CdmResponseType sts; M_TIME( sts = cdm_engine->AddKey( @@ -147,8 +170,8 @@ CdmResponseType WvContentDecryptionModule::AddKey( cdm_engine_add_key_, sts); if (sts == KEY_ADDED && session_id.empty()) { // license type release - cdm_engine->CloseKeySetSession(release_key_set_id); - cdm_by_session_id_.erase(release_key_set_id); + cdm_engine->CloseKeySetSession(*key_set_id); + cdm_by_session_id_.erase(*key_set_id); } return sts; } @@ -175,8 +198,13 @@ CdmResponseType WvContentDecryptionModule::RemoveKeys( const CdmSessionId& session_id) { CdmEngine* cdm_engine = GetCdmForSessionId(session_id); if (!cdm_engine) return SESSION_NOT_FOUND_5; - CdmResponseType sts = cdm_engine->RemoveKeys(session_id); - cdm_engine->GetMetrics()->cdm_engine_remove_keys_.Increment(sts); + CdmResponseType sts; + M_TIME( + sts = cdm_engine->RemoveKeys( + session_id), + cdm_engine->GetMetrics(), + cdm_engine_remove_keys_, + sts); return sts; } @@ -258,15 +286,20 @@ CdmResponseType WvContentDecryptionModule::HandleProvisioningResponse( CdmResponseType WvContentDecryptionModule::Unprovision( CdmSecurityLevel level, const CdmIdentifier& identifier) { CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); - CdmResponseType sts = cdm_engine->Unprovision(level); - cdm_engine->GetMetrics()->cdm_engine_unprovision_.Increment(sts, level); + CdmResponseType sts; + M_TIME( + sts = cdm_engine->Unprovision( + level), + cdm_engine->GetMetrics(), + cdm_engine_unprovision_, + sts, + level); return sts; } CdmResponseType WvContentDecryptionModule::GetUsageInfo( - const std::string& app_id, const CdmIdentifier& identifier, - CdmUsageInfo* usage_info) { - CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); + const std::string& app_id, CdmUsageInfo* usage_info) { + CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier); CdmResponseType sts; M_TIME( sts = cdm_engine->GetUsageInfo( @@ -281,9 +314,8 @@ CdmResponseType WvContentDecryptionModule::GetUsageInfo( CdmResponseType WvContentDecryptionModule::GetUsageInfo( const std::string& app_id, const CdmSecureStopId& ssid, - const CdmIdentifier& identifier, CdmUsageInfo* usage_info) { - CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); + CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier); CdmResponseType sts; M_TIME( sts = cdm_engine->GetUsageInfo( @@ -297,19 +329,28 @@ CdmResponseType WvContentDecryptionModule::GetUsageInfo( } CdmResponseType WvContentDecryptionModule::ReleaseAllUsageInfo( - const std::string& app_id, const CdmIdentifier& identifier) { - CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); - CdmResponseType sts = cdm_engine->ReleaseAllUsageInfo(app_id); - cdm_engine->GetMetrics()->cdm_engine_release_all_usage_info_.Increment(sts); + const std::string& app_id) { + CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier); + CdmResponseType sts; + M_TIME( + sts = cdm_engine->ReleaseAllUsageInfo( + app_id), + cdm_engine->GetMetrics(), + cdm_engine_release_all_usage_info_, + sts); return sts; } CdmResponseType WvContentDecryptionModule::ReleaseUsageInfo( - const CdmUsageInfoReleaseMessage& message, - const CdmIdentifier& identifier) { - CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); - CdmResponseType sts = cdm_engine->ReleaseUsageInfo(message); - cdm_engine->GetMetrics()->cdm_engine_release_usage_info_.Increment(sts); + const CdmUsageInfoReleaseMessage& message) { + CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier); + CdmResponseType sts; + M_TIME( + sts = cdm_engine->ReleaseUsageInfo( + message), + cdm_engine->GetMetrics(), + cdm_engine_release_usage_info_, + sts); return sts; } @@ -325,11 +366,15 @@ CdmResponseType WvContentDecryptionModule::Decrypt( CdmSessionId local_session_id = session_id; if (validate_key_id && Properties::GetSessionSharingId(session_id) != 0) { - bool status = cdm_engine->FindSessionForKey( - *parameters.key_id, &local_session_id); - cdm_engine->GetMetrics()->cdm_engine_find_session_for_key_ - .Increment(status); - if (!status && parameters.is_encrypted) return KEY_NOT_FOUND_IN_SESSION; + bool status; + M_TIME( + status = cdm_engine->FindSessionForKey( + *parameters.key_id, + &local_session_id), + cdm_engine->GetMetrics(), + cdm_engine_find_session_for_key_, + status); + if (!status) return KEY_NOT_FOUND_IN_SESSION; } CdmResponseType sts; M_TIME( @@ -338,8 +383,7 @@ CdmResponseType WvContentDecryptionModule::Decrypt( parameters), cdm_engine->GetMetrics(), cdm_engine_decrypt_, - sts, - metrics::Pow2Bucket(parameters.encrypt_length)); + sts); return sts; } @@ -356,15 +400,7 @@ bool WvContentDecryptionModule::IsValidServiceCertificate( ServiceCertificate cert; CdmResponseType status = cert.Init(certificate); if (status != NO_ERROR) return false; - return cert.HasCertificate(); -} - -void WvContentDecryptionModule::GetSerializedMetrics( - std::string* serialized_metrics) { - AutoLock auto_lock(cdms_lock_); - CloseCdmsWithoutSessions(); - metrics_.SerializeToString(serialized_metrics); - metrics_.Clear(); + return cert.HasCertificate(); } WvContentDecryptionModule::CdmInfo::CdmInfo() @@ -382,14 +418,9 @@ CdmEngine* WvContentDecryptionModule::EnsureCdmForIdentifier( cdms_[identifier].file_system.SetOrigin(identifier.origin); cdms_[identifier].file_system.SetIdentifier( identifier.spoid + identifier.origin); - - // Set the app package name for use by metrics. - cdms_[identifier].cdm_engine->GetMetrics() - ->SetAppPackageName(identifier.app_package_name); } - CdmEngine* cdm_engine = cdms_[identifier].cdm_engine.get(); - return cdm_engine; + return cdms_[identifier].cdm_engine.get(); } CdmEngine* WvContentDecryptionModule::GetCdmForSessionId( @@ -400,34 +431,6 @@ CdmEngine* WvContentDecryptionModule::GetCdmForSessionId( return it->second; } -// This method requires that the caller first acquire cdms_lock_. -void WvContentDecryptionModule::CloseCdmsWithoutSessions() { - for (auto it = cdms_.begin(); it != cdms_.end();) { - if (it->second.cdm_engine->SessionSize() != 0) { - ++it; - } else { - // Retrieve the metrics from the engine and any completed - // sessions. Clear the metrics from any completed sessions. - metrics::EngineMetrics* engine_metrics = - it->second.cdm_engine->GetMetrics(); - // engine_metrics should never be null. - if (engine_metrics != NULL) { - engine_metrics->Serialize( - metrics_.add_metric_sub_group(), - false, // Report complete AND incomplete sessions. - true); // Clear session metrics after reporting. - } else { - // Engine metrics should never be null. - LOGI("WvContentDecryptionModule::CloseCdmsWithoutSessions." - "engine_metrics was unexpectedly NULL."); - } - - // The CDM is no longer used for this identifier, delete it. - it = cdms_.erase(it); - } - } -} - void WvContentDecryptionModule::EnablePolicyTimer() { AutoLock auto_lock(policy_timer_lock_); if (!policy_timer_.IsRunning()) @@ -435,19 +438,23 @@ void WvContentDecryptionModule::EnablePolicyTimer() { } void WvContentDecryptionModule::DisablePolicyTimer(bool force) { - bool cdms_is_empty = false; + bool has_sessions = false; { AutoLock auto_lock(cdms_lock_); - CloseCdmsWithoutSessions(); - cdms_is_empty = cdms_.empty(); + for (auto it = cdms_.begin(); it != cdms_.end();) { + if (it->second.cdm_engine->SessionSize() != 0) { + has_sessions = true; + ++it; + } else { + // The CDM is no longer used for this identifier, delete it. + it = cdms_.erase(it); + } + } } AutoLock auto_lock(policy_timer_lock_); - if(force || cdms_is_empty) { - if (policy_timer_.IsRunning()) { - policy_timer_.Stop(); - } - } + if ((!has_sessions || force) && policy_timer_.IsRunning()) + policy_timer_.Stop(); } void WvContentDecryptionModule::OnTimerEvent() { diff --git a/libwvdrmengine/cdm/test/Android.mk b/libwvdrmengine/cdm/test/Android.mk index b42b99af..32778eff 100644 --- a/libwvdrmengine/cdm/test/Android.mk +++ b/libwvdrmengine/cdm/test/Android.mk @@ -11,10 +11,6 @@ test_name := buffer_reader_test test_src_dir := ../core/test include $(LOCAL_PATH)/unit-test.mk -test_name := cdm_feature_test -test_src_dir := . -include $(LOCAL_PATH)/unit-test.mk - test_name := cdm_engine_test test_src_dir := ../core/test include $(LOCAL_PATH)/unit-test.mk @@ -27,26 +23,10 @@ test_name := cdm_session_unittest test_src_dir := ../core/test include $(LOCAL_PATH)/unit-test.mk -test_name := counter_metric_unittest -test_src_dir := ../metrics/test -include $(LOCAL_PATH)/unit-test.mk - -test_name := crypto_session_unittest -test_src_dir := ../core/test -include $(LOCAL_PATH)/unit-test.mk - test_name := device_files_unittest test_src_dir := ../core/test include $(LOCAL_PATH)/unit-test.mk -test_name := distribution_unittest -test_src_dir := ../metrics/test -include $(LOCAL_PATH)/unit-test.mk - -test_name := event_metric_unittest -test_src_dir := ../metrics/test -include $(LOCAL_PATH)/unit-test.mk - test_name := file_store_unittest test_src_dir := ../core/test include $(LOCAL_PATH)/unit-test.mk @@ -91,16 +71,12 @@ test_name := timer_unittest test_src_dir := . include $(LOCAL_PATH)/unit-test.mk -test_name := usage_table_header_unittest -test_src_dir := ../core/test -include $(LOCAL_PATH)/unit-test.mk - -test_name := value_metric_unittest +test_name := distribution_test test_src_dir := ../metrics/test include $(LOCAL_PATH)/unit-test.mk -test_name := wv_cdm_metrics_test -test_src_dir := . +test_name := event_metric_test +test_src_dir := ../metrics/test include $(LOCAL_PATH)/unit-test.mk test_name := diff --git a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp index d8cb2aa3..c4ec3177 100644 --- a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp +++ b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp @@ -940,9 +940,7 @@ TEST_F(WvCdmExtendedDurationTest, UsageOverflowTest) { DeviceFiles handle(&file_system); EXPECT_TRUE(handle.Init(security_level)); std::vector provider_session_tokens; - EXPECT_TRUE(handle.DeleteAllUsageInfoForApp( - DeviceFiles::GetUsageInfoFileName(""), - &provider_session_tokens)); + EXPECT_TRUE(handle.DeleteAllUsageInfoForApp("", &provider_session_tokens)); for (size_t i = 0; i < kMaxUsageTableSize + 100; ++i) { decryptor_.OpenSession(g_key_system, property_set, kDefaultCdmIdentifier, @@ -961,17 +959,15 @@ TEST_F(WvCdmExtendedDurationTest, UsageOverflowTest) { uint32_t num_usage_info = 0; CdmUsageInfo usage_info; CdmUsageInfoReleaseMessage release_msg; - CdmResponseType status = decryptor_.GetUsageInfo( - "", kDefaultCdmIdentifier, &usage_info); + CdmResponseType status = decryptor_.GetUsageInfo("", &usage_info); EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status); while (usage_info.size() > 0) { for (size_t i = 0; i < usage_info.size(); ++i) { release_msg = GetUsageInfoResponse(g_license_server, g_client_auth, usage_info[i]); - EXPECT_EQ(NO_ERROR, decryptor_.ReleaseUsageInfo(release_msg, - kDefaultCdmIdentifier)); + EXPECT_EQ(NO_ERROR, decryptor_.ReleaseUsageInfo(release_msg)); } - status = decryptor_.GetUsageInfo("", kDefaultCdmIdentifier, &usage_info); + status = decryptor_.GetUsageInfo("", &usage_info); switch (status) { case KEY_MESSAGE: EXPECT_FALSE(usage_info.empty()); break; case NO_ERROR: EXPECT_TRUE(usage_info.empty()); break; @@ -982,142 +978,6 @@ TEST_F(WvCdmExtendedDurationTest, UsageOverflowTest) { } } -// This test verifies that sessions allocated internally during key release -// message generation are deallocated after their time to live period expires -// by timer events (if other sessions are open). -TEST_F(WvCdmExtendedDurationTest, AutomatedOfflineSessionReleaseOnTimerEvent) { - Unprovision(); - Provision(); - - // Leave session open to run the CDM timer - CdmSessionId streaming_session_id; - decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, - &streaming_session_id); - - // override default settings unless configured through the command line - std::string key_id; - std::string client_auth; - GetOfflineConfiguration(&key_id, &client_auth); - - uint32_t initial_open_sessions = - QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS); - - uint32_t max_sessions = - QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_MAX_NUMBER_OF_SESSIONS); - - decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, - &session_id_); - GenerateKeyRequest(kOfflineClip4, kLicenseTypeOffline); - VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false); - - EXPECT_FALSE(key_set_id_.empty()); - decryptor_.CloseSession(session_id_); - CdmKeySetId key_set_id = key_set_id_; - - session_id_.clear(); - key_set_id_.clear(); - decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, - &session_id_); - EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); - decryptor_.CloseSession(session_id_); - - session_id_.clear(); - GenerateKeyRelease(key_set_id); - - uint32_t open_sessions = - QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS); - - EXPECT_GT(open_sessions, initial_open_sessions); - - sleep(kMinute + kClockTolerance); - - open_sessions = - QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS); - - EXPECT_EQ(open_sessions, initial_open_sessions); - - session_id_.clear(); - GenerateKeyRelease(key_set_id); - key_set_id_ = key_set_id; - VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false); - decryptor_.CloseSession(streaming_session_id); -} - -// This test verifies that sessions allocated internally during key release -// message generation are deallocated after their time to live period expires -// when a new session is opened. -TEST_F(WvCdmExtendedDurationTest, AutomatedOfflineSessionReleaseOnOpenSession) { - Unprovision(); - Provision(); - - // override default settings unless configured through the command line - std::string key_id; - std::string client_auth; - GetOfflineConfiguration(&key_id, &client_auth); - - uint32_t initial_open_sessions = - QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS); - - uint32_t max_sessions = - QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_MAX_NUMBER_OF_SESSIONS); - - decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, - &session_id_); - GenerateKeyRequest(kOfflineClip4, kLicenseTypeOffline); - VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false); - - EXPECT_FALSE(key_set_id_.empty()); - decryptor_.CloseSession(session_id_); - CdmKeySetId key_set_id = key_set_id_; - - session_id_.clear(); - key_set_id_.clear(); - decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, - &session_id_); - EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); - decryptor_.CloseSession(session_id_); - - session_id_.clear(); - GenerateKeyRelease(key_set_id); - - decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, - &session_id_); - - EXPECT_GT( - QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS), - initial_open_sessions); - - decryptor_.CloseSession(session_id_); - - EXPECT_GT( - QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS), - initial_open_sessions); - - sleep(kMinute + kClockTolerance); - - EXPECT_GT( - QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS), - initial_open_sessions); - - decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, - &session_id_); - - EXPECT_GT( - QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS), - initial_open_sessions); - - decryptor_.CloseSession(session_id_); - - EXPECT_EQ( - QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS), - initial_open_sessions); - - session_id_.clear(); - GenerateKeyRelease(key_set_id); - key_set_id_ = key_set_id; - VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false); -} - // This test verifies that sessions allocated internally during // key release message generation are deallocated after their // time to live period expires. @@ -1400,8 +1260,7 @@ TEST_P(WvCdmStreamingUsageReportTest, UsageTest) { uint32_t num_usage_info = 0; CdmUsageInfo usage_info; CdmUsageInfoReleaseMessage release_msg; - CdmResponseType status = decryptor_.GetUsageInfo( - "", kDefaultCdmIdentifier, &usage_info); + CdmResponseType status = decryptor_.GetUsageInfo("", &usage_info); EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status); while (usage_info.size() > 0) { for (size_t i = 0; i < usage_info.size(); ++i) { @@ -1411,10 +1270,9 @@ TEST_P(WvCdmStreamingUsageReportTest, UsageTest) { expected_seconds_since_last_playback); release_msg = GetUsageInfoResponse(g_license_server, g_client_auth, usage_info[i]); - EXPECT_EQ(NO_ERROR, decryptor_.ReleaseUsageInfo(release_msg, - kDefaultCdmIdentifier)); + EXPECT_EQ(NO_ERROR, decryptor_.ReleaseUsageInfo(release_msg)); } - status = decryptor_.GetUsageInfo("", kDefaultCdmIdentifier, &usage_info); + status = decryptor_.GetUsageInfo("", &usage_info); switch (status) { case KEY_MESSAGE: EXPECT_FALSE(usage_info.empty()); @@ -1633,7 +1491,7 @@ int main(int argc, char** argv) { g_key_id.assign(g_config->key_id()); } if (g_license_server.empty()) { - g_license_server.assign(g_config->license_server_url()); + g_license_server.assign(g_config->license_server()); } // Displays server url, port and key Id being used diff --git a/libwvdrmengine/cdm/test/cdm_feature_test.cpp b/libwvdrmengine/cdm/test/cdm_feature_test.cpp index 397c6a86..1d331de7 100644 --- a/libwvdrmengine/cdm/test/cdm_feature_test.cpp +++ b/libwvdrmengine/cdm/test/cdm_feature_test.cpp @@ -62,7 +62,8 @@ wvcdm::KeyId g_key_id; wvcdm::CdmKeySystem g_key_system; std::string g_license_server; wvcdm::KeyId g_wrong_key_id; -wvcdm::LicenseServerId g_license_server_id = wvcdm::kContentProtectionUatServer; +wvcdm::ServerConfigurationId g_license_server_id = + wvcdm::kContentProtectionUatServer; std::string g_service_certificate; wvcdm::KeyId kSrmHdKeyId1 = wvcdm::a2bs_hex("30303030303030303030303030303032"); @@ -418,7 +419,7 @@ TEST_F(WvCdmFeatureTest, OEMCertificateProvisioning) { decryptor_.GetProvisioningRequest(cert_type, cert_authority, kDefaultCdmIdentifier, &key_msg_, &provisioning_server_url)); - EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); + EXPECT_EQ(provisioning_server_url, g_config->provisioning_server()); ClientIdentification_TokenType token_type; EXPECT_TRUE(ExtractTokenType(key_msg_, &token_type)); @@ -453,7 +454,7 @@ TEST_F(WvCdmFeatureTest, KeyboxProvisioning) { decryptor_.GetProvisioningRequest(cert_type, cert_authority, kDefaultCdmIdentifier, &key_msg_, &provisioning_server_url)); - EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); + EXPECT_EQ(provisioning_server_url, g_config->provisioning_server()); ClientIdentification_TokenType token_type; EXPECT_TRUE(ExtractTokenType(key_msg_, &token_type)); @@ -704,10 +705,10 @@ int main(int argc, char** argv) { g_key_id.assign(g_config->key_id()); } if (g_service_certificate.empty()) { - g_service_certificate.assign(g_config->service_certificate()); + g_service_certificate.assign(g_config->license_service_certificate()); } if (g_license_server.empty()) { - g_license_server.assign(g_config->license_server_url()); + g_license_server.assign(g_config->license_server()); } // Displays server url, port and key Id being used diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index f54346b8..6501f59c 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -51,7 +51,6 @@ const int kHttpInternalServerError = 500; const wvcdm::CdmIdentifier kExampleIdentifier = { wvcdm::EMPTY_SPOID, - "com.example", "com.example" }; @@ -986,7 +985,7 @@ class TestWvCdmHlsEventListener : public WvCdmEventListener { class WvCdmRequestLicenseTest : public WvCdmTestBase { public: - WvCdmRequestLicenseTest() : license_type_(kLicenseTypeStreaming) {} + WvCdmRequestLicenseTest() {} ~WvCdmRequestLicenseTest() {} protected: @@ -1032,7 +1031,6 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { CdmClientPropertySet* property_set) { CdmKeyRequest key_request; std::string key_set_id; - license_type_ = license_type; EXPECT_EQ(expected_response, decryptor_.GenerateKeyRequest( session_id_, key_set_id, init_data_type, init_data, @@ -1076,7 +1074,6 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { void GenerateKeyRelease(CdmKeySetId key_set_id, CdmClientPropertySet* property_set, CdmKeyMessage* key_msg) { - license_type_ = kLicenseTypeRelease; CdmSessionId session_id; CdmInitData init_data; wvcdm::CdmAppParameterMap app_parameters; @@ -1170,34 +1167,26 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { } void VerifyKeyRequestResponse(const std::string& server_url, - const std::string& client_auth) { + const std::string& client_auth, + bool is_renewal) { std::string response; - VerifyKeyRequestResponse(server_url, client_auth, false); - } - - void VerifyUsageKeyRequestResponse(const std::string& server_url, - const std::string& client_auth) { - std::string response; - VerifyKeyRequestResponse(server_url, client_auth, true); + VerifyKeyRequestResponse(server_url, client_auth, is_renewal, &response); } void VerifyKeyRequestResponse(const std::string& server_url, - const std::string& client_auth, - bool is_usage) { - std::string response; - VerifyKeyRequestResponse(server_url, client_auth, is_usage, &response); - } - - void VerifyKeyRequestResponse(const std::string& server_url, - const std::string& client_auth, - bool is_usage, + const std::string& client_auth, bool is_renewal, std::string* response) { *response = GetKeyRequestResponse(server_url, client_auth); - EXPECT_EQ(decryptor_.AddKey(session_id_, *response, &key_set_id_), - wvcdm::KEY_ADDED); - EXPECT_EQ(is_usage || license_type_ == kLicenseTypeOffline, - key_set_id_.size() > 0); + if (is_renewal) { + // TODO application makes a license request, CDM will renew the license + // when appropriate + EXPECT_EQ(decryptor_.AddKey(session_id_, *response, &key_set_id_), + wvcdm::KEY_ADDED); + } else { + EXPECT_EQ(decryptor_.AddKey(session_id_, *response, &key_set_id_), + wvcdm::KEY_ADDED); + } } void Unprovision() { @@ -1305,7 +1294,6 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { CdmKeyMessage key_msg_; CdmSessionId session_id_; CdmKeySetId key_set_id_; - CdmLicenseType license_type_; }; TEST_F(WvCdmRequestLicenseTest, ProvisioningTest) { @@ -1369,12 +1357,8 @@ TEST_F(WvCdmRequestLicenseTest, PerOriginProvisioningSupportsOldPaths) { // Make sure that the cert exists. std::vector files; ASSERT_TRUE(FileUtils::List(base_path, &files)); - ASSERT_LE(1u, files.size()); - bool found_it = false; - for(std::string file: files) { - if (file == std::string(kOldFileName)) found_it = true; - } - EXPECT_TRUE(found_it); + ASSERT_EQ(1u, files.size()); + EXPECT_EQ(kOldFileName, files[0]); // Reprovision the default identifier. Provision(kDefaultCdmIdentifier, kLevel3); @@ -1619,7 +1603,7 @@ TEST_F(WvCdmRequestLicenseTest, ForceL3Test) { kDefaultCdmIdentifier, NULL, &session_id_)); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); decryptor_.CloseSession(session_id_); } @@ -1635,7 +1619,7 @@ TEST_F(WvCdmRequestLicenseTest, PrivacyModeTest) { EXPECT_EQ(decryptor_.AddKey(session_id_, resp, &key_set_id_), wvcdm::NEED_KEY); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); decryptor_.CloseSession(session_id_); } @@ -1648,7 +1632,7 @@ TEST_F(WvCdmRequestLicenseTest, PrivacyModeWithServiceCertificateTest) { decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); decryptor_.CloseSession(session_id_); } @@ -1693,7 +1677,7 @@ TEST_F(WvCdmRequestLicenseTest, AddStreamingKeyTest) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); decryptor_.CloseSession(session_id_); } @@ -1709,7 +1693,7 @@ TEST_F(WvCdmRequestLicenseTest, AddKeyOfflineTest) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); decryptor_.CloseSession(session_id_); } @@ -1725,7 +1709,7 @@ TEST_F(WvCdmRequestLicenseTest, RestoreOfflineKeyTest) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); CdmKeySetId key_set_id = key_set_id_; EXPECT_FALSE(key_set_id_.empty()); @@ -1750,7 +1734,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeyTest) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); CdmKeySetId key_set_id = key_set_id_; EXPECT_FALSE(key_set_id_.empty()); @@ -1767,7 +1751,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeyTest) { key_set_id_.clear(); GenerateKeyRelease(key_set_id); key_set_id_ = key_set_id; - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); } TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeySessionUsageDisabledTest) { @@ -1786,7 +1770,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeySessionUsageDisabledTest) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); CdmKeySetId key_set_id = key_set_id_; EXPECT_FALSE(key_set_id_.empty()); @@ -1804,7 +1788,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeySessionUsageDisabledTest) { CdmKeyMessage key_msg; GenerateKeyRelease(key_set_id, NULL, &key_msg); key_set_id_ = key_set_id; - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); SignedMessage signed_message; EXPECT_TRUE(signed_message.ParseFromString(key_msg)); @@ -1841,7 +1825,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryOfflineKeyTest) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); CdmKeySetId key_set_id = key_set_id_; EXPECT_FALSE(key_set_id_.empty()); @@ -1869,7 +1853,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryOfflineKeyTest) { key_set_id_.clear(); GenerateKeyRelease(key_set_id); key_set_id_ = key_set_id; - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); } TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) { @@ -1911,7 +1895,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) { decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline, &property_set); - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); CdmKeySetId key_set_id = key_set_id_; EXPECT_FALSE(key_set_id_.empty()); @@ -1939,54 +1923,22 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) { key_set_id_.clear(); GenerateKeyRelease(key_set_id, &property_set, NULL); key_set_id_ = key_set_id; - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); } -TEST_F(WvCdmRequestLicenseTest, - ReleaseRetryL3OfflineKeySessionUsageDisabledTest) { +TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) { Unprovision(); + Provision(kLevelDefault); - TestWvCdmClientPropertySet property_set; - property_set.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3); - - // The default offline asset "offline_clip2" has the session usage table - // entry enabled in the replay control portion of the key control block. - // To have it disabled we must use "offline_clip1", so replace the last - // char in init data with '1' + // override default settings unless configured through the command line std::string key_id; std::string client_auth; GetOfflineConfiguration(&key_id, &client_auth); - key_id[key_id.size()-1] = '1'; - CdmResponseType sts = decryptor_.OpenSession( - g_key_system, &property_set, kDefaultCdmIdentifier, NULL, &session_id_); - - if (NEED_PROVISIONING == sts) { - std::string provisioning_server_url; - CdmCertificateType cert_type = kCertificateWidevine; - std::string cert_authority, cert, wrapped_key; - EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest( - cert_type, cert_authority, kDefaultCdmIdentifier, - &key_msg_, &provisioning_server_url)); - EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); - std::string response = - GetCertRequestResponse(g_config->provisioning_server_url()); - EXPECT_NE(0, static_cast(response.size())); - EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse( - kDefaultCdmIdentifier, response, &cert, - &wrapped_key)); - EXPECT_EQ(NO_ERROR, - decryptor_.OpenSession(g_key_system, &property_set, - kDefaultCdmIdentifier, NULL, - &session_id_)); - } else { - EXPECT_EQ(NO_ERROR, sts); - } - - decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, - NULL, &session_id_); - GenerateKeyRequest(key_id, kLicenseTypeOffline, &property_set); - VerifyKeyRequestResponse(g_license_server, client_auth); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); + GenerateKeyRequest(key_id, kLicenseTypeOffline); + VerifyKeyRequestResponse(g_license_server, client_auth, false); CdmKeySetId key_set_id = key_set_id_; EXPECT_FALSE(key_set_id_.empty()); @@ -1994,27 +1946,33 @@ TEST_F(WvCdmRequestLicenseTest, session_id_.clear(); key_set_id_.clear(); - decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, - NULL, &session_id_); - EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); - decryptor_.CloseSession(session_id_); + StrictMock listener; + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, &listener, + &session_id_); + CdmSessionId restore_session_id = session_id_; + EXPECT_CALL( + listener, + OnSessionKeysChange( + restore_session_id, + AllOf(Each(Pair(_, kKeyStatusUsable)), Not(IsEmpty())), true)); + EXPECT_CALL(listener, OnExpirationUpdate(restore_session_id, _)); + EXPECT_EQ(wvcdm::KEY_ADDED, + decryptor_.RestoreKey(restore_session_id, key_set_id)); session_id_.clear(); key_set_id_.clear(); - GenerateKeyRelease(key_set_id, &property_set, NULL); - - session_id_.clear(); - decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, - NULL, &session_id_); - EXPECT_EQ(wvcdm::GET_RELEASED_LICENSE_ERROR, - decryptor_.RestoreKey(session_id_, key_set_id)); - decryptor_.CloseSession(session_id_); - - session_id_.clear(); - key_set_id_.clear(); - GenerateKeyRelease(key_set_id, &property_set, NULL); + // Maybe called since VerifyKeyRequestResponse could take some time. + EXPECT_CALL(listener, OnSessionRenewalNeeded(restore_session_id)) + .Times(AtLeast(0)); + EXPECT_CALL( + listener, + OnSessionKeysChange( + restore_session_id, + AllOf(Each(Pair(_, kKeyStatusExpired)), Not(IsEmpty())), false)); + GenerateKeyRelease(key_set_id); key_set_id_ = key_set_id; - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); + decryptor_.CloseSession(restore_session_id); } // This test verifies that repeated generation of the key release message @@ -2032,7 +1990,7 @@ TEST_F(WvCdmRequestLicenseTest, AutomatedOfflineSessionReleaseTest) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); CdmKeySetId key_set_id = key_set_id_; EXPECT_FALSE(key_set_id_.empty()); @@ -2066,7 +2024,7 @@ TEST_F(WvCdmRequestLicenseTest, AutomatedOfflineSessionReleaseTest) { open_sessions, QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS)); - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); EXPECT_EQ( --open_sessions, @@ -2077,12 +2035,12 @@ TEST_F(WvCdmRequestLicenseTest, StreamingLicenseRenewal) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); std::string license_server; GenerateRenewalRequest(kLicenseTypeStreaming, &license_server); if (license_server.empty()) license_server = g_license_server; - VerifyKeyRequestResponse(license_server, g_client_auth); + VerifyKeyRequestResponse(license_server, g_client_auth, true); decryptor_.CloseSession(session_id_); } @@ -2095,7 +2053,7 @@ TEST_F(WvCdmRequestLicenseTest, StreamingLicenseRenewalProhibited) { "08011a0d7769646576696e655f746573" // pssh data "74221073747265616d696e675f636c69703131"); GenerateKeyRequest(key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); std::string init_data; wvcdm::CdmAppParameterMap app_parameters; @@ -2121,12 +2079,12 @@ TEST_F(WvCdmRequestLicenseTest, OfflineLicenseRenewal) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); std::string license_server; GenerateRenewalRequest(kLicenseTypeOffline, &license_server); if (license_server.empty()) license_server = g_license_server; - VerifyKeyRequestResponse(license_server, client_auth); + VerifyKeyRequestResponse(license_server, client_auth, true); decryptor_.CloseSession(session_id_); } @@ -2135,7 +2093,7 @@ TEST_F(WvCdmRequestLicenseTest, RemoveKeys) { kDefaultCdmIdentifier, NULL, &session_id_)); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); ASSERT_EQ(NO_ERROR, decryptor_.RemoveKeys(session_id_)); ASSERT_EQ(NO_ERROR, decryptor_.CloseSession(session_id_)); } @@ -2254,7 +2212,7 @@ TEST_P(WvCdmStreamingLicenseRenewalTest, WithClientId) { 0u, license_renewal.encrypted_client_id().encrypted_client_id().size()); } - VerifyKeyRequestResponse(license_server, g_client_auth); + VerifyKeyRequestResponse(license_server, g_client_auth, true); decryptor_.CloseSession(session_id_); } @@ -2396,7 +2354,7 @@ TEST_P(WvCdmOfflineLicenseReleaseTest, WithClientId) { 0u, license_release.encrypted_client_id().encrypted_client_id().size()); } - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); decryptor_.CloseSession(session_id_); } @@ -2420,9 +2378,7 @@ TEST_P(WvCdmUsageTest, WithClientId) { DeviceFiles handle(&file_system); EXPECT_TRUE(handle.Init(security_level)); std::vector psts; - EXPECT_TRUE(handle.DeleteAllUsageInfoForApp( - DeviceFiles::GetUsageInfoFileName(app_id), - &psts)); + EXPECT_TRUE(handle.DeleteAllUsageInfoForApp(app_id, &psts)); RenewWithClientIdTestConfiguration* config = GetParam(); std::string key_id; @@ -2451,7 +2407,7 @@ TEST_P(WvCdmUsageTest, WithClientId) { &property_set); std::string key_response; - VerifyKeyRequestResponse(g_license_server, g_client_auth, true, + VerifyKeyRequestResponse(g_license_server, g_client_auth, false, &key_response); // Validate signed license @@ -2491,8 +2447,7 @@ TEST_P(WvCdmUsageTest, WithClientId) { uint32_t num_usage_info = 0; CdmUsageInfo usage_info; CdmUsageInfoReleaseMessage release_msg; - CdmResponseType status = decryptor_.GetUsageInfo( - app_id, kDefaultCdmIdentifier, &usage_info); + CdmResponseType status = decryptor_.GetUsageInfo(app_id, &usage_info); EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status); // Validate signed renewal request @@ -2523,8 +2478,7 @@ TEST_P(WvCdmUsageTest, WithClientId) { release_msg = GetUsageInfoResponse(g_license_server, g_client_auth, usage_info[0]); - EXPECT_EQ(NO_ERROR, decryptor_.ReleaseUsageInfo(release_msg, - kDefaultCdmIdentifier)); + EXPECT_EQ(NO_ERROR, decryptor_.ReleaseUsageInfo(release_msg)); } INSTANTIATE_TEST_CASE_P( @@ -2542,9 +2496,7 @@ TEST_F(WvCdmRequestLicenseTest, UsageInfoRetryTest) { DeviceFiles handle(&file_system); EXPECT_TRUE(handle.Init(security_level)); std::vector psts; - EXPECT_TRUE(handle.DeleteAllUsageInfoForApp( - DeviceFiles::GetUsageInfoFileName(app_id), - &psts)); + EXPECT_TRUE(handle.DeleteAllUsageInfoForApp(app_id, &psts)); SubSampleInfo* data = &usage_info_sub_samples_icp[0]; decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, @@ -2556,7 +2508,7 @@ TEST_F(WvCdmRequestLicenseTest, UsageInfoRetryTest) { "747265616d696e675f636c697033"); GenerateKeyRequest(key_id, kLicenseTypeStreaming, NULL); - VerifyUsageKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); std::vector decrypt_buffer(data->encrypt_data.size()); CdmDecryptionParameters decryption_parameters( @@ -2575,23 +2527,20 @@ TEST_F(WvCdmRequestLicenseTest, UsageInfoRetryTest) { uint32_t num_usage_info = 0; CdmUsageInfo usage_info; CdmUsageInfoReleaseMessage release_msg; - CdmResponseType status = decryptor_.GetUsageInfo( - app_id, kDefaultCdmIdentifier, &usage_info); + CdmResponseType status = decryptor_.GetUsageInfo(app_id, &usage_info); EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status); // Discard and retry to verify usage reports can be generated multiple times // before release. - status = decryptor_.GetUsageInfo(app_id, kDefaultCdmIdentifier, &usage_info); + status = decryptor_.GetUsageInfo(app_id, &usage_info); EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status); while (usage_info.size() > 0) { for (size_t i = 0; i < usage_info.size(); ++i) { release_msg = GetUsageInfoResponse(g_license_server, g_client_auth, usage_info[i]); - EXPECT_EQ(NO_ERROR, decryptor_.ReleaseUsageInfo(release_msg, - kDefaultCdmIdentifier)); + EXPECT_EQ(NO_ERROR, decryptor_.ReleaseUsageInfo(release_msg)); } - status = decryptor_.GetUsageInfo( - app_id, kDefaultCdmIdentifier, &usage_info); + status = decryptor_.GetUsageInfo(app_id, &usage_info); switch (status) { case KEY_MESSAGE: EXPECT_FALSE(usage_info.empty()); @@ -2630,9 +2579,7 @@ TEST_P(WvCdmUsageInfoTest, UsageInfo) { DeviceFiles handle(&file_system); EXPECT_TRUE(handle.Init(security_level)); std::vector psts; - EXPECT_TRUE(handle.DeleteAllUsageInfoForApp( - DeviceFiles::GetUsageInfoFileName(usage_info_data->app_id), - &psts)); + EXPECT_TRUE(handle.DeleteAllUsageInfoForApp(usage_info_data->app_id, &psts)); for (size_t i = 0; i < usage_info_data->usage_info; ++i) { SubSampleInfo* data = usage_info_data->sub_sample + i; @@ -2648,12 +2595,7 @@ TEST_P(WvCdmUsageInfoTest, UsageInfo) { key_id.append(1, ch); GenerateKeyRequest(key_id, kLicenseTypeStreaming, property_set); - - // TODO(rfrias): streaming_clip6 is a streaming license without a pst - if (ch == '6') - VerifyKeyRequestResponse(g_license_server, g_client_auth, false); - else - VerifyUsageKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); std::vector decrypt_buffer(data->encrypt_data.size()); CdmDecryptionParameters decryption_parameters( @@ -2674,19 +2616,15 @@ TEST_P(WvCdmUsageInfoTest, UsageInfo) { CdmUsageInfo usage_info; CdmUsageInfoReleaseMessage release_msg; CdmResponseType status = - decryptor_.GetUsageInfo(usage_info_data->app_id, kDefaultCdmIdentifier, - &usage_info); + decryptor_.GetUsageInfo(usage_info_data->app_id, &usage_info); EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status); while (usage_info.size() > 0) { for (size_t i = 0; i < usage_info.size(); ++i) { release_msg = GetUsageInfoResponse(g_license_server, g_client_auth, usage_info[i]); - EXPECT_EQ( - NO_ERROR, - decryptor_.ReleaseUsageInfo(release_msg, kDefaultCdmIdentifier)); + EXPECT_EQ(NO_ERROR, decryptor_.ReleaseUsageInfo(release_msg)); } - status = decryptor_.GetUsageInfo(usage_info_data->app_id, - kDefaultCdmIdentifier, &usage_info); + status = decryptor_.GetUsageInfo(usage_info_data->app_id, &usage_info); EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status); } } @@ -2715,8 +2653,7 @@ TEST_F(WvCdmRequestLicenseTest, UsageReleaseAllTest) { DeviceFiles handle(&file_system); EXPECT_TRUE(handle.Init(security_level)); std::vector psts; - EXPECT_TRUE(handle.DeleteAllUsageInfoForApp( - DeviceFiles::GetUsageInfoFileName(""), &psts)); + EXPECT_TRUE(handle.DeleteAllUsageInfoForApp("", &psts)); for (size_t i = 0; i < N_ELEM(usage_info_sub_samples_icp); ++i) { SubSampleInfo* data = usage_info_sub_samples_icp + i; @@ -2733,11 +2670,7 @@ TEST_F(WvCdmRequestLicenseTest, UsageReleaseAllTest) { key_id.append(1, ch); GenerateKeyRequest(key_id, kLicenseTypeStreaming, &property_set); - // TODO(rfrias): streaming_clip6 is a streaming license without a pst - if (ch == '6') - VerifyKeyRequestResponse(g_license_server, g_client_auth, false); - else - VerifyUsageKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); std::vector decrypt_buffer(data->encrypt_data.size()); CdmDecryptionParameters decryption_parameters( @@ -2755,46 +2688,25 @@ TEST_F(WvCdmRequestLicenseTest, UsageReleaseAllTest) { } CdmUsageInfo usage_info; - EXPECT_EQ( - KEY_MESSAGE, - decryptor_.GetUsageInfo(app_id_empty, kDefaultCdmIdentifier, - &usage_info)); + EXPECT_EQ(KEY_MESSAGE, decryptor_.GetUsageInfo(app_id_empty, &usage_info)); EXPECT_TRUE(usage_info.size() > 0); - EXPECT_EQ( - KEY_MESSAGE, - decryptor_.GetUsageInfo(app_id_not_empty, kDefaultCdmIdentifier, - &usage_info)); + EXPECT_EQ(KEY_MESSAGE, + decryptor_.GetUsageInfo(app_id_not_empty, &usage_info)); EXPECT_TRUE(usage_info.size() > 0); - EXPECT_EQ( - NO_ERROR, - decryptor_.ReleaseAllUsageInfo(app_id_not_empty, kDefaultCdmIdentifier)); + EXPECT_EQ(NO_ERROR, decryptor_.ReleaseAllUsageInfo(app_id_not_empty)); - EXPECT_EQ( - NO_ERROR, - decryptor_.GetUsageInfo(app_id_not_empty, kDefaultCdmIdentifier, - &usage_info)); + EXPECT_EQ(NO_ERROR, decryptor_.GetUsageInfo(app_id_not_empty, &usage_info)); EXPECT_TRUE(usage_info.empty()); - EXPECT_EQ( - KEY_MESSAGE, - decryptor_.GetUsageInfo(app_id_empty, kDefaultCdmIdentifier, - &usage_info)); + EXPECT_EQ(KEY_MESSAGE, decryptor_.GetUsageInfo(app_id_empty, &usage_info)); EXPECT_TRUE(usage_info.size() > 0); - EXPECT_EQ( - NO_ERROR, - decryptor_.ReleaseAllUsageInfo(app_id_empty, kDefaultCdmIdentifier)); + EXPECT_EQ(NO_ERROR, decryptor_.ReleaseAllUsageInfo(app_id_empty)); - EXPECT_EQ( - NO_ERROR, - decryptor_.GetUsageInfo(app_id_not_empty, kDefaultCdmIdentifier, - &usage_info)); + EXPECT_EQ(NO_ERROR, decryptor_.GetUsageInfo(app_id_not_empty, &usage_info)); EXPECT_TRUE(usage_info.empty()); - EXPECT_EQ( - NO_ERROR, - decryptor_.GetUsageInfo(app_id_empty, kDefaultCdmIdentifier, - &usage_info)); + EXPECT_EQ(NO_ERROR, decryptor_.GetUsageInfo(app_id_empty, &usage_info)); EXPECT_TRUE(usage_info.empty()); } @@ -2825,7 +2737,7 @@ TEST_F(WvCdmRequestLicenseTest, QueryKeyStatus) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); CdmQueryMap query_info; CdmQueryMap::iterator itr; @@ -3059,7 +2971,7 @@ TEST_F(WvCdmRequestLicenseTest, QueryOemCryptoSessionId) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); CdmQueryMap query_info; CdmQueryMap::iterator itr; @@ -3147,7 +3059,7 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); CdmKeySetId key_set_id = key_set_id_; EXPECT_FALSE(key_set_id_.empty()); decryptor_.CloseSession(session_id_); @@ -3186,7 +3098,7 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); decryptor_.CloseSession(session_id_); if (security_level != kSecurityLevelL1) return; @@ -3211,7 +3123,7 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) { kDefaultCdmIdentifier, NULL, &session_id_)); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, client_auth); + VerifyKeyRequestResponse(g_license_server, client_auth, false); decryptor_.CloseSession(session_id_); } @@ -3219,7 +3131,7 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_OfflineLicenseDecryptionTest) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeOffline); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); /* // key 1, encrypted, 256b @@ -3273,7 +3185,7 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_RestoreOfflineLicenseDecryptionTest) { decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeOffline); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); CdmKeySetId key_set_id = key_set_id_; EXPECT_FALSE(key_set_id_.empty()); decryptor_.CloseSession(session_id_); @@ -3335,7 +3247,7 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_RestoreOfflineLicenseDecryptionTest) { TEST_F(WvCdmRequestLicenseTest, KeyControlBlockDecryptionTest) { decryptor_.OpenSession(g_key_system, &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); DecryptionData data; @@ -3401,7 +3313,7 @@ TEST_P(WvCdmSessionSharingTest, SessionSharingTest) { NULL, &session_id_); CdmSessionId gp_session_id_1 = session_id_; GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); // TODO(rfrias): Move content information to ConfigTestEnv std::string gp_client_auth2 = @@ -3415,7 +3327,7 @@ TEST_P(WvCdmSessionSharingTest, SessionSharingTest) { NULL, &session_id_); CdmSessionId gp_session_id_2 = session_id_; GenerateKeyRequest(gp_key_id2, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, gp_client_auth2); + VerifyKeyRequestResponse(g_license_server, gp_client_auth2, false); SubSampleInfo* data = session_sharing_info->sub_sample; std::vector decrypt_buffer(data->encrypt_data.size()); @@ -3460,7 +3372,7 @@ TEST_F(WvCdmRequestLicenseTest, SessionSharingTest) { NULL, &session_id_); CdmSessionId session_id1 = session_id_; GenerateKeyRequest(init_data1, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); // TODO(rfrias): Move content information to ConfigTestEnv std::string gp_client_auth2 = @@ -3474,7 +3386,7 @@ TEST_F(WvCdmRequestLicenseTest, SessionSharingTest) { NULL, &session_id_); CdmSessionId session_id2 = session_id_; GenerateKeyRequest(init_data2, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, gp_client_auth2); + VerifyKeyRequestResponse(g_license_server, gp_client_auth2, false); SubSampleInfo* data = &single_encrypted_sub_sample_short_expiry; @@ -3496,7 +3408,7 @@ TEST_F(WvCdmRequestLicenseTest, SessionSharingTest) { NULL, &session_id_); CdmSessionId session_id3 = session_id_; GenerateKeyRequest(init_data1, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id1, data->validate_key_id, decryption_parameters)); @@ -3521,7 +3433,7 @@ TEST_F(WvCdmRequestLicenseTest, DecryptionKeyExpiredTest) { &session_id_); if (data->retrieve_key) { GenerateKeyRequest(kCpKeyId, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); } std::vector decrypt_buffer(data->encrypt_data.size()); @@ -3562,7 +3474,7 @@ TEST_F(WvCdmRequestLicenseTest, SessionKeyChangeNotificationTest) { "0801121030313233343536373839616263646566"); // pssh data GenerateKeyRequest(kCpKeyId, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); decryptor_.CloseSession(session_id_); } @@ -3577,7 +3489,7 @@ TEST_P(WvCdmDecryptionTest, DecryptionTest) { &session_id_); if (data->retrieve_key) { GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - VerifyKeyRequestResponse(g_license_server, g_client_auth); + VerifyKeyRequestResponse(g_license_server, g_client_auth, false); } uint32_t decrypt_sample_buffer_size = 0; @@ -3620,71 +3532,18 @@ INSTANTIATE_TEST_CASE_P(Cdm, WvCdmDecryptionTest, &switch_key_encrypted_sub_samples[0], &partial_encrypted_sub_samples[0])); -class WvCdmSessionSharingNoKeyTest - : public WvCdmRequestLicenseTest, - public ::testing::WithParamInterface {}; - -TEST_P(WvCdmSessionSharingNoKeyTest, DecryptionTest) { - SubSampleInfo* data = GetParam(); - - TestWvCdmClientPropertySet property_set; - property_set.set_session_sharing_mode(true); - - decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, - NULL, &session_id_); - CdmSessionId gp_session_id_1 = session_id_; - GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); - - // TODO(rfrias): Move content information to ConfigTestEnv - std::string gp_client_auth2 = - "?source=YOUTUBE&video_id=z3S_NhwueaM&oauth=ya.gtsqawidevine"; - std::string gp_key_id2 = wvcdm::a2bs_hex( - "000000347073736800000000" // blob size and pssh - "edef8ba979d64acea3c827dcd51d21ed00000014" // Widevine system id - "08011210bdf1cb4fffc6506b8b7945b0bd2917fb"); // pssh data - - decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, - NULL, &session_id_); - CdmSessionId gp_session_id_2 = session_id_; - GenerateKeyRequest(gp_key_id2, kLicenseTypeStreaming); - - std::vector decrypt_buffer(data->encrypt_data.size()); - CdmDecryptionParameters decryption_parameters( - &data->key_id, &data->encrypt_data.front(), data->encrypt_data.size(), - &data->iv, data->block_offset, &decrypt_buffer[0]); - decryption_parameters.is_encrypted = data->is_encrypted; - decryption_parameters.is_secure = data->is_secure; - decryption_parameters.subsample_flags = data->subsample_flags; - - EXPECT_EQ(data->is_encrypted ? KEY_NOT_FOUND_IN_SESSION : NO_ERROR, - decryptor_.Decrypt(gp_session_id_2, data->validate_key_id, - decryption_parameters)); - if (!data->is_encrypted) { - EXPECT_TRUE(std::equal(data->decrypt_data.begin(), data->decrypt_data.end(), - decrypt_buffer.begin())); - } - - decryptor_.CloseSession(gp_session_id_1); - decryptor_.CloseSession(gp_session_id_2); -} - -INSTANTIATE_TEST_CASE_P(Cdm, WvCdmSessionSharingNoKeyTest, - ::testing::Values(&clear_sub_sample, - &clear_sub_sample_no_key, - &single_encrypted_sub_sample)); - TEST(VersionNumberTest, VersionNumberChangeCanary) { char release_number[PROPERTY_VALUE_MAX]; ASSERT_GT(property_get("ro.build.version.release", release_number, "Unknown"), 0); - EXPECT_STREQ("8.1.0", release_number) + EXPECT_STREQ("8.0.0", release_number) << "The Android version number has changed. You need to update this test " "and also possibly update the Widevine version number in " "properties_android.cpp."; std::string widevine_version; ASSERT_TRUE(Properties::GetWVCdmVersion(&widevine_version)); - EXPECT_EQ("v5.1.0-android", widevine_version) + EXPECT_EQ("v5.0.0-android", widevine_version) << "The Widevine CDM version number has changed. Did you forget to " "update this test after changing it?"; } @@ -3698,7 +3557,7 @@ TEST_F(WvCdmRequestLicenseTest, AddHlsStreamingKeyTest) { kLicenseTypeStreaming, NULL); //TODO(rfrias): Remove once we switch to git-on-borg std::string license_server = "https://proxy.uat.widevine.com/proxy"; - VerifyKeyRequestResponse(license_server, g_client_auth); + VerifyKeyRequestResponse(license_server, g_client_auth, false); decryptor_.CloseSession(session_id_); } @@ -3742,7 +3601,7 @@ TEST_P(WvHlsDecryptionTest, HlsDecryptionTest) { kLicenseTypeStreaming, NULL); //TODO(rfrias): Remove once we switch to git-on-borg std::string license_server = "https://proxy.uat.widevine.com/proxy"; - VerifyKeyRequestResponse(license_server, g_client_auth); + VerifyKeyRequestResponse(license_server, g_client_auth, false); CdmKeyStatusMap key_status_map = listener.GetKeyStatusMap(); EXPECT_EQ(1u, key_status_map.size()); KeyId key_id = key_status_map.begin()->first; @@ -3796,7 +3655,7 @@ TEST_P(WvHlsFourCCBackwardCompatibilityTest, HlsDecryptionTest) { kLicenseTypeStreaming, NULL); //TODO(rfrias): Remove once we switch to git-on-borg std::string license_server = "https://proxy.uat.widevine.com/proxy"; - VerifyKeyRequestResponse(license_server, g_client_auth); + VerifyKeyRequestResponse(license_server, g_client_auth, false); CdmKeyStatusMap key_status_map = listener.GetKeyStatusMap(); EXPECT_EQ(1u, key_status_map.size()); KeyId key_id = key_status_map.begin()->first; @@ -3950,7 +3809,7 @@ int main(int argc, char** argv) { g_service_certificate.assign(g_config->service_certificate()); } if (g_license_server.empty()) { - g_license_server.assign(g_config->license_server_url()); + g_license_server.assign(g_config->license_server()); } // Displays server url, port and key Id being used diff --git a/libwvdrmengine/cdm/test/unit-test.mk b/libwvdrmengine/cdm/test/unit-test.mk index 33c6007d..234fc8f8 100644 --- a/libwvdrmengine/cdm/test/unit-test.mk +++ b/libwvdrmengine/cdm/test/unit-test.mk @@ -42,7 +42,7 @@ LOCAL_SHARED_LIBRARIES := \ libcutils \ libdl \ liblog \ - libmedia_omx \ + libmedia \ libprotobuf-cpp-lite \ libssl \ libstagefright_foundation \ @@ -51,10 +51,6 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_CFLAGS += -DUNIT_TEST LOCAL_MODULE_OWNER := widevine -LOCAL_PROPRIETARY_MODULE := true - -# When built, explicitly put it in the DATA/bin directory. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/bin LOCAL_PROPRIETARY_MODULE := true diff --git a/libwvdrmengine/cdm/test/wv_cdm_metrics_test.cpp b/libwvdrmengine/cdm/test/wv_cdm_metrics_test.cpp index e9963a90..a411808e 100644 --- a/libwvdrmengine/cdm/test/wv_cdm_metrics_test.cpp +++ b/libwvdrmengine/cdm/test/wv_cdm_metrics_test.cpp @@ -13,7 +13,7 @@ using ::testing::Eq; using ::testing::StrEq; -using ::testing::Ge; +using ::testing::Gt; using ::testing::Test; using wvcdm::CdmResponseType; @@ -53,17 +53,13 @@ TEST_F(WvContentDecryptionModuleMetricsTest, EngineOnlyMetrics) { ASSERT_TRUE(metrics.ParseFromString(serialized_metrics)); EXPECT_THAT(metrics.metric_size(), Eq(0)); ASSERT_THAT(metrics.metric_sub_group_size(), Eq(1)); - ASSERT_THAT(metrics.metric_sub_group(0).metric_size(), Ge(6)); + ASSERT_THAT(metrics.metric_sub_group(0).metric_size(), Gt(0)); EXPECT_THAT(metrics.metric_sub_group(0).metric_sub_group_size(), Eq(0)); - EXPECT_THAT(metrics.metric_sub_group(0).metric(0).name(), - StrEq("/drm/widevine/oemcrypto/initialization_mode")); - // Can't check the initialization mode value. Different devices will have - // different values. EXPECT_THAT( - metrics.metric_sub_group(0).metric(5).name(), + metrics.metric_sub_group(0).metric(0).name(), StrEq("/drm/widevine/cdm_engine/" "get_provisioning_request/time/count{error:0}")); - EXPECT_THAT(metrics.metric_sub_group(0).metric(5).value().int_value(), Eq(1)); + EXPECT_THAT(metrics.metric_sub_group(0).metric(0).value().int_value(), Eq(1)); } @@ -87,14 +83,13 @@ TEST_F(WvContentDecryptionModuleMetricsTest, EngineAndSessionMetrics) { // The outer container will never have metrics. EXPECT_THAT(metrics.metric_size(), Eq(0)); ASSERT_THAT(metrics.metric_sub_group_size(), Eq(1)); - ASSERT_THAT(metrics.metric_sub_group(0).metric_size(), Ge(6)); + ASSERT_THAT(metrics.metric_sub_group(0).metric_size(), Gt(0)); - // Validate engine-level metrics. - EXPECT_THAT(metrics.metric_sub_group(0).metric(0).name(), - StrEq("/drm/widevine/oemcrypto/initialization_mode")); - EXPECT_THAT(metrics.metric_sub_group(0).metric(5).name(), - StrEq("/drm/widevine/cdm_engine/open_session/count{error:7}")); - EXPECT_THAT(metrics.metric_sub_group(0).metric(5).value().int_value(), Eq(1)); + // Validate an engine-level metric. + EXPECT_THAT( + metrics.metric_sub_group(0).metric(0).name(), + StrEq("/drm/widevine/cdm_engine/open_session/time/count{error:7}")); + EXPECT_THAT(metrics.metric_sub_group(0).metric(0).value().int_value(), Eq(1)); // Validate a session-level metric. EXPECT_THAT(metrics.metric_sub_group(0).metric_sub_group_size(), Eq(1)); @@ -106,7 +101,7 @@ TEST_F(WvContentDecryptionModuleMetricsTest, EngineAndSessionMetrics) { TEST_F(WvContentDecryptionModuleMetricsTest, MultipleEngineMetric) { CdmSessionId session_id; wvcdm::CdmKeySystem key_system("com.widevine"); - CdmIdentifier identifier = { "foo", "bar", "baz" }; + CdmIdentifier identifier = { "foo", "bar" }; // Openning the session will fail with NEEDS_PROVISIONING error. But it will // still create some session-level stats. @@ -133,22 +128,17 @@ TEST_F(WvContentDecryptionModuleMetricsTest, MultipleEngineMetric) { for (int i = 0; i < metrics.metric_sub_group_size(); i++) { // Validate the engine-level metric. - ASSERT_THAT(metrics.metric_sub_group(i).metric_size(), Ge(6)); - EXPECT_THAT(metrics.metric_sub_group(i).metric(0).name(), - StrEq("/drm/widevine/oemcrypto/initialization_mode")); - EXPECT_THAT(metrics.metric_sub_group(i).metric(5).name(), - StrEq("/drm/widevine/cdm_engine/open_session/count{error:7}")); - EXPECT_THAT(metrics.metric_sub_group(i).metric(5).value().int_value(), Eq(1)); - + ASSERT_THAT(metrics.metric_sub_group(i).metric_size(), Gt(0)); + EXPECT_THAT( + metrics.metric_sub_group(i).metric(0).name(), + StrEq("/drm/widevine/cdm_engine/open_session/time/count{error:7}")); + EXPECT_THAT(metrics.metric_sub_group(i).metric(0).value().int_value(), Eq(1)); // Validate a session-level metric. EXPECT_THAT(metrics.metric_sub_group(i).metric_sub_group_size(), Eq(1)); EXPECT_THAT( metrics.metric_sub_group(i).metric_sub_group(0).metric(0).name(), StrEq("/drm/widevine/cdm_session/session_id")); } - - // Verify that the second metrics app package name is set. - EXPECT_THAT(metrics.metric_sub_group(1).app_package_name(), StrEq("baz")); } } diff --git a/libwvdrmengine/include/WVErrors.h b/libwvdrmengine/include/WVErrors.h index 77c2bddd..cd632ee5 100644 --- a/libwvdrmengine/include/WVErrors.h +++ b/libwvdrmengine/include/WVErrors.h @@ -237,8 +237,8 @@ enum { kMoveUsageEntryUnknownError = ERROR_DRM_VENDOR_MIN + 225, kCopyOldUsageEntryUnknownError = ERROR_DRM_VENDOR_MIN + 226, kInvalidParametersEng22 = ERROR_DRM_VENDOR_MIN + 227, - kStoreLicenseError4 = ERROR_DRM_VENDOR_MIN + 228, - kListLicensesError = ERROR_DRM_VENDOR_MIN + 229, + kListLicenseError1 = ERROR_DRM_VENDOR_MIN + 228, + kListLicenseError2 = ERROR_DRM_VENDOR_MIN + 229, kInvalidParametersEng23 = ERROR_DRM_VENDOR_MIN + 230, kUsageInformationSupportFailed = ERROR_DRM_VENDOR_MIN + 231, kUsageSupportGetApiFailed = ERROR_DRM_VENDOR_MIN + 232, @@ -253,8 +253,8 @@ enum { kUsageStoreLicenseFailed = ERROR_DRM_VENDOR_MIN + 241, kUsageStoreUsageInfoFailed = ERROR_DRM_VENDOR_MIN + 242, kUsageInvalidLoadEntry = ERROR_DRM_VENDOR_MIN + 243, - kReleaseAllUsageInfoError4 = ERROR_DRM_VENDOR_MIN + 244, - kReleaseAllUsageInfoError5 = ERROR_DRM_VENDOR_MIN + 245, + kReleaseAllUsageInfoError3 = ERROR_DRM_VENDOR_MIN + 244, + kReleaseAllUsageInfoError4 = ERROR_DRM_VENDOR_MIN + 245, kReleaseUsageInfoFailed = ERROR_DRM_VENDOR_MIN + 246, kIncorrectUsageSupportType1 = ERROR_DRM_VENDOR_MIN + 247, kIncorrectUsageSupportType2 = ERROR_DRM_VENDOR_MIN + 248, @@ -264,20 +264,10 @@ enum { kDeleteUsageError1 = ERROR_DRM_VENDOR_MIN + 252, kDeleteUsageError2 = ERROR_DRM_VENDOR_MIN + 253, kDeleteUsageError3 = ERROR_DRM_VENDOR_MIN + 254, - kPrivacyModeError1 = ERROR_DRM_VENDOR_MIN + 255, - kPrivacyModeError2 = ERROR_DRM_VENDOR_MIN + 256, - kPrivacyModeError3 = ERROR_DRM_VENDOR_MIN + 257, - kEmptyResponseError1 = ERROR_DRM_VENDOR_MIN + 258, - kInvalidParametersEng24 = ERROR_DRM_VENDOR_MIN + 259, - kParseResponseError1 = ERROR_DRM_VENDOR_MIN + 260, - kParseResponseError2 = ERROR_DRM_VENDOR_MIN + 261, - kParseResponseError3 = ERROR_DRM_VENDOR_MIN + 262, - kParseResponseError4 = ERROR_DRM_VENDOR_MIN + 263, - kReleaseAllUsageInfoError6 = ERROR_DRM_VENDOR_MIN + 264, // This should always follow the last error code. // The offset value should be updated each time a new error code is added. - kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 264, + kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 254, // Used by crypto test mode kErrorTestMode = ERROR_DRM_VENDOR_MAX, diff --git a/libwvdrmengine/include/mapErrors-inl.h b/libwvdrmengine/include/mapErrors-inl.h index 5a84ad33..cdb3c442 100644 --- a/libwvdrmengine/include/mapErrors-inl.h +++ b/libwvdrmengine/include/mapErrors-inl.h @@ -411,6 +411,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kInvalidParametersEng16; case wvcdm::INVALID_PARAMETERS_ENG_17: return kInvalidParametersEng17; + case wvcdm::INVALID_PARAMETERS_ENG_18: + return kInvalidParametersEng18; case wvcdm::CERT_PROVISIONING_CLIENT_TOKEN_ERROR_1: return kCertProvisioningClientTokenError1; case wvcdm::CERT_PROVISIONING_CLIENT_TOKEN_ERROR_2: @@ -431,8 +433,6 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kLoadUsageHeaderBadMagic; case wvcdm::LOAD_USAGE_HEADER_UNKNOWN_ERROR: return kLoadUsageHeaderUnknownError; - case wvcdm::INVALID_PARAMETERS_ENG_18: - return kInvalidParametersEng18; case wvcdm::INSUFFICIENT_CRYPTO_RESOURCES_3: return kInsufficientCryptoResources3; case wvcdm::CREATE_USAGE_ENTRY_UNKNOWN_ERROR: @@ -459,14 +459,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kMoveUsageEntryUnknownError; case wvcdm::COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR: return kCopyOldUsageEntryUnknownError; - case wvcdm::STORE_LICENSE_ERROR_4: - return kStoreLicenseError4; - case wvcdm::LIST_LICENSES_ERROR: - return kListLicensesError; case wvcdm::INVALID_PARAMETERS_ENG_23: return kInvalidParametersEng23; - case wvcdm::INVALID_PARAMETERS_ENG_24: - return kInvalidParametersEng24; case wvcdm::USAGE_INFORMATION_SUPPORT_FAILED: return kUsageInformationSupportFailed; case wvcdm::USAGE_SUPPORT_GET_API_FAILED: @@ -493,20 +487,22 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kUsageStoreUsageInfoFailed; case wvcdm::USAGE_INVALID_LOAD_ENTRY: return kUsageInvalidLoadEntry; - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_4: - return kReleaseAllUsageInfoError4; - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_5: - return kReleaseAllUsageInfoError5; - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_6: - return kReleaseAllUsageInfoError6; case wvcdm::RELEASE_USAGE_INFO_FAILED: return android::ERROR_DRM_TAMPER_DETECTED; case wvcdm::INCORRECT_USAGE_SUPPORT_TYPE_1: return kIncorrectUsageSupportType1; case wvcdm::INCORRECT_USAGE_SUPPORT_TYPE_2: return kIncorrectUsageSupportType2; + case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_3: + return kReleaseAllUsageInfoError3; + case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_4: + return kReleaseAllUsageInfoError4; case wvcdm::NO_USAGE_ENTRIES: return kNoUsageEntries; + case wvcdm::LIST_LICENSE_ERROR_1: + return kListLicenseError1; + case wvcdm::LIST_LICENSE_ERROR_2: + return kListLicenseError2; case wvcdm::LIST_USAGE_ERROR_1: return kListUsageError1; case wvcdm::LIST_USAGE_ERROR_2: @@ -517,22 +513,6 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kDeleteUsageError2; case wvcdm::DELETE_USAGE_ERROR_3: return kDeleteUsageError3; - case wvcdm::PRIVACY_MODE_ERROR_1: - return kPrivacyModeError1; - case wvcdm::PRIVACY_MODE_ERROR_2: - return kPrivacyModeError2; - case wvcdm::PRIVACY_MODE_ERROR_3: - return kPrivacyModeError3; - case wvcdm::EMPTY_RESPONSE_ERROR_1: - return kEmptyResponseError1; - case wvcdm::PARSE_RESPONSE_ERROR_1: - return kParseResponseError1; - case wvcdm::PARSE_RESPONSE_ERROR_2: - return kParseResponseError2; - case wvcdm::PARSE_RESPONSE_ERROR_3: - return kParseResponseError3; - case wvcdm::PARSE_RESPONSE_ERROR_4: - return kParseResponseError4; case wvcdm::UNUSED_1: case wvcdm::UNUSED_2: diff --git a/libwvdrmengine/include_hidl/TypeConvert.h b/libwvdrmengine/include_hidl/TypeConvert.h index dada0b26..c3cac776 100644 --- a/libwvdrmengine/include_hidl/TypeConvert.h +++ b/libwvdrmengine/include_hidl/TypeConvert.h @@ -70,6 +70,8 @@ template std::vector toVector( return vec; } +Status toStatus(status_t mediaError); + } // namespace widevine } // namespace V1_0 } // namespace drm diff --git a/libwvdrmengine/include_hidl/mapErrors-inl.h b/libwvdrmengine/include_hidl/mapErrors-inl.h index 75b2a504..d3f9e55d 100644 --- a/libwvdrmengine/include_hidl/mapErrors-inl.h +++ b/libwvdrmengine/include_hidl/mapErrors-inl.h @@ -267,8 +267,6 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) { case wvcdm::MOVE_USAGE_ENTRY_UNKNOWN_ERROR: case wvcdm::COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR: case wvcdm::INVALID_PARAMETERS_ENG_22: - case wvcdm::STORE_LICENSE_ERROR_4: - case wvcdm::LIST_LICENSES_ERROR: case wvcdm::INVALID_PARAMETERS_ENG_23: case wvcdm::USAGE_INFORMATION_SUPPORT_FAILED: case wvcdm::USAGE_SUPPORT_GET_API_FAILED: @@ -284,8 +282,6 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) { case wvcdm::USAGE_STORE_USAGE_INFO_FAILED: case wvcdm::USAGE_INVALID_LOAD_ENTRY: case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_4: - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_5: - case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_6: case wvcdm::INCORRECT_USAGE_SUPPORT_TYPE_1: case wvcdm::INCORRECT_USAGE_SUPPORT_TYPE_2: case wvcdm::NO_USAGE_ENTRIES: @@ -294,15 +290,9 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) { case wvcdm::DELETE_USAGE_ERROR_1: case wvcdm::DELETE_USAGE_ERROR_2: case wvcdm::DELETE_USAGE_ERROR_3: - case wvcdm::PRIVACY_MODE_ERROR_1: - case wvcdm::PRIVACY_MODE_ERROR_2: - case wvcdm::PRIVACY_MODE_ERROR_3: - case wvcdm::EMPTY_RESPONSE_ERROR_1: - case wvcdm::INVALID_PARAMETERS_ENG_24: - case wvcdm::PARSE_RESPONSE_ERROR_1: - case wvcdm::PARSE_RESPONSE_ERROR_2: - case wvcdm::PARSE_RESPONSE_ERROR_3: - case wvcdm::PARSE_RESPONSE_ERROR_4: + case wvcdm::LIST_LICENSE_ERROR_1: + case wvcdm::LIST_LICENSE_ERROR_2: + case wvcdm::RELEASE_ALL_USAGE_INFO_ERROR_3: ALOGW("Returns UNKNOWN error for legacy status: %d", res); return Status::ERROR_DRM_UNKNOWN; @@ -313,6 +303,7 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) { case wvcdm::UNUSED_4: case wvcdm::UNUSED_5: case wvcdm::UNUSED_6: + case wvcdm::UNUSED_7: return Status::ERROR_DRM_UNKNOWN; } diff --git a/libwvdrmengine/level3/arm/libwvlevel3.a b/libwvdrmengine/level3/arm/libwvlevel3.a index fbb0a7ea..5add59d6 100644 Binary files a/libwvdrmengine/level3/arm/libwvlevel3.a and b/libwvdrmengine/level3/arm/libwvlevel3.a differ diff --git a/libwvdrmengine/level3/arm64/libwvlevel3.a b/libwvdrmengine/level3/arm64/libwvlevel3.a index 3726e274..6d0c9e32 100644 Binary files a/libwvdrmengine/level3/arm64/libwvlevel3.a and b/libwvdrmengine/level3/arm64/libwvlevel3.a differ diff --git a/libwvdrmengine/level3/mips/Android.mk b/libwvdrmengine/level3/mips/Android.mk index bd3d481c..3ffa9e38 100644 --- a/libwvdrmengine/level3/mips/Android.mk +++ b/libwvdrmengine/level3/mips/Android.mk @@ -3,16 +3,9 @@ include $(CLEAR_VARS) LOCAL_MODULE := libwvlevel3 LOCAL_MODULE_CLASS := STATIC_LIBRARIES LOCAL_MODULE_SUFFIX := .a -LOCAL_SRC_FILES := level3_stubs.cpp - -LOCAL_C_INCLUDES := \ - vendor/widevine/libwvdrmengine/cdm/core/include \ - vendor/widevine/libwvdrmengine/cdm/include \ - vendor/widevine/libwvdrmengine/oemcrypto/include \ - vendor/widevine/libwvdrmengine/third_party/stringencoders/src - +LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX) LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional LOCAL_MODULE_OWNER := widevine -LOCAL_MODULE_TARGET_ARCH := mips mips64 -include $(BUILD_STATIC_LIBRARY) +LOCAL_MODULE_TARGET_ARCH := mips +include $(BUILD_PREBUILT) diff --git a/libwvdrmengine/level3/x86/libwvlevel3.a b/libwvdrmengine/level3/x86/libwvlevel3.a index 2dbd341d..b266793c 100644 Binary files a/libwvdrmengine/level3/x86/libwvlevel3.a and b/libwvdrmengine/level3/x86/libwvlevel3.a differ diff --git a/libwvdrmengine/level3/x86_64/libwvlevel3.a b/libwvdrmengine/level3/x86_64/libwvlevel3.a index acaf02cf..609bd28a 100644 Binary files a/libwvdrmengine/level3/x86_64/libwvlevel3.a and b/libwvdrmengine/level3/x86_64/libwvlevel3.a differ diff --git a/libwvdrmengine/mediacrypto/Android.mk b/libwvdrmengine/mediacrypto/Android.mk index 8cf087b6..cc7a4c16 100644 --- a/libwvdrmengine/mediacrypto/Android.mk +++ b/libwvdrmengine/mediacrypto/Android.mk @@ -18,18 +18,10 @@ LOCAL_C_INCLUDES := \ vendor/widevine/libwvdrmengine/mediacrypto/include \ vendor/widevine/libwvdrmengine/oemcrypto/include \ -LOCAL_HEADER_LIBRARIES := \ - libutils_headers - LOCAL_STATIC_LIBRARIES := \ - libcdm_protos \ - libcrypto \ - -LOCAL_SHARED_LIBRARIES := \ - liblog + libcrypto_static \ LOCAL_MODULE := libwvdrmcryptoplugin -LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional @@ -55,21 +47,16 @@ LOCAL_C_INCLUDES := \ vendor/widevine/libwvdrmengine/mediacrypto/include \ vendor/widevine/libwvdrmengine/oemcrypto/include \ -LOCAL_HEADER_LIBRARIES := \ - libutils_headers - LOCAL_STATIC_LIBRARIES := \ - libcdm_protos \ - libcrypto + libcrypto_static \ + libhidl_utils \ LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ android.hidl.memory@1.0 \ libhidlmemory \ - liblog LOCAL_MODULE := libwvdrmcryptoplugin_hidl -LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional diff --git a/libwvdrmengine/mediacrypto/include_hidl/WVCryptoPlugin.h b/libwvdrmengine/mediacrypto/include_hidl/WVCryptoPlugin.h index 1ea1fd4a..d3ff9914 100644 --- a/libwvdrmengine/mediacrypto/include_hidl/WVCryptoPlugin.h +++ b/libwvdrmengine/mediacrypto/include_hidl/WVCryptoPlugin.h @@ -68,7 +68,7 @@ struct WVCryptoPlugin : public ICryptoPlugin { sp const mCDM; - Status attemptDecrypt( + android::status_t attemptDecrypt( const wvcdm::CdmDecryptionParameters& params, bool haveEncryptedSubsamples, std::string* errorDetailMsg); static wvcdm::CdmResponseType countEncryptedBlocksInPatternedRange( diff --git a/libwvdrmengine/mediacrypto/src_hidl/WVCryptoPlugin.cpp b/libwvdrmengine/mediacrypto/src_hidl/WVCryptoPlugin.cpp index 075f6d88..8b8d10c8 100644 --- a/libwvdrmengine/mediacrypto/src_hidl/WVCryptoPlugin.cpp +++ b/libwvdrmengine/mediacrypto/src_hidl/WVCryptoPlugin.cpp @@ -30,9 +30,12 @@ namespace V1_0 { namespace widevine { using ::android::hardware::drm::V1_0::BufferType; +using ::android::hardware::drm::V1_0::widevine::toStatus; using ::android::hardware::drm::V1_0::widevine::toVector; using ::android::hardware::Void; +using android::status_t; + using wvcdm::CdmDecryptionParameters; using wvcdm::CdmQueryMap; using wvcdm::CdmResponseType; @@ -95,11 +98,7 @@ Return WVCryptoPlugin::setMediaDrmSession( Return WVCryptoPlugin::setSharedBufferBase( const hidl_memory& base, uint32_t bufferId) { - sp hidlMemory = mapMemory(base); - ALOGE_IF(hidlMemory == nullptr, "mapMemory returns nullptr"); - - // allow mapMemory to return nullptr - mSharedBufferMap[bufferId] = hidlMemory; + mSharedBufferMap[bufferId] = mapMemory(base); return Void(); } @@ -145,10 +144,6 @@ Return WVCryptoPlugin::decrypt( std::string errorDetailMsg; sp sourceBase = mSharedBufferMap[source.bufferId]; - if (sourceBase == nullptr) { - _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr"); - return Void(); - } if (source.offset + offset + source.size > sourceBase->getSize()) { _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); @@ -162,11 +157,6 @@ Return WVCryptoPlugin::decrypt( if (destination.type == BufferType::SHARED_MEMORY) { const SharedBuffer& destBuffer = destination.nonsecureMemory; sp destBase = mSharedBufferMap[destBuffer.bufferId]; - if (destBase == nullptr) { - _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr"); - return Void(); - } - if (destBuffer.offset + destBuffer.size > destBase->getSize()) { _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); return Void(); @@ -255,10 +245,10 @@ Return WVCryptoPlugin::decrypt( params.decrypt_buffer_offset = bufferOffset; params.subsample_flags = clearFlags; - Status res = attemptDecrypt(params, haveEncryptedSubsamples, + status_t res = attemptDecrypt(params, haveEncryptedSubsamples, &errorDetailMsg); - if (res != Status::OK) { - _hidl_cb(res, 0, errorDetailMsg.c_str()); + if (res != android::OK) { + _hidl_cb(toStatus(res), 0, errorDetailMsg.c_str()); return Void(); } bufferOffset += subSample.numBytesOfClearData; @@ -274,10 +264,10 @@ Return WVCryptoPlugin::decrypt( params.decrypt_buffer_offset = bufferOffset; params.subsample_flags = encryptedFlags; - Status res = attemptDecrypt(params, haveEncryptedSubsamples, + status_t res = attemptDecrypt(params, haveEncryptedSubsamples, &errorDetailMsg); - if (res != Status::OK) { - _hidl_cb(res, 0, errorDetailMsg.c_str()); + if (res != android::OK) { + _hidl_cb(toStatus(res), 0, errorDetailMsg.c_str()); return Void(); } @@ -328,14 +318,14 @@ Return WVCryptoPlugin::decrypt( return Void(); } -Status WVCryptoPlugin::attemptDecrypt(const CdmDecryptionParameters& params, +status_t WVCryptoPlugin::attemptDecrypt(const CdmDecryptionParameters& params, bool haveEncryptedSubsamples, std::string* errorDetailMsg) { CdmResponseType res = mCDM->Decrypt(mSessionId, haveEncryptedSubsamples, params); if (isCdmResponseTypeSuccess(res)) { - return Status::OK; + return android::OK; } else { ALOGE("Decrypt error result in session %s during %s block: %d", mSessionId.c_str(), @@ -375,10 +365,10 @@ Status WVCryptoPlugin::attemptDecrypt(const CdmDecryptionParameters& params, if (actionableError) { // This error is actionable by the app and should be passed up. - return mapCdmResponseType(res); + return (status_t)mapCdmResponseType(res); } else { // Swallow the specifics of other errors to obscure decrypt internals. - return Status::ERROR_DRM_UNKNOWN; + return kErrorCDMGeneric; } } } diff --git a/libwvdrmengine/mediacrypto/test/Android.mk b/libwvdrmengine/mediacrypto/test/Android.mk index 1fba8755..3c3ff291 100644 --- a/libwvdrmengine/mediacrypto/test/Android.mk +++ b/libwvdrmengine/mediacrypto/test/Android.mk @@ -21,7 +21,7 @@ LOCAL_STATIC_LIBRARIES := \ libcdm \ libcdm_protos \ libcdm_utils \ - libcrypto \ + libcrypto_static \ libjsmn \ libgmock \ libgmock_main \ @@ -45,10 +45,8 @@ LOCAL_MODULE := libwvdrmmediacrypto_test LOCAL_MODULE_TAGS := tests LOCAL_MODULE_OWNER := widevine -LOCAL_PROPRIETARY_MODULE := true -# When built, explicitly put it in the DATA/bin directory. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/bin +LOCAL_PROPRIETARY_MODULE := true ifneq ($(TARGET_ENABLE_MEDIADRM_64), true) LOCAL_MODULE_TARGET_ARCH := arm x86 mips @@ -79,7 +77,7 @@ LOCAL_STATIC_LIBRARIES := \ libcdm \ libcdm_protos \ libcdm_utils \ - libcrypto \ + libcrypto_static \ libjsmn \ libgmock \ libgmock_main \ @@ -87,15 +85,19 @@ LOCAL_STATIC_LIBRARIES := \ libwvlevel3 \ libwvdrmcryptoplugin_hidl \ +# When the GNU linker sees a library, it discards all symbols that it doesn't +# need. libhidl_utils must come after libwvdrmcryptoplugin. +LOCAL_STATIC_LIBRARIES += libhidl_utils + LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ + android.hidl.base@1.0 \ android.hidl.memory@1.0 \ libbinder \ libcutils \ libdl \ libhidlbase \ libhidlmemory \ - libhidltransport \ liblog \ libprotobuf-cpp-lite \ libutils \ @@ -108,10 +110,8 @@ LOCAL_MODULE := libwvdrmmediacrypto_hidl_test LOCAL_MODULE_TAGS := tests LOCAL_MODULE_OWNER := widevine -LOCAL_PROPRIETARY_MODULE := true -# When built, explicitly put it in the DATA/bin directory. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/bin +LOCAL_PROPRIETARY_MODULE := true ifneq ($(TARGET_ENABLE_MEDIADRM_64), true) LOCAL_MODULE_TARGET_ARCH := arm x86 mips diff --git a/libwvdrmengine/mediadrm/Android.mk b/libwvdrmengine/mediadrm/Android.mk index 30141745..32372c5e 100644 --- a/libwvdrmengine/mediadrm/Android.mk +++ b/libwvdrmengine/mediadrm/Android.mk @@ -19,17 +19,7 @@ LOCAL_C_INCLUDES := \ vendor/widevine/libwvdrmengine/mediadrm/include \ vendor/widevine/libwvdrmengine/oemcrypto/include \ -LOCAL_HEADER_LIBRARIES := \ - libutils_headers - -LOCAL_SHARED_LIBRARIES := \ - liblog - -LOCAL_STATIC_LIBRARIES := \ - libcdm_protos - LOCAL_MODULE := libwvdrmdrmplugin -LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional @@ -56,20 +46,13 @@ LOCAL_C_INCLUDES := \ vendor/widevine/libwvdrmengine/mediadrm/include \ vendor/widevine/libwvdrmengine/oemcrypto/include \ -LOCAL_HEADER_LIBRARIES := \ - libutils_headers \ - -LOCAL_STATIC_LIBRARIES := \ - libcdm_protos \ - libcrypto +LOCAL_STATIC_LIBRARIES := libcrypto_static LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ android.hidl.memory@1.0 \ - liblog LOCAL_MODULE := libwvdrmdrmplugin_hidl -LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional diff --git a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp index aea51dcf..5a8603cc 100644 --- a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp @@ -424,7 +424,7 @@ status_t WVDrmPlugin::getSecureStop(const Vector& ssid, CdmUsageInfo cdmUsageInfo; CdmSecureStopId cdmSsid(ssid.begin(), ssid.end()); CdmResponseType res = mCDM->GetUsageInfo( - mPropertySet.app_id(), cdmSsid, mCdmIdentifier, &cdmUsageInfo); + mPropertySet.app_id(), cdmSsid, &cdmUsageInfo); if (isCdmResponseTypeSuccess(res)) { secureStop.clear(); for (CdmUsageInfo::const_iterator iter = cdmUsageInfo.begin(); @@ -442,7 +442,7 @@ status_t WVDrmPlugin::getSecureStop(const Vector& ssid, status_t WVDrmPlugin::getSecureStops(List >& secureStops) { CdmUsageInfo cdmUsageInfo; CdmResponseType res = - mCDM->GetUsageInfo(mPropertySet.app_id(), mCdmIdentifier, &cdmUsageInfo); + mCDM->GetUsageInfo(mPropertySet.app_id(), &cdmUsageInfo); if (isCdmResponseTypeSuccess(res)) { secureStops.clear(); for (CdmUsageInfo::const_iterator iter = cdmUsageInfo.begin(); @@ -457,8 +457,7 @@ status_t WVDrmPlugin::getSecureStops(List >& secureStops) { } status_t WVDrmPlugin::releaseAllSecureStops() { - CdmResponseType res = mCDM->ReleaseAllUsageInfo(mPropertySet.app_id(), - mCdmIdentifier); + CdmResponseType res = mCDM->ReleaseAllUsageInfo(mPropertySet.app_id()); return mapCdmResponseType(res); } @@ -467,7 +466,7 @@ status_t WVDrmPlugin::releaseSecureStops(const Vector& ssRelease) { return android::BAD_VALUE; } CdmUsageInfoReleaseMessage cdmMessage(ssRelease.begin(), ssRelease.end()); - CdmResponseType res = mCDM->ReleaseUsageInfo(cdmMessage, mCdmIdentifier); + CdmResponseType res = mCDM->ReleaseUsageInfo(cdmMessage); return mapCdmResponseType(res); } @@ -476,7 +475,7 @@ status_t WVDrmPlugin::getPropertyString(const String8& name, if (name == "vendor") { value = "Google"; } else if (name == "version") { - return queryProperty(QUERY_KEY_WVCDM_VERSION, value); + value = "1.0"; } else if (name == "description") { value = "Widevine CDM"; } else if (name == "algorithms") { @@ -519,10 +518,6 @@ status_t WVDrmPlugin::getPropertyString(const String8& name, value = mPropertySet.app_id().c_str(); } else if (name == "origin") { value = mCdmIdentifier.origin.c_str(); - } else if (name == "CurrentSRMVersion") { - return queryProperty(QUERY_KEY_CURRENT_SRM_VERSION, value); - } else if (name == "SRMUpdateSupport") { - return queryProperty(QUERY_KEY_SRM_UPDATE_SUPPORT, value); } else { ALOGE("App requested unknown string property %s", name.string()); return android::ERROR_DRM_CANNOT_HANDLE; @@ -533,16 +528,13 @@ status_t WVDrmPlugin::getPropertyString(const String8& name, status_t WVDrmPlugin::getPropertyByteArray(const String8& name, Vector& value) const { + if (name == "deviceUniqueId") { return queryProperty(QUERY_KEY_DEVICE_ID, value); } else if (name == "provisioningUniqueId") { return queryProperty(QUERY_KEY_PROVISIONING_ID, value); } else if (name == "serviceCertificate") { value = ToVector(mPropertySet.service_certificate()); - } else if (name == "metrics") { - std::string metrics_value; - mCDM->GetSerializedMetrics(&metrics_value); - value = ToVector(metrics_value); } else { ALOGE("App requested unknown byte array property %s", name.string()); return android::ERROR_DRM_CANNOT_HANDLE; @@ -1012,11 +1004,6 @@ status_t WVDrmPlugin::mapOEMCryptoResult(OEMCryptoResult res) { bool WVDrmPlugin::initDataResemblesPSSH(const Vector& initData) { const uint8_t* const initDataArray = initData.array(); - if (sizeof(uint32_t) + kPsshTag.size() > initData.size()) { - // The init data is so small that it couldn't contain a size and PSSH tag. - return false; - } - // Extract the size field const uint8_t* const sizeField = &initDataArray[0]; uint32_t nboSize; diff --git a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp index cc9003d6..22989a7f 100644 --- a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp @@ -547,7 +547,7 @@ Return WVDrmPlugin::getSecureStop( CdmUsageInfo cdmUsageInfo; CdmSecureStopId cdmSsId(id.begin(), id.end()); CdmResponseType res = mCDM->GetUsageInfo( - mPropertySet.app_id(), cdmSsId, identifier, &cdmUsageInfo); + mPropertySet.app_id(), cdmSsId, &cdmUsageInfo); if (isCdmResponseTypeSuccess(res)) { std::vector cdmStopVec; @@ -578,7 +578,7 @@ Return WVDrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) { CdmUsageInfo cdmUsageInfo; CdmResponseType res = - mCDM->GetUsageInfo(mPropertySet.app_id(), identifier, &cdmUsageInfo); + mCDM->GetUsageInfo(mPropertySet.app_id(), &cdmUsageInfo); if (isCdmResponseTypeSuccess(res)) { secureStops.clear(); @@ -609,8 +609,7 @@ Return WVDrmPlugin::releaseAllSecureStops() { return status; } - CdmResponseType res = mCDM->ReleaseAllUsageInfo(mPropertySet.app_id(), - identifier); + CdmResponseType res = mCDM->ReleaseAllUsageInfo(mPropertySet.app_id()); return mapCdmResponseType(res); } @@ -629,7 +628,7 @@ Return WVDrmPlugin::releaseSecureStop( const std::vector ssRelease = toVector(secureStopId); CdmUsageInfoReleaseMessage cdmMessage(ssRelease.begin(), ssRelease.end()); - CdmResponseType res = mCDM->ReleaseUsageInfo(cdmMessage, identifier); + CdmResponseType res = mCDM->ReleaseUsageInfo(cdmMessage); return mapCdmResponseType(res); } @@ -642,7 +641,7 @@ Return WVDrmPlugin::getPropertyString(const hidl_string& propertyName, if (name == "vendor") { value = "Google"; } else if (name == "version") { - status = queryProperty(wvcdm::QUERY_KEY_WVCDM_VERSION, value); + value = "1.0"; } else if (name == "description") { value = "Widevine CDM"; } else if (name == "algorithms") { @@ -685,10 +684,6 @@ Return WVDrmPlugin::getPropertyString(const hidl_string& propertyName, value = mPropertySet.app_id().c_str(); } else if (name == "origin") { value = mCdmIdentifierBuilder.origin().c_str(); - } else if (name == "CurrentSRMVersion") { - status = queryProperty(wvcdm::QUERY_KEY_CURRENT_SRM_VERSION, value); - } else if (name == "SRMUpdateSupport") { - status = queryProperty(wvcdm::QUERY_KEY_SRM_UPDATE_SUPPORT, value); } else { ALOGE("App requested unknown string property %s", name.c_str()); status = Status::ERROR_DRM_CANNOT_HANDLE; @@ -720,10 +715,6 @@ Return WVDrmPlugin::getPropertyByteArray( } } else if (name == "serviceCertificate") { value = StrToVector(mPropertySet.service_certificate()); - } else if (name == "metrics") { - std::string metrics_value; - mCDM->GetSerializedMetrics(&metrics_value); - value = StrToVector(metrics_value); } else { ALOGE("App requested unknown byte array property %s", name.c_str()); status = Status::ERROR_DRM_CANNOT_HANDLE; @@ -1375,9 +1366,7 @@ WVDrmPlugin::CdmIdentifierBuilder::CdmIdentifierBuilder( mIsIdentifierSealed(false), mUseSpoid(useSpoid), mAppPackageName(appPackageName), - mParent(parent) { - mCdmIdentifier.app_package_name = mAppPackageName; -} + mParent(parent) {} Status WVDrmPlugin::CdmIdentifierBuilder::getCdmIdentifier( CdmIdentifier* identifier) { diff --git a/libwvdrmengine/mediadrm/src_hidl/WVGenericCryptoInterface.cpp b/libwvdrmengine/mediadrm/src_hidl/WVGenericCryptoInterface.cpp index e8d7b6f4..16100c67 100644 --- a/libwvdrmengine/mediadrm/src_hidl/WVGenericCryptoInterface.cpp +++ b/libwvdrmengine/mediadrm/src_hidl/WVGenericCryptoInterface.cpp @@ -4,7 +4,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "WVCdm" -#include +#include #include "WVGenericCryptoInterface.h" diff --git a/libwvdrmengine/mediadrm/test/Android.mk b/libwvdrmengine/mediadrm/test/Android.mk index 874698d9..75cefba8 100644 --- a/libwvdrmengine/mediadrm/test/Android.mk +++ b/libwvdrmengine/mediadrm/test/Android.mk @@ -22,7 +22,7 @@ LOCAL_STATIC_LIBRARIES := \ libcdm \ libcdm_protos \ libcdm_utils \ - libcrypto \ + libcrypto_static \ libjsmn \ libgmock \ libgmock_main \ @@ -45,10 +45,8 @@ LOCAL_MODULE := libwvdrmdrmplugin_test LOCAL_MODULE_TAGS := tests LOCAL_MODULE_OWNER := widevine -LOCAL_PROPRIETARY_MODULE := true -# When built, explicitly put it in the DATA/bin directory. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/bin +LOCAL_PROPRIETARY_MODULE := true ifneq ($(TARGET_ENABLE_MEDIADRM_64), true) LOCAL_MODULE_TARGET_ARCH := arm x86 mips @@ -80,7 +78,7 @@ LOCAL_STATIC_LIBRARIES := \ libcdm \ libcdm_protos \ libcdm_utils \ - libcrypto \ + libcrypto_static \ libjsmn \ libgmock \ libgmock_main \ @@ -88,15 +86,19 @@ LOCAL_STATIC_LIBRARIES := \ libwvlevel3 \ libwvdrmdrmplugin_hidl \ +# When the GNU linker sees a library, it discards all symbols that it doesn't +# need. libhidl_utils must come after libwvdrmdrmplugin. +LOCAL_STATIC_LIBRARIES += libhidl_utils + LOCAL_SHARED_LIBRARIES := \ android.hardware.drm@1.0 \ + android.hidl.base@1.0 \ android.hidl.memory@1.0 \ libbinder \ libcutils \ libdl \ libhidlbase \ libhidlmemory \ - libhidltransport \ liblog \ libprotobuf-cpp-lite \ libutils \ @@ -109,10 +111,8 @@ LOCAL_MODULE := libwvdrmdrmplugin_hidl_test LOCAL_MODULE_TAGS := tests LOCAL_MODULE_OWNER := widevine -LOCAL_PROPRIETARY_MODULE := true -# When built, explicitly put it in the DATA/bin directory. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/bin +LOCAL_PROPRIETARY_MODULE := true ifneq ($(TARGET_ENABLE_MEDIADRM_64), true) LOCAL_MODULE_TARGET_ARCH := arm x86 mips diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp index 1d0d8985..8b1b5a88 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include "cdm_client_property_set.h" #include "gmock/gmock.h" @@ -94,7 +93,6 @@ using wvcdm::KEY_ID_SIZE; using wvcdm::KEY_IV_SIZE; using wvcdm::KEY_SET_ID_PREFIX; using wvcdm::NEVER_EXPIRES; -using wvcdm::QUERY_KEY_CURRENT_SRM_VERSION; using wvcdm::QUERY_KEY_DEVICE_ID; using wvcdm::QUERY_KEY_MAX_NUMBER_OF_SESSIONS; using wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS; @@ -102,9 +100,7 @@ using wvcdm::QUERY_KEY_OEMCRYPTO_API_VERSION; using wvcdm::QUERY_KEY_OEMCRYPTO_SESSION_ID; using wvcdm::QUERY_KEY_PROVISIONING_ID; using wvcdm::QUERY_KEY_SECURITY_LEVEL; -using wvcdm::QUERY_KEY_SRM_UPDATE_SUPPORT; using wvcdm::QUERY_KEY_SYSTEM_ID; -using wvcdm::QUERY_KEY_WVCDM_VERSION; using wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1; using wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3; using wvcdm::SecurityLevel; @@ -118,20 +114,7 @@ const std::string kAppId("com.unittest.mock.app.id"); const uint8_t* const kUnprovisionResponse = reinterpret_cast("unprovision"); const size_t kUnprovisionResponseSize = 11; -const std::string kDeviceId("0123456789\0ABCDEF", 17); - -// This is a serialized MetricsGroup message containing a small amount of -// sample data. This ensures we're able to extract it via a property. -const char kSerializedMetrics[] = { - 0x0a, 0x0a, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x02, 0x08, 0x00, - 0x0a, 0x12, 0x0a, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x12, 0x09, 0x11, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x15, 0x0a, 0x05, - 0x74, 0x65, 0x73, 0x74, 0x33, 0x12, 0x0c, 0x1a, 0x0a, 0x74, 0x65, 0x73, - 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65 -}; - -#define N_ELEM(a) (sizeof(a)/sizeof(a[0])) -} // anonymous namespace +} class MockCDM : public WvContentDecryptionModule { public: @@ -181,24 +164,19 @@ class MockCDM : public WvContentDecryptionModule { MOCK_METHOD2(Unprovision, CdmResponseType(CdmSecurityLevel, const CdmIdentifier&)); + MOCK_METHOD2(GetUsageInfo, CdmResponseType(const std::string&, + CdmUsageInfo*)); + MOCK_METHOD3(GetUsageInfo, CdmResponseType(const std::string&, - const CdmIdentifier&, - CdmUsageInfo*)); - - MOCK_METHOD4(GetUsageInfo, CdmResponseType(const std::string&, const CdmSecureStopId&, - const CdmIdentifier&, CdmUsageInfo*)); - MOCK_METHOD2(ReleaseAllUsageInfo, CdmResponseType(const std::string&, - const CdmIdentifier&)); + MOCK_METHOD1(ReleaseAllUsageInfo, CdmResponseType(const std::string&)); - MOCK_METHOD2(ReleaseUsageInfo, - CdmResponseType(const CdmUsageInfoReleaseMessage&, const CdmIdentifier&)); + MOCK_METHOD1(ReleaseUsageInfo, + CdmResponseType(const CdmUsageInfoReleaseMessage&)); MOCK_METHOD1(IsValidServiceCertificate, bool(const std::string&)); - - MOCK_METHOD1(GetSerializedMetrics, void(std::string*)); }; class MockCrypto : public WVGenericCryptoInterface { @@ -341,7 +319,7 @@ TEST_F(WVDrmPluginTest, ClosesSessions) { ASSERT_EQ(Status::OK, status); } -TEST_F(WVDrmPluginTest, ClosesSessionWithError) { +TEST_F(WVDrmPluginTest, ClosesSessionWithoutReturningError) { android::sp> cdm = new StrictMock(); StrictMock crypto; std::string appPackageName; @@ -351,7 +329,7 @@ TEST_F(WVDrmPluginTest, ClosesSessionWithError) { WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); Status status = plugin.closeSession(toHidlVec(sessionId)); - ASSERT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status); + ASSERT_EQ(Status::OK, status); } // TODO b/35325611 Fix this disabled test @@ -438,7 +416,7 @@ TEST_F(WVDrmPluginTest, DISABLED_GeneratesKeyRequests) { {kIsoBmffMimeType, initData, cdmPsshBox}, // ISO-BMFF, old passing style {kWebmMimeType, initData, cdmInitData} // WebM }; - size_t testSetCount = N_ELEM(testSets); + size_t testSetCount = sizeof(testSets) / sizeof(TestSet); // Set up the expected calls. Per gMock rules, this must be done for all test // sets prior to testing any of them. @@ -813,8 +791,8 @@ TEST_F(WVDrmPluginTest, UnprovisionsDevice) { .Times(1); WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); - Status res = plugin.unprovisionDevice(); - ASSERT_EQ(Status::OK, res); + status_t res = plugin.unprovisionDevice(); + ASSERT_EQ(android::OK, res); } TEST_F(WVDrmPluginTest, MuxesUnprovisioningErrors) { @@ -834,12 +812,12 @@ TEST_F(WVDrmPluginTest, MuxesUnprovisioningErrors) { .WillOnce(testing::Return(wvcdm::UNKNOWN_ERROR)); WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); - Status res = plugin.unprovisionDevice(); - ASSERT_NE(Status::OK, res); + status_t res = plugin.unprovisionDevice(); + ASSERT_NE(android::OK, res); res = plugin.unprovisionDevice(); - ASSERT_NE(Status::OK, res); + ASSERT_NE(android::OK, res); res = plugin.unprovisionDevice(); - ASSERT_NE(Status::OK, res); + ASSERT_NE(android::OK, res); } TEST_F(WVDrmPluginTest, UnprovisionsOrigin) { @@ -847,6 +825,8 @@ TEST_F(WVDrmPluginTest, UnprovisionsOrigin) { StrictMock crypto; std::string appPackageName; + std::vector cert; + std::vector key; std::vector specialResponse; specialResponse.assign( kUnprovisionResponse, kUnprovisionResponse + kUnprovisionResponseSize); @@ -870,38 +850,16 @@ TEST_F(WVDrmPluginTest, UnprovisionsOrigin) { }); } -TEST_F(WVDrmPluginTest, UnprovisionsGloballyWithSpoid) { - android::sp> cdm = new StrictMock(); - StrictMock crypto; - std::string appPackageName; - - std::vector specialResponse; - specialResponse.assign( - kUnprovisionResponse, kUnprovisionResponse + kUnprovisionResponseSize); - - EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _)) - .WillRepeatedly(DoAll(SetArgPointee<2>(kDeviceId), - testing::Return(wvcdm::NO_ERROR))); - - EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL1, HasOrigin(EMPTY_ORIGIN))) - .Times(1); - EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, HasOrigin(EMPTY_ORIGIN))) - .Times(1); - - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, true); - plugin.provideProvisionResponse( - toHidlVec(specialResponse), - [&](Status status, hidl_vec /* cert */, - hidl_vec /* key */) { - EXPECT_EQ(Status::OK, status); - }); -} - -TEST_F(WVDrmPluginTest, WillNotUnprovisionWithoutOriginOrSpoid) { +TEST_F(WVDrmPluginTest, WillNotUnprovisionWithoutOrigin) { + // This test is only valid on SPOID-free devices. SPOID devices can + // unprovision without an origin because the empty-origin provisioning is + // not global. android::sp> cdm = new StrictMock(); StrictMock crypto; std::string appPackageName; + std::vector cert; + std::vector key; std::vector specialResponse; specialResponse.assign( kUnprovisionResponse, kUnprovisionResponse + kUnprovisionResponseSize); @@ -923,6 +881,8 @@ TEST_F(WVDrmPluginTest, MuxesOriginUnprovisioningErrors) { StrictMock crypto; std::string appPackageName; + std::vector cert; + std::vector key; std::vector specialResponse; specialResponse.assign( kUnprovisionResponse, kUnprovisionResponse + kUnprovisionResponseSize); @@ -986,8 +946,8 @@ TEST_F(WVDrmPluginTest, GetsSecureStops) { } const char* app_id = "my_app_id"; - EXPECT_CALL(*cdm, GetUsageInfo(StrEq(app_id), _, _)) - .WillOnce(DoAll(SetArgPointee<2>(cdmStops), + EXPECT_CALL(*cdm, GetUsageInfo(StrEq(app_id), _)) + .WillOnce(DoAll(SetArgPointee<1>(cdmStops), testing::Return(wvcdm::NO_ERROR))); std::list > stops; @@ -1027,7 +987,7 @@ TEST_F(WVDrmPluginTest, ReleasesAllSecureStops) { StrictMock crypto; std::string appPackageName; - EXPECT_CALL(*cdm, ReleaseAllUsageInfo(StrEq(""), _)) + EXPECT_CALL(*cdm, ReleaseAllUsageInfo(StrEq(""))) .Times(1); WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); @@ -1055,8 +1015,7 @@ TEST_F(WVDrmPluginTest, ReleasesSecureStop) { message.assign(messageRaw, messageRaw + kMessageSize); EXPECT_CALL(*cdm, ReleaseUsageInfo(ElementsAreArray(messageRaw, - kMessageSize), - _)) + kMessageSize))) .Times(1); WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); @@ -1075,15 +1034,12 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { CdmQueryMap l3Map; l3Map[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_L3; + static const std::string deviceId("0123456789\0ABCDEF", 17); static const std::string systemId = "The Universe"; static const std::string provisioningId("Life\0&Everything", 16); static const std::string openSessions = "42"; static const std::string maxSessions = "54"; static const std::string oemCryptoApiVersion = "13"; - static const std::string currentSRMVersion = "1"; - static const std::string cdmVersion = "Infinity Minus 1"; - std::string serializedMetrics( - kSerializedMetrics, kSerializedMetrics + sizeof(kSerializedMetrics)); EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SECURITY_LEVEL, _)) .WillOnce(DoAll(SetArgPointee<2>(QUERY_VALUE_SECURITY_LEVEL_L1), @@ -1092,7 +1048,7 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { testing::Return(wvcdm::NO_ERROR))); EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _)) - .WillOnce(DoAll(SetArgPointee<2>(kDeviceId), + .WillOnce(DoAll(SetArgPointee<2>(deviceId), testing::Return(wvcdm::NO_ERROR))); EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SYSTEM_ID, _)) @@ -1115,21 +1071,6 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { .WillOnce(DoAll(SetArgPointee<2>(oemCryptoApiVersion), testing::Return(wvcdm::NO_ERROR))); - EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SRM_UPDATE_SUPPORT, _)) - .WillOnce(DoAll(SetArgPointee<2>("True"), - testing::Return(wvcdm::NO_ERROR))); - - EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_CURRENT_SRM_VERSION, _)) - .WillOnce(DoAll(SetArgPointee<2>(currentSRMVersion), - testing::Return(wvcdm::NO_ERROR))); - - EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_WVCDM_VERSION, _)) - .WillOnce(DoAll(SetArgPointee<2>(cdmVersion), - testing::Return(wvcdm::NO_ERROR))); - - EXPECT_CALL(*cdm, GetSerializedMetrics(_)) - .WillOnce(SetArgPointee<0>(serializedMetrics)); - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); std::string stringResult; std::vector vectorResult; @@ -1143,7 +1084,7 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { plugin.getPropertyString( hidl_string("version"), [&](Status status, hidl_string stringResult) { ASSERT_EQ(Status::OK, status); - EXPECT_STREQ(cdmVersion.c_str(), stringResult.c_str()); + EXPECT_STREQ("1.0", stringResult.c_str()); }); plugin.getPropertyString( @@ -1160,36 +1101,36 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { plugin.getPropertyString( hidl_string("securityLevel"), - [&](Status status, hidl_string stringResult) { + [&](Status status, hidl_string stringResult) { ASSERT_EQ(Status::OK, status); EXPECT_STREQ(QUERY_VALUE_SECURITY_LEVEL_L1.c_str(), stringResult.c_str()); }); plugin.getPropertyString( hidl_string("securityLevel"), - [&](Status status, hidl_string stringResult) { + [&](Status status, hidl_string stringResult) { ASSERT_EQ(Status::OK, status); EXPECT_STREQ(QUERY_VALUE_SECURITY_LEVEL_L3.c_str(), stringResult.c_str()); }); plugin.getPropertyByteArray( hidl_string("deviceUniqueId"), - [&](Status status, hidl_vec vectorResult) { + [&](Status status, hidl_vec vectorResult) { ASSERT_EQ(Status::OK, status); std::vector id(vectorResult); - EXPECT_THAT(id, ElementsAreArray(kDeviceId.data(), kDeviceId.size())); + EXPECT_THAT(id, ElementsAreArray(deviceId.data(), deviceId.size())); }); plugin.getPropertyString( hidl_string("systemId"), - [&](Status status, hidl_string stringResult) { + [&](Status status, hidl_string stringResult) { ASSERT_EQ(Status::OK, status); EXPECT_STREQ(systemId.c_str(), stringResult.c_str()); }); plugin.getPropertyByteArray( hidl_string("provisioningUniqueId"), - [&](Status status, hidl_vec vectorResult) { + [&](Status status, hidl_vec vectorResult) { ASSERT_EQ(Status::OK, status); std::vector id(vectorResult); EXPECT_THAT(id, ElementsAreArray(provisioningId.data(), @@ -1198,46 +1139,23 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { plugin.getPropertyString( hidl_string("numberOfOpenSessions"), - [&](Status status, hidl_string stringResult) { + [&](Status status, hidl_string stringResult) { ASSERT_EQ(Status::OK, status); EXPECT_EQ(openSessions, stringResult.c_str()); }); plugin.getPropertyString( hidl_string("maxNumberOfSessions"), - [&](Status status, hidl_string stringResult) { + [&](Status status, hidl_string stringResult) { ASSERT_EQ(Status::OK, status); EXPECT_EQ(maxSessions, stringResult.c_str()); }); plugin.getPropertyString( hidl_string("oemCryptoApiVersion"), - [&](Status status, hidl_string stringResult) { + [&](Status status, hidl_string stringResult) { ASSERT_EQ(Status::OK, status); - EXPECT_STREQ(oemCryptoApiVersion.c_str(), stringResult.c_str()); - }); - - plugin.getPropertyString( - hidl_string("SRMUpdateSupport"), - [&](Status status, hidl_string stringResult) { - ASSERT_EQ(Status::OK, status); - EXPECT_STREQ("True", stringResult.c_str()); - }); - - plugin.getPropertyString( - hidl_string("CurrentSRMVersion"), - [&](Status status, hidl_string stringResult) { - ASSERT_EQ(Status::OK, status); - EXPECT_STREQ(currentSRMVersion.c_str(), stringResult.c_str()); - }); - - plugin.getPropertyByteArray( - hidl_string("metrics"), - [&](Status status, hidl_vec vectorResult) { - ASSERT_EQ(Status::OK, status); - std::vector id(vectorResult); - EXPECT_THAT(id, ElementsAreArray(serializedMetrics.data(), - serializedMetrics.size())); + EXPECT_EQ(oemCryptoApiVersion, stringResult.c_str()); }); } @@ -1289,117 +1207,6 @@ TEST_F(WVDrmPluginTest, DoesNotSetUnknownProperties) { ASSERT_NE(Status::OK, status); } -TEST_F(WVDrmPluginTest, CompliesWithSpoidVariability) { - StrictMock crypto; - - const std::string kDeviceIds[] = { - kDeviceId, - kDeviceId + " the Second", - }; - const size_t kDeviceCount = N_ELEM(kDeviceIds); - - const std::string kAppNames[] = { - std::string("com.google.widevine"), - std::string("com.youtube"), - }; - const size_t kAppCount = N_ELEM(kAppNames); - - const std::string kOrigins[] = { - kOrigin, - kOrigin + " but not that one, the other one.", - std::string(/* Intentionally Empty */), - }; - const size_t kOriginCount = N_ELEM(kOrigins); - - const size_t kPluginCount = 2; - - const size_t kPluginsPerCdm = kAppCount * kOriginCount * kPluginCount; - - // We will get kPluginCount SPOIDs for every app package name + device id + - // origin combination. - std::vector - spoids[kDeviceCount][kAppCount][kOriginCount][kPluginCount]; - - for (size_t deviceIndex = 0; deviceIndex < kDeviceCount; ++deviceIndex) { - const std::string& deviceId = kDeviceIds[deviceIndex]; - - android::sp> cdm = new StrictMock(); - - EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_DEVICE_ID, _)) - .Times(AtLeast(kPluginsPerCdm)) - .WillRepeatedly(DoAll(SetArgPointee<2>(deviceId), - testing::Return(wvcdm::NO_ERROR))); - - for (size_t appIndex = 0; appIndex < kAppCount; ++appIndex) { - const std::string& appPackageName = kAppNames[appIndex]; - - for (size_t originIndex = 0; originIndex < kOriginCount; ++originIndex) { - const std::string& origin = kOrigins[originIndex]; - - for (size_t pluginIndex = 0; - pluginIndex < kPluginCount; - ++pluginIndex) { - WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, true); - - if (!origin.empty()) { - ASSERT_EQ(Status::OK, - plugin.setPropertyString(hidl_string("origin"), - hidl_string(origin))); - } - - plugin.getPropertyByteArray( - hidl_string("deviceUniqueId"), - [&](Status status, hidl_vec vectorResult) { - ASSERT_EQ(Status::OK, status); - spoids[deviceIndex][appIndex][originIndex][pluginIndex] = - vectorResult; - }); - } - } - } - } - - // This nest of loops makes sure all the SPOIDs we retrieved above are - // identical if their parameters were identical and dissimilar otherwise. - for (size_t deviceIndex = 0; deviceIndex < kDeviceCount; ++deviceIndex) { - for (size_t appIndex = 0; appIndex < kAppCount; ++appIndex) { - for (size_t originIndex = 0; originIndex < kOriginCount; ++originIndex) { - for (size_t pluginIndex = 0; - pluginIndex < kPluginCount; - ++pluginIndex) { - const std::vector& firstSpoid = - spoids[deviceIndex][appIndex][originIndex][pluginIndex]; - - for (size_t deviceIndex2 = 0; - deviceIndex2 < kDeviceCount; - ++deviceIndex2) { - for (size_t appIndex2 = 0; appIndex2 < kAppCount; ++appIndex2) { - for (size_t originIndex2 = 0; - originIndex2 < kOriginCount; - ++originIndex2) { - for (size_t pluginIndex2 = 0; - pluginIndex2 < kPluginCount; - ++pluginIndex2) { - const std::vector& secondSpoid = - spoids[deviceIndex2][appIndex2][originIndex2][pluginIndex2]; - - if (deviceIndex == deviceIndex2 && - appIndex == appIndex2 && - originIndex == originIndex2) { - EXPECT_EQ(firstSpoid, secondSpoid); - } else { - EXPECT_NE(firstSpoid, secondSpoid); - } - } - } - } - } - } - } - } - } -} - TEST_F(WVDrmPluginTest, FailsGenericMethodsWithoutAnAlgorithmSet) { android::sp> cdm = new StrictMock(); StrictMock crypto; @@ -2364,7 +2171,7 @@ TEST_F(WVDrmPluginTest, CanSetSessionSharing) { } WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false); - Status res; + status_t res; // Test turning on session sharing Status status = plugin.setPropertyString(hidl_string("sessionSharing"), diff --git a/libwvdrmengine/mediadrm/test/legacy_src/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/legacy_src/WVDrmPlugin_test.cpp index 9130cbc6..286ec0d1 100644 --- a/libwvdrmengine/mediadrm/test/legacy_src/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/legacy_src/WVDrmPlugin_test.cpp @@ -32,16 +32,7 @@ const String8 kAppId("com.unittest.mock.app.id"); const uint8_t* const kUnprovisionResponse = reinterpret_cast("unprovision"); const size_t kUnprovisionResponseSize = 11; - -// This is a serialized MetricsGroup message containing a small amount of -// sample data. This ensures we're able to extract it via a property. -const char kSerializedMetrics[] = { - 0x0a, 0x0a, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x12, 0x02, 0x08, 0x00, - 0x0a, 0x12, 0x0a, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x12, 0x09, 0x11, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x15, 0x0a, 0x05, - 0x74, 0x65, 0x73, 0x74, 0x33, 0x12, 0x0c, 0x1a, 0x0a, 0x74, 0x65, 0x73, - 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65}; -} // anonymous namespace +} class MockCDM : public WvContentDecryptionModule { public: @@ -91,24 +82,19 @@ class MockCDM : public WvContentDecryptionModule { MOCK_METHOD2(Unprovision, CdmResponseType(CdmSecurityLevel, const CdmIdentifier&)); + MOCK_METHOD2(GetUsageInfo, CdmResponseType(const std::string&, + CdmUsageInfo*)); + MOCK_METHOD3(GetUsageInfo, CdmResponseType(const std::string&, - const CdmIdentifier&, - CdmUsageInfo*)); - - MOCK_METHOD4(GetUsageInfo, CdmResponseType(const std::string&, const CdmSecureStopId&, - const CdmIdentifier&, CdmUsageInfo*)); - MOCK_METHOD2(ReleaseAllUsageInfo, CdmResponseType(const std::string&, - const CdmIdentifier&)); + MOCK_METHOD1(ReleaseAllUsageInfo, CdmResponseType(const std::string&)); - MOCK_METHOD2(ReleaseUsageInfo, - CdmResponseType(const CdmUsageInfoReleaseMessage&, const CdmIdentifier&)); + MOCK_METHOD1(ReleaseUsageInfo, + CdmResponseType(const CdmUsageInfoReleaseMessage&)); MOCK_METHOD1(IsValidServiceCertificate, bool(const std::string&)); - - MOCK_METHOD1(GetSerializedMetrics, void(std::string*)); }; class MockCrypto : public WVGenericCryptoInterface { @@ -241,7 +227,7 @@ TEST_F(WVDrmPluginTest, ClosesSessions) { ASSERT_EQ(OK, res); } -TEST_F(WVDrmPluginTest, ClosesSessionWithError) { +TEST_F(WVDrmPluginTest, ClosesSessionWithoutReturningError) { android::sp> cdm = new StrictMock(); StrictMock crypto; WVDrmPlugin plugin(cdm.get(), &crypto); @@ -251,7 +237,7 @@ TEST_F(WVDrmPluginTest, ClosesSessionWithError) { status_t res = plugin.closeSession(sessionId); - ASSERT_EQ(ERROR_DRM_SESSION_NOT_OPENED, res); + ASSERT_EQ(OK, res); } TEST_F(WVDrmPluginTest, GeneratesKeyRequests) { @@ -769,8 +755,8 @@ TEST_F(WVDrmPluginTest, GetsSecureStops) { cdmStops.push_back(string(stopsRaw[i], stopsRaw[i] + kStopSize)); } - EXPECT_CALL(*cdm, GetUsageInfo(StrEq(app_id), _, _)) - .WillOnce(DoAll(SetArgPointee<2>(cdmStops), + EXPECT_CALL(*cdm, GetUsageInfo(StrEq(app_id), _)) + .WillOnce(DoAll(SetArgPointee<1>(cdmStops), Return(wvcdm::NO_ERROR))); List > stops; @@ -800,7 +786,7 @@ TEST_F(WVDrmPluginTest, ReleasesAllSecureStops) { status_t res = plugin.setPropertyString(String8("appId"), String8("")); ASSERT_EQ(OK, res); - EXPECT_CALL(*cdm, ReleaseAllUsageInfo(StrEq(""), _)) + EXPECT_CALL(*cdm, ReleaseAllUsageInfo(StrEq(""))) .Times(1); res = plugin.releaseAllSecureStops(); @@ -822,8 +808,7 @@ TEST_F(WVDrmPluginTest, ReleasesSecureStops) { message.appendArray(messageRaw, kMessageSize); EXPECT_CALL(*cdm, ReleaseUsageInfo(ElementsAreArray(messageRaw, - kMessageSize), - _)) + kMessageSize))) .Times(1); status_t res = plugin.releaseSecureStops(message); @@ -848,10 +833,6 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { static const string openSessions = "15"; static const string maxSessions = "18"; static const string oemCryptoApiVersion = "10"; - static const string currentSRMVersion = "1"; - static const string cdmVersion = "Infinity Minus 1"; - string serializedMetrics(kSerializedMetrics, - kSerializedMetrics + sizeof(kSerializedMetrics)); EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SECURITY_LEVEL, _)) .WillOnce(DoAll(SetArgPointee<2>(QUERY_VALUE_SECURITY_LEVEL_L1), @@ -883,21 +864,6 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { .WillOnce(DoAll(SetArgPointee<2>(oemCryptoApiVersion), Return(wvcdm::NO_ERROR))); - EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SRM_UPDATE_SUPPORT, _)) - .WillOnce(DoAll(SetArgPointee<2>("True"), - testing::Return(wvcdm::NO_ERROR))); - - EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_CURRENT_SRM_VERSION, _)) - .WillOnce(DoAll(SetArgPointee<2>(currentSRMVersion), - testing::Return(wvcdm::NO_ERROR))); - - EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_WVCDM_VERSION, _)) - .WillOnce(DoAll(SetArgPointee<2>(cdmVersion), - Return(wvcdm::NO_ERROR))); - - EXPECT_CALL(*cdm, GetSerializedMetrics(_)) - .WillOnce(SetArgPointee<0>(serializedMetrics)); - String8 stringResult; Vector vectorResult; @@ -907,7 +873,7 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { res = plugin.getPropertyString(String8("version"), stringResult); ASSERT_EQ(OK, res); - EXPECT_STREQ(cdmVersion.c_str(), stringResult.string()); + EXPECT_STREQ("1.0", stringResult.string()); res = plugin.getPropertyString(String8("description"), stringResult); ASSERT_EQ(OK, res); @@ -948,21 +914,7 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { res = plugin.getPropertyString(String8("oemCryptoApiVersion"), stringResult); ASSERT_EQ(OK, res); - EXPECT_STREQ(oemCryptoApiVersion.c_str(), stringResult.string()); - - res = plugin.getPropertyString(String8("SRMUpdateSupport"), stringResult); - ASSERT_EQ(OK, res); - EXPECT_STREQ("True", stringResult.string()); - - res = plugin.getPropertyString(String8("CurrentSRMVersion"), stringResult); - ASSERT_EQ(OK, res); - EXPECT_STREQ(currentSRMVersion.c_str(), stringResult.string()); - - vectorResult.clear(); - res = plugin.getPropertyByteArray(String8("metrics"), vectorResult); - ASSERT_EQ(OK, res); - EXPECT_THAT(vectorResult, ElementsAreArray(serializedMetrics.data(), - serializedMetrics.size())); + EXPECT_EQ(oemCryptoApiVersion, stringResult.string()); } TEST_F(WVDrmPluginTest, DoesNotGetUnknownProperties) { diff --git a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h index 8fca7c9b..79fc2e0d 100644 --- a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h +++ b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h @@ -78,7 +78,6 @@ typedef enum OEMCryptoResult { OEMCrypto_ERROR_LICENSE_INACTIVE = 47, OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE = 48, OEMCrypto_ERROR_ENTRY_IN_USE = 49, - OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE = 50, // Reserved. Do not use. } OEMCryptoResult; /* diff --git a/libwvdrmengine/oemcrypto/mock/Android.mk b/libwvdrmengine/oemcrypto/mock/Android.mk index f2b406be..9a3e43bb 100644 --- a/libwvdrmengine/oemcrypto/mock/Android.mk +++ b/libwvdrmengine/oemcrypto/mock/Android.mk @@ -26,7 +26,6 @@ LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/../include \ $(LOCAL_PATH)/src \ vendor/widevine/libwvdrmengine/cdm/core/include \ - vendor/widevine/libwvdrmengine/third_party/stringencoders/src \ LOCAL_SHARED_LIBRARIES := \ libcutils \ @@ -39,7 +38,7 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_STATIC_LIBRARIES := \ libcdm_utils \ - libcrypto \ + libcrypto_static \ # Proprietary modules are put in vendor/lib instead of /system/lib. LOCAL_PROPRIETARY_MODULE := true diff --git a/libwvdrmengine/oemcrypto/mock/src/oem_cert.h b/libwvdrmengine/oemcrypto/mock/src/oem_cert.h index 8dd846c2..db85d5ab 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oem_cert.h +++ b/libwvdrmengine/oemcrypto/mock/src/oem_cert.h @@ -5,10 +5,767 @@ #include #include -extern const uint8_t kOEMPrivateKey[]; -extern const size_t kOEMPrivateKeySize; +namespace { +const uint32_t kOEMSystemId_UAT = 7346; -extern const uint8_t kOEMPublicCert[]; -extern const size_t kOEMPublicCertSize; +const uint8_t kOEMPrivateKey_UAT[] = { + 0x30, 0x82, 0x06, 0xfe, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, + 0x06, 0xe8, 0x30, 0x82, 0x06, 0xe4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, + 0x81, 0x00, 0xf5, 0x09, 0x64, 0x4a, 0x26, 0xfe, 0xc0, 0x98, 0x55, 0x6a, + 0x1d, 0x5d, 0x1c, 0xc7, 0x38, 0xaf, 0xfd, 0x49, 0x9e, 0x85, 0x3f, 0xd6, + 0x45, 0x0e, 0x99, 0x09, 0x85, 0x69, 0x84, 0x3c, 0xfe, 0x72, 0xa5, 0x56, + 0xfa, 0x11, 0x4f, 0x6b, 0x7d, 0x32, 0x2b, 0x0c, 0xbf, 0x8f, 0xac, 0x47, + 0x96, 0x22, 0x82, 0x3d, 0xf5, 0x64, 0x74, 0x7e, 0x62, 0x68, 0x74, 0xcd, + 0x0a, 0xec, 0x84, 0xc5, 0x15, 0x06, 0x0e, 0x5a, 0x2f, 0x20, 0xe3, 0xc9, + 0x67, 0xcd, 0xdd, 0x01, 0xb8, 0xb3, 0x18, 0x87, 0x8c, 0xa9, 0x58, 0x86, + 0x0f, 0xb6, 0xc3, 0x42, 0x7e, 0x87, 0x48, 0x5e, 0x10, 0x49, 0xc7, 0xd7, + 0xb7, 0xb8, 0xa6, 0x34, 0x08, 0x0c, 0x94, 0xf4, 0xbb, 0x2a, 0x06, 0xa4, + 0x4f, 0xec, 0xbc, 0xc4, 0x37, 0xbe, 0x99, 0x10, 0x23, 0x37, 0x24, 0xb1, + 0xdf, 0xcb, 0xe6, 0x3f, 0xc1, 0xf0, 0x0f, 0x04, 0x03, 0xc8, 0xb0, 0x1e, + 0xd6, 0xb8, 0xae, 0x77, 0xe1, 0x4d, 0x6d, 0x97, 0x69, 0x6d, 0x8a, 0x73, + 0x66, 0x32, 0x57, 0x6f, 0xcf, 0xea, 0x1e, 0x7b, 0x87, 0x03, 0x75, 0xb1, + 0xef, 0x83, 0x64, 0x26, 0xf1, 0x3f, 0xbf, 0xe6, 0x28, 0x03, 0x72, 0x57, + 0xbf, 0x47, 0x29, 0x99, 0x8f, 0x74, 0x1d, 0x01, 0x16, 0xad, 0xb2, 0xdf, + 0x80, 0xa4, 0xd3, 0x8b, 0xeb, 0x61, 0xd1, 0x40, 0x68, 0xb9, 0xa2, 0xa5, + 0xef, 0x2b, 0xe5, 0x78, 0xe8, 0x28, 0x88, 0x87, 0xb7, 0x53, 0x49, 0xbb, + 0xe4, 0xea, 0x0d, 0x5e, 0x96, 0xa5, 0xdd, 0x1f, 0x0b, 0x25, 0x8b, 0xb5, + 0x95, 0x46, 0xe7, 0xba, 0xb8, 0xc4, 0x0a, 0x36, 0xb1, 0x89, 0xeb, 0x27, + 0x5d, 0xd9, 0x97, 0x24, 0x59, 0xa3, 0x9b, 0xb0, 0x23, 0x0b, 0xd2, 0xec, + 0x65, 0x91, 0xf9, 0xf0, 0xa0, 0x74, 0x5f, 0xb4, 0xce, 0x22, 0x27, 0x18, + 0x37, 0xe2, 0x4b, 0xfc, 0x91, 0xf9, 0x09, 0x15, 0xe6, 0xdb, 0x06, 0x9b, + 0x4d, 0x82, 0xdc, 0x36, 0x14, 0x48, 0xc6, 0xd5, 0x87, 0xca, 0xec, 0x5a, + 0xa2, 0x29, 0x33, 0xef, 0x22, 0x0c, 0x4b, 0xbf, 0xe7, 0x2f, 0x95, 0xe1, + 0xd3, 0xa5, 0xd8, 0xaa, 0x44, 0x77, 0x29, 0xa3, 0x20, 0x33, 0xd2, 0x51, + 0xa2, 0xf9, 0x4a, 0x6f, 0xf7, 0x3e, 0xf7, 0x0b, 0x8a, 0xec, 0xc1, 0x99, + 0x1d, 0x47, 0xf3, 0x74, 0x02, 0x04, 0xab, 0x8e, 0x62, 0x4c, 0x9e, 0x00, + 0xc2, 0x84, 0xd7, 0xd0, 0xf8, 0xe4, 0x1c, 0x9d, 0x98, 0x15, 0xa8, 0x8f, + 0x08, 0x98, 0x4e, 0x5a, 0xfa, 0xd6, 0x60, 0x87, 0x12, 0xdc, 0x8e, 0xfd, + 0xcb, 0xb3, 0x13, 0x97, 0x7a, 0xa8, 0x8c, 0x56, 0x2e, 0x49, 0x26, 0x60, + 0xe9, 0x4a, 0xdc, 0xec, 0x3f, 0xf0, 0x94, 0xcd, 0x90, 0x8e, 0x7c, 0x21, + 0x3f, 0x80, 0x14, 0x33, 0xdd, 0xb0, 0x00, 0xe2, 0x09, 0x37, 0x06, 0xdd, + 0x17, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x81, 0x00, + 0xa1, 0xc9, 0x44, 0xad, 0x6d, 0x17, 0xd1, 0x04, 0x03, 0x89, 0x5f, 0xbf, + 0xe5, 0xcb, 0x68, 0x13, 0x52, 0xf2, 0x33, 0xb7, 0x19, 0x12, 0x19, 0x60, + 0x6d, 0x0d, 0x0b, 0x48, 0x42, 0xe6, 0x9e, 0xbe, 0x05, 0x8a, 0xea, 0xeb, + 0x58, 0xfb, 0xc8, 0x9a, 0xc2, 0x2f, 0xd5, 0x9f, 0x40, 0x09, 0xb8, 0x08, + 0x2a, 0xe4, 0x4b, 0xcc, 0xba, 0xd9, 0xe3, 0x91, 0xc2, 0x64, 0xcb, 0x6c, + 0xa4, 0xb1, 0x17, 0x93, 0x7b, 0x10, 0x72, 0x83, 0x8d, 0xc2, 0xa2, 0x46, + 0x1b, 0x41, 0x12, 0xb9, 0x35, 0x5d, 0xf2, 0x32, 0xb1, 0xdf, 0x3a, 0x2a, + 0xda, 0xbb, 0x61, 0x9d, 0x62, 0xdb, 0xb0, 0x77, 0x76, 0x7a, 0x68, 0xb4, + 0x83, 0x10, 0x61, 0xac, 0x25, 0x01, 0x7d, 0x3e, 0x5f, 0x4a, 0x47, 0xf7, + 0x30, 0x1f, 0x82, 0x0a, 0xd7, 0x36, 0xff, 0x79, 0x5e, 0x42, 0x0f, 0x58, + 0xaa, 0x3a, 0xb8, 0x8b, 0x0e, 0xef, 0x00, 0xac, 0x96, 0x14, 0x96, 0x83, + 0x33, 0xb6, 0xb5, 0x4c, 0x91, 0x2a, 0x62, 0x92, 0xcf, 0xd2, 0x27, 0xcc, + 0xdf, 0x4c, 0x55, 0x03, 0xe8, 0x82, 0x78, 0xff, 0x80, 0xcb, 0x2e, 0x30, + 0x1b, 0x85, 0x56, 0xce, 0x57, 0x9e, 0xd8, 0x16, 0x86, 0x7d, 0x87, 0x2e, + 0xae, 0x39, 0xd4, 0xac, 0xbe, 0xa5, 0xc4, 0x5a, 0x85, 0x7a, 0xea, 0x8e, + 0x69, 0x9a, 0xbd, 0x9c, 0x45, 0x33, 0xf8, 0xb1, 0x70, 0xc1, 0x8c, 0xaa, + 0xad, 0x3d, 0x76, 0x08, 0x5b, 0x7d, 0x12, 0x93, 0x03, 0x70, 0xe6, 0x5f, + 0xb2, 0xac, 0x78, 0xae, 0xbe, 0xc5, 0x31, 0xc8, 0x6d, 0x2c, 0x1c, 0x2f, + 0x41, 0x37, 0xf6, 0x88, 0xd3, 0x80, 0x93, 0xed, 0x55, 0xb1, 0xaa, 0x49, + 0xe8, 0x42, 0xd0, 0x19, 0x20, 0x58, 0xe7, 0x2d, 0x10, 0xf2, 0x69, 0x49, + 0xe9, 0x47, 0x95, 0xbb, 0xce, 0xa7, 0xe9, 0x86, 0x46, 0x1c, 0xd1, 0x1f, + 0xd4, 0xa9, 0xeb, 0x28, 0x57, 0x78, 0x6c, 0xc6, 0x6f, 0x84, 0x3b, 0xb4, + 0x8c, 0xe5, 0xd3, 0x23, 0x8b, 0xbe, 0x83, 0x75, 0x5e, 0xea, 0xcd, 0x93, + 0xd2, 0x42, 0x86, 0xfd, 0x2b, 0x67, 0x72, 0xe0, 0x46, 0x9c, 0xf7, 0xc1, + 0xe9, 0x5d, 0xad, 0xac, 0xcb, 0x57, 0xb4, 0xe7, 0x87, 0x25, 0x7d, 0x5a, + 0x43, 0x90, 0xa3, 0x2e, 0xbf, 0x36, 0xbd, 0x4c, 0xba, 0xec, 0x0f, 0x21, + 0x51, 0xda, 0x66, 0xb8, 0x1e, 0xac, 0x33, 0xeb, 0xa1, 0x3e, 0x72, 0x15, + 0x10, 0x45, 0xc0, 0xe4, 0xdb, 0x04, 0x6d, 0xaf, 0x66, 0xc2, 0xfc, 0x35, + 0x04, 0x60, 0x7d, 0x2f, 0x5e, 0x9e, 0x83, 0xf6, 0x72, 0x92, 0x6a, 0x9f, + 0xba, 0x94, 0x97, 0x33, 0xe1, 0x1d, 0x42, 0xda, 0xad, 0xa5, 0x8b, 0xad, + 0x2f, 0x2f, 0x32, 0x16, 0x88, 0x54, 0x88, 0xb2, 0x85, 0xe2, 0x33, 0x08, + 0x43, 0xc8, 0x68, 0x69, 0xaa, 0xea, 0x9a, 0xbf, 0x41, 0x12, 0xe6, 0xf1, + 0x02, 0x81, 0xc1, 0x00, 0xfe, 0x96, 0xe7, 0xc8, 0x89, 0x61, 0x2b, 0x58, + 0xaa, 0xcd, 0x37, 0x46, 0x13, 0xa1, 0x2a, 0xc8, 0x1b, 0x76, 0xde, 0x4c, + 0xb3, 0x00, 0x4f, 0x6b, 0x02, 0xc0, 0x10, 0xef, 0x87, 0xe2, 0x6d, 0x7f, + 0x10, 0x57, 0xec, 0xde, 0x70, 0x60, 0xb5, 0x8f, 0x6d, 0x17, 0x35, 0xbd, + 0xfd, 0x6a, 0x2c, 0xbb, 0xf0, 0x48, 0x5b, 0x32, 0x41, 0xf6, 0xc0, 0x62, + 0x3a, 0x88, 0xc5, 0x41, 0x83, 0x85, 0x56, 0xa7, 0x11, 0xf4, 0xd2, 0xa9, + 0xb3, 0xa3, 0xcb, 0xae, 0xca, 0xee, 0x1c, 0x52, 0x7f, 0x04, 0x34, 0x61, + 0xb9, 0x8d, 0xa3, 0x26, 0x88, 0xce, 0x3d, 0xdb, 0x9c, 0xbf, 0xcc, 0xc4, + 0x38, 0x8b, 0xf2, 0xe4, 0x7e, 0xcc, 0x46, 0x86, 0x7a, 0x3c, 0xb7, 0x95, + 0x3f, 0xbd, 0x81, 0x45, 0xc3, 0x1d, 0xbb, 0xf8, 0x56, 0x6e, 0xa5, 0x88, + 0x2d, 0xff, 0x78, 0xc0, 0xc2, 0x4a, 0x4f, 0xea, 0xb8, 0x81, 0xf3, 0x96, + 0x5e, 0xd8, 0xcb, 0x96, 0x42, 0xa3, 0x21, 0x03, 0xc8, 0x00, 0xbf, 0x95, + 0xc7, 0x83, 0x80, 0xc6, 0xc2, 0x38, 0xe4, 0xaf, 0xb2, 0x0e, 0x80, 0x92, + 0x97, 0x21, 0x16, 0xce, 0x39, 0xd3, 0x95, 0xb7, 0xc3, 0x78, 0xe1, 0x1c, + 0xc0, 0x5a, 0xbc, 0x9b, 0x68, 0x3f, 0xd6, 0x42, 0xcd, 0xca, 0x0b, 0x6d, + 0x9f, 0xde, 0x6b, 0x98, 0x3b, 0x47, 0x57, 0xb9, 0x2d, 0x92, 0x52, 0x29, + 0xc5, 0xed, 0xb5, 0x0d, 0x02, 0x81, 0xc1, 0x00, 0xf6, 0x64, 0xef, 0xef, + 0x57, 0xdb, 0x06, 0xae, 0x36, 0x86, 0x11, 0xaf, 0x96, 0xb9, 0xb1, 0x29, + 0x53, 0xce, 0x24, 0x60, 0x96, 0x8f, 0xd0, 0xb7, 0x4b, 0x60, 0x1e, 0xb3, + 0x1f, 0xae, 0x15, 0x41, 0xf1, 0x56, 0xd6, 0xf3, 0x07, 0xf8, 0xd7, 0xdd, + 0x1c, 0x82, 0xe8, 0xe0, 0xff, 0xb3, 0x41, 0x0d, 0x41, 0x96, 0x0d, 0xf2, + 0x03, 0xb0, 0x68, 0xed, 0xda, 0x8b, 0x83, 0x18, 0x4d, 0xae, 0xaf, 0x72, + 0xa1, 0x82, 0xe5, 0x5a, 0xdc, 0x2a, 0x5f, 0x93, 0x29, 0xc7, 0x24, 0xa0, + 0x8e, 0x32, 0x4c, 0x0e, 0xca, 0x6d, 0x14, 0x69, 0x5b, 0x61, 0xc5, 0xdc, + 0x0e, 0x50, 0x0c, 0x14, 0x84, 0x8b, 0xee, 0x9e, 0x1e, 0x8c, 0x3d, 0xdb, + 0x24, 0xe7, 0x99, 0x6d, 0x3c, 0xaf, 0xe6, 0x3b, 0xaa, 0xb4, 0xe4, 0x42, + 0x13, 0x53, 0x3e, 0x02, 0x47, 0x0d, 0x3a, 0x2b, 0x97, 0x71, 0x9f, 0x1b, + 0x76, 0x2d, 0xe5, 0x9c, 0x5e, 0x46, 0x5f, 0x36, 0xbf, 0x18, 0xb1, 0x1d, + 0x9a, 0xeb, 0x4d, 0x5e, 0x83, 0xd5, 0x3e, 0x5f, 0xf2, 0x6a, 0x56, 0x79, + 0x0f, 0x54, 0xec, 0x41, 0xc0, 0xdc, 0x29, 0x42, 0x45, 0xae, 0x47, 0x1c, + 0x7a, 0xd5, 0xb7, 0x92, 0x1e, 0x66, 0xb8, 0x1a, 0x2f, 0x53, 0xd2, 0x6d, + 0x42, 0x3c, 0x6c, 0x02, 0x01, 0x03, 0x9e, 0x9a, 0x95, 0x35, 0x81, 0x21, + 0x53, 0x53, 0x16, 0xda, 0x8a, 0x80, 0x8c, 0xcd, 0x02, 0x81, 0xc1, 0x00, + 0xd5, 0xba, 0x05, 0xf7, 0x7a, 0x2d, 0x52, 0xe0, 0x6a, 0xf3, 0x40, 0xd5, + 0xd9, 0xa0, 0xd1, 0x73, 0x90, 0x6a, 0xe8, 0x10, 0x67, 0xad, 0x78, 0xfe, + 0x93, 0x1e, 0x7e, 0x99, 0x37, 0xf0, 0x44, 0x90, 0x09, 0x3e, 0x67, 0x22, + 0x0e, 0x21, 0x82, 0x0a, 0x58, 0x40, 0xc5, 0xe3, 0x2b, 0x9d, 0x38, 0xd4, + 0xc5, 0xd1, 0x58, 0x8e, 0x06, 0x86, 0x89, 0xd7, 0x6c, 0xe0, 0x69, 0x08, + 0xa8, 0xcb, 0x05, 0x85, 0xd8, 0x33, 0x39, 0xaf, 0x31, 0x99, 0xee, 0x62, + 0x5d, 0x06, 0x2c, 0x4c, 0xad, 0x48, 0xf0, 0x58, 0xa2, 0x17, 0x5f, 0xc1, + 0xf7, 0xd3, 0x7c, 0x66, 0xa3, 0x5e, 0xf9, 0x1e, 0x39, 0x82, 0x73, 0x74, + 0x93, 0x66, 0x16, 0x46, 0xca, 0xd3, 0xb2, 0x22, 0xdf, 0x91, 0xcd, 0xb6, + 0xad, 0x28, 0x87, 0x26, 0xe2, 0x18, 0x9d, 0x6a, 0x87, 0x83, 0x12, 0xf2, + 0x6f, 0xa9, 0x47, 0x11, 0xfb, 0xb7, 0x4c, 0xb1, 0x0e, 0x0a, 0xde, 0x4e, + 0xd4, 0xbe, 0x71, 0xf6, 0xe4, 0xae, 0x8c, 0x27, 0xc7, 0x88, 0x84, 0x51, + 0x57, 0xb7, 0xbf, 0x74, 0x27, 0xfc, 0xb8, 0xbf, 0x57, 0x94, 0x75, 0xba, + 0xc7, 0x1c, 0xf3, 0x71, 0x83, 0xee, 0x34, 0xbd, 0x98, 0x56, 0x14, 0x44, + 0x3a, 0xee, 0x6c, 0x87, 0x44, 0x8f, 0xbb, 0xac, 0x5a, 0x2b, 0xb5, 0x13, + 0xe5, 0x9f, 0xec, 0xeb, 0x0e, 0x70, 0xe9, 0xfd, 0x1b, 0xa6, 0x84, 0xf9, + 0x02, 0x81, 0xc0, 0x4e, 0x82, 0x26, 0xf9, 0x6a, 0x52, 0xfd, 0xb3, 0xf0, + 0xe7, 0x93, 0x27, 0x11, 0xad, 0xa5, 0x47, 0x77, 0xce, 0x8d, 0x44, 0xc1, + 0x74, 0x9d, 0x9a, 0x69, 0xc7, 0xfc, 0xc0, 0x32, 0x6d, 0xf3, 0x94, 0x09, + 0x64, 0x14, 0x25, 0x67, 0xfa, 0xe0, 0x3d, 0x31, 0xe2, 0x7c, 0x75, 0x84, + 0xc4, 0x07, 0x0c, 0x44, 0x43, 0x9d, 0xb9, 0xe9, 0x77, 0x02, 0x58, 0x17, + 0x74, 0xb0, 0x96, 0xc3, 0xd9, 0xcf, 0x49, 0x85, 0x31, 0x02, 0x07, 0x8b, + 0x73, 0x6c, 0xf4, 0xa5, 0x31, 0x30, 0xf8, 0x7f, 0x96, 0x83, 0x29, 0x8b, + 0x52, 0x6a, 0x58, 0x8f, 0xa7, 0x7d, 0xb5, 0xfa, 0x51, 0x83, 0x27, 0xde, + 0x7b, 0xff, 0xd2, 0x1e, 0x05, 0xad, 0x87, 0xf0, 0x20, 0x63, 0x80, 0xac, + 0xff, 0x97, 0x2a, 0x97, 0xdf, 0xff, 0x83, 0x16, 0x49, 0x45, 0xce, 0xcf, + 0xf8, 0xe4, 0xfa, 0x12, 0xcd, 0x3f, 0x57, 0x2e, 0xb6, 0xbd, 0x1c, 0xaf, + 0xe5, 0x58, 0x5d, 0x47, 0x52, 0x84, 0xcc, 0xdc, 0x19, 0xf1, 0x93, 0x16, + 0x0a, 0x92, 0x4f, 0x5c, 0x1c, 0x89, 0xe5, 0x14, 0xff, 0x88, 0x30, 0x03, + 0x55, 0xa3, 0x47, 0xdc, 0x90, 0x05, 0x54, 0x8b, 0xc7, 0x21, 0x30, 0xcb, + 0xc3, 0x0b, 0x12, 0x3c, 0xd6, 0x46, 0x8c, 0x4d, 0xb8, 0x96, 0xe9, 0xa4, + 0x8d, 0x14, 0xb2, 0x48, 0xac, 0xbd, 0xb2, 0x72, 0xac, 0x5c, 0xf1, 0xd1, + 0x83, 0xd8, 0x59, 0x02, 0x81, 0xc0, 0x2d, 0x65, 0xc1, 0xc7, 0x0f, 0xca, + 0xbc, 0x5d, 0xa1, 0x30, 0x28, 0x27, 0x51, 0xcc, 0xc9, 0x6c, 0x7b, 0x76, + 0x43, 0xa9, 0x77, 0xd8, 0x29, 0xa3, 0x80, 0x57, 0x3b, 0xe9, 0x72, 0x1c, + 0x51, 0x37, 0xc2, 0x0b, 0x74, 0xb7, 0xaa, 0x63, 0xd5, 0xe2, 0x9b, 0x3a, + 0x3c, 0x78, 0x50, 0xcb, 0x88, 0x1a, 0xd6, 0x59, 0xdc, 0xb3, 0x05, 0xbf, + 0xe5, 0xc5, 0xb5, 0xe3, 0x9b, 0xba, 0xe7, 0xbb, 0x4d, 0x45, 0xb3, 0x4c, + 0xf2, 0x48, 0x65, 0xe7, 0x6b, 0xee, 0x12, 0xc8, 0xd5, 0xea, 0xf0, 0x89, + 0xf9, 0x03, 0xa3, 0xd9, 0x5f, 0x62, 0x2d, 0x1a, 0x55, 0x51, 0x5d, 0xf6, + 0xca, 0x6e, 0x5f, 0xf0, 0x66, 0x02, 0xf4, 0x20, 0xe6, 0xe9, 0xc4, 0xd7, + 0x36, 0x8d, 0x00, 0xce, 0x23, 0xfd, 0x90, 0xd4, 0x19, 0x5c, 0xe9, 0xcb, + 0x23, 0xe2, 0x2c, 0xf5, 0xe1, 0x6f, 0x9d, 0xb5, 0xdf, 0xea, 0x51, 0xdd, + 0x02, 0xd8, 0x40, 0xd6, 0x7f, 0x4b, 0xdb, 0x0e, 0xe2, 0x27, 0x4d, 0x0d, + 0x9b, 0x2e, 0xf7, 0xc8, 0x22, 0xca, 0x63, 0x3c, 0x2c, 0xe5, 0xa8, 0x42, + 0x26, 0xd9, 0xfc, 0xdc, 0x42, 0xc8, 0x07, 0x64, 0xa2, 0x98, 0xae, 0xb4, + 0x57, 0x02, 0x02, 0xb2, 0x2d, 0xc8, 0x59, 0x73, 0x9b, 0xee, 0xc0, 0x9a, + 0x42, 0x9a, 0xef, 0xc2, 0x27, 0x24, 0x2b, 0x20, 0x92, 0xad, 0x50, 0xfe, + 0x2c, 0x2d, 0xb6, 0xb6, 0xb5, 0xba +}; + +const size_t kOEMPrivateKeySize_UAT = sizeof(kOEMPrivateKey_UAT); + +const uint8_t kOEMPublicCert_UAT[] = { + 0x30, 0x82, 0x09, 0xf7, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x07, 0x02, 0xa0, 0x82, 0x09, 0xe8, 0x30, 0x82, 0x09, 0xe4, 0x02, + 0x01, 0x01, 0x31, 0x00, 0x30, 0x0f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x02, 0x04, 0x00, 0xa0, 0x82, 0x09, + 0xc8, 0x30, 0x82, 0x04, 0x1a, 0x30, 0x82, 0x03, 0x02, 0xa0, 0x03, 0x02, + 0x01, 0x02, 0x02, 0x11, 0x00, 0xf2, 0xa1, 0x08, 0xdf, 0x12, 0x84, 0xb9, + 0x73, 0x6c, 0x23, 0x73, 0xe1, 0x1f, 0xf3, 0xac, 0x7a, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, + 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, + 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, + 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, 0x30, 0x30, 0x2e, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x47, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x20, 0x4f, 0x45, 0x4d, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x3b, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x37, 0x33, 0x34, 0x36, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x37, 0x30, 0x33, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x32, 0x30, 0x38, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x6d, 0x31, 0x12, 0x30, 0x10, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x37, 0x33, 0x34, 0x36, 0x2d, + 0x6c, 0x65, 0x61, 0x66, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, + 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, + 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, + 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x30, 0x82, 0x01, + 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30, 0x82, 0x01, + 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xf5, 0x09, 0x64, 0x4a, 0x26, 0xfe, + 0xc0, 0x98, 0x55, 0x6a, 0x1d, 0x5d, 0x1c, 0xc7, 0x38, 0xaf, 0xfd, 0x49, + 0x9e, 0x85, 0x3f, 0xd6, 0x45, 0x0e, 0x99, 0x09, 0x85, 0x69, 0x84, 0x3c, + 0xfe, 0x72, 0xa5, 0x56, 0xfa, 0x11, 0x4f, 0x6b, 0x7d, 0x32, 0x2b, 0x0c, + 0xbf, 0x8f, 0xac, 0x47, 0x96, 0x22, 0x82, 0x3d, 0xf5, 0x64, 0x74, 0x7e, + 0x62, 0x68, 0x74, 0xcd, 0x0a, 0xec, 0x84, 0xc5, 0x15, 0x06, 0x0e, 0x5a, + 0x2f, 0x20, 0xe3, 0xc9, 0x67, 0xcd, 0xdd, 0x01, 0xb8, 0xb3, 0x18, 0x87, + 0x8c, 0xa9, 0x58, 0x86, 0x0f, 0xb6, 0xc3, 0x42, 0x7e, 0x87, 0x48, 0x5e, + 0x10, 0x49, 0xc7, 0xd7, 0xb7, 0xb8, 0xa6, 0x34, 0x08, 0x0c, 0x94, 0xf4, + 0xbb, 0x2a, 0x06, 0xa4, 0x4f, 0xec, 0xbc, 0xc4, 0x37, 0xbe, 0x99, 0x10, + 0x23, 0x37, 0x24, 0xb1, 0xdf, 0xcb, 0xe6, 0x3f, 0xc1, 0xf0, 0x0f, 0x04, + 0x03, 0xc8, 0xb0, 0x1e, 0xd6, 0xb8, 0xae, 0x77, 0xe1, 0x4d, 0x6d, 0x97, + 0x69, 0x6d, 0x8a, 0x73, 0x66, 0x32, 0x57, 0x6f, 0xcf, 0xea, 0x1e, 0x7b, + 0x87, 0x03, 0x75, 0xb1, 0xef, 0x83, 0x64, 0x26, 0xf1, 0x3f, 0xbf, 0xe6, + 0x28, 0x03, 0x72, 0x57, 0xbf, 0x47, 0x29, 0x99, 0x8f, 0x74, 0x1d, 0x01, + 0x16, 0xad, 0xb2, 0xdf, 0x80, 0xa4, 0xd3, 0x8b, 0xeb, 0x61, 0xd1, 0x40, + 0x68, 0xb9, 0xa2, 0xa5, 0xef, 0x2b, 0xe5, 0x78, 0xe8, 0x28, 0x88, 0x87, + 0xb7, 0x53, 0x49, 0xbb, 0xe4, 0xea, 0x0d, 0x5e, 0x96, 0xa5, 0xdd, 0x1f, + 0x0b, 0x25, 0x8b, 0xb5, 0x95, 0x46, 0xe7, 0xba, 0xb8, 0xc4, 0x0a, 0x36, + 0xb1, 0x89, 0xeb, 0x27, 0x5d, 0xd9, 0x97, 0x24, 0x59, 0xa3, 0x9b, 0xb0, + 0x23, 0x0b, 0xd2, 0xec, 0x65, 0x91, 0xf9, 0xf0, 0xa0, 0x74, 0x5f, 0xb4, + 0xce, 0x22, 0x27, 0x18, 0x37, 0xe2, 0x4b, 0xfc, 0x91, 0xf9, 0x09, 0x15, + 0xe6, 0xdb, 0x06, 0x9b, 0x4d, 0x82, 0xdc, 0x36, 0x14, 0x48, 0xc6, 0xd5, + 0x87, 0xca, 0xec, 0x5a, 0xa2, 0x29, 0x33, 0xef, 0x22, 0x0c, 0x4b, 0xbf, + 0xe7, 0x2f, 0x95, 0xe1, 0xd3, 0xa5, 0xd8, 0xaa, 0x44, 0x77, 0x29, 0xa3, + 0x20, 0x33, 0xd2, 0x51, 0xa2, 0xf9, 0x4a, 0x6f, 0xf7, 0x3e, 0xf7, 0x0b, + 0x8a, 0xec, 0xc1, 0x99, 0x1d, 0x47, 0xf3, 0x74, 0x02, 0x04, 0xab, 0x8e, + 0x62, 0x4c, 0x9e, 0x00, 0xc2, 0x84, 0xd7, 0xd0, 0xf8, 0xe4, 0x1c, 0x9d, + 0x98, 0x15, 0xa8, 0x8f, 0x08, 0x98, 0x4e, 0x5a, 0xfa, 0xd6, 0x60, 0x87, + 0x12, 0xdc, 0x8e, 0xfd, 0xcb, 0xb3, 0x13, 0x97, 0x7a, 0xa8, 0x8c, 0x56, + 0x2e, 0x49, 0x26, 0x60, 0xe9, 0x4a, 0xdc, 0xec, 0x3f, 0xf0, 0x94, 0xcd, + 0x90, 0x8e, 0x7c, 0x21, 0x3f, 0x80, 0x14, 0x33, 0xdd, 0xb0, 0x00, 0xe2, + 0x09, 0x37, 0x06, 0xdd, 0x17, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, + 0xd6, 0x79, 0x04, 0x01, 0x01, 0x04, 0x04, 0x02, 0x02, 0x1c, 0xb2, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8e, 0x2d, 0x13, 0x1e, 0x60, + 0xaa, 0xda, 0x52, 0x53, 0x55, 0x64, 0x3a, 0xdc, 0xb6, 0x7a, 0xc0, 0xba, + 0xfa, 0xeb, 0x20, 0xab, 0xb6, 0x63, 0xcf, 0xcd, 0x9b, 0xdb, 0x71, 0xf3, + 0xa0, 0xd6, 0x91, 0xbf, 0x0c, 0xc1, 0xae, 0x8f, 0x02, 0x18, 0x00, 0x54, + 0xfb, 0x49, 0x03, 0x34, 0x8d, 0x92, 0x9d, 0x5d, 0x8d, 0xa8, 0x1c, 0x20, + 0x0f, 0x85, 0x60, 0xf9, 0xf6, 0x8b, 0xbb, 0x2b, 0x82, 0xce, 0xb3, 0xe2, + 0x91, 0xe7, 0xbd, 0x91, 0x61, 0x52, 0x36, 0x40, 0x9f, 0x2f, 0x5e, 0xa6, + 0x5d, 0x2f, 0xb3, 0x81, 0xe7, 0xf1, 0x87, 0xbe, 0xc5, 0x9d, 0x67, 0x5a, + 0xf7, 0x41, 0x1e, 0x73, 0xb0, 0x1e, 0xdc, 0x4f, 0x8d, 0x53, 0x21, 0x38, + 0x1b, 0xfd, 0x92, 0x43, 0x68, 0x83, 0x03, 0xd0, 0x9a, 0xca, 0x92, 0x14, + 0x73, 0x04, 0x94, 0x2a, 0x93, 0x22, 0x60, 0x5e, 0xee, 0xb6, 0xec, 0x0f, + 0xb0, 0xc8, 0x92, 0x97, 0xfb, 0x5d, 0xed, 0x1f, 0xa0, 0x5f, 0xe4, 0x98, + 0x2f, 0xf6, 0x13, 0x78, 0x99, 0xec, 0xb3, 0xf1, 0x0d, 0x27, 0xaa, 0x19, + 0x95, 0x39, 0xdb, 0xb0, 0x7b, 0x96, 0x74, 0x03, 0x5e, 0x51, 0xf5, 0x15, + 0x27, 0xce, 0xca, 0x0b, 0x2a, 0x0d, 0x43, 0xb3, 0x68, 0x17, 0x1e, 0x11, + 0x60, 0xd9, 0x84, 0x9b, 0xc3, 0x53, 0xce, 0xbd, 0xf4, 0x61, 0x51, 0x4b, + 0x41, 0x00, 0x7e, 0xe1, 0x5f, 0x69, 0xb3, 0x4a, 0x89, 0x7e, 0x47, 0x67, + 0xfd, 0x76, 0xf8, 0x94, 0x2f, 0x72, 0xb6, 0x14, 0x08, 0x2c, 0x16, 0x4e, + 0x9d, 0x37, 0x62, 0xbf, 0x11, 0x67, 0xc0, 0x70, 0x71, 0xec, 0x55, 0x51, + 0x4e, 0x46, 0x76, 0xb4, 0xc3, 0xeb, 0x52, 0x06, 0x17, 0x06, 0xce, 0x61, + 0x43, 0xce, 0x26, 0x80, 0x68, 0xb6, 0x2d, 0x57, 0xba, 0x8c, 0x7d, 0xb7, + 0xc5, 0x05, 0x2c, 0xf8, 0xa3, 0x69, 0xf8, 0x96, 0xad, 0xac, 0xd1, 0x30, + 0x82, 0x05, 0xa6, 0x30, 0x82, 0x03, 0x8e, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x10, 0x73, 0xd1, 0xe1, 0x1d, 0xa9, 0x75, 0xfd, 0x0c, 0xda, 0x7f, + 0xfa, 0x43, 0x3c, 0x26, 0xbd, 0x3d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x7e, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, + 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x11, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, + 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, + 0x76, 0x69, 0x6e, 0x65, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x1a, 0x77, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x65, 0x6d, 0x2d, 0x72, 0x6f, 0x6f, 0x74, + 0x2d, 0x70, 0x72, 0x6f, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, + 0x33, 0x31, 0x34, 0x30, 0x33, 0x30, 0x32, 0x34, 0x31, 0x5a, 0x17, 0x0d, + 0x32, 0x37, 0x30, 0x33, 0x31, 0x34, 0x30, 0x33, 0x30, 0x32, 0x34, 0x31, + 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, + 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, + 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, + 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, 0x30, 0x30, + 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x20, 0x4f, 0x45, 0x4d, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x3b, 0x20, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x37, 0x33, 0x34, 0x36, 0x30, + 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, + 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa5, 0x45, 0x13, 0xf2, + 0xb2, 0xcb, 0x4b, 0x0f, 0xb4, 0x44, 0x25, 0x9c, 0x8a, 0x68, 0x54, 0xd5, + 0x45, 0x1e, 0x15, 0x89, 0x5b, 0xb8, 0xce, 0xda, 0x5a, 0x42, 0xe6, 0x9a, + 0x8c, 0xc1, 0xcb, 0xe8, 0xc5, 0xf5, 0x8f, 0x49, 0x0e, 0x02, 0xef, 0x5e, + 0x97, 0x1a, 0x91, 0xa4, 0x94, 0xc3, 0x50, 0x13, 0xe5, 0x13, 0xb7, 0x7f, + 0x26, 0x53, 0x19, 0xb0, 0x37, 0xa5, 0xef, 0xe6, 0x2a, 0x39, 0xdc, 0x93, + 0x37, 0xe2, 0x3d, 0x7f, 0xcb, 0x4b, 0x93, 0xa2, 0xc3, 0x69, 0x78, 0xc9, + 0x01, 0xfa, 0x68, 0x3b, 0xe0, 0xe2, 0x22, 0x6c, 0xeb, 0xe4, 0x8a, 0xa8, + 0x3e, 0xf5, 0x20, 0x82, 0xa8, 0x62, 0x68, 0x59, 0x78, 0x24, 0xde, 0xef, + 0x47, 0x43, 0xb1, 0x6c, 0x38, 0x29, 0xd3, 0x69, 0x3f, 0xae, 0x35, 0x57, + 0x75, 0x80, 0xc9, 0x21, 0xe7, 0x01, 0xb9, 0x54, 0x8b, 0x6e, 0x4e, 0x2e, + 0x5a, 0x5b, 0x77, 0xa4, 0x22, 0xc2, 0x7b, 0x95, 0xb9, 0x39, 0x2c, 0xbd, + 0xc2, 0x1e, 0x02, 0xa6, 0xb2, 0xbc, 0x0f, 0x7a, 0xcb, 0xdc, 0xbc, 0xbc, + 0x90, 0x66, 0xe3, 0xca, 0x46, 0x53, 0x3e, 0x98, 0xff, 0x2e, 0x78, 0x9f, + 0xd3, 0xa1, 0x12, 0x93, 0x66, 0x7d, 0xcc, 0x94, 0x6b, 0xec, 0x19, 0x0e, + 0x20, 0x45, 0x22, 0x57, 0x6d, 0x9e, 0xd0, 0x89, 0xf2, 0xa9, 0x34, 0xdc, + 0xab, 0xa5, 0x73, 0x47, 0x38, 0xe3, 0x7f, 0x98, 0x3a, 0x61, 0xae, 0x6c, + 0x4d, 0xf2, 0x31, 0x90, 0xcb, 0x83, 0xc1, 0xee, 0xb4, 0xf2, 0x9a, 0x28, + 0x5f, 0xbb, 0x7d, 0x89, 0xdf, 0xa2, 0x31, 0xb6, 0x1d, 0x39, 0x2b, 0x70, + 0xbf, 0x1e, 0xad, 0xe1, 0x74, 0x94, 0x1d, 0xf8, 0xc5, 0x1a, 0x8d, 0x13, + 0x45, 0xf0, 0x6a, 0x80, 0x0c, 0x5d, 0xbb, 0x46, 0x8a, 0x43, 0xd0, 0xff, + 0x21, 0x39, 0x57, 0x53, 0x5b, 0x51, 0xf8, 0xa2, 0x8f, 0x7f, 0x27, 0xc7, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x10, 0x30, 0x82, 0x01, + 0x0c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, + 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, + 0x04, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0xe8, 0xe9, 0xac, 0x16, 0x5c, 0x5e, 0xb2, 0xe8, 0xeb, 0xff, 0x57, 0x27, + 0x20, 0x08, 0x72, 0x63, 0x9b, 0xe5, 0xb5, 0x16, 0x30, 0x81, 0xb2, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xaa, 0x30, 0x81, 0xa7, 0x80, 0x14, + 0x04, 0x94, 0x66, 0xaa, 0xf9, 0x61, 0x89, 0xb6, 0xdb, 0xb5, 0xf7, 0x13, + 0x38, 0x3d, 0x62, 0x84, 0xb8, 0x18, 0x0a, 0x8f, 0xa1, 0x81, 0x83, 0xa4, + 0x81, 0x80, 0x30, 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, + 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, + 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, + 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, 0x23, 0x30, + 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1a, 0x77, 0x69, 0x64, 0x65, + 0x76, 0x69, 0x6e, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x65, 0x6d, + 0x2d, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x72, 0x6f, 0x64, 0x82, 0x09, + 0x00, 0xdf, 0x86, 0x05, 0x31, 0x01, 0xbe, 0x9a, 0x9a, 0x30, 0x12, 0x06, + 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x04, 0x01, 0x01, 0x04, + 0x04, 0x02, 0x02, 0x1c, 0xb2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, + 0x00, 0x25, 0xce, 0xd2, 0x02, 0x48, 0xbb, 0xbe, 0xfc, 0xb6, 0xa4, 0x87, + 0x87, 0xe0, 0x21, 0x7d, 0xfa, 0x23, 0xc3, 0x0d, 0x73, 0x8f, 0x46, 0xe7, + 0x09, 0x59, 0xda, 0x2e, 0x55, 0x59, 0xff, 0x3c, 0x1b, 0xf6, 0xf8, 0x9a, + 0xc4, 0x1c, 0xf7, 0xac, 0xca, 0xe7, 0x63, 0xf2, 0xc7, 0xd6, 0x0c, 0x2d, + 0xa6, 0xad, 0x55, 0xf4, 0x10, 0x0e, 0xa8, 0x82, 0x0f, 0x88, 0xb5, 0x44, + 0xe8, 0x8e, 0x84, 0x08, 0xf7, 0xdd, 0xe7, 0x10, 0xce, 0x71, 0x56, 0x57, + 0x3f, 0xed, 0x48, 0xee, 0xe2, 0x5d, 0x08, 0x0a, 0x58, 0xe4, 0xfe, 0xbc, + 0x8c, 0x27, 0x1a, 0x46, 0x3f, 0xd5, 0x2d, 0xdb, 0x0b, 0x71, 0x73, 0xd1, + 0x49, 0xf3, 0x5c, 0x86, 0x4d, 0x0a, 0xe1, 0xeb, 0x53, 0x21, 0x38, 0x4f, + 0xec, 0x1e, 0xc2, 0x68, 0x1f, 0x7d, 0xa6, 0x33, 0xe9, 0xa5, 0x37, 0x2a, + 0xef, 0xcd, 0x78, 0x56, 0xb3, 0x39, 0x60, 0xf4, 0xa5, 0xf9, 0x2b, 0x85, + 0xcf, 0xe6, 0x1c, 0x7c, 0x8a, 0x5d, 0xe8, 0x26, 0x02, 0xcf, 0x7a, 0x56, + 0x1f, 0xae, 0x0d, 0x71, 0x20, 0xee, 0xec, 0x3b, 0xae, 0x95, 0x25, 0x15, + 0xc8, 0xf6, 0x92, 0x5d, 0xb8, 0x9b, 0xc2, 0xb4, 0x95, 0x33, 0x13, 0x76, + 0x45, 0xbe, 0x21, 0xe2, 0x3a, 0x69, 0x66, 0xd7, 0xff, 0x22, 0x00, 0x89, + 0xc9, 0x44, 0xb6, 0x54, 0x38, 0x1f, 0x33, 0xe4, 0xda, 0x7b, 0x87, 0xf3, + 0x23, 0xed, 0xf5, 0x16, 0x08, 0xbe, 0x4b, 0xea, 0x91, 0x8f, 0x91, 0x8b, + 0x4e, 0xd1, 0x02, 0x06, 0xa2, 0x77, 0x15, 0x03, 0x46, 0x11, 0x7d, 0x5b, + 0xea, 0x7a, 0xf6, 0x86, 0x7d, 0x96, 0xb7, 0x73, 0x9b, 0x5b, 0x32, 0xc3, + 0xf8, 0x92, 0x36, 0xe3, 0xe3, 0x2f, 0xe8, 0xf1, 0x72, 0xec, 0x0d, 0x50, + 0xd4, 0x86, 0xc5, 0x62, 0x83, 0xf1, 0x2a, 0x4c, 0xd1, 0xbf, 0x76, 0x62, + 0xd4, 0x21, 0x11, 0x68, 0xb2, 0xd6, 0x8d, 0xc4, 0xf8, 0xe4, 0x70, 0x85, + 0x19, 0xa7, 0x82, 0x27, 0x2c, 0x24, 0x21, 0x7a, 0x3b, 0xad, 0x8a, 0xd3, + 0xae, 0xda, 0x78, 0x3c, 0x6c, 0xab, 0xa2, 0xaa, 0x36, 0xf0, 0x1c, 0x58, + 0xd4, 0x72, 0x5e, 0xe8, 0x8b, 0x41, 0x08, 0xf5, 0x85, 0xdd, 0xee, 0x99, + 0x12, 0xf4, 0xd6, 0x41, 0x83, 0x69, 0xe7, 0x79, 0x19, 0xa3, 0x74, 0xc4, + 0x34, 0x2a, 0x8a, 0x7e, 0x4d, 0xbb, 0x2c, 0x49, 0x19, 0xf7, 0x98, 0x98, + 0xfc, 0x81, 0xf7, 0x9b, 0x7f, 0xff, 0xd9, 0x66, 0xf4, 0x51, 0x14, 0x29, + 0x2a, 0x14, 0x1d, 0x4f, 0xbd, 0x91, 0xba, 0x6f, 0x32, 0x34, 0x3c, 0x40, + 0x28, 0x6c, 0x97, 0xf8, 0x6d, 0x38, 0xcd, 0xa3, 0x7b, 0x18, 0xc8, 0x77, + 0x58, 0x4d, 0x53, 0x30, 0x7f, 0x4d, 0x89, 0xca, 0x95, 0x6e, 0xb5, 0xb8, + 0x8e, 0xc8, 0x2d, 0x18, 0x2f, 0x52, 0x2a, 0xde, 0xac, 0x56, 0x8d, 0x8c, + 0x67, 0x14, 0xf6, 0xb9, 0xf1, 0x65, 0xd3, 0x22, 0x43, 0xa3, 0x98, 0x42, + 0x20, 0x43, 0x4c, 0xdf, 0xf2, 0xeb, 0x31, 0x8c, 0x0e, 0x53, 0x5b, 0x99, + 0x82, 0xc3, 0x48, 0x04, 0x53, 0xad, 0x96, 0xb6, 0x9f, 0x52, 0xcc, 0x01, + 0xc8, 0xb3, 0x87, 0x6b, 0x9e, 0xea, 0xa9, 0xeb, 0xda, 0xac, 0xf9, 0x6f, + 0xde, 0xa1, 0x44, 0x32, 0x52, 0x49, 0x47, 0xff, 0x65, 0x79, 0x1e, 0xc5, + 0x73, 0x17, 0xb3, 0x36, 0xfc, 0x45, 0xca, 0x90, 0x37, 0x59, 0x1e, 0x16, + 0xab, 0x09, 0x69, 0xcf, 0xda, 0x56, 0x51, 0xfd, 0xeb, 0xcf, 0xcb, 0x8f, + 0xb1, 0xc3, 0x45, 0x2b, 0x7c, 0x0a, 0xa5, 0x9c, 0x0d, 0x2c, 0xad, 0x1c, + 0xd3, 0x33, 0xdd, 0xfe, 0x93, 0x69, 0xa2, 0x4b, 0x4b, 0xcf, 0x1d, 0x20, + 0x98, 0x4a, 0x4f, 0x5b, 0xe9, 0x24, 0xca, 0xfa, 0x18, 0x11, 0x81, 0x8b, + 0x7a, 0xb4, 0x5a, 0xc8, 0xdf, 0x6f, 0x5f, 0x21, 0x07, 0x31, 0x00 +}; + +const size_t kOEMPublicCertSize_UAT = sizeof(kOEMPublicCert_UAT); + +const uint32_t kOEMSystemId_TEST = 2001093; + +const uint8_t kOEMPrivateKey_TEST[] = { + 0x30, 0x82, 0x06, 0xfd, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, + 0x06, 0xe7, 0x30, 0x82, 0x06, 0xe3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, + 0x81, 0x00, 0xda, 0x30, 0x9c, 0xd2, 0xd9, 0xdb, 0xb7, 0x25, 0x86, 0xdc, + 0x99, 0x87, 0x91, 0x40, 0xca, 0x02, 0x76, 0xc4, 0xc6, 0x00, 0xcb, 0x60, + 0x8c, 0xb2, 0x01, 0xde, 0x9d, 0x44, 0x4c, 0x72, 0x42, 0xc2, 0xf1, 0x96, + 0x13, 0xa2, 0x15, 0xb2, 0x9c, 0x09, 0x11, 0x73, 0x96, 0x4e, 0xd3, 0xda, + 0xb4, 0xaf, 0xd5, 0x69, 0x69, 0xd9, 0xbe, 0x19, 0x5e, 0x49, 0x21, 0x01, + 0xf7, 0x31, 0xdd, 0x14, 0xea, 0x41, 0x5e, 0x81, 0xc5, 0x76, 0xff, 0x50, + 0xba, 0xa7, 0x0b, 0x81, 0x22, 0xba, 0x2b, 0x58, 0x7b, 0x5d, 0xb3, 0xaf, + 0xd1, 0xb4, 0x66, 0x8e, 0x70, 0x55, 0xd8, 0x4d, 0x47, 0xb7, 0x00, 0x2c, + 0x52, 0x46, 0x33, 0xa1, 0x5f, 0xca, 0xd8, 0xb1, 0xc5, 0x04, 0x0e, 0xb7, + 0xd8, 0x0a, 0xca, 0x7c, 0x2a, 0x11, 0x3d, 0xec, 0x7f, 0x4c, 0xea, 0xaa, + 0x8e, 0x1d, 0xef, 0x9e, 0x2b, 0x9e, 0x79, 0x09, 0x7e, 0xf4, 0xd0, 0xa3, + 0x58, 0xb5, 0x4e, 0x1c, 0xfb, 0x07, 0x17, 0xc4, 0xef, 0x30, 0xa3, 0x91, + 0xb6, 0x5f, 0xf8, 0xdb, 0x05, 0x73, 0x85, 0x9b, 0xe1, 0x16, 0xf1, 0x8e, + 0xe4, 0x9f, 0xe7, 0x54, 0xcf, 0x52, 0x84, 0xe7, 0x71, 0xe7, 0x38, 0x67, + 0x8e, 0x96, 0x59, 0x9b, 0x97, 0xa2, 0xc0, 0x01, 0xd5, 0x41, 0x36, 0xfa, + 0xc1, 0x61, 0x96, 0x6c, 0x38, 0x7d, 0xdd, 0x1c, 0x24, 0x2e, 0x57, 0x67, + 0x7c, 0x70, 0xd1, 0x8a, 0x8a, 0xe2, 0x6f, 0x66, 0xd2, 0xaa, 0x3e, 0xfa, + 0x4c, 0x4a, 0x68, 0xba, 0x86, 0x6e, 0x33, 0xfe, 0x30, 0xd2, 0xf4, 0x96, + 0x58, 0xe2, 0x35, 0x94, 0x4f, 0x11, 0xc7, 0x0a, 0x21, 0xe5, 0xd4, 0x1a, + 0x3c, 0xfd, 0x82, 0xbb, 0x34, 0x21, 0xdb, 0x2f, 0xd8, 0xd1, 0xbe, 0x38, + 0xe8, 0x47, 0x45, 0x04, 0x27, 0xb0, 0x19, 0x65, 0x6f, 0x55, 0xcd, 0x56, + 0x3a, 0xcc, 0xc1, 0xaf, 0xce, 0x59, 0x2e, 0xe6, 0x89, 0x24, 0x48, 0x94, + 0xc8, 0x73, 0x45, 0xc8, 0xe5, 0x1d, 0xe1, 0xf8, 0x7d, 0x88, 0xe5, 0x07, + 0x42, 0xb2, 0x80, 0x17, 0xf6, 0x67, 0x2a, 0x33, 0xa0, 0xca, 0x81, 0x0e, + 0xc4, 0x99, 0x93, 0x02, 0x8c, 0x90, 0x1d, 0x46, 0xad, 0x61, 0xec, 0xca, + 0xdd, 0x8e, 0x8b, 0x9f, 0x32, 0xab, 0xbf, 0xfa, 0xa6, 0x28, 0xda, 0x63, + 0xa2, 0xf0, 0x20, 0x52, 0x26, 0x06, 0x05, 0x59, 0xe1, 0x4a, 0x8d, 0x5e, + 0x6a, 0x65, 0xd8, 0x8e, 0x6e, 0x49, 0xa4, 0xa8, 0xc0, 0xba, 0x7b, 0x21, + 0x31, 0x7a, 0xd1, 0xb5, 0x46, 0x9e, 0xa5, 0x45, 0xeb, 0xdf, 0x38, 0xc4, + 0x1e, 0x10, 0xc6, 0xb6, 0x83, 0x46, 0x96, 0x63, 0xe5, 0xef, 0x7c, 0xdb, + 0x65, 0x3e, 0xec, 0x42, 0x00, 0x71, 0x78, 0x83, 0xfc, 0x73, 0x4f, 0x4e, + 0xb9, 0x01, 0x80, 0xd4, 0x7d, 0xf2, 0x72, 0x8d, 0x41, 0x7b, 0xee, 0xb5, + 0xca, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x80, 0x2b, + 0xeb, 0x6d, 0x25, 0xe4, 0x44, 0x9d, 0xf1, 0x27, 0xdc, 0x6f, 0xeb, 0x22, + 0x09, 0xf0, 0x9f, 0xde, 0x58, 0x6d, 0xa2, 0xeb, 0x4d, 0x5c, 0x04, 0xd8, + 0xeb, 0x7e, 0xac, 0xa8, 0xd6, 0xb7, 0x29, 0x96, 0x87, 0xa7, 0x1c, 0x11, + 0x52, 0x0a, 0xa6, 0xa8, 0xa4, 0xa3, 0xb4, 0xea, 0x60, 0x33, 0xce, 0xd1, + 0x1e, 0x8e, 0xf8, 0x0d, 0x93, 0xfd, 0xae, 0xaa, 0xbe, 0x42, 0x8b, 0xfe, + 0xfc, 0x9e, 0xca, 0xd9, 0xc3, 0x35, 0x84, 0x66, 0x90, 0x51, 0x82, 0x1e, + 0x86, 0xb7, 0xfe, 0xd1, 0x8a, 0xd6, 0x0a, 0x5e, 0x89, 0x1d, 0xa5, 0x3a, + 0x9f, 0xa1, 0x6d, 0x26, 0x45, 0x28, 0x12, 0x66, 0x2e, 0x85, 0xc1, 0x2b, + 0xd3, 0x67, 0xfc, 0xe4, 0xf1, 0xa3, 0xbe, 0xd5, 0x57, 0x9c, 0x5d, 0x4f, + 0xb4, 0xfe, 0xa2, 0xc9, 0xdc, 0x39, 0x23, 0xba, 0x78, 0xea, 0x72, 0x8c, + 0x31, 0x42, 0x86, 0x7b, 0xc6, 0xb5, 0x8f, 0x82, 0x0f, 0xdf, 0x63, 0x5f, + 0x7d, 0xe5, 0xe9, 0xdf, 0x96, 0xfc, 0xae, 0xc5, 0xbe, 0x26, 0xff, 0xda, + 0x8f, 0xfb, 0xe0, 0xed, 0x1c, 0x1b, 0x8b, 0x0a, 0xc4, 0xc0, 0xb0, 0x8f, + 0x58, 0x3b, 0x03, 0x59, 0x4d, 0x5d, 0x58, 0x35, 0xba, 0x62, 0xb1, 0x51, + 0x08, 0x48, 0xd5, 0xb1, 0xe0, 0xac, 0x94, 0x9c, 0x04, 0x8d, 0xb8, 0x9f, + 0x16, 0xd9, 0xa8, 0x3c, 0x41, 0xd5, 0xe6, 0x9e, 0x21, 0x6e, 0xa2, 0xc7, + 0xdb, 0x2a, 0xeb, 0x2d, 0x54, 0xbd, 0xa0, 0x16, 0x90, 0xa1, 0x73, 0x15, + 0xf1, 0x88, 0xb0, 0xa0, 0xa0, 0x5d, 0xf3, 0x1a, 0x7d, 0x60, 0x6c, 0x59, + 0xcd, 0x1a, 0xb6, 0x6a, 0x5b, 0xca, 0x4a, 0x86, 0x35, 0xc4, 0x9d, 0xfc, + 0x27, 0x38, 0x8c, 0x53, 0x69, 0x8e, 0xba, 0x4b, 0x1f, 0x4a, 0x31, 0x70, + 0x41, 0xc5, 0x7d, 0x35, 0xf0, 0xe6, 0xc8, 0x70, 0xc9, 0x83, 0x8e, 0x05, + 0xbe, 0x97, 0x82, 0xb2, 0x59, 0xfc, 0xb4, 0x63, 0x98, 0xa3, 0x3b, 0x17, + 0xdc, 0xe7, 0xa4, 0x30, 0xce, 0xd1, 0x76, 0xc7, 0x42, 0xce, 0x92, 0x1b, + 0xdd, 0xde, 0xa1, 0xdd, 0xeb, 0x88, 0xb4, 0xd0, 0x90, 0xb6, 0xe9, 0x91, + 0x3b, 0xb5, 0x2a, 0x8c, 0xad, 0x48, 0x15, 0xd3, 0x69, 0x46, 0xfe, 0x43, + 0x11, 0xd9, 0x5b, 0x56, 0x66, 0xb1, 0x5f, 0xf4, 0x0f, 0x68, 0xb5, 0x55, + 0x17, 0x5c, 0x41, 0xd7, 0xdc, 0x2d, 0xd2, 0x6a, 0x9c, 0xd8, 0xd0, 0x45, + 0xff, 0xc7, 0x30, 0x81, 0xc8, 0x57, 0xe6, 0x6e, 0x12, 0xd7, 0xa1, 0x6f, + 0x51, 0x9d, 0x0b, 0x7c, 0x00, 0xbd, 0xa7, 0xc5, 0x7e, 0x58, 0x9b, 0x6a, + 0xf3, 0xe6, 0x17, 0x43, 0x89, 0x04, 0xa0, 0xf5, 0x61, 0xa8, 0xf9, 0xff, + 0x5f, 0x9f, 0xa5, 0x4b, 0xa7, 0xdb, 0x60, 0xea, 0xb9, 0x80, 0x5d, 0x1c, + 0x58, 0x2a, 0x60, 0x96, 0x6a, 0xba, 0xc7, 0xf3, 0xfc, 0x13, 0x41, 0x02, + 0x81, 0xc1, 0x00, 0xf3, 0x45, 0x5f, 0x13, 0x38, 0xa4, 0x51, 0x17, 0x3a, + 0xf9, 0x4d, 0x9f, 0x71, 0x98, 0x26, 0x27, 0xfb, 0x81, 0xe6, 0x49, 0x88, + 0x8d, 0x2f, 0xc6, 0x13, 0x41, 0x08, 0xef, 0x8b, 0x7d, 0xec, 0x62, 0x73, + 0x02, 0x73, 0xa8, 0x98, 0x77, 0x4c, 0x46, 0x7c, 0x62, 0xec, 0x9e, 0xa7, + 0xab, 0x19, 0x21, 0x8c, 0x2f, 0xad, 0xb8, 0x17, 0x3b, 0x83, 0x9b, 0x32, + 0xb8, 0xf4, 0x49, 0x70, 0x47, 0x3c, 0x2a, 0xb0, 0x8f, 0xdc, 0x9a, 0xa4, + 0x3e, 0xef, 0x3e, 0xce, 0x43, 0x7e, 0x28, 0xdd, 0x9e, 0x46, 0xf0, 0x28, + 0x86, 0xbf, 0xdd, 0x2f, 0xf7, 0xc6, 0x1c, 0xa0, 0xec, 0x14, 0x54, 0x23, + 0xce, 0x32, 0xd5, 0xc5, 0x77, 0x7f, 0xf0, 0x8c, 0x8b, 0x39, 0x86, 0x9d, + 0x18, 0xb6, 0x2c, 0xc9, 0x65, 0x20, 0xcf, 0x58, 0xeb, 0xe7, 0x21, 0xc3, + 0x49, 0x7e, 0x1e, 0xa7, 0xe0, 0x8a, 0xe4, 0x1f, 0x77, 0x8c, 0x25, 0xfb, + 0x97, 0x05, 0x6b, 0x10, 0xa5, 0xff, 0x00, 0xb9, 0x5b, 0xf4, 0x6f, 0x06, + 0x50, 0xe7, 0xdf, 0xa2, 0x22, 0x71, 0x9f, 0x8c, 0x32, 0x04, 0x68, 0x5e, + 0x89, 0x04, 0x53, 0x99, 0x57, 0xf6, 0x70, 0x7a, 0x7f, 0x4d, 0xfe, 0xd0, + 0xf9, 0xc2, 0x52, 0xb3, 0x0e, 0x81, 0x95, 0xcb, 0xb6, 0x7d, 0x89, 0x46, + 0x04, 0x50, 0xce, 0xf1, 0x3e, 0xb8, 0x75, 0x57, 0xde, 0xa0, 0xf6, 0x5f, + 0xf1, 0x19, 0xeb, 0x02, 0x81, 0xc1, 0x00, 0xe5, 0x9b, 0x47, 0x51, 0xed, + 0x05, 0x0c, 0x94, 0xa4, 0x5b, 0xd0, 0x2d, 0x62, 0x2a, 0x02, 0x76, 0xc9, + 0x77, 0x32, 0x18, 0x8c, 0xc8, 0x85, 0x9a, 0x4e, 0x3b, 0x47, 0x4e, 0xb0, + 0x8f, 0x61, 0x03, 0xc1, 0xf5, 0xe3, 0x57, 0x12, 0xd6, 0xad, 0x42, 0xaf, + 0xe1, 0x37, 0xe2, 0x7a, 0xcf, 0xd7, 0x34, 0xbb, 0xb7, 0xa4, 0xfd, 0xd7, + 0x5a, 0x44, 0x09, 0xa1, 0xdf, 0x7b, 0x26, 0x74, 0xb7, 0x05, 0xf8, 0x46, + 0xd3, 0x33, 0x03, 0x09, 0xc4, 0xb7, 0x71, 0xba, 0x96, 0x55, 0x64, 0xa1, + 0x3f, 0x4f, 0xcb, 0x05, 0x97, 0x87, 0x8c, 0xeb, 0xd6, 0x66, 0x02, 0xe1, + 0x32, 0xed, 0x7b, 0xed, 0xad, 0xb7, 0x99, 0xba, 0x80, 0x36, 0x92, 0xcc, + 0xa9, 0x0a, 0x8a, 0x34, 0x8b, 0x9b, 0x34, 0x3b, 0x50, 0xf5, 0xd0, 0xeb, + 0x49, 0x96, 0xb0, 0xab, 0x10, 0x45, 0x53, 0xeb, 0x63, 0xc3, 0x51, 0x52, + 0xbf, 0xe9, 0xbd, 0x7a, 0x59, 0xe1, 0x3b, 0x62, 0xd7, 0x91, 0x47, 0x31, + 0x4c, 0x9c, 0x31, 0x42, 0x55, 0x88, 0x65, 0xcd, 0x3e, 0x72, 0xf0, 0x04, + 0xd0, 0x57, 0x13, 0x6f, 0x25, 0xde, 0x66, 0xa2, 0xe7, 0x4d, 0x1f, 0xd1, + 0xae, 0x19, 0x60, 0x68, 0xc3, 0xb4, 0xb4, 0x7b, 0xc5, 0x22, 0x8b, 0xf8, + 0x4e, 0xad, 0xc8, 0x8a, 0x40, 0xb8, 0xcc, 0x01, 0xe6, 0x0e, 0xe7, 0xbe, + 0x17, 0x65, 0x02, 0xb5, 0xa8, 0x24, 0x25, 0x02, 0x81, 0xc0, 0x3e, 0x4f, + 0x1c, 0x64, 0xfd, 0xf3, 0x08, 0x5a, 0x1c, 0xde, 0xd2, 0x04, 0xee, 0xc1, + 0x7b, 0xb4, 0x6d, 0xf4, 0xfd, 0x99, 0x04, 0x02, 0xb5, 0xa3, 0xd4, 0x36, + 0xaa, 0x25, 0x40, 0xe3, 0x45, 0xf2, 0x89, 0x66, 0xad, 0x5d, 0x17, 0x80, + 0x26, 0xe7, 0x3e, 0xe0, 0xcf, 0x9e, 0x6b, 0x6f, 0xa5, 0x86, 0x34, 0x33, + 0xda, 0x18, 0xf6, 0xca, 0x65, 0x91, 0x10, 0xd2, 0xd2, 0xaf, 0x24, 0xb4, + 0xfa, 0x32, 0x2c, 0xfb, 0x0c, 0x14, 0x07, 0xd1, 0x9e, 0xd1, 0xc5, 0x5f, + 0x00, 0x27, 0x53, 0x6c, 0x40, 0xdb, 0x2e, 0x66, 0x25, 0x2a, 0x70, 0x28, + 0xd4, 0x73, 0x6c, 0xbc, 0x4b, 0x10, 0xaa, 0x03, 0x1c, 0x7e, 0x28, 0x8f, + 0xcd, 0x13, 0x3d, 0xcc, 0x43, 0x35, 0xb9, 0x73, 0x24, 0xe6, 0x1f, 0xc7, + 0x69, 0x39, 0xf2, 0x9a, 0xa9, 0x9e, 0xba, 0x38, 0x4e, 0xb7, 0x67, 0x64, + 0x59, 0xee, 0xc8, 0x28, 0x84, 0x9b, 0x0d, 0xef, 0xc6, 0x91, 0x7f, 0xb8, + 0x24, 0xb2, 0x78, 0xc7, 0x96, 0xba, 0x01, 0x32, 0x23, 0xd1, 0xe1, 0xe3, + 0x54, 0x9a, 0xfa, 0xfb, 0xac, 0xa9, 0x56, 0xdd, 0x5d, 0x60, 0x54, 0x3c, + 0x75, 0x80, 0xa5, 0xbf, 0x89, 0xa8, 0xa4, 0xb9, 0xf4, 0x0d, 0xde, 0x92, + 0xee, 0x9a, 0x01, 0x8d, 0x82, 0x65, 0xf0, 0xab, 0x16, 0x4f, 0x8a, 0xf6, + 0xf7, 0xa4, 0x06, 0x97, 0x9d, 0x3e, 0xbd, 0xa0, 0x31, 0x75, 0x02, 0x81, + 0xc0, 0x1a, 0xe3, 0x9b, 0x6f, 0x99, 0xbd, 0x5c, 0xa2, 0xcf, 0xb8, 0xbc, + 0xe1, 0x83, 0xbc, 0x7d, 0xbb, 0x61, 0x8e, 0xa6, 0xfc, 0x3f, 0x08, 0x80, + 0xb4, 0xf8, 0x72, 0x72, 0xc0, 0x61, 0x66, 0xf9, 0x2a, 0x92, 0x7d, 0x74, + 0x59, 0x4f, 0x28, 0x7a, 0xf3, 0xf3, 0x5b, 0x01, 0xcb, 0x71, 0x2c, 0x83, + 0xfc, 0x75, 0xfb, 0x64, 0xc4, 0x21, 0x83, 0x3d, 0xb2, 0x8f, 0x15, 0x77, + 0xfb, 0xa1, 0xf1, 0x89, 0x2e, 0x71, 0x44, 0xec, 0x95, 0x6f, 0x80, 0x6d, + 0x27, 0x51, 0x7d, 0xa7, 0x94, 0x78, 0x59, 0xcc, 0xc3, 0x6e, 0xed, 0x36, + 0xff, 0xa6, 0xe2, 0xdd, 0xe1, 0x7a, 0x74, 0x17, 0x61, 0xcb, 0x0c, 0xec, + 0x12, 0x81, 0xc7, 0xe0, 0x1c, 0x43, 0x01, 0x8c, 0xed, 0x70, 0x87, 0xe4, + 0xee, 0x32, 0x00, 0x22, 0x39, 0x8c, 0x44, 0x7a, 0xf4, 0x47, 0xa4, 0x49, + 0x2a, 0x31, 0xc7, 0xe6, 0x28, 0xd0, 0xf3, 0x0e, 0xb1, 0x94, 0xf1, 0x8f, + 0xb1, 0xff, 0xba, 0x55, 0x16, 0x2c, 0x4c, 0xd7, 0x81, 0xe1, 0x4d, 0xd9, + 0x02, 0x6b, 0x0d, 0xe4, 0x31, 0xfd, 0xae, 0x54, 0x74, 0x3f, 0x31, 0x05, + 0x21, 0xa9, 0xf4, 0x42, 0x90, 0xf6, 0x62, 0x58, 0x30, 0x75, 0x34, 0x6e, + 0x26, 0x30, 0xd4, 0x7e, 0x5e, 0x3b, 0xff, 0x22, 0xd4, 0xf8, 0x73, 0xe9, + 0xf0, 0x62, 0x4c, 0x89, 0xf4, 0x53, 0xcb, 0xb3, 0x95, 0xa4, 0xa6, 0x83, + 0x4d, 0x02, 0x81, 0xc1, 0x00, 0xf0, 0x0f, 0xf2, 0x41, 0x51, 0x00, 0xb8, + 0x7d, 0x23, 0xfd, 0xeb, 0xb4, 0xe2, 0x18, 0x20, 0x09, 0x37, 0x77, 0x44, + 0xe3, 0x4b, 0x88, 0xac, 0xab, 0x39, 0x28, 0x9b, 0x50, 0x57, 0xc8, 0x16, + 0xf3, 0xeb, 0x5f, 0x7f, 0xc5, 0x3a, 0x53, 0x70, 0x11, 0x37, 0x6c, 0x50, + 0xc3, 0xc4, 0x13, 0x26, 0x56, 0x31, 0x63, 0x7b, 0x34, 0xd2, 0xde, 0x40, + 0x15, 0xaa, 0xf8, 0x27, 0x5b, 0x79, 0x5b, 0xeb, 0x2c, 0xb0, 0x6d, 0x50, + 0x84, 0x86, 0x75, 0xff, 0x4a, 0x8c, 0x19, 0xa4, 0x1a, 0x54, 0xca, 0x7c, + 0xc7, 0xe5, 0x86, 0xc0, 0xd7, 0xf7, 0xf8, 0xfb, 0x01, 0xf3, 0x30, 0x10, + 0xd6, 0x74, 0x24, 0x64, 0x9f, 0x95, 0x94, 0x25, 0xc9, 0x2c, 0x04, 0x19, + 0x84, 0xea, 0xcc, 0xe9, 0x3e, 0x10, 0x2f, 0xd9, 0x33, 0xf9, 0x4d, 0x08, + 0x55, 0x98, 0xe6, 0x39, 0xfe, 0x27, 0x11, 0x07, 0xb3, 0xb8, 0x66, 0x88, + 0x0a, 0xde, 0x1f, 0x2c, 0x90, 0xbf, 0xc8, 0x44, 0xac, 0xc4, 0xbe, 0x30, + 0x82, 0xa7, 0x5e, 0x11, 0xa0, 0xe7, 0xbd, 0x21, 0xa9, 0x18, 0xf4, 0xe1, + 0x9f, 0x4d, 0x9f, 0x43, 0xd5, 0x2b, 0xe5, 0xdd, 0x96, 0xa4, 0x5c, 0xdc, + 0x28, 0x9b, 0x9e, 0xd9, 0x0d, 0x04, 0xb6, 0x82, 0xe3, 0x75, 0xd1, 0xbb, + 0x4d, 0x2b, 0x49, 0x21, 0xb7, 0x8a, 0x7b, 0x47, 0x81, 0x57, 0x5a, 0x1e, + 0x09, 0xdc, 0xe8, 0xe5, 0x29 +}; + +const size_t kOEMPrivateKeySize_TEST = sizeof(kOEMPrivateKey_TEST); + +const uint8_t kOEMPublicCert_TEST[] = { + 0x30, 0x82, 0x09, 0xff, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x07, 0x02, 0xa0, 0x82, 0x09, 0xf0, 0x30, 0x82, 0x09, 0xec, 0x02, + 0x01, 0x01, 0x31, 0x00, 0x30, 0x0f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x02, 0x04, 0x00, 0xa0, 0x82, 0x09, + 0xd0, 0x30, 0x82, 0x04, 0x20, 0x30, 0x82, 0x03, 0x08, 0xa0, 0x03, 0x02, + 0x01, 0x02, 0x02, 0x10, 0x72, 0xa8, 0x0e, 0x1d, 0x3e, 0x4c, 0xec, 0x0c, + 0x57, 0xd8, 0xae, 0xf1, 0xe9, 0x43, 0xda, 0x2b, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, + 0x81, 0x8e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, + 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, + 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x57, + 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, 0x33, 0x30, 0x31, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x20, 0x4f, 0x45, 0x4d, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x3b, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x20, 0x69, 0x64, 0x3a, 0x20, 0x32, 0x30, 0x30, 0x31, 0x30, 0x39, 0x33, + 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x33, 0x31, 0x37, 0x31, 0x31, + 0x30, 0x38, 0x30, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x33, 0x31, + 0x35, 0x31, 0x31, 0x30, 0x38, 0x30, 0x36, 0x5a, 0x30, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0c, 0x32, 0x30, 0x30, + 0x31, 0x30, 0x39, 0x33, 0x2d, 0x6c, 0x65, 0x61, 0x66, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, + 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, + 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, + 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, + 0x6e, 0x65, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, + 0x8f, 0x00, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xda, + 0x30, 0x9c, 0xd2, 0xd9, 0xdb, 0xb7, 0x25, 0x86, 0xdc, 0x99, 0x87, 0x91, + 0x40, 0xca, 0x02, 0x76, 0xc4, 0xc6, 0x00, 0xcb, 0x60, 0x8c, 0xb2, 0x01, + 0xde, 0x9d, 0x44, 0x4c, 0x72, 0x42, 0xc2, 0xf1, 0x96, 0x13, 0xa2, 0x15, + 0xb2, 0x9c, 0x09, 0x11, 0x73, 0x96, 0x4e, 0xd3, 0xda, 0xb4, 0xaf, 0xd5, + 0x69, 0x69, 0xd9, 0xbe, 0x19, 0x5e, 0x49, 0x21, 0x01, 0xf7, 0x31, 0xdd, + 0x14, 0xea, 0x41, 0x5e, 0x81, 0xc5, 0x76, 0xff, 0x50, 0xba, 0xa7, 0x0b, + 0x81, 0x22, 0xba, 0x2b, 0x58, 0x7b, 0x5d, 0xb3, 0xaf, 0xd1, 0xb4, 0x66, + 0x8e, 0x70, 0x55, 0xd8, 0x4d, 0x47, 0xb7, 0x00, 0x2c, 0x52, 0x46, 0x33, + 0xa1, 0x5f, 0xca, 0xd8, 0xb1, 0xc5, 0x04, 0x0e, 0xb7, 0xd8, 0x0a, 0xca, + 0x7c, 0x2a, 0x11, 0x3d, 0xec, 0x7f, 0x4c, 0xea, 0xaa, 0x8e, 0x1d, 0xef, + 0x9e, 0x2b, 0x9e, 0x79, 0x09, 0x7e, 0xf4, 0xd0, 0xa3, 0x58, 0xb5, 0x4e, + 0x1c, 0xfb, 0x07, 0x17, 0xc4, 0xef, 0x30, 0xa3, 0x91, 0xb6, 0x5f, 0xf8, + 0xdb, 0x05, 0x73, 0x85, 0x9b, 0xe1, 0x16, 0xf1, 0x8e, 0xe4, 0x9f, 0xe7, + 0x54, 0xcf, 0x52, 0x84, 0xe7, 0x71, 0xe7, 0x38, 0x67, 0x8e, 0x96, 0x59, + 0x9b, 0x97, 0xa2, 0xc0, 0x01, 0xd5, 0x41, 0x36, 0xfa, 0xc1, 0x61, 0x96, + 0x6c, 0x38, 0x7d, 0xdd, 0x1c, 0x24, 0x2e, 0x57, 0x67, 0x7c, 0x70, 0xd1, + 0x8a, 0x8a, 0xe2, 0x6f, 0x66, 0xd2, 0xaa, 0x3e, 0xfa, 0x4c, 0x4a, 0x68, + 0xba, 0x86, 0x6e, 0x33, 0xfe, 0x30, 0xd2, 0xf4, 0x96, 0x58, 0xe2, 0x35, + 0x94, 0x4f, 0x11, 0xc7, 0x0a, 0x21, 0xe5, 0xd4, 0x1a, 0x3c, 0xfd, 0x82, + 0xbb, 0x34, 0x21, 0xdb, 0x2f, 0xd8, 0xd1, 0xbe, 0x38, 0xe8, 0x47, 0x45, + 0x04, 0x27, 0xb0, 0x19, 0x65, 0x6f, 0x55, 0xcd, 0x56, 0x3a, 0xcc, 0xc1, + 0xaf, 0xce, 0x59, 0x2e, 0xe6, 0x89, 0x24, 0x48, 0x94, 0xc8, 0x73, 0x45, + 0xc8, 0xe5, 0x1d, 0xe1, 0xf8, 0x7d, 0x88, 0xe5, 0x07, 0x42, 0xb2, 0x80, + 0x17, 0xf6, 0x67, 0x2a, 0x33, 0xa0, 0xca, 0x81, 0x0e, 0xc4, 0x99, 0x93, + 0x02, 0x8c, 0x90, 0x1d, 0x46, 0xad, 0x61, 0xec, 0xca, 0xdd, 0x8e, 0x8b, + 0x9f, 0x32, 0xab, 0xbf, 0xfa, 0xa6, 0x28, 0xda, 0x63, 0xa2, 0xf0, 0x20, + 0x52, 0x26, 0x06, 0x05, 0x59, 0xe1, 0x4a, 0x8d, 0x5e, 0x6a, 0x65, 0xd8, + 0x8e, 0x6e, 0x49, 0xa4, 0xa8, 0xc0, 0xba, 0x7b, 0x21, 0x31, 0x7a, 0xd1, + 0xb5, 0x46, 0x9e, 0xa5, 0x45, 0xeb, 0xdf, 0x38, 0xc4, 0x1e, 0x10, 0xc6, + 0xb6, 0x83, 0x46, 0x96, 0x63, 0xe5, 0xef, 0x7c, 0xdb, 0x65, 0x3e, 0xec, + 0x42, 0x00, 0x71, 0x78, 0x83, 0xfc, 0x73, 0x4f, 0x4e, 0xb9, 0x01, 0x80, + 0xd4, 0x7d, 0xf2, 0x72, 0x8d, 0x41, 0x7b, 0xee, 0xb5, 0xca, 0xf7, 0x02, + 0x03, 0x01, 0x00, 0x01, 0xa3, 0x17, 0x30, 0x15, 0x30, 0x13, 0x06, 0x0a, + 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x04, 0x01, 0x01, 0x04, 0x05, + 0x02, 0x03, 0x1e, 0x88, 0xc5, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x17, 0x78, 0x3e, 0x21, 0x3a, 0x55, 0x67, 0xdc, 0xa6, 0x41, 0x46, + 0xcd, 0x41, 0x8f, 0x4d, 0x0c, 0x5f, 0xaa, 0x4c, 0x6d, 0xcc, 0xa1, 0xed, + 0x69, 0x9a, 0x59, 0xa0, 0xc1, 0x10, 0x9e, 0x96, 0x2b, 0x2f, 0x36, 0xfb, + 0x82, 0xc9, 0x5f, 0x71, 0x76, 0x00, 0x38, 0x8f, 0x32, 0xed, 0xec, 0x41, + 0x4a, 0x3b, 0x4e, 0x3b, 0x2f, 0xf9, 0x1e, 0x04, 0xdc, 0xc0, 0x14, 0x55, + 0xec, 0xdb, 0xba, 0x50, 0x6f, 0x0e, 0xc1, 0xec, 0xde, 0x5e, 0xf4, 0xa0, + 0x58, 0x9e, 0x41, 0x72, 0xbc, 0xb2, 0x1f, 0xb5, 0x7e, 0xc0, 0xa8, 0xb2, + 0xf4, 0xe5, 0xe6, 0x67, 0x99, 0x6b, 0x90, 0xbe, 0xd8, 0x14, 0x7a, 0x9a, + 0xbf, 0x7d, 0x3d, 0xdf, 0xfb, 0xb3, 0x88, 0x3e, 0x62, 0x1f, 0xef, 0xd0, + 0xc7, 0xb3, 0xfe, 0xde, 0x4e, 0x85, 0x15, 0xca, 0xaf, 0x39, 0xc8, 0x5c, + 0x47, 0x54, 0x48, 0x38, 0x97, 0x6c, 0x8c, 0x98, 0x55, 0x22, 0x43, 0x45, + 0xf9, 0xb5, 0x6c, 0x84, 0x32, 0xcb, 0x01, 0x1c, 0x3e, 0x94, 0xb1, 0x57, + 0x47, 0x8b, 0xcd, 0x26, 0x78, 0xa2, 0x5f, 0x88, 0x24, 0xb3, 0x2b, 0xb4, + 0x4d, 0x04, 0xb2, 0xbc, 0x84, 0x3e, 0x95, 0x41, 0xd7, 0x6a, 0x0d, 0x11, + 0x26, 0x96, 0x99, 0x14, 0xd8, 0x2c, 0x9a, 0xdb, 0x92, 0x95, 0xe5, 0x92, + 0x07, 0x55, 0xf6, 0x1b, 0x8c, 0x55, 0x87, 0x58, 0xe0, 0xd1, 0x39, 0xf3, + 0x91, 0x41, 0x32, 0x83, 0x0d, 0x06, 0x97, 0x28, 0x7d, 0x3b, 0x4d, 0x8d, + 0x26, 0xb4, 0x8c, 0x9b, 0x0a, 0xd2, 0x09, 0x8d, 0xd2, 0xa9, 0xbc, 0x54, + 0xad, 0xb4, 0x7a, 0x6c, 0xa4, 0xd4, 0x26, 0xea, 0xc7, 0xf1, 0x56, 0x9e, + 0xd6, 0xe0, 0xae, 0xc9, 0x40, 0x6f, 0x22, 0x23, 0x36, 0xaa, 0xb4, 0x01, + 0x65, 0xc6, 0x22, 0x65, 0x4e, 0x07, 0xf0, 0xd6, 0xe6, 0xb4, 0xa1, 0xb3, + 0xd6, 0x69, 0xeb, 0xd9, 0x26, 0x30, 0x82, 0x05, 0xa8, 0x30, 0x82, 0x03, + 0x90, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x11, 0x00, 0xe5, 0xc7, 0xfc, + 0x08, 0x78, 0xc3, 0x6d, 0x1d, 0xec, 0xff, 0x0b, 0xe7, 0xb2, 0xca, 0xb1, + 0x89, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x0b, 0x05, 0x00, 0x30, 0x7d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, + 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, + 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, + 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x19, 0x77, 0x69, + 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, + 0x65, 0x6d, 0x2d, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x64, 0x65, 0x76, 0x30, + 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x33, 0x31, 0x37, 0x30, 0x30, 0x35, + 0x37, 0x32, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x33, 0x31, 0x35, + 0x30, 0x30, 0x35, 0x37, 0x32, 0x34, 0x5a, 0x30, 0x81, 0x8e, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, + 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, + 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, + 0x69, 0x6e, 0x65, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x2a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x4f, 0x45, 0x4d, + 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x3b, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x69, 0x64, 0x3a, + 0x20, 0x32, 0x30, 0x30, 0x31, 0x30, 0x39, 0x33, 0x30, 0x82, 0x01, 0x22, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, + 0x02, 0x82, 0x01, 0x01, 0x00, 0xa5, 0x45, 0x13, 0xf2, 0xb2, 0xcb, 0x4b, + 0x0f, 0xb4, 0x44, 0x25, 0x9c, 0x8a, 0x68, 0x54, 0xd5, 0x45, 0x1e, 0x15, + 0x89, 0x5b, 0xb8, 0xce, 0xda, 0x5a, 0x42, 0xe6, 0x9a, 0x8c, 0xc1, 0xcb, + 0xe8, 0xc5, 0xf5, 0x8f, 0x49, 0x0e, 0x02, 0xef, 0x5e, 0x97, 0x1a, 0x91, + 0xa4, 0x94, 0xc3, 0x50, 0x13, 0xe5, 0x13, 0xb7, 0x7f, 0x26, 0x53, 0x19, + 0xb0, 0x37, 0xa5, 0xef, 0xe6, 0x2a, 0x39, 0xdc, 0x93, 0x37, 0xe2, 0x3d, + 0x7f, 0xcb, 0x4b, 0x93, 0xa2, 0xc3, 0x69, 0x78, 0xc9, 0x01, 0xfa, 0x68, + 0x3b, 0xe0, 0xe2, 0x22, 0x6c, 0xeb, 0xe4, 0x8a, 0xa8, 0x3e, 0xf5, 0x20, + 0x82, 0xa8, 0x62, 0x68, 0x59, 0x78, 0x24, 0xde, 0xef, 0x47, 0x43, 0xb1, + 0x6c, 0x38, 0x29, 0xd3, 0x69, 0x3f, 0xae, 0x35, 0x57, 0x75, 0x80, 0xc9, + 0x21, 0xe7, 0x01, 0xb9, 0x54, 0x8b, 0x6e, 0x4e, 0x2e, 0x5a, 0x5b, 0x77, + 0xa4, 0x22, 0xc2, 0x7b, 0x95, 0xb9, 0x39, 0x2c, 0xbd, 0xc2, 0x1e, 0x02, + 0xa6, 0xb2, 0xbc, 0x0f, 0x7a, 0xcb, 0xdc, 0xbc, 0xbc, 0x90, 0x66, 0xe3, + 0xca, 0x46, 0x53, 0x3e, 0x98, 0xff, 0x2e, 0x78, 0x9f, 0xd3, 0xa1, 0x12, + 0x93, 0x66, 0x7d, 0xcc, 0x94, 0x6b, 0xec, 0x19, 0x0e, 0x20, 0x45, 0x22, + 0x57, 0x6d, 0x9e, 0xd0, 0x89, 0xf2, 0xa9, 0x34, 0xdc, 0xab, 0xa5, 0x73, + 0x47, 0x38, 0xe3, 0x7f, 0x98, 0x3a, 0x61, 0xae, 0x6c, 0x4d, 0xf2, 0x31, + 0x90, 0xcb, 0x83, 0xc1, 0xee, 0xb4, 0xf2, 0x9a, 0x28, 0x5f, 0xbb, 0x7d, + 0x89, 0xdf, 0xa2, 0x31, 0xb6, 0x1d, 0x39, 0x2b, 0x70, 0xbf, 0x1e, 0xad, + 0xe1, 0x74, 0x94, 0x1d, 0xf8, 0xc5, 0x1a, 0x8d, 0x13, 0x45, 0xf0, 0x6a, + 0x80, 0x0c, 0x5d, 0xbb, 0x46, 0x8a, 0x43, 0xd0, 0xff, 0x21, 0x39, 0x57, + 0x53, 0x5b, 0x51, 0xf8, 0xa2, 0x8f, 0x7f, 0x27, 0xc7, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x82, 0x01, 0x0f, 0x30, 0x82, 0x01, 0x0b, 0x30, 0x12, + 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, + 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xe8, 0xe9, 0xac, + 0x16, 0x5c, 0x5e, 0xb2, 0xe8, 0xeb, 0xff, 0x57, 0x27, 0x20, 0x08, 0x72, + 0x63, 0x9b, 0xe5, 0xb5, 0x16, 0x30, 0x81, 0xb0, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x81, 0xa8, 0x30, 0x81, 0xa5, 0x80, 0x14, 0x7e, 0x03, 0xe5, + 0x06, 0x62, 0x3b, 0x2c, 0x21, 0xa5, 0x52, 0xa1, 0xe8, 0xee, 0x2c, 0xd2, + 0x52, 0xe4, 0xf6, 0xbb, 0x6e, 0xa1, 0x81, 0x81, 0xa4, 0x7f, 0x30, 0x7d, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, + 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, + 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x57, 0x69, 0x64, + 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x19, 0x77, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x65, 0x6d, 0x2d, 0x72, 0x6f, 0x6f, + 0x74, 0x2d, 0x64, 0x65, 0x76, 0x82, 0x09, 0x00, 0x95, 0xd7, 0xb5, 0xfc, + 0xcf, 0x8e, 0xcb, 0x51, 0x30, 0x13, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0xd6, 0x79, 0x04, 0x01, 0x01, 0x04, 0x05, 0x02, 0x03, 0x1e, 0x88, + 0xc5, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x73, 0x48, 0x8c, + 0x6f, 0x11, 0xfe, 0x4b, 0x27, 0xca, 0xdd, 0x57, 0xfe, 0xcb, 0x27, 0xca, + 0xaf, 0x1c, 0x78, 0x4c, 0x95, 0x16, 0x2a, 0x11, 0x28, 0x9e, 0x2e, 0x93, + 0xa5, 0x1f, 0x3f, 0x80, 0x8d, 0x44, 0xc6, 0xaa, 0x12, 0x25, 0x6c, 0x6c, + 0xe3, 0xa7, 0x6d, 0xa3, 0xe1, 0xf5, 0x6a, 0x69, 0xb1, 0x18, 0x89, 0x0e, + 0x61, 0x4a, 0xa5, 0x5c, 0x0b, 0xf8, 0x7d, 0x2d, 0x8e, 0xbc, 0xf4, 0x2e, + 0x61, 0xa6, 0xf9, 0x32, 0xf8, 0x47, 0x8b, 0xf5, 0x3d, 0xd9, 0xb7, 0x3b, + 0x7d, 0xc6, 0xe5, 0x14, 0x8f, 0xeb, 0x72, 0x9e, 0x2b, 0xfc, 0x12, 0xef, + 0xa1, 0x26, 0xce, 0xad, 0xd5, 0x5c, 0x74, 0x50, 0x76, 0xf4, 0xd1, 0xac, + 0xdd, 0x09, 0x37, 0xde, 0xa8, 0xcd, 0x0b, 0x35, 0x89, 0x19, 0x66, 0xce, + 0x6b, 0x79, 0x1a, 0x86, 0x12, 0x7e, 0x60, 0xb4, 0x1c, 0x86, 0x34, 0x39, + 0xe5, 0x88, 0x55, 0x2b, 0x28, 0xd1, 0x7c, 0x11, 0x23, 0xa6, 0xef, 0x24, + 0xcb, 0x3b, 0xd2, 0x07, 0xe2, 0x54, 0x88, 0x41, 0xdc, 0x16, 0x16, 0x74, + 0x8a, 0x81, 0x2b, 0x53, 0x42, 0x17, 0xef, 0x87, 0xdd, 0x27, 0x8c, 0x23, + 0xcd, 0x2d, 0x2d, 0xde, 0x9c, 0x1a, 0x0e, 0xda, 0xd2, 0xbe, 0xb0, 0x8d, + 0x9d, 0x2b, 0x46, 0x54, 0x97, 0x8d, 0x24, 0x4f, 0x3e, 0x92, 0x25, 0xf6, + 0x04, 0xb7, 0x69, 0x5d, 0x1c, 0x80, 0x0e, 0x30, 0x9b, 0x37, 0xc6, 0xc1, + 0x6b, 0x1a, 0xda, 0xfe, 0x10, 0xcd, 0x0d, 0xa7, 0x56, 0xa0, 0x31, 0x97, + 0xe6, 0xa1, 0xb5, 0x6f, 0x40, 0x1a, 0xcc, 0x01, 0x52, 0xbc, 0x72, 0xfd, + 0x0a, 0x83, 0x8a, 0x2a, 0xea, 0xad, 0xc5, 0x1e, 0x12, 0x56, 0x23, 0x52, + 0xca, 0x35, 0xdb, 0xef, 0x45, 0x8c, 0x31, 0xa3, 0x1f, 0xe2, 0xb5, 0x9c, + 0xfe, 0xb8, 0x44, 0x3a, 0x09, 0xe1, 0x9e, 0x32, 0x2f, 0x7f, 0xac, 0x70, + 0x80, 0xc4, 0xa7, 0x29, 0x02, 0xad, 0xeb, 0xbd, 0x5d, 0x92, 0xbc, 0x85, + 0x6c, 0x10, 0x9b, 0x5f, 0x07, 0xfc, 0x94, 0x4d, 0xff, 0xa6, 0x37, 0x87, + 0x9e, 0x50, 0x33, 0x66, 0x29, 0xfd, 0x51, 0x62, 0x45, 0x5c, 0x45, 0x75, + 0xcd, 0xf1, 0x9b, 0x42, 0x0d, 0xa7, 0xe9, 0x91, 0xd6, 0x7c, 0x23, 0x5b, + 0xa1, 0xe8, 0x7b, 0xaf, 0xba, 0x75, 0x13, 0x24, 0x6e, 0x12, 0xf5, 0x44, + 0x29, 0x75, 0x22, 0xdc, 0xe5, 0xfa, 0xa6, 0x25, 0xa2, 0x76, 0x45, 0xf7, + 0xf9, 0x96, 0x73, 0x22, 0xd1, 0xf1, 0xe8, 0xd5, 0xa3, 0x46, 0x7f, 0x72, + 0x2c, 0x26, 0x61, 0x68, 0x89, 0xc9, 0x0a, 0xc5, 0x20, 0x78, 0x5b, 0xaa, + 0x59, 0x8d, 0x3e, 0x26, 0x75, 0x3b, 0x12, 0xba, 0xae, 0x5a, 0x42, 0x78, + 0x3f, 0xd7, 0xb2, 0x7f, 0x49, 0x68, 0xa3, 0xc8, 0xaa, 0xdb, 0xc4, 0x41, + 0x89, 0x9a, 0x12, 0xa4, 0x1c, 0x87, 0x25, 0x5c, 0x97, 0x33, 0x92, 0xd8, + 0x5f, 0x83, 0x2d, 0x47, 0x71, 0x86, 0x91, 0xbc, 0x36, 0x95, 0xb2, 0x72, + 0x4a, 0x9c, 0x67, 0xad, 0x76, 0x26, 0xda, 0x0b, 0x68, 0x49, 0x04, 0x29, + 0x0a, 0x4a, 0xa4, 0x9a, 0x8f, 0xd9, 0xfb, 0x39, 0xdc, 0x38, 0xa1, 0xf4, + 0x00, 0x6f, 0x6f, 0x9e, 0x99, 0x03, 0x7c, 0x8c, 0xc5, 0x3f, 0xfc, 0x63, + 0x9a, 0x4e, 0xd8, 0x21, 0x05, 0xd2, 0x2d, 0x9e, 0x07, 0xdf, 0xf6, 0x20, + 0xb8, 0xe7, 0xc2, 0x40, 0x49, 0x69, 0x76, 0xf9, 0xff, 0xeb, 0xb8, 0x27, + 0x94, 0x72, 0x37, 0x63, 0x8d, 0x3a, 0x2d, 0x4f, 0x57, 0x11, 0x5f, 0x3c, + 0x62, 0xa5, 0x39, 0x4d, 0x01, 0x3f, 0x58, 0xbf, 0x59, 0xb3, 0xd9, 0xa2, + 0xd7, 0x3a, 0xdd, 0x2a, 0x65, 0x97, 0x9b, 0xa7, 0x6d, 0xc0, 0x6b, 0x4a, + 0x46, 0xfe, 0x55, 0x46, 0x27, 0x75, 0x2c, 0x0a, 0x8b, 0xc4, 0xf9, 0x1e, + 0x20, 0x5a, 0xbf, 0xf7, 0x88, 0x31, 0x00 +}; + +const size_t kOEMPublicCertSize_TEST = sizeof(kOEMPublicCert_TEST); + +// Refer to the following in main modules +const uint32_t kOEMSystemId = kOEMSystemId_TEST; + +const uint8_t* kOEMPrivateKey = kOEMPrivateKey_TEST; +const uint8_t* kOEMPublicCert = kOEMPublicCert_TEST; + +const size_t kOEMPrivateKeySize = kOEMPrivateKeySize_TEST; +const size_t kOEMPublicCertSize = kOEMPublicCertSize_TEST; + +} // namespace #endif // OEM_CERT_H_ diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_auth_mock.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_auth_mock.h index adb8bfe1..0267c2a3 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_auth_mock.h +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_auth_mock.h @@ -8,7 +8,7 @@ #include #include -#include "openssl/rsa.h" +#include #include "OEMCryptoCENC.h" // Needed for enums only. #include "oemcrypto_key_mock.h" @@ -44,7 +44,7 @@ class AuthenticationRoot { return keybox().key_data_length(); } - const uint8_t* const DeviceToken() { + const uint8_t* DeviceToken() { return keybox().key_data(); } diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_mod.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_mod.cpp index 4e37a591..a31e455b 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_mod.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_mod.cpp @@ -34,9 +34,14 @@ // an OEMCryptoResult and returned. // srm_load_version: If this is set, then it will be used as the // new srm version after loading an SRM -- ignoring the contents of the SRM. +// If srm_load_version is -1, then the buffer passed into LoadSRM will be +// parsed. // srm_blacklisted_device_attached: If set to "1", then a // oemcrypto will act as if a blacklisted device is attached -- i.e. // playback will be restricted to the local display only. +// srm_attached_device_id: If nonzero, the id of a blacklisted device. +// If this id is in the revocation list of an SRM file when it is loaded, +// playback will be restricted to the local display only. // security_patch_level: This is the value returned by // OEMCrypto_Security_Patch_Level. If the key control block requires a // higher level, then OEMCrypto_LoadKeys will fail. @@ -72,6 +77,7 @@ #include "oemcrypto_engine_mock.h" #include "oemcrypto_logging.h" #include "properties.h" +#include "string_conversions.h" namespace wvoec_mock { namespace { @@ -126,9 +132,9 @@ class AndroidModifiableCryptoEngine : public CryptoEngine { } while (!feof(file)) { char name[80 + 1]; - int value; - if (fscanf(file, "%80s %d", name, &value)) { - LOGV("Option %s = %d", name, value); + int64_t value; + if (fscanf(file, "%80s %lld", name, &value)) { + LOGD("Option %s = %lld", name, value); options_[std::string(name)] = value; } } @@ -136,17 +142,17 @@ class AndroidModifiableCryptoEngine : public CryptoEngine { InitializeLogging(); } - int GetOption(const std::string &key, int default_value) { + int64_t GetOption(const std::string &key, int64_t default_value) { MaybeReadOptionsFile(); if (options_.find(key) == options_.end() ) { - LOGV("Option %s not set. Using default %d", key.c_str(), default_value); + LOGW("Option %s not set. Using default %lld", key.c_str(), default_value); return default_value; } return options_[key]; } void InitializeLogging() { - int log_level = GetOption("log_level", 3); + int log_level = GetOption("log_level", wvcdm::LOG_DEBUG); int categories = 0; if (GetOption("kLoggingTraceOEMCryptoCalls", 0) > 0) categories |= kLoggingTraceOEMCryptoCalls; @@ -362,6 +368,19 @@ class AndroidModifiableCryptoEngine : public CryptoEngine { } } + // Convert uint24 or uint40 into a uint64. + int64_t unpack_odd_bytes(const uint8_t *buffer, size_t length) { + uint8_t small_buffer[8]; + memset(small_buffer, 0, 8); + if (length > 8) { + LOGE("OEMCrypto Mock: programmer error. unpack %d bytes.", length); + length = 8; + } + size_t offset = 8 - length; + memcpy(small_buffer + offset, buffer, length); + return wvcdm::htonll64(*reinterpret_cast(small_buffer)); + } + OEMCryptoResult load_srm(const uint8_t *buffer, size_t buffer_length) { if (!srm_update_supported()) { LOGE("OEMCrypto mock update not supported, but load_srm called."); @@ -384,29 +403,65 @@ class AndroidModifiableCryptoEngine : public CryptoEngine { srm_loaded_ = true; return OEMCrypto_SUCCESS; } - if (buffer_length < 4) { - LOGE("OEMCrypto mock bad buffer size: %d.", buffer_length); + if (buffer_length < 395) { + LOGE("OEMCrypto mock bad buffer size: %ld < 395.", buffer_length); return OEMCrypto_ERROR_SHORT_BUFFER; } - uint8_t srm_id = buffer[0]; - uint8_t first_nibble = srm_id >> 4; - uint8_t second_nibble = srm_id & 0x0F; + uint8_t srm_id = buffer[0] >> 4; + uint8_t hdcp2_indicator = buffer[0] & 0x0F; uint8_t reserved = buffer[1]; uint16_t version = htons(*reinterpret_cast(&buffer[2])); - if (reserved) + if (reserved) { LOGE("OEMCrypto mock. SRM's second byte nonzero: %02X.", reserved); - if (first_nibble == 8 && second_nibble == 0) { - LOGI("OEMCrypto mock loading HDCP1 SRM. version = %d.", version); - } else if (first_nibble == 9 && second_nibble == 1) { - LOGI("OEMCrypto mock loading HDCP2 SRM. version = %d.", version); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + uint8_t generation = buffer[4]; + if (generation > 1) { + LOGW("OEMCrypto mock. SRM Generation number is %d, but only first gen is parsed.", + generation); + LOGW("If the revoked device is in a a later generation, it will not be recognized."); + } + int64_t length = unpack_odd_bytes(buffer + 5, 3); // 24 bits. + if (length + 5 != buffer_length) { + LOGW("OEMCrypto mock. SRM length is %lld = 0x%llx, but I expected %zd = 0x%zx.", + length, length, buffer_length - 5, buffer_length - 5); + } + int64_t count = 0; + const uint8_t *ids; + if (srm_id == 8 && hdcp2_indicator == 0) { + // https://www.digital-cp.com/sites/default/files/specifications/HDCP%20Specification%20Rev1_4_Secure.pdf + count = buffer[8]; + LOGI("OEMCrypto mock loading HDCP1 SRM. version = %d. count=%lld.", + version, count); + ids = buffer + 9; + if (buffer_length < 9 + count*5) { + LOGE("OEMCrypto mock bad buffer size for count = %lld: %d < %lld.", + count, buffer_length, 12 + count*5); + return OEMCrypto_ERROR_SHORT_BUFFER; + } + } else if (srm_id == 9 && hdcp2_indicator == 1) { + // https://www.digital-cp.com/sites/default/files/specifications/HDCP%20on%20HDMI%20Specification%20Rev2_2_Final1.pdf + count = unpack_odd_bytes(buffer + 8, 2) >> 6; // 10 bits = 2 bytes - 6. + LOGI("OEMCrypto mock loading HDCP2 SRM. version = %d. count=%lld.", + version, count); + ids = buffer + 12; + if (buffer_length < 12 + count*5) { + LOGE("OEMCrypto mock bad buffer size for count: %d < %ld.", + buffer_length, 12 + count*5); + return OEMCrypto_ERROR_SHORT_BUFFER; + } } else { LOGE("OEMCrypto mock bad buffer start: %02X%02X%02X%02X...", buffer[0], buffer[1], buffer[2], buffer[3]); return OEMCrypto_ERROR_INVALID_CONTEXT; } - // Note: we ignore the signature. Use system property srm_load_fail to - // simulate a bad signature. + for(size_t i = 0; i < count; i++) { + int64_t id = unpack_odd_bytes(ids + 5*i, 5); + srm_revocation_list_.push_back(id); + LOGI("OEMCrypto mock SRM revokes device %lld = 0x%llx", id, id); + } srm_loaded_ = true; + srm_version_ = version; return OEMCrypto_SUCCESS; } @@ -421,6 +476,9 @@ class AndroidModifiableCryptoEngine : public CryptoEngine { } bool srm_blacklisted_device_attached() { + if (GetOption("srm_load_version", -1) < 0) { + return scan_revoked_list(); + } static int blacklisted = 0; int new_value = GetOption("srm_blacklisted_device_attached", 0); if (new_value != blacklisted) { @@ -431,6 +489,31 @@ class AndroidModifiableCryptoEngine : public CryptoEngine { return blacklisted > 0; } + bool scan_revoked_list() { + static int64_t old_attached_id = 0; + int64_t attached_id = GetOption("srm_attached_device_id", 0); + bool print_all_ids = false; + if (attached_id != old_attached_id) { + LOGD("OEMCrypto mock -- ID of attached device is %lld = 0x%lld", + attached_id, attached_id); + old_attached_id = attached_id; + print_all_ids = true; + } + for (size_t i = 0; i < srm_revocation_list_.size(); i++) { + if (print_all_ids) { + LOGD("OEMCrypto mock: %d) revoked id %lld = 0x%lld.", i, + srm_revocation_list_[i], srm_revocation_list_[i]); + } + if (srm_revocation_list_[i] == attached_id) { + LOGD("OEMCrypto mock: attached device %lld = 0x%lld is revoked.", + attached_id, attached_id); + return true; + } + } + LOGD("OEMCrypto mock: attached device %lld is not revoked.", attached_id); + return false; + } + virtual void adjust_destination(OEMCrypto_DestBufferDesc *out_description, size_t data_length, uint8_t subsample_flags) { if (out_description->type != OEMCrypto_BufferType_Secure) return; @@ -488,8 +571,10 @@ class AndroidModifiableCryptoEngine : public CryptoEngine { // Current srm version. Before an SRM has been loaded, this will be set from // the system property. int srm_version_; + // List of forbidden/revoked devices. + std::vector srm_revocation_list_; - std::map options_; + std::map options_; std::string options_file_; bool level1_valid_; diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h index 4cc07964..6d6502ea 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h @@ -59,7 +59,7 @@ class CryptoEngine { size_t DeviceRootTokenLength() { return root_of_trust_.DeviceTokenLength(); } - const uint8_t* const DeviceRootToken() { + const uint8_t* DeviceRootToken() { return root_of_trust_.DeviceToken(); } diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp index d888a3f8..b1f099dc 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp @@ -1314,6 +1314,9 @@ extern "C" OEMCryptoResult OEMCrypto_GetHDCPCapability( if (maximum == NULL) return OEMCrypto_ERROR_UNKNOWN_FAILURE; *current = crypto_engine->config_current_hdcp_capability(); *maximum = crypto_engine->config_maximum_hdcp_capability(); + if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { + LOGI("-- current_hdcp=%d, max_hdcp=%d\n", *current, *maximum); + } return OEMCrypto_SUCCESS; } @@ -1602,15 +1605,14 @@ extern "C" OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session, } extern "C" OEMCryptoResult OEMCrypto_DeleteUsageEntry( - OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length, - const uint8_t* message, size_t message_length, const uint8_t* signature, - size_t signature_length) { + OEMCrypto_SESSION, const uint8_t*, size_t, const uint8_t*, size_t, + const uint8_t*, size_t) { // TODO(fredgc): delete this. return OEMCrypto_ERROR_NOT_IMPLEMENTED; } -extern "C" OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst, - size_t pst_length) { +extern "C" OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t*, + size_t) { // TODO(fredgc): delete this. return OEMCrypto_ERROR_NOT_IMPLEMENTED; } @@ -1637,7 +1639,12 @@ extern "C" bool OEMCrypto_IsSRMUpdateSupported() { LOGE("OEMCrypto_IsSRMUpdateSupported: OEMCrypto Not Initialized."); return false; } - return crypto_engine->srm_update_supported(); + bool result = crypto_engine->srm_update_supported(); + if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { + LOGI("-- OEMCryptoResult OEMCrypto_IsSRMUpdateSupported returning %s\n", + result ? "TRUE" : "FALSE"); + } + return result; } extern "C" OEMCryptoResult OEMCrypto_GetCurrentSRMVersion(uint16_t* version) { @@ -1651,7 +1658,13 @@ extern "C" OEMCryptoResult OEMCrypto_GetCurrentSRMVersion(uint16_t* version) { if (crypto_engine->config_local_display_only()) { return OEMCrypto_LOCAL_DISPLAY_ONLY; } - return crypto_engine->current_srm_version(version); + OEMCryptoResult result = crypto_engine->current_srm_version(version); + if (result == OEMCrypto_SUCCESS && + LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { + LOGI("-- OEMCryptoResult OEMCrypto_GetCurrentSRMVersion returning %d\n", + *version); + } + return result; } extern "C" OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_rsa_key_shared.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_rsa_key_shared.cpp index e5b07118..ff65577f 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_rsa_key_shared.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_rsa_key_shared.cpp @@ -48,8 +48,12 @@ bool RSA_shared_ptr::LoadPkcs8RsaKey(const uint8_t* buffer, size_t length) { bool success = true; PKCS8_PRIV_KEY_INFO* pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL); if (pkcs8_pki == NULL) { - LOGE("[LoadPkcs8RsaKey(): d2i_PKCS8_PRIV_KEY_INFO_bio returned NULL]"); - success = false; + BIO_reset(bio); + pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL); + if (pkcs8_pki == NULL) { + LOGE("[LoadPkcs8RsaKey(): d2i_PKCS8_PRIV_KEY_INFO_bio returned NULL]"); + success = false; + } } EVP_PKEY* evp = NULL; if (success) { diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_session.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_session.cpp index f8951f60..705935aa 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_session.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_session.cpp @@ -192,14 +192,9 @@ bool SessionContext::GenerateSignature(const uint8_t* message, return false; } - const uint8_t *mac_key = NULL; - if (mac_key_client_.size() == wvcdm::MAC_KEY_SIZE) { - // If we have a mac key, use it. - mac_key = &mac_key_client_[0]; - } else if (usage_entry_status_ == kUsageEntryLoaded) { - // If not, but we have a usage entry, use its key. - mac_key = usage_entry_->mac_key_client(); - } else { + if (mac_key_client_.empty() || + mac_key_client_.size() != wvcdm::MAC_KEY_SIZE) { + LOGE("[GenerateSignature(): No MAC Key]"); return false; } @@ -209,7 +204,7 @@ bool SessionContext::GenerateSignature(const uint8_t* message, } unsigned int md_len = *signature_length; - if (HMAC(EVP_sha256(), mac_key, wvcdm::MAC_KEY_SIZE, message, + if (HMAC(EVP_sha256(), &mac_key_client_[0], mac_key_client_.size(), message, message_length, signature, &md_len)) { *signature_length = md_len; return true; @@ -426,6 +421,8 @@ OEMCryptoResult SessionContext::LoadKeys( LOGW("[LoadKeys: SRM blacklisted device attached]"); srm_requirements_status_ = InvalidSRMVersion; } else { + LOGI("[LoadKeys: SRM Versions is %d, required: %d]", + current_version, minimum_version); srm_requirements_status_ = ValidSRMVersion; } } @@ -736,7 +733,7 @@ bool SessionContext::LoadRSAKey(const uint8_t* pkcs8_rsa_key, return false; } if ((memcmp(pkcs8_rsa_key, "SIGN", 4) == 0)) { - uint32_t* schemes_n = (uint32_t*)(pkcs8_rsa_key + 4); + const uint32_t* schemes_n = (const uint32_t*)(pkcs8_rsa_key + 4); allowed_schemes_ = htonl(*schemes_n); pkcs8_rsa_key += 8; rsa_key_length -= 8; diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.h index 51d21320..0afc00c9 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.h +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.h @@ -69,8 +69,6 @@ class UsageTableEntry { void set_index(int32_t index) { data_.index = index; } uint32_t index() { return data_.index; } static size_t SignedEntrySize(); - const uint8_t* mac_key_server() { return data_.mac_key_server; } - const uint8_t* mac_key_client() { return data_.mac_key_client; } private: UsageTable* usage_table_; // Owner of this object. @@ -81,11 +79,8 @@ class UsageTableEntry { class UsageTable { public: - UsageTable(CryptoEngine* ce, wvcdm::FileSystem* /* file_system */) - : ce_(ce), - /* TODO: unused: file_system_(file_system), */ - header_loaded_(false), - old_table_(NULL){}; + explicit UsageTable(CryptoEngine* ce) + : ce_(ce), header_loaded_(false), old_table_(NULL){}; ~UsageTable(); OEMCryptoResult CreateNewUsageEntry(SessionContext* session, @@ -128,7 +123,6 @@ class UsageTable { bool LoadGenerationNumber(bool or_make_new_one); CryptoEngine* ce_; - /* TODO: unused: wvcdm::FileSystem* file_system_; */ bool header_loaded_; int64_t master_generation_number_; std::vector generation_numbers_; diff --git a/libwvdrmengine/oemcrypto/test/Android.mk b/libwvdrmengine/oemcrypto/test/Android.mk index 5b9a1d1b..2f78507d 100644 --- a/libwvdrmengine/oemcrypto/test/Android.mk +++ b/libwvdrmengine/oemcrypto/test/Android.mk @@ -6,10 +6,8 @@ LOCAL_MODULE:=oemcrypto_test LOCAL_MODULE_TAGS := tests LOCAL_MODULE_OWNER := widevine -LOCAL_PROPRIETARY_MODULE := true -# When built, explicitly put it in the DATA/bin directory. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/bin +LOCAL_PROPRIETARY_MODULE := true ifneq ($(TARGET_ENABLE_MEDIADRM_64), true) LOCAL_MODULE_TARGET_ARCH := arm x86 mips diff --git a/libwvdrmengine/oemcrypto/test/common.mk b/libwvdrmengine/oemcrypto/test/common.mk index 74be3313..162b9b04 100644 --- a/libwvdrmengine/oemcrypto/test/common.mk +++ b/libwvdrmengine/oemcrypto/test/common.mk @@ -16,7 +16,6 @@ LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/../include \ $(LOCAL_PATH)/../mock/src \ vendor/widevine/libwvdrmengine/cdm/core/include \ - vendor/widevine/libwvdrmengine/third_party/stringencoders/src \ LOCAL_STATIC_LIBRARIES := \ libcdm \ @@ -31,7 +30,7 @@ LOCAL_SHARED_LIBRARIES := \ libcutils \ libdl \ liblog \ - libmedia_omx \ + libmedia \ libstagefright_foundation \ libutils \ libz \ diff --git a/libwvdrmengine/oemcrypto/test/oec_device_features.cpp b/libwvdrmengine/oemcrypto/test/oec_device_features.cpp index 84444760..4d02b4d8 100644 --- a/libwvdrmengine/oemcrypto/test/oec_device_features.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_device_features.cpp @@ -218,6 +218,8 @@ const char* ProvisioningMethodName(OEMCrypto_ProvisioningMethod method) { case OEMCrypto_OEMCertificate: return "OEMCrypto_OEMCertificate"; } + // Not reachable + return ""; } } // namespace wvoec diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp index 927d6a80..a81071b9 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp @@ -589,35 +589,45 @@ void Session::LoadOEMCert(bool verify_cert) { openssl_ptr bio( BIO_new_mem_buf(&public_cert[0], public_cert_length)); ASSERT_TRUE(bio.NotNull()); - openssl_ptr cert( - PEM_read_bio_X509(bio.get(), NULL, 0, NULL)); + openssl_ptr cert( + d2i_PKCS7_bio(bio.get(), NULL)); ASSERT_TRUE(cert.NotNull()); - openssl_ptr pubkey(X509_get_pubkey(cert.get())); - ASSERT_TRUE(pubkey.NotNull()); - public_rsa_ = EVP_PKEY_get1_RSA(pubkey.get()); - if (!public_rsa_) { - cout << "d2i_RSAPrivateKey failed.\n"; - dump_openssl_error(); - ASSERT_TRUE(NULL != public_rsa_); - } - if (verify_cert) { - vector buffer(80); - X509_NAME* name = X509_get_subject_name(cert.get()); - printf(" OEM Certificate Name: %s\n", - X509_NAME_oneline(name, &buffer[0], buffer.size())); - openssl_ptr store(X509_STORE_new()); - ASSERT_TRUE(store.NotNull()); - openssl_ptr store_ctx( - X509_STORE_CTX_new()); - ASSERT_TRUE(store_ctx.NotNull()); - X509_STORE_CTX_init(store_ctx.get(), store.get(), cert.get(), NULL); - // TODO(fredgc): Verify cert is signed by Google. - int result = X509_verify_cert(store_ctx.get()); - ASSERT_GE(0, result) << " OEM Cert not valid. " - << X509_verify_cert_error_string(store_ctx->error); - if (result == 0) { - printf("Cert not verified: %s.\n", - X509_verify_cert_error_string(store_ctx->error)); + + EXPECT_EQ(OBJ_obj2nid(cert->type), NID_pkcs7_signed); + STACK_OF(X509)* certs = cert->d.sign->cert; + for (int i = 0; certs && i < sk_X509_num(certs); i++) { + X509* x509_cert = sk_X509_value(certs, i); + openssl_ptr pubkey(X509_get_pubkey(x509_cert)); + ASSERT_TRUE(pubkey.NotNull()); + if (i == 0) { + public_rsa_ = EVP_PKEY_get1_RSA(pubkey.get()); + if (!public_rsa_) { + cout << "d2i_RSAPrivateKey failed.\n"; + dump_openssl_error(); + ASSERT_TRUE(NULL != public_rsa_); + } + } + if (verify_cert) { + vector buffer(80); + + X509_NAME* name = X509_get_subject_name(x509_cert); + printf(" OEM Certificate Name: %s\n", + X509_NAME_oneline(name, &buffer[0], buffer.size())); + openssl_ptr store(X509_STORE_new()); + ASSERT_TRUE(store.NotNull()); + openssl_ptr store_ctx( + X509_STORE_CTX_new()); + ASSERT_TRUE(store_ctx.NotNull()); + + X509_STORE_CTX_init(store_ctx.get(), store.get(), x509_cert, NULL); + // TODO(fredgc): Verify cert is signed by Google. + int result = X509_verify_cert(store_ctx.get()); + ASSERT_GE(0, result) << " OEM Cert not valid. " + << X509_verify_cert_error_string(store_ctx->error); + if (result == 0) { + printf("Cert not verified: %s.\n", + X509_verify_cert_error_string(store_ctx->error)); + } } } } @@ -673,6 +683,7 @@ void Session::RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted, wrapped_key->clear(); } } + void Session::RewrapRSAKey30(const struct RSAPrivateKeyMessage& encrypted, const std::vector& encrypted_message_key, vector* wrapped_key, bool force) { @@ -786,9 +797,11 @@ void Session::VerifyRSASignature(const vector& message, RSA_Padding_Scheme padding_scheme) { EXPECT_TRUE(NULL != public_rsa_) << "No public RSA key loaded in test code.\n"; + EXPECT_EQ(static_cast(RSA_size(public_rsa_)), signature_length) << "Signature size is wrong. " << signature_length << ", should be " << RSA_size(public_rsa_) << "\n"; + if (padding_scheme == kSign_RSASSA_PSS) { openssl_ptr pkey(EVP_PKEY_new()); ASSERT_EQ(1, EVP_PKEY_set1_RSA(pkey.get(), public_rsa_)); @@ -927,9 +940,6 @@ void Session::GenerateReport(const std::string& pst, EXPECT_GE(kHardwareSecureClock, pst_report().clock_security_level()); EXPECT_EQ(pst.length(), pst_report().pst_length()); EXPECT_EQ(0, memcmp(pst.c_str(), pst_report().pst(), pst.length())); - // Also, we the session to be able to sign the release message with the - // correct mac keys from the usage table entry. - ASSERT_NO_FATAL_FAILURE(VerifyClientSignature()); } void Session::VerifyPST(const Test_PST_Report& expected) { diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.h b/libwvdrmengine/oemcrypto/test/oec_session_util.h index e7c992e7..7895d4e3 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.h +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.h @@ -18,7 +18,9 @@ using namespace std; // GTest requires PrintTo to be in the same namespace as the thing it prints, // which is std::vector in this case. namespace std { + void PrintTo(const vector& value, ostream* os); + } // namespace std namespace wvoec { @@ -293,8 +295,7 @@ class Session { wvcdm::Unpacked_PST_Report pst_report() { return wvcdm::Unpacked_PST_Report(&pst_report_buffer_[0]); } - // Verify the values in the PST report. The signature should have been - // verified in GenerateReport, above. + // Verify the PST report. void VerifyPST(const Test_PST_Report& report); // Generate and Verify the Usage Report. If any time is greater than 10 // minutes, it is assumed to be an absolute time, and time_since will be diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index 70a83e98..2e09667c 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -590,7 +590,6 @@ TEST_F(OEMCryptoProv30Test, OEMCertSignatureLargeBuffer) { ASSERT_NO_FATAL_FAILURE(s.LoadOEMCert()); OEMCryptoResult sts; // Sign a Message - static size_t kMaxMessageSize = 8 * 1024; vector data(kMaxMessageSize); RAND_pseudo_bytes(&data[0], data.size()); size_t signature_length = 0; @@ -1198,7 +1197,7 @@ TEST_P(SessionTestAlternateVerification, LoadKeys) { if (target_api_ > 8 && target_api_ < 100) { snprintf(buffer, 5, "kc%02d", target_api_); } - for (size_t i = 0; i < s.num_keys(); i++) { + for (unsigned int i = 0; i < s.num_keys(); i++) { memcpy(s.license().keys[i].control.verification, buffer, 4); } ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); @@ -1332,19 +1331,21 @@ TEST_F(OEMCryptoSessionTests, AntiRollbackHardwareRequired) { TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) { uint8_t patch_level = OEMCrypto_Security_Patch_Level(); printf(" Current Patch Level: %u.\n", patch_level); - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); - ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage( - 0, patch_level << wvoec_mock::kControlSecurityPatchLevelShift, 0)); - ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), - &s.signature()[0], s.signature().size(), - s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), - s.key_array(), NULL, 0, NULL)); + { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); + ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage( + 0, patch_level << wvoec_mock::kControlSecurityPatchLevelShift, 0)); + ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); + ASSERT_EQ( + OEMCrypto_SUCCESS, + OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), + &s.signature()[0], s.signature().size(), + s.encrypted_license().mac_key_iv, + s.encrypted_license().mac_keys, s.num_keys(), + s.key_array(), NULL, 0, NULL)); + } if (patch_level < 0x3F) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); @@ -4373,7 +4374,7 @@ class GenericCryptoKeyIdLengthTest : public GenericCryptoTest { } } - void TestWithKey(unsigned int key_index) { + void TestWithKey(int key_index) { ASSERT_LT(key_index, session_.num_keys()); EncryptAndLoadKeys(); vector encrypted; diff --git a/libwvdrmengine/run_all_unit_tests.sh b/libwvdrmengine/run_all_unit_tests.sh index 2b022643..bb23ff2f 100755 --- a/libwvdrmengine/run_all_unit_tests.sh +++ b/libwvdrmengine/run_all_unit_tests.sh @@ -19,12 +19,10 @@ fi adb_shell_run() { local test_file=$1 shift - if adb shell ls /data/bin/$test_file &> /dev/null; then - test_file=/data/bin/$test_file + if adb shell ls /data/widevine_tests/$test_file &> /dev/null; then + test_file=/data/widevine_tests/$test_file else - echo "Please install the test on the device in /data/bin, " - echo "or begin execution by running ./build_and_run_all_unit_tests.sh" - exit 1 + test_file=/vendor/bin/$test_file fi echo $test_file local tmp_log="$OUT/mediadrmtest.log" @@ -51,7 +49,7 @@ if [ -z "$ANDROID_BUILD_TOP" ]; then fi echo "waiting for device" -ADB_OUTPUT=`adb root && echo ". " && adb wait-for-device remount` +ADB_OUTPUT=`adb root && adb wait-for-device remount` echo $ADB_OUTPUT if echo $ADB_OUTPUT | grep -qi "verity"; then echo @@ -64,47 +62,31 @@ fi # Disable DroidGuard to prevent provisioning collisions set_droidguard disable -# Run oemcrypto tests first due to historical test order issues adb_shell_run oemcrypto_test \ GTEST_FILTER="$GTEST_FILTER:*Level1Required" FORCE_LEVEL3_OEMCRYPTO=yes adb_shell_run oemcrypto_test - -# Run request_license_test next to ensure device is provisioned adb_shell_run request_license_test - # cdm_extended_duration_test takes >30 minutes to run. # adb_shell_run cdm_extended_duration_test - -# cdm_feature_test to be run with modified/mock oemcrypto -# adb_shell_run cdm_feature_test - -# Additional tests -adb_shell_run base64_test -adb_shell_run buffer_reader_test +adb_shell_run policy_engine_unittest +adb_shell_run policy_engine_constraints_unittest +adb_shell_run libwvdrmmediacrypto_test +adb_shell_run libwvdrmmediacrypto_hidl_test +adb_shell_run libwvdrmdrmplugin_test +adb_shell_run libwvdrmdrmplugin_hidl_test adb_shell_run cdm_engine_test adb_shell_run cdm_session_unittest -adb_shell_run counter_metric_unittest -adb_shell_run crypto_session_unittest -adb_shell_run device_files_unittest -adb_shell_run distribution_unittest -adb_shell_run event_metric_unittest adb_shell_run file_store_unittest adb_shell_run file_utils_unittest -adb_shell_run http_socket_test -adb_shell_run initialization_data_unittest -adb_shell_run libwvdrmdrmplugin_hidl_test -adb_shell_run libwvdrmdrmplugin_test -adb_shell_run libwvdrmmediacrypto_hidl_test -adb_shell_run libwvdrmmediacrypto_test -adb_shell_run license_keys_unittest adb_shell_run license_unittest -adb_shell_run policy_engine_constraints_unittest -adb_shell_run policy_engine_unittest +adb_shell_run license_keys_unittest +adb_shell_run initialization_data_unittest +adb_shell_run device_files_unittest adb_shell_run service_certificate_unittest adb_shell_run timer_unittest -adb_shell_run usage_table_header_unittest -adb_shell_run value_metric_unittest -adb_shell_run wv_cdm_metrics_test +adb_shell_run buffer_reader_test +adb_shell_run distribution_test +adb_shell_run event_metric_test # Run the non-Treble test on non-Treble devices if adb shell ls /vendor/lib/mediadrm/libwvdrmengine.so &> /dev/null || diff --git a/libwvdrmengine/test/castv2/Android.mk b/libwvdrmengine/test/castv2/Android.mk index 1b2b54b3..8b255b06 100644 --- a/libwvdrmengine/test/castv2/Android.mk +++ b/libwvdrmengine/test/castv2/Android.mk @@ -3,9 +3,6 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional -# When built, explicitly put it in the data/app partition. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - LOCAL_CERTIFICATE := platform LOCAL_SRC_FILES := $(call all-java-files-under, src) diff --git a/libwvdrmengine/test/castv2/AndroidManifest.xml b/libwvdrmengine/test/castv2/AndroidManifest.xml index f4fa5112..67d6dec4 100644 --- a/libwvdrmengine/test/castv2/AndroidManifest.xml +++ b/libwvdrmengine/test/castv2/AndroidManifest.xml @@ -11,7 +11,6 @@ - diff --git a/libwvdrmengine/test/java/Android.mk b/libwvdrmengine/test/java/Android.mk index 93bdadcd..f3795525 100644 --- a/libwvdrmengine/test/java/Android.mk +++ b/libwvdrmengine/test/java/Android.mk @@ -11,9 +11,6 @@ LOCAL_JAVA_LIBRARIES := org.apache.http.legacy LOCAL_DEX_PREOPT := false -# When built, explicitly put it in the data/app partition. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - # TODO: This test app depends on framework implementation details. # LOCAL_SDK_VERSION := current diff --git a/libwvdrmengine/test/java/AndroidManifest.xml b/libwvdrmengine/test/java/AndroidManifest.xml index a8f94fce..eff32480 100644 --- a/libwvdrmengine/test/java/AndroidManifest.xml +++ b/libwvdrmengine/test/java/AndroidManifest.xml @@ -7,7 +7,6 @@ - diff --git a/libwvdrmengine/test/unit/Android.mk b/libwvdrmengine/test/unit/Android.mk index fced9690..439c8857 100644 --- a/libwvdrmengine/test/unit/Android.mk +++ b/libwvdrmengine/test/unit/Android.mk @@ -18,7 +18,7 @@ LOCAL_C_INCLUDES := \ vendor/widevine/libwvdrmengine/oemcrypto/include \ LOCAL_STATIC_LIBRARIES := \ - libcrypto \ + libcrypto_static \ libgtest \ libgtest_main \ @@ -33,10 +33,8 @@ LOCAL_MODULE := libwvdrmengine_test LOCAL_MODULE_TAGS := tests LOCAL_MODULE_OWNER := widevine -LOCAL_PROPRIETARY_MODULE := true -# When built, explicitly put it in the DATA/bin directory. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/bin +LOCAL_PROPRIETARY_MODULE := true ifneq ($(TARGET_ENABLE_MEDIADRM_64), true) LOCAL_MODULE_TARGET_ARCH := arm x86 mips @@ -64,7 +62,7 @@ LOCAL_C_INCLUDES := \ vendor/widevine/libwvdrmengine/oemcrypto/include \ LOCAL_STATIC_LIBRARIES := \ - libcrypto \ + libcrypto_static \ libgtest \ libgtest_main \ @@ -83,10 +81,8 @@ LOCAL_MODULE := libwvdrmengine_hidl_test LOCAL_MODULE_TAGS := tests LOCAL_MODULE_OWNER := widevine -LOCAL_PROPRIETARY_MODULE := true -# When built, explicitly put it in the DATA/bin directory. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/bin +LOCAL_PROPRIETARY_MODULE := true ifneq ($(TARGET_ENABLE_MEDIADRM_64), true) LOCAL_MODULE_TARGET_ARCH := arm x86 mips diff --git a/libwvdrmengine/test/unit/legacy_src/WVCreatePluginFactories_test.cpp b/libwvdrmengine/test/unit/legacy_src/WVCreatePluginFactories_test.cpp index 7b9fec2a..391e119f 100644 --- a/libwvdrmengine/test/unit/legacy_src/WVCreatePluginFactories_test.cpp +++ b/libwvdrmengine/test/unit/legacy_src/WVCreatePluginFactories_test.cpp @@ -3,21 +3,20 @@ // #include "gtest/gtest.h" +#include #include "WVCreatePluginFactories.h" -#include - using namespace android; TEST(CreatePluginFactoriesTest, CreatesDrmFactory) { - std::unique_ptr factory(createDrmFactory()); + UniquePtr factory(createDrmFactory()); EXPECT_NE((DrmFactory*)NULL, factory.get()) << "createDrmFactory() returned null"; } TEST(CreatePluginFactoriesTest, CreatesCryptoFactory) { - std::unique_ptr factory(createCryptoFactory()); + UniquePtr factory(createCryptoFactory()); EXPECT_NE((CryptoFactory*)NULL, factory.get()) << "createCryptoFactory() returned null"; diff --git a/libwvdrmengine/test/unit/legacy_src/WVCryptoFactory_test.cpp b/libwvdrmengine/test/unit/legacy_src/WVCryptoFactory_test.cpp index bee0b7f6..987a7586 100644 --- a/libwvdrmengine/test/unit/legacy_src/WVCryptoFactory_test.cpp +++ b/libwvdrmengine/test/unit/legacy_src/WVCryptoFactory_test.cpp @@ -2,11 +2,11 @@ * Copyright 2012 Google Inc. All Rights Reserved. */ +#include + #include "gtest/gtest.h" #include "WVCryptoFactory.h" -#include - using namespace wvdrm; const uint8_t kWidevineUUID[16] = { @@ -25,7 +25,7 @@ const uint8_t kUnknownUUID[16] = { }; TEST(WVCryptoFactoryTest, SupportsSupportedCryptoSchemes) { - std::unique_ptr factory(new WVCryptoFactory()); + UniquePtr factory(new WVCryptoFactory()); EXPECT_TRUE(factory->isCryptoSchemeSupported(kWidevineUUID)) << "WVPluginFactory does not support Widevine's UUID"; @@ -35,7 +35,7 @@ TEST(WVCryptoFactoryTest, SupportsSupportedCryptoSchemes) { } TEST(WVCryptoFactoryTest, DoesNotSupportUnsupportedCryptoSchemes) { - std::unique_ptr factory(new WVCryptoFactory()); + UniquePtr factory(new WVCryptoFactory()); EXPECT_FALSE(factory->isCryptoSchemeSupported(kUnknownUUID)) << "WVPluginFactory incorrectly claims to support an unknown UUID"; diff --git a/libwvdrmengine/test/unit/legacy_src/WVDrmFactory_test.cpp b/libwvdrmengine/test/unit/legacy_src/WVDrmFactory_test.cpp index 711960a5..a920358f 100644 --- a/libwvdrmengine/test/unit/legacy_src/WVDrmFactory_test.cpp +++ b/libwvdrmengine/test/unit/legacy_src/WVDrmFactory_test.cpp @@ -3,6 +3,7 @@ */ #include "gtest/gtest.h" +#include #include "WVDrmFactory.h" using namespace wvdrm; diff --git a/libwvdrmengine/third_party/stringencoders/LICENSE b/libwvdrmengine/third_party/stringencoders/LICENSE index b30c35ad..d03c4b21 100644 --- a/libwvdrmengine/third_party/stringencoders/LICENSE +++ b/libwvdrmengine/third_party/stringencoders/LICENSE @@ -1,36 +1,22 @@ -MODP_B64 - High performance base64 encoder/decoder -https://github.com/client9/stringencoders +The MIT License (MIT) -Copyright 2005, 2006, 2007, 2016 -Nick Galbreath -- nickg [at] client9 [dot] com -All rights reserved. +Copyright (c) 2016 Nick Galbreath -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. - Neither the name of the client9.com nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This is the standard "new" BSD license: -http://www.opensource.org/licenses/bsd-license.php diff --git a/libwvdrmengine/third_party/stringencoders/src/config.h b/libwvdrmengine/third_party/stringencoders/src/config.h index 48630b0f..e69de29b 100644 --- a/libwvdrmengine/third_party/stringencoders/src/config.h +++ b/libwvdrmengine/third_party/stringencoders/src/config.h @@ -1 +0,0 @@ -// dummy diff --git a/libwvdrmengine/third_party/stringencoders/src/modp_b64.cpp b/libwvdrmengine/third_party/stringencoders/src/modp_b64.cpp index 18e8293a..41ed1881 100644 --- a/libwvdrmengine/third_party/stringencoders/src/modp_b64.cpp +++ b/libwvdrmengine/third_party/stringencoders/src/modp_b64.cpp @@ -1,43 +1,12 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set expandtab shiftwidth=4 tabstop=4: */ /** * \file modp_b64.c *
  * MODP_B64 - High performance base64 encoder/decoder
  * https://github.com/client9/stringencoders
  *
- * Copyright © 2005, 2006, 2007  Nick Galbreath
+ * Copyright © 2005-2016 Nick Galbreath
  * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- *   Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- *   Neither the name of the modp.com nor the names of its
- *   contributors may be used to endorse or promote products derived from
- *   this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This is the standard "new" BSD license:
- * http://www.opensource.org/licenses/bsd-license.php
+ * Released under MIT license. See LICENSE for details.
  * 
*/ @@ -50,7 +19,7 @@ /* public header */ #include "modp_b64.h" -/* if on motoral, sun, ibm; uncomment this */ +/* if on motorola, sun, ibm; uncomment this */ /* #define WORDS_BIGENDIAN 1 */ /* else for Intel, Amd; uncomment this */ /* #undef WORDS_BIGENDIAN */ @@ -62,7 +31,7 @@ /** * you can control if we use padding by commenting out this * next line. However, I highly recommend you use padding and not - * using it should only be for compatability with a 3rd party. + * using it should only be for compatibility with a 3rd party. * Also, 'no padding' is not tested! */ #define DOPAD 1 @@ -79,8 +48,8 @@ size_t modp_b64_encode(char* dest, const char* str, size_t len) { size_t i = 0; - const uint8_t* s = (const uint8_t*) str; - uint8_t* p = (uint8_t*) dest; + const uint8_t* s = (const uint8_t*)str; + uint8_t* p = (uint8_t*)dest; /* unsigned here is important! */ /* uint8_t is fastest on G4, amd */ @@ -89,7 +58,9 @@ size_t modp_b64_encode(char* dest, const char* str, size_t len) if (len > 2) { for (i = 0; i < len - 2; i += 3) { - t1 = s[i]; t2 = s[i+1]; t3 = s[i+2]; + t1 = s[i]; + t2 = s[i + 1]; + t3 = s[i + 2]; *p++ = e0[t1]; *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; *p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)]; @@ -108,7 +79,8 @@ size_t modp_b64_encode(char* dest, const char* str, size_t len) *p++ = CHARPAD; break; default: /* case 2 */ - t1 = s[i]; t2 = s[i+1]; + t1 = s[i]; + t2 = s[i + 1]; *p++ = e0[t1]; *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; *p++ = e2[(t2 & 0x0F) << 2]; @@ -119,38 +91,40 @@ size_t modp_b64_encode(char* dest, const char* str, size_t len) return (size_t)(p - (uint8_t*)dest); } -#ifdef WORDS_BIGENDIAN /* BIG ENDIAN -- SUN / IBM / MOTOROLA */ +#ifdef WORDS_BIGENDIAN /* BIG ENDIAN -- SUN / IBM / MOTOROLA */ size_t modp_b64_decode(char* dest, const char* src, size_t len) { size_t i; - if (len == 0) return 0; + if (len == 0) + return 0; #ifdef DOPAD /* if padding is used, then the message must be at least 4 chars and be a multiple of 4. there can be at most 2 pad chars at the end */ - if (len < 4 || (len % 4 != 0)) return -1; - if (src[len-1] == CHARPAD) { + if (len < 4 || (len % 4 != 0)) + return -1; + if (src[len - 1] == CHARPAD) { len--; - if (src[len -1] == CHARPAD) { + if (src[len - 1] == CHARPAD) { len--; } } -#endif /* DOPAD */ +#endif /* DOPAD */ size_t leftover = len % 4; - size_t chunks = (leftover == 0) ? len / 4 - 1 : len /4; + size_t chunks = (leftover == 0) ? len / 4 - 1 : len / 4; - uint8_t* p = (uint8_t*) dest; + uint8_t* p = (uint8_t*)dest; uint32_t x = 0; - uint32_t* destInt = (uint32_t*) p; - uint32_t* srcInt = (uint32_t*) src; + uint32_t* destInt = (uint32_t*)p; + uint32_t* srcInt = (uint32_t*)src; uint32_t y = *srcInt++; for (i = 0; i < chunks; ++i) { - x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | - d2[y >> 8 & 0xff] | d3[y & 0xff]; + x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | d2[y >> 8 & 0xff] | d3[y & 0xff]; - if (x >= BADCHAR) return -1; + if (x >= BADCHAR) + return -1; *destInt = x << 8; p += 3; destInt = (uint32_t*)p; @@ -159,33 +133,33 @@ size_t modp_b64_decode(char* dest, const char* src, size_t len) switch (leftover) { case 0: - x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | - d2[y >> 8 & 0xff] | d3[y & 0xff]; - if (x >= BADCHAR) return -1; + x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | d2[y >> 8 & 0xff] | d3[y & 0xff]; + if (x >= BADCHAR) + return -1; *p++ = ((uint8_t*)&x)[1]; *p++ = ((uint8_t*)&x)[2]; *p = ((uint8_t*)&x)[3]; - return (chunks+1)*3; + return (chunks + 1) * 3; #ifndef DOPAD - case 1: /* with padding this is an impossible case */ + case 1: /* with padding this is an impossible case */ x = d3[y >> 24]; - *p = (uint8_t)x; + *p = (uint8_t)x; break; #endif case 2: - x = d3[y >> 24] *64 + d3[(y >> 16) & 0xff]; - *p = (uint8_t)(x >> 4); + x = d3[y >> 24] * 64 + d3[(y >> 16) & 0xff]; + *p = (uint8_t)(x >> 4); break; - default: /* case 3 */ - x = (d3[y >> 24] *64 + d3[(y >> 16) & 0xff])*64 + - d3[(y >> 8) & 0xff]; - *p++ = (uint8_t) (x >> 10); - *p = (uint8_t) (x >> 2); + default: /* case 3 */ + x = (d3[y >> 24] * 64 + d3[(y >> 16) & 0xff]) * 64 + d3[(y >> 8) & 0xff]; + *p++ = (uint8_t)(x >> 10); + *p = (uint8_t)(x >> 2); break; } - if (x >= BADCHAR) return -1; - return 3*chunks + (6*leftover)/8; + if (x >= BADCHAR) + return -1; + return 3 * chunks + (6 * leftover) / 8; } #else /* LITTLE ENDIAN -- INTEL AND FRIENDS */ @@ -199,10 +173,11 @@ size_t modp_b64_decode(char* dest, const char* src, size_t len) uint8_t* p; uint32_t x; uint32_t* destInt; - const uint32_t* srcInt = (const uint32_t*) src; + const uint32_t* srcInt = (const uint32_t*)src; uint32_t y = *srcInt++; - if (len == 0) return 0; + if (len == 0) + return 0; #ifdef DOPAD /* @@ -213,53 +188,47 @@ size_t modp_b64_decode(char* dest, const char* src, size_t len) return (size_t)-1; /* error */ } /* there can be at most 2 pad chars at the end */ - if (src[len-1] == CHARPAD) { + if (src[len - 1] == CHARPAD) { len--; - if (src[len -1] == CHARPAD) { + if (src[len - 1] == CHARPAD) { len--; } } #endif leftover = len % 4; - chunks = (leftover == 0) ? len / 4 - 1 : len /4; + chunks = (leftover == 0) ? len / 4 - 1 : len / 4; - p = (uint8_t*) dest; + p = (uint8_t*)dest; x = 0; - destInt = (uint32_t*) p; - srcInt = (const uint32_t*) src; + destInt = (uint32_t*)p; + srcInt = (const uint32_t*)src; y = *srcInt++; for (i = 0; i < chunks; ++i) { - x = d0[y & 0xff] | - d1[(y >> 8) & 0xff] | - d2[(y >> 16) & 0xff] | - d3[(y >> 24) & 0xff]; + x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff]; if (x >= BADCHAR) { return (size_t)-1; } - *destInt = x ; + *destInt = x; p += 3; destInt = (uint32_t*)p; - y = *srcInt++;} - + y = *srcInt++; + } switch (leftover) { case 0: - x = d0[y & 0xff] | - d1[(y >> 8) & 0xff] | - d2[(y >> 16) & 0xff] | - d3[(y >> 24) & 0xff]; + x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff]; if (x >= BADCHAR) { return (size_t)-1; } - *p++ = ((uint8_t*)(&x))[0]; - *p++ = ((uint8_t*)(&x))[1]; - *p = ((uint8_t*)(&x))[2]; - return (chunks+1)*3; + *p++ = ((uint8_t*)(&x))[0]; + *p++ = ((uint8_t*)(&x))[1]; + *p = ((uint8_t*)(&x))[2]; + return (chunks + 1) * 3; #ifndef DOPAD - case 1: /* with padding this is an impossible case */ + case 1: /* with padding this is an impossible case */ x = d0[y & 0xff]; *p = *((uint8_t*)(&x)); /* i.e. first char/byte in int */ break; @@ -269,11 +238,9 @@ size_t modp_b64_decode(char* dest, const char* src, size_t len) *p = *((uint8_t*)(&x)); /* i.e. first char */ break; default: /* case 3, 2 output bytes */ - x = d0[y & 0xff] | - d1[y >> 8 & 0xff ] | - d2[y >> 16 & 0xff]; /* 0x3c */ - *p++ = ((uint8_t*)(&x))[0]; - *p = ((uint8_t*)(&x))[1]; + x = d0[y & 0xff] | d1[y >> 8 & 0xff] | d2[y >> 16 & 0xff]; /* 0x3c */ + *p++ = ((uint8_t*)(&x))[0]; + *p = ((uint8_t*)(&x))[1]; break; } @@ -281,7 +248,7 @@ size_t modp_b64_decode(char* dest, const char* src, size_t len) return (size_t)-1; } - return 3*chunks + (6*leftover)/8; + return 3 * chunks + (6 * leftover) / 8; } -#endif /* if bigendian / else / endif */ +#endif /* if bigendian / else / endif */ diff --git a/libwvdrmengine/third_party/stringencoders/src/modp_b64.h b/libwvdrmengine/third_party/stringencoders/src/modp_b64.h index 9545adbd..3e03ac5e 100644 --- a/libwvdrmengine/third_party/stringencoders/src/modp_b64.h +++ b/libwvdrmengine/third_party/stringencoders/src/modp_b64.h @@ -1,6 +1,3 @@ -/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set expandtab shiftwidth=4 tabstop=4: */ - /** * \file modp_b64.h * \brief High performance base 64 encode and decode @@ -12,23 +9,29 @@ *
  * High performance base64 encoder / decoder
  *
- * Copyright © 2005, 2006, 2007 Nick Galbreath
+ * Copyright © 2005-2016 Nick Galbreath
  * All rights reserved.
  *
  * https://github.com/client9/stringencoders
  *
- * Released under bsd license.  See modp_b64.c for details.
+ * Released under MIT license.  See LICENSE for details.
  * 
* * This uses the standard base 64 alphabet. If you are planning * to embed a base 64 encoding inside a URL use modp_b64w instead. * + * ATTENTION: the algorithm may require ALIGNED strings. For Intel + * chips alignment doens't (perhaps a performance issues). But for + * Sparc and maybe ARM, use of unaligned strings can core dump. + * see https://github.com/client9/stringencoders/issues/1 + * see https://github.com/client9/stringencoders/issues/42 */ #ifndef COM_MODP_STRINGENCODERS_B64 #define COM_MODP_STRINGENCODERS_B64 -#include +#include "extern_c_begin.h" +#include "modp_stdint.h" /** * \brief Encode a raw binary string into base 64. @@ -91,7 +94,7 @@ size_t modp_b64_decode(char* dest, const char* src, size_t len); * * +1 is for any extra null. */ -#define modp_b64_encode_len(A) ((A+2)/3 * 4 + 1) +#define modp_b64_encode_len(A) ((A + 2) / 3 * 4 + 1) /** * Given a base64 string of length len, @@ -127,52 +130,54 @@ size_t modp_b64_decode(char* dest, const char* src, size_t len); * // foo is filled out now * \endcode */ -#define modp_b64_encode_strlen(A) ((A + 2)/ 3 * 4) +#define modp_b64_encode_strlen(A) ((A + 2) / 3 * 4) + +#include "extern_c_end.h" #ifdef __cplusplus #include #include namespace modp { - /** \brief b64 encode a cstr with len +/** \brief b64 encode a cstr with len * * \param[in] s the input string to encode * \param[in] len the length of the input string * \return a newly allocated b64 string. Empty if failed. */ - inline std::string b64_encode(const char* s, size_t len) - { - std::string x(modp_b64_encode_len(len), '\0'); - size_t d = modp_b64_encode(const_cast(x.data()), s, len); - if (d == (size_t)-1) { - x.clear(); - } else { - x.erase(d, std::string::npos); - } - return x; +inline std::string b64_encode(const char* s, size_t len) +{ + std::string x(modp_b64_encode_len(len), '\0'); + size_t d = modp_b64_encode(const_cast(x.data()), s, len); + if (d == (size_t)-1) { + x.clear(); + } else { + x.erase(d, std::string::npos); } + return x; +} - /** \brief b64 encode a cstr +/** \brief b64 encode a cstr * * \param[in] s the input string to encode * \return a newly allocated b64 string. Empty if failed. */ - inline std::string b64_encode(const char* s) - { - return b64_encode(s, strlen(s)); - } +inline std::string b64_encode(const char* s) +{ + return b64_encode(s, strlen(s)); +} - /** \brief b64 encode a const std::string +/** \brief b64 encode a const std::string * * \param[in] s the input string to encode * \return a newly allocated b64 string. Empty if failed. */ - inline std::string b64_encode(const std::string& s) - { - return b64_encode(s.data(), s.size()); - } +inline std::string b64_encode(const std::string& s) +{ + return b64_encode(s.data(), s.size()); +} - /** +/** * base 64 encode a string (self-modifing) * * This function is for C++ only (duh) @@ -180,31 +185,31 @@ namespace modp { * \param[in,out] s the string to be decoded * \return a reference to the input string */ - inline std::string& b64_encode(std::string& s) - { - std::string x(b64_encode(s.data(), s.size())); - s.swap(x); - return s; - } +inline std::string& b64_encode(std::string& s) +{ + std::string x(b64_encode(s.data(), s.size())); + s.swap(x); + return s; +} - inline std::string b64_decode(const char* src, size_t len) - { - std::string x(modp_b64_decode_len(len)+1, '\0'); - size_t d = modp_b64_decode(const_cast(x.data()), src, len); - if (d == (size_t)-1) { - x.clear(); - } else { - x.erase(d, std::string::npos); - } - return x; +inline std::string b64_decode(const char* src, size_t len) +{ + std::string x(modp_b64_decode_len(len) + 1, '\0'); + size_t d = modp_b64_decode(const_cast(x.data()), src, len); + if (d == (size_t)-1) { + x.clear(); + } else { + x.erase(d, std::string::npos); } + return x; +} - inline std::string b64_decode(const char* src) - { - return b64_decode(src, strlen(src)); - } +inline std::string b64_decode(const char* src) +{ + return b64_decode(src, strlen(src)); +} - /** +/** * base 64 decode a string (self-modifing) * On failure, the string is empty. * @@ -213,18 +218,17 @@ namespace modp { * \param[in,out] s the string to be decoded * \return a reference to the input string */ - inline std::string& b64_decode(std::string& s) - { - std::string x(b64_decode(s.data(), s.size())); - s.swap(x); - return s; - } - - inline std::string b64_decode(const std::string& s) - { - return b64_decode(s.data(), s.size()); - } +inline std::string& b64_decode(std::string& s) +{ + std::string x(b64_decode(s.data(), s.size())); + s.swap(x); + return s; +} +inline std::string b64_decode(const std::string& s) +{ + return b64_decode(s.data(), s.size()); +} } #endif /* __cplusplus */ diff --git a/libwvdrmengine/third_party/stringencoders/src/modp_b64_data.h b/libwvdrmengine/third_party/stringencoders/src/modp_b64_data.h index 1635df9b..34a0fa8b 100644 --- a/libwvdrmengine/third_party/stringencoders/src/modp_b64_data.h +++ b/libwvdrmengine/third_party/stringencoders/src/modp_b64_data.h @@ -1,286 +1,283 @@ -#include +#include "modp_stdint.h" #define CHAR62 '+' #define CHAR63 '/' #define CHARPAD '=' static const uint8_t e0[256] = { - 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', - 'C', 'C', 'D', 'D', 'D', 'D', 'E', 'E', 'E', 'E', - 'F', 'F', 'F', 'F', 'G', 'G', 'G', 'G', 'H', 'H', - 'H', 'H', 'I', 'I', 'I', 'I', 'J', 'J', 'J', 'J', - 'K', 'K', 'K', 'K', 'L', 'L', 'L', 'L', 'M', 'M', - 'M', 'M', 'N', 'N', 'N', 'N', 'O', 'O', 'O', 'O', - 'P', 'P', 'P', 'P', 'Q', 'Q', 'Q', 'Q', 'R', 'R', - 'R', 'R', 'S', 'S', 'S', 'S', 'T', 'T', 'T', 'T', - 'U', 'U', 'U', 'U', 'V', 'V', 'V', 'V', 'W', 'W', - 'W', 'W', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y', - 'Z', 'Z', 'Z', 'Z', 'a', 'a', 'a', 'a', 'b', 'b', - 'b', 'b', 'c', 'c', 'c', 'c', 'd', 'd', 'd', 'd', - 'e', 'e', 'e', 'e', 'f', 'f', 'f', 'f', 'g', 'g', - 'g', 'g', 'h', 'h', 'h', 'h', 'i', 'i', 'i', 'i', - 'j', 'j', 'j', 'j', 'k', 'k', 'k', 'k', 'l', 'l', - 'l', 'l', 'm', 'm', 'm', 'm', 'n', 'n', 'n', 'n', - 'o', 'o', 'o', 'o', 'p', 'p', 'p', 'p', 'q', 'q', - 'q', 'q', 'r', 'r', 'r', 'r', 's', 's', 's', 's', - 't', 't', 't', 't', 'u', 'u', 'u', 'u', 'v', 'v', - 'v', 'v', 'w', 'w', 'w', 'w', 'x', 'x', 'x', 'x', - 'y', 'y', 'y', 'y', 'z', 'z', 'z', 'z', '0', '0', - '0', '0', '1', '1', '1', '1', '2', '2', '2', '2', - '3', '3', '3', '3', '4', '4', '4', '4', '5', '5', - '5', '5', '6', '6', '6', '6', '7', '7', '7', '7', - '8', '8', '8', '8', '9', '9', '9', '9', '+', '+', - '+', '+', '/', '/', '/', '/' + 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', + 'C', 'C', 'D', 'D', 'D', 'D', 'E', 'E', 'E', 'E', + 'F', 'F', 'F', 'F', 'G', 'G', 'G', 'G', 'H', 'H', + 'H', 'H', 'I', 'I', 'I', 'I', 'J', 'J', 'J', 'J', + 'K', 'K', 'K', 'K', 'L', 'L', 'L', 'L', 'M', 'M', + 'M', 'M', 'N', 'N', 'N', 'N', 'O', 'O', 'O', 'O', + 'P', 'P', 'P', 'P', 'Q', 'Q', 'Q', 'Q', 'R', 'R', + 'R', 'R', 'S', 'S', 'S', 'S', 'T', 'T', 'T', 'T', + 'U', 'U', 'U', 'U', 'V', 'V', 'V', 'V', 'W', 'W', + 'W', 'W', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y', + 'Z', 'Z', 'Z', 'Z', 'a', 'a', 'a', 'a', 'b', 'b', + 'b', 'b', 'c', 'c', 'c', 'c', 'd', 'd', 'd', 'd', + 'e', 'e', 'e', 'e', 'f', 'f', 'f', 'f', 'g', 'g', + 'g', 'g', 'h', 'h', 'h', 'h', 'i', 'i', 'i', 'i', + 'j', 'j', 'j', 'j', 'k', 'k', 'k', 'k', 'l', 'l', + 'l', 'l', 'm', 'm', 'm', 'm', 'n', 'n', 'n', 'n', + 'o', 'o', 'o', 'o', 'p', 'p', 'p', 'p', 'q', 'q', + 'q', 'q', 'r', 'r', 'r', 'r', 's', 's', 's', 's', + 't', 't', 't', 't', 'u', 'u', 'u', 'u', 'v', 'v', + 'v', 'v', 'w', 'w', 'w', 'w', 'x', 'x', 'x', 'x', + 'y', 'y', 'y', 'y', 'z', 'z', 'z', 'z', '0', '0', + '0', '0', '1', '1', '1', '1', '2', '2', '2', '2', + '3', '3', '3', '3', '4', '4', '4', '4', '5', '5', + '5', '5', '6', '6', '6', '6', '7', '7', '7', '7', + '8', '8', '8', '8', '9', '9', '9', '9', '+', '+', + '+', '+', '/', '/', '/', '/' }; - static const uint8_t e1[256] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', - 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', - 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', - 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', - 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', '+', '/' + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', + 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', + 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', + 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', + 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', '+', '/' }; - static const uint8_t e2[256] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', - 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', - 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', - 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', - 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', '+', '/' + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', + 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', + 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', + 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', + 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', '+', '/' }; - #ifdef WORDS_BIGENDIAN /* SPECIAL DECODE TABLES FOR BIG ENDIAN (IBM/MOTOROLA/SUN) CPUS */ static const uint32_t d0[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x00f80000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00fc0000, -0x00d00000, 0x00d40000, 0x00d80000, 0x00dc0000, 0x00e00000, 0x00e40000, -0x00e80000, 0x00ec0000, 0x00f00000, 0x00f40000, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00040000, 0x00080000, 0x000c0000, 0x00100000, 0x00140000, 0x00180000, -0x001c0000, 0x00200000, 0x00240000, 0x00280000, 0x002c0000, 0x00300000, -0x00340000, 0x00380000, 0x003c0000, 0x00400000, 0x00440000, 0x00480000, -0x004c0000, 0x00500000, 0x00540000, 0x00580000, 0x005c0000, 0x00600000, -0x00640000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x00680000, 0x006c0000, 0x00700000, 0x00740000, 0x00780000, -0x007c0000, 0x00800000, 0x00840000, 0x00880000, 0x008c0000, 0x00900000, -0x00940000, 0x00980000, 0x009c0000, 0x00a00000, 0x00a40000, 0x00a80000, -0x00ac0000, 0x00b00000, 0x00b40000, 0x00b80000, 0x00bc0000, 0x00c00000, -0x00c40000, 0x00c80000, 0x00cc0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x00f80000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00fc0000, + 0x00d00000, 0x00d40000, 0x00d80000, 0x00dc0000, 0x00e00000, 0x00e40000, + 0x00e80000, 0x00ec0000, 0x00f00000, 0x00f40000, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00040000, 0x00080000, 0x000c0000, 0x00100000, 0x00140000, 0x00180000, + 0x001c0000, 0x00200000, 0x00240000, 0x00280000, 0x002c0000, 0x00300000, + 0x00340000, 0x00380000, 0x003c0000, 0x00400000, 0x00440000, 0x00480000, + 0x004c0000, 0x00500000, 0x00540000, 0x00580000, 0x005c0000, 0x00600000, + 0x00640000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x00680000, 0x006c0000, 0x00700000, 0x00740000, 0x00780000, + 0x007c0000, 0x00800000, 0x00840000, 0x00880000, 0x008c0000, 0x00900000, + 0x00940000, 0x00980000, 0x009c0000, 0x00a00000, 0x00a40000, 0x00a80000, + 0x00ac0000, 0x00b00000, 0x00b40000, 0x00b80000, 0x00bc0000, 0x00c00000, + 0x00c40000, 0x00c80000, 0x00cc0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; static const uint32_t d1[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x0003e000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0003f000, -0x00034000, 0x00035000, 0x00036000, 0x00037000, 0x00038000, 0x00039000, -0x0003a000, 0x0003b000, 0x0003c000, 0x0003d000, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, -0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, -0x0000d000, 0x0000e000, 0x0000f000, 0x00010000, 0x00011000, 0x00012000, -0x00013000, 0x00014000, 0x00015000, 0x00016000, 0x00017000, 0x00018000, -0x00019000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x0001a000, 0x0001b000, 0x0001c000, 0x0001d000, 0x0001e000, -0x0001f000, 0x00020000, 0x00021000, 0x00022000, 0x00023000, 0x00024000, -0x00025000, 0x00026000, 0x00027000, 0x00028000, 0x00029000, 0x0002a000, -0x0002b000, 0x0002c000, 0x0002d000, 0x0002e000, 0x0002f000, 0x00030000, -0x00031000, 0x00032000, 0x00033000, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x0003e000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0003f000, + 0x00034000, 0x00035000, 0x00036000, 0x00037000, 0x00038000, 0x00039000, + 0x0003a000, 0x0003b000, 0x0003c000, 0x0003d000, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, + 0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, + 0x0000d000, 0x0000e000, 0x0000f000, 0x00010000, 0x00011000, 0x00012000, + 0x00013000, 0x00014000, 0x00015000, 0x00016000, 0x00017000, 0x00018000, + 0x00019000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x0001a000, 0x0001b000, 0x0001c000, 0x0001d000, 0x0001e000, + 0x0001f000, 0x00020000, 0x00021000, 0x00022000, 0x00023000, 0x00024000, + 0x00025000, 0x00026000, 0x00027000, 0x00028000, 0x00029000, 0x0002a000, + 0x0002b000, 0x0002c000, 0x0002d000, 0x0002e000, 0x0002f000, 0x00030000, + 0x00031000, 0x00032000, 0x00033000, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; static const uint32_t d2[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x00000f80, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000fc0, -0x00000d00, 0x00000d40, 0x00000d80, 0x00000dc0, 0x00000e00, 0x00000e40, -0x00000e80, 0x00000ec0, 0x00000f00, 0x00000f40, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00000040, 0x00000080, 0x000000c0, 0x00000100, 0x00000140, 0x00000180, -0x000001c0, 0x00000200, 0x00000240, 0x00000280, 0x000002c0, 0x00000300, -0x00000340, 0x00000380, 0x000003c0, 0x00000400, 0x00000440, 0x00000480, -0x000004c0, 0x00000500, 0x00000540, 0x00000580, 0x000005c0, 0x00000600, -0x00000640, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x00000680, 0x000006c0, 0x00000700, 0x00000740, 0x00000780, -0x000007c0, 0x00000800, 0x00000840, 0x00000880, 0x000008c0, 0x00000900, -0x00000940, 0x00000980, 0x000009c0, 0x00000a00, 0x00000a40, 0x00000a80, -0x00000ac0, 0x00000b00, 0x00000b40, 0x00000b80, 0x00000bc0, 0x00000c00, -0x00000c40, 0x00000c80, 0x00000cc0, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x00000f80, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000fc0, + 0x00000d00, 0x00000d40, 0x00000d80, 0x00000dc0, 0x00000e00, 0x00000e40, + 0x00000e80, 0x00000ec0, 0x00000f00, 0x00000f40, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00000040, 0x00000080, 0x000000c0, 0x00000100, 0x00000140, 0x00000180, + 0x000001c0, 0x00000200, 0x00000240, 0x00000280, 0x000002c0, 0x00000300, + 0x00000340, 0x00000380, 0x000003c0, 0x00000400, 0x00000440, 0x00000480, + 0x000004c0, 0x00000500, 0x00000540, 0x00000580, 0x000005c0, 0x00000600, + 0x00000640, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x00000680, 0x000006c0, 0x00000700, 0x00000740, 0x00000780, + 0x000007c0, 0x00000800, 0x00000840, 0x00000880, 0x000008c0, 0x00000900, + 0x00000940, 0x00000980, 0x000009c0, 0x00000a00, 0x00000a40, 0x00000a80, + 0x00000ac0, 0x00000b00, 0x00000b40, 0x00000b80, 0x00000bc0, 0x00000c00, + 0x00000c40, 0x00000c80, 0x00000cc0, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; static const uint32_t d3[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x0000003e, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000003f, -0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, -0x0000003a, 0x0000003b, 0x0000003c, 0x0000003d, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, -0x00000007, 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, -0x0000000d, 0x0000000e, 0x0000000f, 0x00000010, 0x00000011, 0x00000012, -0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 0x00000018, -0x00000019, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x0000001a, 0x0000001b, 0x0000001c, 0x0000001d, 0x0000001e, -0x0000001f, 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, -0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, 0x0000002a, -0x0000002b, 0x0000002c, 0x0000002d, 0x0000002e, 0x0000002f, 0x00000030, -0x00000031, 0x00000032, 0x00000033, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x0000003e, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000003f, + 0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, + 0x0000003a, 0x0000003b, 0x0000003c, 0x0000003d, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, + 0x00000007, 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, + 0x0000000d, 0x0000000e, 0x0000000f, 0x00000010, 0x00000011, 0x00000012, + 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 0x00000018, + 0x00000019, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x0000001a, 0x0000001b, 0x0000001c, 0x0000001d, 0x0000001e, + 0x0000001f, 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, + 0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, 0x0000002a, + 0x0000002b, 0x0000002c, 0x0000002d, 0x0000002e, 0x0000002f, 0x00000030, + 0x00000031, 0x00000032, 0x00000033, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; @@ -290,190 +287,190 @@ static const uint32_t d3[256] = { /* SPECIAL DECODE TABLES FOR LITTLE ENDIAN (INTEL) CPUS */ static const uint32_t d0[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x000000f8, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000fc, -0x000000d0, 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4, -0x000000e8, 0x000000ec, 0x000000f0, 0x000000f4, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00000004, 0x00000008, 0x0000000c, 0x00000010, 0x00000014, 0x00000018, -0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c, 0x00000030, -0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048, -0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060, -0x00000064, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078, -0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090, -0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8, -0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc, 0x000000c0, -0x000000c4, 0x000000c8, 0x000000cc, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x000000f8, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000fc, + 0x000000d0, 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4, + 0x000000e8, 0x000000ec, 0x000000f0, 0x000000f4, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00000004, 0x00000008, 0x0000000c, 0x00000010, 0x00000014, 0x00000018, + 0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c, 0x00000030, + 0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048, + 0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060, + 0x00000064, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078, + 0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090, + 0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8, + 0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc, 0x000000c0, + 0x000000c4, 0x000000c8, 0x000000cc, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; static const uint32_t d1[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x0000e003, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000f003, -0x00004003, 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003, -0x0000a003, 0x0000b003, 0x0000c003, 0x0000d003, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, -0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, -0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001, -0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001, -0x00009001, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x0000a001, 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001, -0x0000f001, 0x00000002, 0x00001002, 0x00002002, 0x00003002, 0x00004002, -0x00005002, 0x00006002, 0x00007002, 0x00008002, 0x00009002, 0x0000a002, -0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002, 0x00000003, -0x00001003, 0x00002003, 0x00003003, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x0000e003, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000f003, + 0x00004003, 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003, + 0x0000a003, 0x0000b003, 0x0000c003, 0x0000d003, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, + 0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, + 0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001, + 0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001, + 0x00009001, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x0000a001, 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001, + 0x0000f001, 0x00000002, 0x00001002, 0x00002002, 0x00003002, 0x00004002, + 0x00005002, 0x00006002, 0x00007002, 0x00008002, 0x00009002, 0x0000a002, + 0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002, 0x00000003, + 0x00001003, 0x00002003, 0x00003003, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; static const uint32_t d2[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x00800f00, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00c00f00, -0x00000d00, 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00, -0x00800e00, 0x00c00e00, 0x00000f00, 0x00400f00, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00400000, 0x00800000, 0x00c00000, 0x00000100, 0x00400100, 0x00800100, -0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200, 0x00000300, -0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400, -0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600, -0x00400600, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x00800600, 0x00c00600, 0x00000700, 0x00400700, 0x00800700, -0x00c00700, 0x00000800, 0x00400800, 0x00800800, 0x00c00800, 0x00000900, -0x00400900, 0x00800900, 0x00c00900, 0x00000a00, 0x00400a00, 0x00800a00, -0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00, 0x00000c00, -0x00400c00, 0x00800c00, 0x00c00c00, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x00800f00, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00c00f00, + 0x00000d00, 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00, + 0x00800e00, 0x00c00e00, 0x00000f00, 0x00400f00, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00400000, 0x00800000, 0x00c00000, 0x00000100, 0x00400100, 0x00800100, + 0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200, 0x00000300, + 0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400, + 0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600, + 0x00400600, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x00800600, 0x00c00600, 0x00000700, 0x00400700, 0x00800700, + 0x00c00700, 0x00000800, 0x00400800, 0x00800800, 0x00c00800, 0x00000900, + 0x00400900, 0x00800900, 0x00c00900, 0x00000a00, 0x00400a00, 0x00800a00, + 0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00, 0x00000c00, + 0x00400c00, 0x00800c00, 0x00c00c00, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; static const uint32_t d3[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x003e0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003f0000, -0x00340000, 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000, -0x003a0000, 0x003b0000, 0x003c0000, 0x003d0000, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00010000, 0x00020000, 0x00030000, 0x00040000, 0x00050000, 0x00060000, -0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000, 0x000c0000, -0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000, -0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000, -0x00190000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x001a0000, 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000, -0x001f0000, 0x00200000, 0x00210000, 0x00220000, 0x00230000, 0x00240000, -0x00250000, 0x00260000, 0x00270000, 0x00280000, 0x00290000, 0x002a0000, -0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000, 0x00300000, -0x00310000, 0x00320000, 0x00330000, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x003e0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003f0000, + 0x00340000, 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000, + 0x003a0000, 0x003b0000, 0x003c0000, 0x003d0000, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00010000, 0x00020000, 0x00030000, 0x00040000, 0x00050000, 0x00060000, + 0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000, 0x000c0000, + 0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000, + 0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000, + 0x00190000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x001a0000, 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000, + 0x001f0000, 0x00200000, 0x00210000, 0x00220000, 0x00230000, 0x00240000, + 0x00250000, 0x00260000, 0x00270000, 0x00280000, 0x00290000, 0x002a0000, + 0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000, 0x00300000, + 0x00310000, 0x00320000, 0x00330000, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; diff --git a/libwvdrmengine/third_party/stringencoders/src/modp_b64w.cpp b/libwvdrmengine/third_party/stringencoders/src/modp_b64w.cpp index 84a40e37..45fa360d 100644 --- a/libwvdrmengine/third_party/stringencoders/src/modp_b64w.cpp +++ b/libwvdrmengine/third_party/stringencoders/src/modp_b64w.cpp @@ -1,56 +1,25 @@ -/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set expandtab shiftwidth=4 tabstop=4: */ /** * \file modp_b64w.c *
  * MODP_B64 - High performance base64 encoder/decoder
- * http://code.google.com/p/stringencoders/
+ * https://github.com/client9/stringencoders
  *
- * Copyright © 2005, 2006, 2007  Nick Galbreath -- nickg [at] modp [dot] com
+ * Copyright © 2005-2016 Nick Galbreath
  * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- *   Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- *   Neither the name of the modp.com nor the names of its
- *   contributors may be used to endorse or promote products derived from
- *   this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * This is the standard "new" BSD license:
- * http://www.opensource.org/licenses/bsd-license.php
+ * Released under MIT license. See LICENSE for details.
  * 
*/ -/* public header */ -#include "modp_b64w.h" - /* * If you are ripping this out of the library, comment out the next * line and uncomment the next lines as approrpiate */ #include "config.h" -/* if on motoral, sun, ibm; uncomment this */ +/* public header */ +#include "modp_b64w.h" + +/* if on motorola, sun, ibm; uncomment this */ /* #define WORDS_BIGENDIAN 1 */ /* else for Intel, Amd; uncomment this */ /* #undef WORDS_BIGENDIAN */ @@ -62,7 +31,7 @@ /** * you can control if we use padding by commenting out this * next line. However, I highly recommend you use padding and not - * using it should only be for compatability with a 3rd party. + * using it should only be for compatibility with a 3rd party. * Also, 'no padding' is not tested! */ #define DOPAD 1 @@ -76,23 +45,27 @@ #define CHARPAD '\0' #endif -int modp_b64w_encode(char* dest, const char* str, int len) +size_t modp_b64w_encode(char* dest, const char* str, size_t len) { - int i; - const uint8_t* s = (const uint8_t*) str; - uint8_t* p = (uint8_t*) dest; + size_t i = 0; + const uint8_t* s = (const uint8_t*)str; + uint8_t* p = (uint8_t*)dest; /* unsigned here is important! */ /* uint8_t is fastest on G4, amd */ /* uint32_t is fastest on Intel */ uint32_t t1, t2, t3; - for (i = 0; i < len - 2; i += 3) { - t1 = s[i]; t2 = s[i+1]; t3 = s[i+2]; - *p++ = e0[t1]; - *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; - *p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)]; - *p++ = e2[t3]; + if (len > 2) { + for (i = 0; i < len - 2; i += 3) { + t1 = s[i]; + t2 = s[i + 1]; + t3 = s[i + 2]; + *p++ = e0[t1]; + *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; + *p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)]; + *p++ = e2[t3]; + } } switch (len - i) { @@ -106,7 +79,8 @@ int modp_b64w_encode(char* dest, const char* str, int len) *p++ = CHARPAD; break; default: /* case 2 */ - t1 = s[i]; t2 = s[i+1]; + t1 = s[i]; + t2 = s[i + 1]; *p++ = e0[t1]; *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; *p++ = e2[(t2 & 0x0F) << 2]; @@ -114,41 +88,43 @@ int modp_b64w_encode(char* dest, const char* str, int len) } *p = '\0'; - return (int)(p - (uint8_t*)dest); + return (size_t)(p - (uint8_t*)dest); } -#ifdef WORDS_BIGENDIAN /* BIG ENDIAN -- SUN / IBM / MOTOROLA */ -int modp_b64w_decode(char* dest, const char* src, int len) +#ifdef WORDS_BIGENDIAN /* BIG ENDIAN -- SUN / IBM / MOTOROLA */ +size_t modp_b64w_decode(char* dest, const char* src, size_t len) { - int i; - if (len == 0) return 0; + size_t i; + if (len == 0) + return 0; #ifdef DOPAD /* if padding is used, then the message must be at least 4 chars and be a multiple of 4. there can be at most 2 pad chars at the end */ - if (len < 4 || (len % 4 != 0)) return -1; - if (src[len-1] == CHARPAD) { + if (len < 4 || (len % 4 != 0)) + return -1; + if (src[len - 1] == CHARPAD) { len--; - if (src[len -1] == CHARPAD) { + if (src[len - 1] == CHARPAD) { len--; } } -#endif /* DOPAD */ +#endif /* DOPAD */ - int leftover = len % 4; - int chunks = (leftover == 0) ? len / 4 - 1 : len /4; + size_t leftover = len % 4; + size_t chunks = (leftover == 0) ? len / 4 - 1 : len / 4; - uint8_t* p = (uint8_t*) dest; + uint8_t* p = (uint8_t*)dest; uint32_t x = 0; - uint32_t* destInt = (uint32_t*) p; - uint32_t* srcInt = (uint32_t*) src; + uint32_t* destInt = (uint32_t*)p; + uint32_t* srcInt = (uint32_t*)src; uint32_t y = *srcInt++; for (i = 0; i < chunks; ++i) { - x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | - d2[y >> 8 & 0xff] | d3[y & 0xff]; + x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | d2[y >> 8 & 0xff] | d3[y & 0xff]; - if (x >= BADCHAR) return -1; + if (x >= BADCHAR) + return -1; *destInt = x << 8; p += 3; destInt = (uint32_t*)p; @@ -157,113 +133,122 @@ int modp_b64w_decode(char* dest, const char* src, int len) switch (leftover) { case 0: - x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | - d2[y >> 8 & 0xff] | d3[y & 0xff]; - if (x >= BADCHAR) return -1; + x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | d2[y >> 8 & 0xff] | d3[y & 0xff]; + if (x >= BADCHAR) + return -1; *p++ = ((uint8_t*)&x)[1]; *p++ = ((uint8_t*)&x)[2]; *p = ((uint8_t*)&x)[3]; - return (chunks+1)*3; + return (chunks + 1) * 3; #ifndef DOPAD - case 1: /* with padding this is an impossible case */ + case 1: /* with padding this is an impossible case */ x = d3[y >> 24]; - *p = (uint8_t)x; + *p = (uint8_t)x; break; #endif case 2: - x = d3[y >> 24] *64 + d3[(y >> 16) & 0xff]; - *p = (uint8_t)(x >> 4); + x = d3[y >> 24] * 64 + d3[(y >> 16) & 0xff]; + *p = (uint8_t)(x >> 4); break; - default: /* case 3 */ - x = (d3[y >> 24] *64 + d3[(y >> 16) & 0xff])*64 + - d3[(y >> 8) & 0xff]; - *p++ = (uint8_t) (x >> 10); - *p = (uint8_t) (x >> 2); + default: /* case 3 */ + x = (d3[y >> 24] * 64 + d3[(y >> 16) & 0xff]) * 64 + d3[(y >> 8) & 0xff]; + *p++ = (uint8_t)(x >> 10); + *p = (uint8_t)(x >> 2); break; } - if (x >= BADCHAR) return -1; - return 3*chunks + (6*leftover)/8; + if (x >= BADCHAR) + return -1; + return 3 * chunks + (6 * leftover) / 8; } #else /* LITTLE ENDIAN -- INTEL AND FRIENDS */ -int modp_b64w_decode(char* dest, const char* src, int len) +size_t modp_b64w_decode(char* dest, const char* src, size_t len) { - int i; - if (len == 0) return 0; + size_t i; + size_t leftover; + size_t chunks; + + uint8_t* p; + uint32_t x; + uint32_t* destInt; + const uint32_t* srcInt = (const uint32_t*)src; + uint32_t y = *srcInt++; + + if (len == 0) + return 0; #ifdef DOPAD /* * if padding is used, then the message must be at least * 4 chars and be a multiple of 4 */ - if (len < 4 || (len % 4 != 0)) return -1; /* error */ + if (len < 4 || (len % 4 != 0)) { + return (size_t)-1; /* error */ + } /* there can be at most 2 pad chars at the end */ - if (src[len-1] == CHARPAD) { + if (src[len - 1] == CHARPAD) { len--; - if (src[len -1] == CHARPAD) { + if (src[len - 1] == CHARPAD) { len--; } } #endif - int leftover = len % 4; - int chunks = (leftover == 0) ? len / 4 - 1 : len /4; + leftover = len % 4; + chunks = (leftover == 0) ? len / 4 - 1 : len / 4; - uint8_t* p = (uint8_t*) dest; - uint32_t x = 0; - uint32_t* destInt = (uint32_t*) p; - uint32_t* srcInt = (uint32_t*) src; - uint32_t y = *srcInt++; + p = (uint8_t*)dest; + x = 0; + destInt = (uint32_t*)p; + srcInt = (const uint32_t*)src; + y = *srcInt++; for (i = 0; i < chunks; ++i) { - x = d0[y & 0xff] | - d1[(y >> 8) & 0xff] | - d2[(y >> 16) & 0xff] | - d3[(y >> 24) & 0xff]; + x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff]; - if (x >= BADCHAR) return -1; - *destInt = x ; + if (x >= BADCHAR) { + return (size_t)-1; + } + *destInt = x; p += 3; destInt = (uint32_t*)p; - y = *srcInt++;} - + y = *srcInt++; + } switch (leftover) { case 0: - x = d0[y & 0xff] | - d1[(y >> 8) & 0xff] | - d2[(y >> 16) & 0xff] | - d3[(y >> 24) & 0xff]; + x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff]; - if (x >= BADCHAR) return -1; - *p++ = ((uint8_t*)(&x))[0]; - *p++ = ((uint8_t*)(&x))[1]; - *p = ((uint8_t*)(&x))[2]; - return (chunks+1)*3; - break; + if (x >= BADCHAR) { + return (size_t)-1; + } + *p++ = ((uint8_t*)(&x))[0]; + *p++ = ((uint8_t*)(&x))[1]; + *p = ((uint8_t*)(&x))[2]; + return (chunks + 1) * 3; #ifndef DOPAD - case 1: /* with padding this is an impossible case */ + case 1: /* with padding this is an impossible case */ x = d0[y & 0xff]; - *p = *((uint8_t*)(&x)); // i.e. first char/byte in int + *p = *((uint8_t*)(&x)); /* i.e. first char/byte in int */ break; #endif - case 2: // * case 2, 1 output byte */ + case 2: /* case 2, 1 output byte */ x = d0[y & 0xff] | d1[y >> 8 & 0xff]; - *p = *((uint8_t*)(&x)); // i.e. first char + *p = *((uint8_t*)(&x)); /* i.e. first char */ break; default: /* case 3, 2 output bytes */ - x = d0[y & 0xff] | - d1[y >> 8 & 0xff ] | - d2[y >> 16 & 0xff]; /* 0x3c */ - *p++ = ((uint8_t*)(&x))[0]; - *p = ((uint8_t*)(&x))[1]; + x = d0[y & 0xff] | d1[y >> 8 & 0xff] | d2[y >> 16 & 0xff]; /* 0x3c */ + *p++ = ((uint8_t*)(&x))[0]; + *p = ((uint8_t*)(&x))[1]; break; } - if (x >= BADCHAR) return -1; + if (x >= BADCHAR) { + return (size_t)-1; + } - return 3*chunks + (6*leftover)/8; + return 3 * chunks + (6 * leftover) / 8; } -#endif /* if bigendian / else / endif */ +#endif /* if bigendian / else / endif */ diff --git a/libwvdrmengine/third_party/stringencoders/src/modp_b64w.h b/libwvdrmengine/third_party/stringencoders/src/modp_b64w.h index 3fa31a13..08208678 100644 --- a/libwvdrmengine/third_party/stringencoders/src/modp_b64w.h +++ b/libwvdrmengine/third_party/stringencoders/src/modp_b64w.h @@ -1,20 +1,16 @@ -/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set expandtab shiftwidth=4 tabstop=4: */ - /** - * \file *
  * High performance WEB-SAFE base64 encoder / decoder
  *
- * Copyright © 2005, 2006, 2007 Nick Galbreath -- nickg [at] modp [dot] com
+ * Copyright © 2005-2016 Nick Galbreath -- nickg [at] client9 [dot] com
  * All rights reserved.
  *
- * http://code.google.com/p/stringencoders/
+ * https://github.com/client9/stringencoders/
  *
- * Released under bsd license.  See modp_b64w.c for details.
+ * Released under MIT license.  See LICENSE for details.
  * 
* - * This uses a "URL-safe" or "WEB-safe" encoding. THe standard + * This uses a "URL-safe" or "WEB-safe" encoding. The standard * base 64 encoding uses the characters '+', '/' and '=' have special * restrictions when used inside a URL. * @@ -29,18 +25,11 @@ #ifndef COM_MODP_STRINGENCODERS_B64W #define COM_MODP_STRINGENCODERS_B64W -#ifdef __cplusplus -#define BEGIN_C extern "C" { -#define END_C } -#else -#define BEGIN_C -#define END_C -#endif - -BEGIN_C +#include "extern_c_begin.h" +#include "modp_stdint.h" /** - * Encode a raw binary string into web-safe base 64. + * \brief Encode a raw binary string into web-safe base 64. * \param[out] dest should be allocated by the caller to contain * at least modp_b64w_encode_len(len) bytes (see below) * This will contain the null-terminated b64w encoded result @@ -64,10 +53,10 @@ BEGIN_C * \endcode * */ -int modp_b64w_encode(char* dest, const char* src, int len); +size_t modp_b64w_encode(char* dest, const char* src, size_t len); /** - * Decode a web-safe base64 encoded string + * \brief Decode a web-safe base64 encoded string * * \param[out] dest should be allocated by the caller to contain at least * len * 3 / 4 bytes. @@ -87,7 +76,7 @@ int modp_b64w_encode(char* dest, const char* src, int len); * if (len == -1) { error } * \endcode */ -int modp_b64w_decode(char* dest, const char* src, int len); +size_t modp_b64w_decode(char* dest, const char* src, size_t len); /** * Given a source string of length len, this returns the amount of @@ -99,7 +88,7 @@ int modp_b64w_decode(char* dest, const char* src, int len); * * +1 is for any extra null. */ -#define modp_b64w_encode_len(A) ((A+2)/3 * 4 + 1) +#define modp_b64w_encode_len(A) ((A + 2) / 3 * 4 + 1) /** * Given a base64 string of length len, @@ -116,7 +105,7 @@ int modp_b64w_decode(char* dest, const char* src, int len); * Will return the strlen of the output from encoding. * This may be less than the required number of bytes allocated. * - * This allows you to 'deserialized' a struct + * This allows you to 'deserialized' a struct: * \code * char* b64wencoded = "..."; * int len = strlen(b64wencoded); @@ -135,9 +124,9 @@ int modp_b64w_decode(char* dest, const char* src, int len); * // foo is filled out now * \endcode */ -#define modp_b64w_encode_strlen(A) ((A + 2)/ 3 * 4) +#define modp_b64w_encode_strlen(A) ((A + 2) / 3 * 4) -END_C +#include "extern_c_end.h" #ifdef __cplusplus #include @@ -145,42 +134,45 @@ END_C namespace modp { - /** \brief b64w encode a cstr with len +/** \brief b64w encode a cstr with len * * \param[in] s the input string to encode * \param[in] len the length of the input string * \return a newly allocated b64w string. Empty if failed. */ - inline std::string b64w_encode(const char* s, size_t len) - { - std::string x(modp_b64w_encode_len(len), '\0'); - int d = modp_b64w_encode(const_cast(x.data()), s, - static_cast(len)); +inline std::string b64w_encode(const char* s, size_t len) +{ + std::string x(modp_b64w_encode_len(len), '\0'); + size_t d = modp_b64w_encode(const_cast(x.data()), s, len); + if (d == (size_t)-1) { + x.clear(); + } else { x.erase(d, std::string::npos); - return x; } + return x; +} - /** \brief b64w encode a cstr +/** \brief b64w encode a cstr * * \param[in] s the input string to encode * \return a newly allocated b64w string. Empty if failed. */ - inline std::string b64w_encode(const char* s) - { - return b64w_encode(s, static_cast(strlen(s))); - } +inline std::string b64w_encode(const char* s) +{ + return b64w_encode(s, strlen(s)); +} - /** \brief b64w encode a const std::string +/** \brief b64w encode a const std::string * * \param[in] s the input string to encode * \return a newly allocated b64w string. Empty if failed. */ - inline std::string b64w_encode(const std::string& s) - { - return b64w_encode(s.data(), s.size()); - } +inline std::string b64w_encode(const std::string& s) +{ + return b64w_encode(s.data(), s.size()); +} - /** \brief self-modifing b64w encode +/** \brief self-modifing b64w encode * * web-safe base 64 decode a string (self-modifing) * On failure, the string is empty. @@ -188,32 +180,31 @@ namespace modp { * \param[in,out] s the string to be decoded * \return a reference to the input string */ - inline std::string& b64w_encode(std::string& s) - { - std::string x(b64w_encode(s.data(), s.size())); - s.swap(x); - return s; - } +inline std::string& b64w_encode(std::string& s) +{ + std::string x(b64w_encode(s.data(), s.size())); + s.swap(x); + return s; +} - inline std::string b64w_decode(const char* src, size_t len) - { - std::string x(modp_b64w_decode_len(len)+1, '\0'); - int d = modp_b64w_decode(const_cast(x.data()), src, - static_cast(len)); - if (d < 0) { - x.clear(); - } else { - x.erase(d, std::string::npos); - } - return x; +inline std::string b64w_decode(const char* src, size_t len) +{ + std::string x(modp_b64w_decode_len(len) + 1, '\0'); + size_t d = modp_b64w_decode(const_cast(x.data()), src, len); + if (d == (size_t)-1) { + x.clear(); + } else { + x.erase(d, std::string::npos); } + return x; +} - inline std::string b64w_decode(const char* src) - { - return b64w_decode(src, strlen(src)); - } +inline std::string b64w_decode(const char* src) +{ + return b64w_decode(src, strlen(src)); +} - /** +/** * base 64 decode a string (self-modifing) * On failure, the string is empty. * @@ -222,20 +213,19 @@ namespace modp { * \param[in,out] s the string to be decoded * \return a reference to the input string */ - inline std::string& b64w_decode(std::string& s) - { - std::string x(b64w_decode(s.data(), s.size())); - s.swap(x); - return s; - } +inline std::string& b64w_decode(std::string& s) +{ + std::string x(b64w_decode(s.data(), s.size())); + s.swap(x); + return s; +} - inline std::string b64w_decode(const std::string& s) - { - return b64w_decode(s.data(), s.size()); - } +inline std::string b64w_decode(const std::string& s) +{ + return b64w_decode(s.data(), s.size()); +} } #endif /* __cplusplus */ #endif /* MODP_B64W */ - diff --git a/libwvdrmengine/third_party/stringencoders/src/modp_b64w_data.h b/libwvdrmengine/third_party/stringencoders/src/modp_b64w_data.h index ecb5723c..6698c2fa 100644 --- a/libwvdrmengine/third_party/stringencoders/src/modp_b64w_data.h +++ b/libwvdrmengine/third_party/stringencoders/src/modp_b64w_data.h @@ -1,286 +1,283 @@ -#include +#include "modp_stdint.h" #define CHAR62 '-' #define CHAR63 '_' #define CHARPAD '=' -static const unsigned char e0[256] = { - 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', - 'C', 'C', 'D', 'D', 'D', 'D', 'E', 'E', 'E', 'E', - 'F', 'F', 'F', 'F', 'G', 'G', 'G', 'G', 'H', 'H', - 'H', 'H', 'I', 'I', 'I', 'I', 'J', 'J', 'J', 'J', - 'K', 'K', 'K', 'K', 'L', 'L', 'L', 'L', 'M', 'M', - 'M', 'M', 'N', 'N', 'N', 'N', 'O', 'O', 'O', 'O', - 'P', 'P', 'P', 'P', 'Q', 'Q', 'Q', 'Q', 'R', 'R', - 'R', 'R', 'S', 'S', 'S', 'S', 'T', 'T', 'T', 'T', - 'U', 'U', 'U', 'U', 'V', 'V', 'V', 'V', 'W', 'W', - 'W', 'W', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y', - 'Z', 'Z', 'Z', 'Z', 'a', 'a', 'a', 'a', 'b', 'b', - 'b', 'b', 'c', 'c', 'c', 'c', 'd', 'd', 'd', 'd', - 'e', 'e', 'e', 'e', 'f', 'f', 'f', 'f', 'g', 'g', - 'g', 'g', 'h', 'h', 'h', 'h', 'i', 'i', 'i', 'i', - 'j', 'j', 'j', 'j', 'k', 'k', 'k', 'k', 'l', 'l', - 'l', 'l', 'm', 'm', 'm', 'm', 'n', 'n', 'n', 'n', - 'o', 'o', 'o', 'o', 'p', 'p', 'p', 'p', 'q', 'q', - 'q', 'q', 'r', 'r', 'r', 'r', 's', 's', 's', 's', - 't', 't', 't', 't', 'u', 'u', 'u', 'u', 'v', 'v', - 'v', 'v', 'w', 'w', 'w', 'w', 'x', 'x', 'x', 'x', - 'y', 'y', 'y', 'y', 'z', 'z', 'z', 'z', '0', '0', - '0', '0', '1', '1', '1', '1', '2', '2', '2', '2', - '3', '3', '3', '3', '4', '4', '4', '4', '5', '5', - '5', '5', '6', '6', '6', '6', '7', '7', '7', '7', - '8', '8', '8', '8', '9', '9', '9', '9', '-', '-', - '-', '-', '_', '_', '_', '_' +static const uint8_t e0[256] = { + 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', + 'C', 'C', 'D', 'D', 'D', 'D', 'E', 'E', 'E', 'E', + 'F', 'F', 'F', 'F', 'G', 'G', 'G', 'G', 'H', 'H', + 'H', 'H', 'I', 'I', 'I', 'I', 'J', 'J', 'J', 'J', + 'K', 'K', 'K', 'K', 'L', 'L', 'L', 'L', 'M', 'M', + 'M', 'M', 'N', 'N', 'N', 'N', 'O', 'O', 'O', 'O', + 'P', 'P', 'P', 'P', 'Q', 'Q', 'Q', 'Q', 'R', 'R', + 'R', 'R', 'S', 'S', 'S', 'S', 'T', 'T', 'T', 'T', + 'U', 'U', 'U', 'U', 'V', 'V', 'V', 'V', 'W', 'W', + 'W', 'W', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y', + 'Z', 'Z', 'Z', 'Z', 'a', 'a', 'a', 'a', 'b', 'b', + 'b', 'b', 'c', 'c', 'c', 'c', 'd', 'd', 'd', 'd', + 'e', 'e', 'e', 'e', 'f', 'f', 'f', 'f', 'g', 'g', + 'g', 'g', 'h', 'h', 'h', 'h', 'i', 'i', 'i', 'i', + 'j', 'j', 'j', 'j', 'k', 'k', 'k', 'k', 'l', 'l', + 'l', 'l', 'm', 'm', 'm', 'm', 'n', 'n', 'n', 'n', + 'o', 'o', 'o', 'o', 'p', 'p', 'p', 'p', 'q', 'q', + 'q', 'q', 'r', 'r', 'r', 'r', 's', 's', 's', 's', + 't', 't', 't', 't', 'u', 'u', 'u', 'u', 'v', 'v', + 'v', 'v', 'w', 'w', 'w', 'w', 'x', 'x', 'x', 'x', + 'y', 'y', 'y', 'y', 'z', 'z', 'z', 'z', '0', '0', + '0', '0', '1', '1', '1', '1', '2', '2', '2', '2', + '3', '3', '3', '3', '4', '4', '4', '4', '5', '5', + '5', '5', '6', '6', '6', '6', '7', '7', '7', '7', + '8', '8', '8', '8', '9', '9', '9', '9', '-', '-', + '-', '-', '_', '_', '_', '_' }; - -static const unsigned char e1[256] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '-', '_', 'A', 'B', - 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', - 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', - 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', - 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', '-', '_' +static const uint8_t e1[256] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '-', '_', 'A', 'B', + 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', + 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', + 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', + 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', '-', '_' }; - -static const unsigned char e2[256] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '-', '_', 'A', 'B', - 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', - 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', - 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', - 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', '-', '_' +static const uint8_t e2[256] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '-', '_', 'A', 'B', + 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', + 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '-', '_', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', + 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', + 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', '-', '_' }; - #ifdef WORDS_BIGENDIAN /* SPECIAL DECODE TABLES FOR BIG ENDIAN (IBM/MOTOROLA/SUN) CPUS */ static const uint32_t d0[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00f80000, 0x01ffffff, 0x01ffffff, -0x00d00000, 0x00d40000, 0x00d80000, 0x00dc0000, 0x00e00000, 0x00e40000, -0x00e80000, 0x00ec0000, 0x00f00000, 0x00f40000, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00040000, 0x00080000, 0x000c0000, 0x00100000, 0x00140000, 0x00180000, -0x001c0000, 0x00200000, 0x00240000, 0x00280000, 0x002c0000, 0x00300000, -0x00340000, 0x00380000, 0x003c0000, 0x00400000, 0x00440000, 0x00480000, -0x004c0000, 0x00500000, 0x00540000, 0x00580000, 0x005c0000, 0x00600000, -0x00640000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00fc0000, -0x01ffffff, 0x00680000, 0x006c0000, 0x00700000, 0x00740000, 0x00780000, -0x007c0000, 0x00800000, 0x00840000, 0x00880000, 0x008c0000, 0x00900000, -0x00940000, 0x00980000, 0x009c0000, 0x00a00000, 0x00a40000, 0x00a80000, -0x00ac0000, 0x00b00000, 0x00b40000, 0x00b80000, 0x00bc0000, 0x00c00000, -0x00c40000, 0x00c80000, 0x00cc0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00f80000, 0x01ffffff, 0x01ffffff, + 0x00d00000, 0x00d40000, 0x00d80000, 0x00dc0000, 0x00e00000, 0x00e40000, + 0x00e80000, 0x00ec0000, 0x00f00000, 0x00f40000, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00040000, 0x00080000, 0x000c0000, 0x00100000, 0x00140000, 0x00180000, + 0x001c0000, 0x00200000, 0x00240000, 0x00280000, 0x002c0000, 0x00300000, + 0x00340000, 0x00380000, 0x003c0000, 0x00400000, 0x00440000, 0x00480000, + 0x004c0000, 0x00500000, 0x00540000, 0x00580000, 0x005c0000, 0x00600000, + 0x00640000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00fc0000, + 0x01ffffff, 0x00680000, 0x006c0000, 0x00700000, 0x00740000, 0x00780000, + 0x007c0000, 0x00800000, 0x00840000, 0x00880000, 0x008c0000, 0x00900000, + 0x00940000, 0x00980000, 0x009c0000, 0x00a00000, 0x00a40000, 0x00a80000, + 0x00ac0000, 0x00b00000, 0x00b40000, 0x00b80000, 0x00bc0000, 0x00c00000, + 0x00c40000, 0x00c80000, 0x00cc0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; static const uint32_t d1[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0003e000, 0x01ffffff, 0x01ffffff, -0x00034000, 0x00035000, 0x00036000, 0x00037000, 0x00038000, 0x00039000, -0x0003a000, 0x0003b000, 0x0003c000, 0x0003d000, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, -0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, -0x0000d000, 0x0000e000, 0x0000f000, 0x00010000, 0x00011000, 0x00012000, -0x00013000, 0x00014000, 0x00015000, 0x00016000, 0x00017000, 0x00018000, -0x00019000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0003f000, -0x01ffffff, 0x0001a000, 0x0001b000, 0x0001c000, 0x0001d000, 0x0001e000, -0x0001f000, 0x00020000, 0x00021000, 0x00022000, 0x00023000, 0x00024000, -0x00025000, 0x00026000, 0x00027000, 0x00028000, 0x00029000, 0x0002a000, -0x0002b000, 0x0002c000, 0x0002d000, 0x0002e000, 0x0002f000, 0x00030000, -0x00031000, 0x00032000, 0x00033000, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0003e000, 0x01ffffff, 0x01ffffff, + 0x00034000, 0x00035000, 0x00036000, 0x00037000, 0x00038000, 0x00039000, + 0x0003a000, 0x0003b000, 0x0003c000, 0x0003d000, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, + 0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, + 0x0000d000, 0x0000e000, 0x0000f000, 0x00010000, 0x00011000, 0x00012000, + 0x00013000, 0x00014000, 0x00015000, 0x00016000, 0x00017000, 0x00018000, + 0x00019000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0003f000, + 0x01ffffff, 0x0001a000, 0x0001b000, 0x0001c000, 0x0001d000, 0x0001e000, + 0x0001f000, 0x00020000, 0x00021000, 0x00022000, 0x00023000, 0x00024000, + 0x00025000, 0x00026000, 0x00027000, 0x00028000, 0x00029000, 0x0002a000, + 0x0002b000, 0x0002c000, 0x0002d000, 0x0002e000, 0x0002f000, 0x00030000, + 0x00031000, 0x00032000, 0x00033000, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; static const uint32_t d2[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000f80, 0x01ffffff, 0x01ffffff, -0x00000d00, 0x00000d40, 0x00000d80, 0x00000dc0, 0x00000e00, 0x00000e40, -0x00000e80, 0x00000ec0, 0x00000f00, 0x00000f40, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00000040, 0x00000080, 0x000000c0, 0x00000100, 0x00000140, 0x00000180, -0x000001c0, 0x00000200, 0x00000240, 0x00000280, 0x000002c0, 0x00000300, -0x00000340, 0x00000380, 0x000003c0, 0x00000400, 0x00000440, 0x00000480, -0x000004c0, 0x00000500, 0x00000540, 0x00000580, 0x000005c0, 0x00000600, -0x00000640, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000fc0, -0x01ffffff, 0x00000680, 0x000006c0, 0x00000700, 0x00000740, 0x00000780, -0x000007c0, 0x00000800, 0x00000840, 0x00000880, 0x000008c0, 0x00000900, -0x00000940, 0x00000980, 0x000009c0, 0x00000a00, 0x00000a40, 0x00000a80, -0x00000ac0, 0x00000b00, 0x00000b40, 0x00000b80, 0x00000bc0, 0x00000c00, -0x00000c40, 0x00000c80, 0x00000cc0, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000f80, 0x01ffffff, 0x01ffffff, + 0x00000d00, 0x00000d40, 0x00000d80, 0x00000dc0, 0x00000e00, 0x00000e40, + 0x00000e80, 0x00000ec0, 0x00000f00, 0x00000f40, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00000040, 0x00000080, 0x000000c0, 0x00000100, 0x00000140, 0x00000180, + 0x000001c0, 0x00000200, 0x00000240, 0x00000280, 0x000002c0, 0x00000300, + 0x00000340, 0x00000380, 0x000003c0, 0x00000400, 0x00000440, 0x00000480, + 0x000004c0, 0x00000500, 0x00000540, 0x00000580, 0x000005c0, 0x00000600, + 0x00000640, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000fc0, + 0x01ffffff, 0x00000680, 0x000006c0, 0x00000700, 0x00000740, 0x00000780, + 0x000007c0, 0x00000800, 0x00000840, 0x00000880, 0x000008c0, 0x00000900, + 0x00000940, 0x00000980, 0x000009c0, 0x00000a00, 0x00000a40, 0x00000a80, + 0x00000ac0, 0x00000b00, 0x00000b40, 0x00000b80, 0x00000bc0, 0x00000c00, + 0x00000c40, 0x00000c80, 0x00000cc0, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; static const uint32_t d3[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000003e, 0x01ffffff, 0x01ffffff, -0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, -0x0000003a, 0x0000003b, 0x0000003c, 0x0000003d, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, -0x00000007, 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, -0x0000000d, 0x0000000e, 0x0000000f, 0x00000010, 0x00000011, 0x00000012, -0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 0x00000018, -0x00000019, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000003f, -0x01ffffff, 0x0000001a, 0x0000001b, 0x0000001c, 0x0000001d, 0x0000001e, -0x0000001f, 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, -0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, 0x0000002a, -0x0000002b, 0x0000002c, 0x0000002d, 0x0000002e, 0x0000002f, 0x00000030, -0x00000031, 0x00000032, 0x00000033, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000003e, 0x01ffffff, 0x01ffffff, + 0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, + 0x0000003a, 0x0000003b, 0x0000003c, 0x0000003d, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, + 0x00000007, 0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c, + 0x0000000d, 0x0000000e, 0x0000000f, 0x00000010, 0x00000011, 0x00000012, + 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 0x00000018, + 0x00000019, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000003f, + 0x01ffffff, 0x0000001a, 0x0000001b, 0x0000001c, 0x0000001d, 0x0000001e, + 0x0000001f, 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, + 0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, 0x0000002a, + 0x0000002b, 0x0000002c, 0x0000002d, 0x0000002e, 0x0000002f, 0x00000030, + 0x00000031, 0x00000032, 0x00000033, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; @@ -290,190 +287,190 @@ static const uint32_t d3[256] = { /* SPECIAL DECODE TABLES FOR LITTLE ENDIAN (INTEL) CPUS */ static const uint32_t d0[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000f8, 0x01ffffff, 0x01ffffff, -0x000000d0, 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4, -0x000000e8, 0x000000ec, 0x000000f0, 0x000000f4, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00000004, 0x00000008, 0x0000000c, 0x00000010, 0x00000014, 0x00000018, -0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c, 0x00000030, -0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048, -0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060, -0x00000064, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000fc, -0x01ffffff, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078, -0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090, -0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8, -0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc, 0x000000c0, -0x000000c4, 0x000000c8, 0x000000cc, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000f8, 0x01ffffff, 0x01ffffff, + 0x000000d0, 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4, + 0x000000e8, 0x000000ec, 0x000000f0, 0x000000f4, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00000004, 0x00000008, 0x0000000c, 0x00000010, 0x00000014, 0x00000018, + 0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c, 0x00000030, + 0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048, + 0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060, + 0x00000064, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000fc, + 0x01ffffff, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078, + 0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090, + 0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8, + 0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc, 0x000000c0, + 0x000000c4, 0x000000c8, 0x000000cc, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; static const uint32_t d1[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000e003, 0x01ffffff, 0x01ffffff, -0x00004003, 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003, -0x0000a003, 0x0000b003, 0x0000c003, 0x0000d003, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, -0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, -0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001, -0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001, -0x00009001, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000f003, -0x01ffffff, 0x0000a001, 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001, -0x0000f001, 0x00000002, 0x00001002, 0x00002002, 0x00003002, 0x00004002, -0x00005002, 0x00006002, 0x00007002, 0x00008002, 0x00009002, 0x0000a002, -0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002, 0x00000003, -0x00001003, 0x00002003, 0x00003003, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000e003, 0x01ffffff, 0x01ffffff, + 0x00004003, 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003, + 0x0000a003, 0x0000b003, 0x0000c003, 0x0000d003, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, + 0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, + 0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001, + 0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001, + 0x00009001, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000f003, + 0x01ffffff, 0x0000a001, 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001, + 0x0000f001, 0x00000002, 0x00001002, 0x00002002, 0x00003002, 0x00004002, + 0x00005002, 0x00006002, 0x00007002, 0x00008002, 0x00009002, 0x0000a002, + 0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002, 0x00000003, + 0x00001003, 0x00002003, 0x00003003, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; static const uint32_t d2[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00800f00, 0x01ffffff, 0x01ffffff, -0x00000d00, 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00, -0x00800e00, 0x00c00e00, 0x00000f00, 0x00400f00, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00400000, 0x00800000, 0x00c00000, 0x00000100, 0x00400100, 0x00800100, -0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200, 0x00000300, -0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400, -0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600, -0x00400600, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00c00f00, -0x01ffffff, 0x00800600, 0x00c00600, 0x00000700, 0x00400700, 0x00800700, -0x00c00700, 0x00000800, 0x00400800, 0x00800800, 0x00c00800, 0x00000900, -0x00400900, 0x00800900, 0x00c00900, 0x00000a00, 0x00400a00, 0x00800a00, -0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00, 0x00000c00, -0x00400c00, 0x00800c00, 0x00c00c00, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00800f00, 0x01ffffff, 0x01ffffff, + 0x00000d00, 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00, + 0x00800e00, 0x00c00e00, 0x00000f00, 0x00400f00, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00400000, 0x00800000, 0x00c00000, 0x00000100, 0x00400100, 0x00800100, + 0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200, 0x00000300, + 0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400, + 0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600, + 0x00400600, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00c00f00, + 0x01ffffff, 0x00800600, 0x00c00600, 0x00000700, 0x00400700, 0x00800700, + 0x00c00700, 0x00000800, 0x00400800, 0x00800800, 0x00c00800, 0x00000900, + 0x00400900, 0x00800900, 0x00c00900, 0x00000a00, 0x00400a00, 0x00800a00, + 0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00, 0x00000c00, + 0x00400c00, 0x00800c00, 0x00c00c00, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; static const uint32_t d3[256] = { -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003e0000, 0x01ffffff, 0x01ffffff, -0x00340000, 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000, -0x003a0000, 0x003b0000, 0x003c0000, 0x003d0000, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, -0x00010000, 0x00020000, 0x00030000, 0x00040000, 0x00050000, 0x00060000, -0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000, 0x000c0000, -0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000, -0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000, -0x00190000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003f0000, -0x01ffffff, 0x001a0000, 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000, -0x001f0000, 0x00200000, 0x00210000, 0x00220000, 0x00230000, 0x00240000, -0x00250000, 0x00260000, 0x00270000, 0x00280000, 0x00290000, 0x002a0000, -0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000, 0x00300000, -0x00310000, 0x00320000, 0x00330000, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, -0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003e0000, 0x01ffffff, 0x01ffffff, + 0x00340000, 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000, + 0x003a0000, 0x003b0000, 0x003c0000, 0x003d0000, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, + 0x00010000, 0x00020000, 0x00030000, 0x00040000, 0x00050000, 0x00060000, + 0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000, 0x000c0000, + 0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000, + 0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000, + 0x00190000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003f0000, + 0x01ffffff, 0x001a0000, 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000, + 0x001f0000, 0x00200000, 0x00210000, 0x00220000, 0x00230000, 0x00240000, + 0x00250000, 0x00260000, 0x00270000, 0x00280000, 0x00290000, 0x002a0000, + 0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000, 0x00300000, + 0x00310000, 0x00320000, 0x00330000, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, + 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff }; diff --git a/libwvdrmengine/vts/vendor_module/Android.mk b/libwvdrmengine/vts/vendor_module/Android.mk index 2812e80a..f34413f0 100644 --- a/libwvdrmengine/vts/vendor_module/Android.mk +++ b/libwvdrmengine/vts/vendor_module/Android.mk @@ -24,7 +24,7 @@ LOCAL_STATIC_LIBRARIES := \ libgtest \ libcdm \ libcdm_utils \ - libcrypto + libcrypto_static LOCAL_SHARED_LIBRARIES := \ libcutils \ @@ -35,7 +35,6 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_MODULE := libvtswidevine LOCAL_MODULE_RELATIVE_PATH := drm-vts-test-libs LOCAL_MODULE_TAGS := optional -LOCAL_PROPRIETARY_MODULE := true include $(BUILD_SHARED_LIBRARY) diff --git a/libwvdrmengine/vts/vendor_module/vts_module.cpp b/libwvdrmengine/vts/vendor_module/vts_module.cpp index 16d89eec..205abb67 100644 --- a/libwvdrmengine/vts/vendor_module/vts_module.cpp +++ b/libwvdrmengine/vts/vendor_module/vts_module.cpp @@ -87,8 +87,6 @@ namespace widevine_vts { WidevineVTSVendorModule_V1::getContentConfigurations() const { vector configurations; - - // Content Configuration #1 { const string serverUrl = "http://widevine-proxy.appspot.com/proxy"; const vector initData = a2b_hex(