Refactor oemcrypto mock into stand alone reference code
Merge from Widevine repo of http://go/wvgerrit/46204 Refactor utility code - split the mock, step 1 Merge from Widevine repo of http://go/wvgerrit/46205 Move some OEMCrypto types to common header - split the mock, step 2 Merge from Widevine repo of http://go/wvgerrit/46206 Split mock into two -- step 3 Merge from Widevine repo of http://go/wvgerrit/47460 Split the mock into two -- step 3.5 The CL moves several files used by oemcrypto and cdm into a common subdirectory, so that it may more easily be shared with partners. The CORE_DISALLOW_COPY_AND_ASSIGN macro was moved to its own header in the util/include directory. This CL removes some references to the mock from other code, and puts some constants and types, such as the definition of the keybox, into a header in oemcrypto. Test: tested as part of http://go/ag/4674759 bug: 76393338 Change-Id: I75b4bde7062ed8ee572c97ebc2f4da018f4be0c9
This commit is contained in:
@@ -91,6 +91,7 @@ LOCAL_STATIC_LIBRARIES := libcrypto
|
||||
LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include \
|
||||
|
||||
LOCAL_HEADER_LIBRARIES := \
|
||||
@@ -100,15 +101,16 @@ LOCAL_SHARED_LIBRARIES := \
|
||||
liblog
|
||||
|
||||
SRC_DIR := cdm/src
|
||||
UTIL_SRC_DIR := cdm/util/src
|
||||
CORE_SRC_DIR := cdm/core/src
|
||||
LOCAL_SRC_FILES := \
|
||||
$(CORE_SRC_DIR)/properties.cpp \
|
||||
$(CORE_SRC_DIR)/string_conversions.cpp \
|
||||
$(SRC_DIR)/clock.cpp \
|
||||
$(SRC_DIR)/file_store.cpp \
|
||||
$(SRC_DIR)/file_utils.cpp \
|
||||
$(SRC_DIR)/lock.cpp \
|
||||
$(SRC_DIR)/log.cpp \
|
||||
$(UTIL_SRC_DIR)/string_conversions.cpp \
|
||||
$(UTIL_SRC_DIR)/clock.cpp \
|
||||
$(UTIL_SRC_DIR)/file_store.cpp \
|
||||
$(UTIL_SRC_DIR)/file_utils.cpp \
|
||||
$(UTIL_SRC_DIR)/lock.cpp \
|
||||
$(UTIL_SRC_DIR)/log.cpp \
|
||||
$(SRC_DIR)/properties_android.cpp \
|
||||
$(SRC_DIR)/timer.cpp \
|
||||
|
||||
@@ -160,6 +162,7 @@ LOCAL_C_INCLUDES := \
|
||||
frameworks/native/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/metrics/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/include \
|
||||
vendor/widevine/libwvdrmengine/mediacrypto/include \
|
||||
@@ -217,6 +220,7 @@ LOCAL_C_INCLUDES := \
|
||||
frameworks/native/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/metrics/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/include_hidl \
|
||||
vendor/widevine/libwvdrmengine/include \
|
||||
|
||||
@@ -9,6 +9,7 @@ LOCAL_CFLAGS := -DDYNAMIC_ADAPTER
|
||||
LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/metrics/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include \
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "wv_cdm_types.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "certificate_provisioning.h"
|
||||
#include "clock.h"
|
||||
#include "crypto_session.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "file_store.h"
|
||||
#include "initialization_data.h"
|
||||
#include "lock.h"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "crypto_session.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "device_files.h"
|
||||
#include "file_store.h"
|
||||
#include "initialization_data.h"
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <string>
|
||||
|
||||
#include "cdm_session.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "lock.h"
|
||||
#include "shared_ptr.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "crypto_session.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "license_protocol.pb.h"
|
||||
#include "metrics_collections.h"
|
||||
#include "oemcrypto_adapter.h"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// ClientIdentification fills in the ClientIdentification portion
|
||||
// of the License or Provisioning request messages.
|
||||
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "license_protocol.pb.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "key_session.h"
|
||||
#include "lock.h"
|
||||
#include "metrics_collections.h"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "device_files.pb.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "scoped_ptr.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
|
||||
@@ -31,4 +31,4 @@ class EntitlementKeySession : public ContentKeySession {
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_ENTITLEMENT_KEY_SESSSION_H_
|
||||
#endif // WVCDM_CORE_ENTITLEMENT_KEY_SESSSION_H_
|
||||
|
||||
@@ -43,4 +43,4 @@ typedef std::map<std::string, CryptoSessionId> SubLicenseSessionMap;
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_KEY_SESSSION_H_
|
||||
#endif // WVCDM_CORE_KEY_SESSSION_H_
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "initialization_data.h"
|
||||
#include "license_protocol.pb.h"
|
||||
#include "scoped_ptr.h"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <map>
|
||||
|
||||
#include "crypto_session.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "license_protocol.pb.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "license_key_status.h"
|
||||
#include "license_protocol.pb.h"
|
||||
#include "scoped_ptr.h"
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "cdm_client_property_set.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "lock.h"
|
||||
#include "scoped_ptr.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef WVCDM_CORE_SCOPED_PTR_H_
|
||||
#define WVCDM_CORE_SCOPED_PTR_H_
|
||||
|
||||
#include "wv_cdm_types.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "license_protocol.pb.h"
|
||||
#include "privacy_crypto.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "crypto_session.h"
|
||||
#include "device_files.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "file_store.h"
|
||||
#include "lock.h"
|
||||
#include "metrics_collections.h"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef WVCDM_CORE_WV_CDM_EVENT_LISTENER_H_
|
||||
#define WVCDM_CORE_WV_CDM_EVENT_LISTENER_H_
|
||||
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
@@ -155,7 +155,7 @@ enum CdmResponseType {
|
||||
/* previously RESTORE_OFFLINE_LICENSE_ERROR_1 = 112 */
|
||||
RESTORE_OFFLINE_LICENSE_ERROR_2 = 113,
|
||||
NOT_INITIALIZED_ERROR = 114, /* prior to pi, SESSION_INIT_ERROR_1 = 114 */
|
||||
REINIT_ERROR = 115, /* prior to pi, SESSION_INIT_ERROR_2 = 115 */
|
||||
REINIT_ERROR = 115, /* prior to pi, SESSION_INIT_ERROR_2 = 115 */
|
||||
/* previously SESSION_INIT_GET_KEYBOX_ERROR = 116 */
|
||||
SESSION_NOT_FOUND_1 = 117,
|
||||
SESSION_NOT_FOUND_2 = 118,
|
||||
@@ -345,10 +345,6 @@ enum CdmKeyStatus {
|
||||
};
|
||||
typedef std::map<KeyId, CdmKeyStatus> CdmKeyStatusMap;
|
||||
|
||||
#define CORE_DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName&); \
|
||||
void operator=(const TypeName&)
|
||||
|
||||
enum CdmLicenseType {
|
||||
kLicenseTypeOffline,
|
||||
kLicenseTypeStreaming,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "cdm_engine.h"
|
||||
#include "config_test_env.h"
|
||||
#include "device_files.h"
|
||||
#include "initialization_data.h"
|
||||
#include "file_store.h"
|
||||
#include "license_request.h"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define CDM_TEST_CONFIG_TEST_ENV_H_
|
||||
|
||||
#include <string>
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
// Declare class ConfigTestEnv - holds the configuration settings needed
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
#include "license_request.h"
|
||||
#include "log.h"
|
||||
#include "oec_session_util.h"
|
||||
#include "../../oemcrypto/mock/src/oemcrypto_key_mock.h"
|
||||
#include "oemcrypto_session_tests_helper.h"
|
||||
#include "oemcrypto_types.h"
|
||||
#include "properties.h"
|
||||
#include "string_conversions.h"
|
||||
#include "url_request.h"
|
||||
@@ -113,13 +113,13 @@ class WvGenericOperationsTest : public testing::Test,
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
oec_util_session_.FillSimpleMessage(duration, control, nonce, pst));
|
||||
oec_util_session_.license().keys[kGenericEncrypt].control.control_bits |=
|
||||
htonl(wvoec_mock::kControlAllowEncrypt);
|
||||
htonl(wvoec::kControlAllowEncrypt);
|
||||
oec_util_session_.license().keys[kGenericDecrypt].control.control_bits |=
|
||||
htonl(wvoec_mock::kControlAllowDecrypt);
|
||||
htonl(wvoec::kControlAllowDecrypt);
|
||||
oec_util_session_.license().keys[kGenericSign].control.control_bits |=
|
||||
htonl(wvoec_mock::kControlAllowSign);
|
||||
htonl(wvoec::kControlAllowSign);
|
||||
oec_util_session_.license().keys[kGenericVerify].control.control_bits |=
|
||||
htonl(wvoec_mock::kControlAllowVerify);
|
||||
htonl(wvoec::kControlAllowVerify);
|
||||
|
||||
oec_util_session_.license().keys[kGenericSign].key_data_length =
|
||||
wvcdm::MAC_KEY_SIZE;
|
||||
@@ -387,10 +387,10 @@ class WvGenericOperationsDataTest : public WvGenericOperationsTest {
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
oec_util_session_.FillSimpleMessage(duration, control, nonce, pst));
|
||||
oec_util_session_.license().keys[kGenericEncrypt].control.control_bits |=
|
||||
htonl(wvoec_mock::kControlAllowEncrypt |
|
||||
wvoec_mock::kControlAllowDecrypt);
|
||||
htonl(wvoec::kControlAllowEncrypt |
|
||||
wvoec::kControlAllowDecrypt);
|
||||
oec_util_session_.license().keys[kGenericSign].control.control_bits |=
|
||||
htonl(wvoec_mock::kControlAllowSign | wvoec_mock::kControlAllowVerify);
|
||||
htonl(wvoec::kControlAllowSign | wvoec::kControlAllowVerify);
|
||||
|
||||
oec_util_session_.license().keys[kGenericSign].key_data_length =
|
||||
wvcdm::MAC_KEY_SIZE;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <gtest/gtest_prod.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "wv_cdm_types.h" // CORE_DISALLOW_COPY_AND_ASSIGN
|
||||
#include "disallow_copy_and_assign.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define CDM_TEST_LICENSE_REQUEST_H_
|
||||
|
||||
#include <string>
|
||||
#include "wv_cdm_types.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#define CDM_TEST_URL_REQUEST_H_
|
||||
|
||||
#include <string>
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "http_socket.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
#ifndef CDM_BASE_TIMER_H_
|
||||
#define CDM_BASE_TIMER_H_
|
||||
|
||||
#include "wv_cdm_types.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#include "disallow_copy_and_assign.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
#include "cdm_identifier.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "file_store.h"
|
||||
#include "lock.h"
|
||||
#include "metrics.pb.h"
|
||||
|
||||
@@ -23,6 +23,7 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/test \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/metrics/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include \
|
||||
|
||||
LOCAL_C_INCLUDES += external/protobuf/src
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Clock - Platform independent interface for a time library
|
||||
//
|
||||
#ifndef WVCDM_CORE_CLOCK_H_
|
||||
#define WVCDM_CORE_CLOCK_H_
|
||||
#ifndef WVCDM_UTIL_CLOCK_H_
|
||||
#define WVCDM_UTIL_CLOCK_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -23,4 +21,4 @@ class Clock {
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_CLOCK_H_
|
||||
#endif // WVCDM_UTIL_CLOCK_H_
|
||||
15
libwvdrmengine/cdm/util/include/disallow_copy_and_assign.h
Normal file
15
libwvdrmengine/cdm/util/include/disallow_copy_and_assign.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright 2018 Google Inc. All Rights Reserved.
|
||||
|
||||
#ifndef WVCDM_UTIL_DISALLOW_COPY_AND_ASSIGN_H_
|
||||
#define WVCDM_UTIL_DISALLOW_COPY_AND_ASSIGN_H_
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
#define CORE_DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName&); \
|
||||
void operator=(const TypeName&)
|
||||
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_UTIL_DISALLOW_COPY_AND_ASSIGN_H_
|
||||
@@ -1,17 +1,15 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// File - Platform independent interface for a File class
|
||||
//
|
||||
#ifndef WVCDM_CORE_FILE_STORE_H_
|
||||
#define WVCDM_CORE_FILE_STORE_H_
|
||||
#ifndef WVCDM_UTIL_FILE_STORE_H_
|
||||
#define WVCDM_UTIL_FILE_STORE_H_
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "wv_cdm_types.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
@@ -79,4 +77,4 @@ class FileSystem {
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_FILE_STORE_H_
|
||||
#endif // WVCDM_UTIL_FILE_STORE_H_
|
||||
@@ -1,13 +1,11 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Lock - Platform independent interface for a Mutex class
|
||||
//
|
||||
#ifndef WVCDM_CORE_LOCK_H_
|
||||
#define WVCDM_CORE_LOCK_H_
|
||||
#ifndef WVCDM_UTIL_LOCK_H_
|
||||
#define WVCDM_UTIL_LOCK_H_
|
||||
|
||||
#include "wv_cdm_types.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
@@ -50,4 +48,4 @@ class AutoLock {
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_LOCK_H_
|
||||
#endif // WVCDM_UTIL_LOCK_H_
|
||||
@@ -1,11 +1,9 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Log - Platform independent interface for a Logging class
|
||||
//
|
||||
#ifndef WVCDM_CORE_LOG_H_
|
||||
#define WVCDM_CORE_LOG_H_
|
||||
#ifndef WVCDM_UTIL_LOG_H_
|
||||
#define WVCDM_UTIL_LOG_H_
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
@@ -31,6 +29,7 @@ void Log(const char* file, const char* function, int line, LogPriority level,
|
||||
const char* fmt, ...);
|
||||
|
||||
// Log APIs
|
||||
#ifndef LOGE
|
||||
#define LOGE(...) Log(__FILE__, __func__, __LINE__, \
|
||||
wvcdm::LOG_ERROR, __VA_ARGS__)
|
||||
#define LOGW(...) Log(__FILE__, __func__, __LINE__, \
|
||||
@@ -41,6 +40,7 @@ void Log(const char* file, const char* function, int line, LogPriority level,
|
||||
wvcdm::LOG_DEBUG, __VA_ARGS__)
|
||||
#define LOGV(...) Log(__FILE__, __func__, __LINE__, \
|
||||
wvcdm::LOG_VERBOSE, __VA_ARGS__)
|
||||
#endif
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_LOG_H_
|
||||
#endif // WVCDM_UTIL_LOG_H_
|
||||
@@ -1,9 +1,7 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
#ifndef WVCDM_CORE_STRING_CONVERSIONS_H_
|
||||
#define WVCDM_CORE_STRING_CONVERSIONS_H_
|
||||
#ifndef WVCDM_UTIL_STRING_CONVERSIONS_H_
|
||||
#define WVCDM_UTIL_STRING_CONVERSIONS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@@ -29,4 +27,4 @@ inline int64_t ntohll64(int64_t x) { return htonll64(x); }
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_STRING_CONVERSIONS_H_
|
||||
#endif // WVCDM_UTIL_STRING_CONVERSIONS_H_
|
||||
@@ -1,6 +1,4 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
#include "string_conversions.h"
|
||||
|
||||
@@ -7,6 +7,7 @@ LOCAL_CFLAGS := \
|
||||
LOCAL_C_INCLUDES := \
|
||||
system/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/level3/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include
|
||||
LOCAL_MODULE := libwvlevel3
|
||||
|
||||
@@ -7,6 +7,7 @@ LOCAL_CFLAGS := \
|
||||
LOCAL_C_INCLUDES := \
|
||||
system/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/level3/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include
|
||||
LOCAL_MODULE := libwvlevel3
|
||||
|
||||
@@ -7,6 +7,7 @@ LOCAL_CFLAGS := \
|
||||
LOCAL_C_INCLUDES := \
|
||||
system/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/level3/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include
|
||||
LOCAL_MODULE := libwvlevel3
|
||||
|
||||
@@ -7,6 +7,7 @@ LOCAL_CFLAGS := \
|
||||
LOCAL_C_INCLUDES := \
|
||||
system/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/level3/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include
|
||||
LOCAL_MODULE := libwvlevel3
|
||||
|
||||
@@ -7,6 +7,7 @@ LOCAL_CFLAGS := \
|
||||
LOCAL_C_INCLUDES := \
|
||||
system/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/level3/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include
|
||||
LOCAL_MODULE := libwvlevel3
|
||||
|
||||
@@ -7,6 +7,7 @@ LOCAL_CFLAGS := \
|
||||
LOCAL_C_INCLUDES := \
|
||||
system/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/level3/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include
|
||||
LOCAL_MODULE := libwvlevel3
|
||||
|
||||
@@ -14,6 +14,7 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/metrics/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/include \
|
||||
vendor/widevine/libwvdrmengine/mediacrypto/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include \
|
||||
@@ -49,6 +50,7 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/metrics/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/include_hidl \
|
||||
vendor/widevine/libwvdrmengine/include \
|
||||
vendor/widevine/libwvdrmengine/mediacrypto/include_hidl \
|
||||
|
||||
@@ -14,6 +14,7 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/metrics/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/mediacrypto/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include \
|
||||
|
||||
@@ -70,6 +71,7 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/metrics/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/include_hidl \
|
||||
vendor/widevine/libwvdrmengine/mediacrypto/include_hidl \
|
||||
vendor/widevine/libwvdrmengine/mediacrypto/include \
|
||||
|
||||
@@ -15,6 +15,7 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/metrics/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/include \
|
||||
vendor/widevine/libwvdrmengine/mediadrm/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include \
|
||||
@@ -51,6 +52,7 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/metrics/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/include_hidl \
|
||||
vendor/widevine/libwvdrmengine/include \
|
||||
vendor/widevine/libwvdrmengine/mediadrm/include_hidl \
|
||||
|
||||
@@ -14,6 +14,7 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/metrics/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/include \
|
||||
vendor/widevine/libwvdrmengine/mediadrm/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include \
|
||||
@@ -70,6 +71,7 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/metrics/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/include_hidl \
|
||||
vendor/widevine/libwvdrmengine/include \
|
||||
vendor/widevine/libwvdrmengine/mediadrm/include_hidl \
|
||||
@@ -133,6 +135,7 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/metrics/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
vendor/widevine/libwvdrmengine/include_hidl \
|
||||
vendor/widevine/libwvdrmengine/include \
|
||||
vendor/widevine/libwvdrmengine/mediadrm/include_hidl \
|
||||
|
||||
67
libwvdrmengine/oemcrypto/include/oemcrypto_types.h
Normal file
67
libwvdrmengine/oemcrypto/include/oemcrypto_types.h
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WV_OEMCRYPTO_TYPES_H_
|
||||
#define WV_OEMCRYPTO_TYPES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace wvoec {
|
||||
|
||||
// This is the format of a Widevine keybox.
|
||||
typedef struct WidevineKeybox { // 128 bytes total.
|
||||
// C character string identifying the device. Null terminated.
|
||||
uint8_t device_id_[32];
|
||||
// 128 bit AES key assigned to device. Generated by Widevine.
|
||||
uint8_t device_key_[16];
|
||||
// Key Data. Encrypted data.
|
||||
uint8_t data_[72];
|
||||
// Constant code used to recognize a valid keybox "kbox" = 0x6b626f78.
|
||||
uint8_t magic_[4];
|
||||
// The CRC checksum of the first 124 bytes of the keybox.
|
||||
uint8_t crc_[4];
|
||||
} WidevineKeybox;
|
||||
|
||||
// Key Control Block Bit Masks:
|
||||
const uint32_t kControlObserveDataPath = (1<<31);
|
||||
const uint32_t kControlObserveHDCP = (1<<30);
|
||||
const uint32_t kControlObserveCGMS = (1<<29);
|
||||
const uint32_t kControlRequireAntiRollbackHardware = (1<<28);
|
||||
const uint32_t kSharedLicense = (1<<23);
|
||||
const uint32_t kControlSRMVersionRequired = (1<<22);
|
||||
const uint32_t kControlDisableAnalogOutput = (1<<21);
|
||||
const uint32_t kControlSecurityPatchLevelShift = 15;
|
||||
const uint32_t kControlSecurityPatchLevelMask =
|
||||
(0x3F<<kControlSecurityPatchLevelShift);
|
||||
const uint32_t kControlReplayMask = (0x03<<13);
|
||||
const uint32_t kControlNonceRequired = (0x01<<13);
|
||||
const uint32_t kControlNonceOrEntry = (0x02<<13);
|
||||
const uint32_t kControlHDCPVersionShift = 9;
|
||||
const uint32_t kControlHDCPVersionMask = (0x0F<<kControlHDCPVersionShift);
|
||||
const uint32_t kControlAllowEncrypt = (1<<8);
|
||||
const uint32_t kControlAllowDecrypt = (1<<7);
|
||||
const uint32_t kControlAllowSign = (1<<6);
|
||||
const uint32_t kControlAllowVerify = (1<<5);
|
||||
const uint32_t kControlDataPathSecure = (1<<4);
|
||||
const uint32_t kControlNonceEnabled = (1<<3);
|
||||
const uint32_t kControlHDCPRequired = (1<<2);
|
||||
const uint32_t kControlCGMSMask = (0x03);
|
||||
const uint32_t kControlCGMSCopyFreely = (0x00);
|
||||
const uint32_t kControlCGMSCopyOnce = (0x02);
|
||||
const uint32_t kControlCGMSCopyNever = (0x03);
|
||||
|
||||
// Various constants and sizes:
|
||||
static const size_t KEY_CONTROL_SIZE = 16;
|
||||
static const size_t KEY_ID_SIZE = 16;
|
||||
static const size_t KEY_IV_SIZE = 16;
|
||||
static const size_t KEY_PAD_SIZE = 16;
|
||||
static const size_t KEY_SIZE = 16;
|
||||
static const size_t MAC_KEY_SIZE = 32;
|
||||
static const size_t KEYBOX_KEY_DATA_SIZE = 72;
|
||||
static const size_t SRM_REQUIREMENT_SIZE = 12;
|
||||
|
||||
|
||||
} // namespace wvoec
|
||||
|
||||
#endif // WV_OEMCRYPTO_TYPES_H_
|
||||
@@ -84,12 +84,12 @@ class Unpacked_PST_Report {
|
||||
int64_t time;
|
||||
memcpy(&time, buffer_ + kseconds_since_license_received_offset,
|
||||
sizeof(int64_t));
|
||||
return wvcdm::ntohll64(time);
|
||||
return ntohll64(time);
|
||||
}
|
||||
|
||||
// Parameter time is in host byte order.
|
||||
void set_seconds_since_license_received(int64_t time) const {
|
||||
time = wvcdm::ntohll64(time);
|
||||
time = ntohll64(time);
|
||||
memcpy(buffer_ + kseconds_since_license_received_offset, &time,
|
||||
sizeof(int64_t));
|
||||
}
|
||||
@@ -99,12 +99,12 @@ class Unpacked_PST_Report {
|
||||
int64_t time;
|
||||
memcpy(&time, buffer_ + kseconds_since_first_decrypt_offset,
|
||||
sizeof(int64_t));
|
||||
return wvcdm::ntohll64(time);
|
||||
return ntohll64(time);
|
||||
}
|
||||
|
||||
// Parameter time is in host byte order.
|
||||
void set_seconds_since_first_decrypt(int64_t time) const {
|
||||
time = wvcdm::ntohll64(time);
|
||||
time = ntohll64(time);
|
||||
memcpy(buffer_ + kseconds_since_first_decrypt_offset, &time,
|
||||
sizeof(int64_t));
|
||||
}
|
||||
@@ -114,12 +114,12 @@ class Unpacked_PST_Report {
|
||||
int64_t time;
|
||||
memcpy(&time, buffer_ + kseconds_since_last_decrypt_offset,
|
||||
sizeof(int64_t));
|
||||
return wvcdm::ntohll64(time);
|
||||
return ntohll64(time);
|
||||
}
|
||||
|
||||
// Parameter time is in host byte order.
|
||||
void set_seconds_since_last_decrypt(int64_t time) const {
|
||||
time = wvcdm::ntohll64(time);
|
||||
time = ntohll64(time);
|
||||
memcpy(buffer_ + kseconds_since_last_decrypt_offset, &time,
|
||||
sizeof(int64_t));
|
||||
}
|
||||
|
||||
@@ -1,599 +0,0 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
//
|
||||
// This file contains oemcrypto engine properties that reads data from a file
|
||||
// to decide what it's current status is. It is used for testing cdm code.
|
||||
// The following properties are read from the file:
|
||||
// log_level: logging level to use.
|
||||
// 0 = LOG_ERROR,
|
||||
// 1 = LOG_WARN,
|
||||
// 2 = LOG_INFO,
|
||||
// 3 = LOG_DEBUG,
|
||||
// 4 = LOG_VERBOSE
|
||||
// kLogging*: All logging flags found in oemcrypto/include/oemcrypto_logging.h
|
||||
// can be turned on (1) or off (0).
|
||||
// security_level: returned by OEMCrypto_SecurityLevel.
|
||||
// secure_lib: If set, then this will be used as a path to
|
||||
// the L1 liboemcrypto.so that we can use secure buffers.
|
||||
// current_hdcp: returned by OEMCrypto_GetHDCPCapability and
|
||||
// used to verify the key control block in methods like DecryptCENC.
|
||||
// HDCP_NONE = 0, // No HDCP supported, no secure data path.
|
||||
// HDCP_V1 = 1, // HDCP version 1.0
|
||||
// HDCP_V2 = 2, // HDCP version 2.0 Type 1.
|
||||
// HDCP_V2_1 = 3, // HDCP version 2.1 Type 1.
|
||||
// HDCP_V2_2 = 4, // HDCP version 2.2 Type 1.
|
||||
// HDCP_NO_DIGITAL_OUTPUT = 0xff // No digital output.
|
||||
// max_hdcp: returned by OEMCrypto_GetHDCPCapability. Same values as above.
|
||||
// srm_update_supported: If "1", then srm update is supported.
|
||||
// srm_initial_version: Initial value for srm version.
|
||||
// This will be ignored after a reset. If this is not set, CurrentSRM will
|
||||
// return NOT_IMPLEMENTED.
|
||||
// srm_load_fail: If set to a nonzero number, then load_srm will
|
||||
// fail and the version will not be updated. The number is converted to
|
||||
// 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.
|
||||
// max_buffer_size: maximum size of a buffer accepted by DecryptCENC and
|
||||
// friends. If this is 0, there is no restriction. If it is 1, the
|
||||
// minimum allowed value is used.
|
||||
// use_keybox: If this is 1, then the test keybox is used. If this is zero,
|
||||
// then the test OEM certificate is used.
|
||||
// use_fallback: If this is nonzero, then the installed Level 1 library will
|
||||
// be used to play content to a secure buffer. Decryption and key
|
||||
// verification are done by the mock, but then the data is copied to the
|
||||
// secure buffer using OEMCrypto_CopyBuffer. The filename of the fallback
|
||||
// library is hardcoded to "level1_backup_liboemcrypto.so". It is
|
||||
// recommended you use the install script to ensure you have the right
|
||||
// filename.
|
||||
//
|
||||
#include <arpa/inet.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "log.h"
|
||||
#include "oem_cert.h"
|
||||
#include "oemcrypto_engine_mock.h"
|
||||
#include "oemcrypto_logging.h"
|
||||
#include "properties.h"
|
||||
#include "string_conversions.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace {
|
||||
typedef OEMCryptoResult (*L1_Initialize_t)(void);
|
||||
typedef OEMCryptoResult (*L1_Terminate_t)(void);
|
||||
typedef OEMCryptoResult (*L1_CopyBuffer_t)(const uint8_t* data_addr,
|
||||
size_t data_length,
|
||||
OEMCrypto_DestBufferDesc* out_buffer,
|
||||
uint8_t subsample_flags);
|
||||
const std::string kDefaultOptionsFile = "/data/mediadrm/oemcrypto/options.txt";
|
||||
} // namespace
|
||||
|
||||
class AndroidModifiableCryptoEngine : public CryptoEngine {
|
||||
public:
|
||||
AndroidModifiableCryptoEngine(std::auto_ptr<wvcdm::FileSystem> file_system)
|
||||
: CryptoEngine(file_system),
|
||||
options_file_(kDefaultOptionsFile),
|
||||
srm_loaded_(false),
|
||||
srm_version_(0),
|
||||
level1_valid_(false),
|
||||
level1_library_(NULL) {
|
||||
std::string path;
|
||||
if (wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL3,
|
||||
&path)) {
|
||||
options_file_ = path + "options.txt";
|
||||
}
|
||||
}
|
||||
|
||||
void MaybeReadOptionsFile() {
|
||||
static time_t last_check = 0;
|
||||
static time_t last_changed = 0;
|
||||
time_t now = time(NULL);
|
||||
if (now > last_check + 5) { // Check every five seconds.
|
||||
last_check = now;
|
||||
struct stat file_stat;
|
||||
if (stat(options_file_.c_str(), &file_stat)) {
|
||||
LOGE("Could not stat %s: %s", options_file_.c_str(), strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (file_stat.st_mtime > last_changed) {
|
||||
last_changed = file_stat.st_mtime;
|
||||
ReadOptionsFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReadOptionsFile() {
|
||||
FILE *file = fopen(options_file_.c_str(), "r");
|
||||
if (!file) {
|
||||
LOGE("Could not read %s %s", options_file_.c_str(), strerror(errno));
|
||||
return;
|
||||
}
|
||||
while (!feof(file)) {
|
||||
char name[80 + 1];
|
||||
int64_t value;
|
||||
if (fscanf(file, "%80s %lld", name, &value)) {
|
||||
LOGD("Option %s = %lld", name, value);
|
||||
options_[std::string(name)] = value;
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
InitializeLogging();
|
||||
}
|
||||
|
||||
int64_t GetOption(const std::string &key, int64_t default_value) {
|
||||
MaybeReadOptionsFile();
|
||||
if (options_.find(key) == options_.end() ) {
|
||||
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", wvcdm::LOG_DEBUG);
|
||||
int categories = 0;
|
||||
if (GetOption("kLoggingTraceOEMCryptoCalls", 0) > 0)
|
||||
categories |= kLoggingTraceOEMCryptoCalls;
|
||||
if (GetOption("kLoggingDumpContentKeys", 0) > 0)
|
||||
categories |= kLoggingDumpContentKeys;
|
||||
if (GetOption("kLoggingDumpKeyControlBlocks", 0) > 0)
|
||||
categories |= kLoggingDumpKeyControlBlocks;
|
||||
if (GetOption("kLoggingDumpDerivedKeys", 0) > 0)
|
||||
categories |= kLoggingDumpDerivedKeys;
|
||||
if (GetOption("kLoggingTraceNonce", 0) > 0)
|
||||
categories |= kLoggingTraceNonce;
|
||||
if (GetOption("kLoggingTraceDecryption", 0) > 0)
|
||||
categories |= kLoggingTraceDecryption;
|
||||
if (GetOption("kLoggingTraceUsageTable", 0) > 0)
|
||||
categories |= kLoggingTraceUsageTable;
|
||||
if (GetOption("kLoggingTraceDecryptCalls", 0) > 0)
|
||||
categories |= kLoggingTraceDecryptCalls;
|
||||
if (GetOption("kLoggingDumpTraceAll", 0) > 0)
|
||||
categories |= kLoggingDumpTraceAll;
|
||||
SetLoggingSettings(log_level, categories);
|
||||
}
|
||||
|
||||
#define QUOTE_DEFINE(A) #A
|
||||
#define QUOTE(A) QUOTE_DEFINE(A)
|
||||
#define LOOKUP(Name, Function) \
|
||||
Name = (L1_##Name##t)dlsym(level1_library_, QUOTE(Function)); \
|
||||
if (!Name) { \
|
||||
LOGW("Could not load L1 %s.", \
|
||||
QUOTE(Function)); \
|
||||
Terminate(); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
virtual bool Initialize() {
|
||||
LOGD("OEMCrypto Mock With Options " " " __DATE__ " " __TIME__);
|
||||
MaybeReadOptionsFile();
|
||||
if (!GetOption("use_fallback", 1)) {
|
||||
LOGD("Level 1 fallback ignored.");
|
||||
return true;
|
||||
}
|
||||
level1_library_ = dlopen("level1_backup_liboemcrypto.so", RTLD_NOW);
|
||||
if (level1_library_ == NULL) {
|
||||
LOGE("Could not load backup: %s", dlerror());
|
||||
return false;
|
||||
}
|
||||
LOOKUP(Initialize_, OEMCrypto_Initialize);
|
||||
LOOKUP(Terminate_, OEMCrypto_Terminate);
|
||||
LOOKUP(CopyBuffer_, OEMCrypto_CopyBuffer);
|
||||
level1_valid_ = true;
|
||||
OEMCryptoResult sts = Initialize_();
|
||||
LOGD("L1 fall back initialized. status = %d.", sts);
|
||||
if (sts != OEMCrypto_SUCCESS) {
|
||||
LOGW("Terminating L1 because init failed.");
|
||||
Terminate();
|
||||
LOGW("Continuing Mock without L1 fallback.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Terminate() {
|
||||
if (level1_valid_) Terminate_();
|
||||
if (level1_library_ != NULL) {
|
||||
LOGD("Closing L1 fall back.\n");
|
||||
dlclose(level1_library_);
|
||||
level1_valid_ = false;
|
||||
level1_library_ = NULL;
|
||||
CopyBuffer_ = NULL;
|
||||
Initialize_ = NULL;
|
||||
Terminate_ = NULL;
|
||||
} else {
|
||||
LOGD("Terminate mock.\n");
|
||||
}
|
||||
}
|
||||
|
||||
const char *HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value) {
|
||||
switch (value) {
|
||||
case HDCP_NONE:
|
||||
return "No HDCP supported, no secure data path";
|
||||
case HDCP_V1:
|
||||
return "HDCP version 1.0";
|
||||
case HDCP_V2:
|
||||
return "HDCP version 2.0";
|
||||
case HDCP_V2_1:
|
||||
return "HDCP version 2.1";
|
||||
case HDCP_V2_2:
|
||||
return "HDCP version 2.2";
|
||||
case HDCP_NO_DIGITAL_OUTPUT:
|
||||
return "No HDCP device attached/using local display with secure path";
|
||||
default:
|
||||
return "<INVALID VALUE>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OEMCrypto_ProvisioningMethod config_provisioning_method() {
|
||||
if (GetOption("use_keybox", 1)) {
|
||||
return OEMCrypto_Keybox;
|
||||
} else {
|
||||
return OEMCrypto_OEMCertificate;
|
||||
}
|
||||
}
|
||||
|
||||
OEMCryptoResult get_oem_certificate(SessionContext* session,
|
||||
uint8_t* public_cert,
|
||||
size_t* public_cert_length) {
|
||||
if (GetOption("use_keybox", 1)) {
|
||||
LOGD("OEM Cert asked for when use_keybox = 1.");
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
if (kOEMPublicCertSize == 0) {
|
||||
LOGD("OEM Cert Size is 0.");
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
if (public_cert_length == NULL) {
|
||||
LOGD("OEM Cert length is 0.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if (*public_cert_length < kOEMPublicCertSize) {
|
||||
*public_cert_length = kOEMPublicCertSize;
|
||||
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||
}
|
||||
*public_cert_length = kOEMPublicCertSize;
|
||||
if (public_cert == NULL) {
|
||||
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||
}
|
||||
memcpy(public_cert, kOEMPublicCert, kOEMPublicCertSize);
|
||||
if (!session->LoadRSAKey(kOEMPrivateKey, kOEMPrivateKeySize)) {
|
||||
LOGE("Private RSA Key did not load correctly.");
|
||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||
}
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
// Returns "L3" for a software only library. L1 is for hardware protected
|
||||
// data paths.
|
||||
const char *config_security_level() {
|
||||
switch (GetOption("security_level", 0)) {
|
||||
default:
|
||||
LOGW("Option security_level not set. Default is L3.");
|
||||
case 3:
|
||||
return "L3";
|
||||
case 2:
|
||||
return "L2";
|
||||
case 1:
|
||||
return "L1";
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the HDCP version currently in use.
|
||||
OEMCrypto_HDCP_Capability config_current_hdcp_capability() {
|
||||
static OEMCrypto_HDCP_Capability current_hdcp = HDCP_NONE;
|
||||
OEMCrypto_HDCP_Capability new_current_hdcp =
|
||||
static_cast<OEMCrypto_HDCP_Capability>(GetOption("current_hdcp", 0));
|
||||
if (current_hdcp != new_current_hdcp) {
|
||||
LOGI("OEMCrypto current HDCP changed from %d (%s) to %d (%s)", current_hdcp,
|
||||
HDCPCapabilityAsString(current_hdcp), new_current_hdcp,
|
||||
HDCPCapabilityAsString(new_current_hdcp));
|
||||
current_hdcp = new_current_hdcp;
|
||||
}
|
||||
return current_hdcp;
|
||||
}
|
||||
|
||||
// Returns the max HDCP version supported.
|
||||
OEMCrypto_HDCP_Capability config_maximum_hdcp_capability() {
|
||||
static OEMCrypto_HDCP_Capability max_hdcp = HDCP_NONE;
|
||||
MaybeReadOptionsFile();
|
||||
OEMCrypto_HDCP_Capability new_max_hdcp =
|
||||
static_cast<OEMCrypto_HDCP_Capability>(GetOption("max_hdcp", 0));
|
||||
if (max_hdcp != new_max_hdcp) {
|
||||
LOGI("OEMCrypto max HDCP changed from %d (%s) to %d (%s)", max_hdcp,
|
||||
HDCPCapabilityAsString(max_hdcp), new_max_hdcp,
|
||||
HDCPCapabilityAsString(new_max_hdcp));
|
||||
max_hdcp = new_max_hdcp;
|
||||
}
|
||||
return max_hdcp;
|
||||
}
|
||||
|
||||
// This should start at 0, and be incremented only when a security patch has
|
||||
// been applied to the device that fixes a security bug.
|
||||
uint8_t config_security_patch_level() {
|
||||
return GetOption("security_patch_level", 0);
|
||||
}
|
||||
|
||||
size_t max_buffer_size() {
|
||||
int max = GetOption("max_buffer_size", 0);
|
||||
// If max is 1, just use default max buffer.
|
||||
if (max == 1) return CryptoEngine::max_buffer_size();
|
||||
return max; // If 0, no restriction. If something else, use that restriction.
|
||||
}
|
||||
|
||||
bool srm_update_supported() {
|
||||
int supported = GetOption("srm_update_supported", 0);
|
||||
LOGI("OEMCrypto mock %s supporting SRM update.",
|
||||
supported ? "is" : "is not");
|
||||
return supported != 0;
|
||||
}
|
||||
|
||||
OEMCryptoResult current_srm_version(uint16_t *version) {
|
||||
if (srm_loaded_) {
|
||||
LOGV("SRM loaded. version used is %d.", srm_version_);
|
||||
*version = srm_version_;
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
int value = GetOption("srm_initial_version", -1);
|
||||
if (value > 0) {
|
||||
LOGV("SRM version from get option: %d.", value);
|
||||
srm_version_ = value;
|
||||
*version = value;
|
||||
return OEMCrypto_SUCCESS;
|
||||
} else {
|
||||
LOGI("SRM initial version is %d -- reporting not implemented.", value);
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
// 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<const int64_t*>(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.");
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
int result = GetOption("srm_load_fail", 0);
|
||||
if (result > 0) {
|
||||
LOGE("OEMCrypto mock load_srm returning error %d.", result);
|
||||
return static_cast<OEMCryptoResult>(result);
|
||||
}
|
||||
int new_version = GetOption("srm_load_version", -1);
|
||||
if (new_version >= 0) {
|
||||
if (new_version < srm_version_) {
|
||||
LOGE("New SRM version is lower than existing SRM version: %d < %d",
|
||||
new_version, srm_version_);
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
srm_version_ = new_version;
|
||||
LOGI("OEMCrypto mock told to change SRM version to %d.", srm_version_);
|
||||
srm_loaded_ = true;
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
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] >> 4;
|
||||
uint8_t hdcp2_indicator = buffer[0] & 0x0F;
|
||||
uint8_t reserved = buffer[1];
|
||||
uint16_t version = htons(*reinterpret_cast<const uint16_t *>(&buffer[2]));
|
||||
if (reserved) {
|
||||
LOGE("OEMCrypto mock. SRM's second byte nonzero: %02X.", reserved);
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
OEMCryptoResult remove_srm() {
|
||||
if (!srm_update_supported()) {
|
||||
LOGE("OEMCrypto mock update not supported, bug load_srm called.");
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
srm_version_ = 0;
|
||||
srm_loaded_ = false;
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
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) {
|
||||
LOGI("SRM blacklisted device changed from %d to %d", blacklisted,
|
||||
new_value);
|
||||
blacklisted = new_value;
|
||||
}
|
||||
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 int nonce_flood_count() { GetOption("nonce_flood_count", 20); }
|
||||
|
||||
virtual void adjust_destination(OEMCrypto_DestBufferDesc *out_description,
|
||||
size_t data_length, uint8_t subsample_flags) {
|
||||
if (out_description->type != OEMCrypto_BufferType_Secure) return;
|
||||
if (!level1_valid_) {
|
||||
static bool warned_once = false;
|
||||
if (!warned_once) {
|
||||
warned_once = true;
|
||||
LOGW("OEMCrypto Mock: given secure buffer with no level1 fallback.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (subsample_flags & OEMCrypto_FirstSubsample) {
|
||||
final_destination_.type = OEMCrypto_BufferType_Secure;
|
||||
final_destination_.buffer.secure.handle =
|
||||
out_description->buffer.secure.handle;
|
||||
final_destination_.buffer.secure.max_length =
|
||||
out_description->buffer.secure.max_length;
|
||||
final_destination_.buffer.secure.offset =
|
||||
out_description->buffer.secure.offset;
|
||||
temp_buffer_.resize(final_destination_.buffer.secure.max_length);
|
||||
temp_buffer_length_ = 0;
|
||||
}
|
||||
if (temp_buffer_length_ != out_description->buffer.secure.offset) {
|
||||
LOGW("OEMCrypto: offset into secure buffer is not correct %zd != %zd.",
|
||||
temp_buffer_length_, out_description->buffer.secure.offset);
|
||||
}
|
||||
size_t new_length = temp_buffer_length_ + data_length;
|
||||
if (new_length > temp_buffer_.size()) {
|
||||
LOGW("Temp buffer was not big enough. %zd > %zd.", new_length,
|
||||
temp_buffer_.size());
|
||||
temp_buffer_.resize(new_length);
|
||||
}
|
||||
destination_ = &temp_buffer_[temp_buffer_length_];
|
||||
temp_buffer_length_ = new_length;
|
||||
}
|
||||
|
||||
// Push destination buffer to L1 output.
|
||||
virtual OEMCryptoResult PushDestination(
|
||||
OEMCrypto_DestBufferDesc *out_description, uint8_t subsample_flags) {
|
||||
if (level1_valid_ &&
|
||||
(out_description->type == OEMCrypto_BufferType_Secure)) {
|
||||
if (subsample_flags & OEMCrypto_LastSubsample) {
|
||||
return CopyBuffer_(&temp_buffer_[0], temp_buffer_length_,
|
||||
&final_destination_,
|
||||
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample);
|
||||
}
|
||||
}
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
private:
|
||||
// If the SRM version has been loaded or not. If not, we use the system
|
||||
// property to find the current SRM version.
|
||||
bool srm_loaded_;
|
||||
// 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<int64_t> srm_revocation_list_;
|
||||
|
||||
std::map<std::string, int64_t> options_;
|
||||
|
||||
std::string options_file_;
|
||||
bool level1_valid_;
|
||||
void* level1_library_;
|
||||
L1_CopyBuffer_t CopyBuffer_;
|
||||
L1_Initialize_t Initialize_;
|
||||
L1_Terminate_t Terminate_;
|
||||
OEMCrypto_DestBufferDesc final_destination_;
|
||||
std::vector<uint8_t> temp_buffer_;
|
||||
size_t temp_buffer_length_; // Length of temp buffer currently in use.
|
||||
};
|
||||
|
||||
CryptoEngine* CryptoEngine::MakeCryptoEngine(
|
||||
std::auto_ptr<wvcdm::FileSystem> file_system) {
|
||||
return new AndroidModifiableCryptoEngine(file_system);
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WV_KEYBOX_H_
|
||||
#define WV_KEYBOX_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace wvoec_mock {
|
||||
|
||||
// This is the format of a Widevine keybox.
|
||||
typedef struct { // 128 bytes total.
|
||||
// C character string identifying the device. Null terminated.
|
||||
uint8_t device_id_[32];
|
||||
// 128 bit AES key assigned to device. Generated by Widevine.
|
||||
uint8_t device_key_[16];
|
||||
// Key Data. Encrypted data.
|
||||
uint8_t data_[72];
|
||||
// Constant code used to recognize a valid keybox "kbox" = 0x6b626f78.
|
||||
uint8_t magic_[4];
|
||||
// The CRC checksum of the first 124 bytes of the keybox.
|
||||
uint8_t crc_[4];
|
||||
} WidevineKeybox;
|
||||
|
||||
} // namespace wvoec_mock
|
||||
|
||||
#endif // WV_KEYBOX_H_
|
||||
@@ -1,121 +0,0 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
|
||||
#include <string>
|
||||
#include <gtest/gtest.h>
|
||||
#include "log.h"
|
||||
#include "oemcrypto_logging.h"
|
||||
#include "oemcrypto_mock.cpp"
|
||||
|
||||
class OEMCryptoLoggingTest : public ::testing::Test {
|
||||
protected:
|
||||
OEMCryptoLoggingTest() {}
|
||||
|
||||
void SetUp() {
|
||||
::testing::Test::SetUp();
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
|
||||
}
|
||||
|
||||
void TearDown() {
|
||||
OEMCrypto_Terminate();
|
||||
::testing::Test::TearDown();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(OEMCryptoLoggingTest, TestDumpHexFunctions) {
|
||||
uint8_t vector[] = {0xFA, 0x11, 0x28, 0x33};
|
||||
std::string buffer;
|
||||
wvoec_mock::dump_hex_helper(buffer, "name", vector, 4u);
|
||||
ASSERT_EQ("name = \n wvcdm::a2b_hex(\"FA112833\");\n", buffer);
|
||||
|
||||
uint8_t vector2[] = {
|
||||
0xFA, 0x11, 0x28, 0x33, 0xFA, 0x11, 0x28, 0x33, 0xFA, 0x11,
|
||||
0x28, 0x33, 0xFA, 0x11, 0x28, 0x33, 0xFA, 0x11, 0x28, 0x33,
|
||||
0xFA, 0x11, 0x28, 0x33, 0x01, 0x14, 0x28, 0xAB, 0xFA, 0xCD,
|
||||
0xEF, 0x67, 0x01, 0x14, 0x28, 0xAB, 0xFA, 0xCD, 0xEF, 0x67,
|
||||
};
|
||||
|
||||
buffer.clear(); // dump_hex_helper appends to buffer
|
||||
wvoec_mock::dump_hex_helper(buffer, "name", vector2, 40u);
|
||||
ASSERT_EQ(
|
||||
"name = \n "
|
||||
"wvcdm::a2b_hex("
|
||||
"\"FA112833FA112833FA112833FA112833FA112833FA112833011428ABFACDEF67\"\n "
|
||||
" \"011428ABFACDEF67\");\n",
|
||||
buffer);
|
||||
|
||||
buffer.clear(); // dump_hex_helper appends to buffer
|
||||
wvoec_mock::dump_array_part_helper(buffer, "array", 5u, "name", vector2, 40u);
|
||||
ASSERT_EQ(
|
||||
"std::string s5_name = \n "
|
||||
"wvcdm::a2b_hex("
|
||||
"\"FA112833FA112833FA112833FA112833FA112833FA112833011428ABFACDEF67\"\n "
|
||||
" \"011428ABFACDEF67\");\narray[5].name = message_ptr + "
|
||||
"message.find(s5_name.data());\n",
|
||||
buffer);
|
||||
|
||||
buffer.clear(); // dump_hex_helper appends to buffer
|
||||
wvoec_mock::dump_array_part_helper(buffer, "array", 5u, "name", NULL, 40u);
|
||||
ASSERT_EQ("array[5].name = NULL;\n", buffer);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoggingTest, TestChangeLoggingLevel) {
|
||||
wvoec_mock::SetLoggingLevel(wvcdm::LOG_WARN);
|
||||
ASSERT_EQ(wvcdm::LOG_WARN, wvcdm::g_cutoff);
|
||||
|
||||
wvoec_mock::SetLoggingLevel(wvcdm::LOG_INFO);
|
||||
ASSERT_EQ(wvcdm::LOG_INFO, wvcdm::g_cutoff);
|
||||
|
||||
wvoec_mock::SetLoggingSettings(wvcdm::LOG_WARN,
|
||||
wvoec_mock::kLoggingDumpTraceAll);
|
||||
ASSERT_EQ(wvcdm::LOG_WARN, wvcdm::g_cutoff);
|
||||
ASSERT_TRUE(wvoec_mock::LogCategoryEnabled(wvoec_mock::kLoggingDumpTraceAll));
|
||||
wvoec_mock::TurnOffLoggingForAllCategories();
|
||||
|
||||
wvoec_mock::SetLoggingLevel(wvcdm::LOG_VERBOSE);
|
||||
ASSERT_EQ(wvcdm::LOG_VERBOSE, wvcdm::g_cutoff);
|
||||
|
||||
wvoec_mock::SetLoggingLevel(wvcdm::LOG_WARN);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoggingTest, TestChangeLoggingCategories) {
|
||||
using namespace wvoec_mock;
|
||||
TurnOffLoggingForAllCategories();
|
||||
ASSERT_FALSE(LogCategoryEnabled(kLoggingTraceDecryption |
|
||||
kLoggingTraceOEMCryptoCalls));
|
||||
|
||||
AddLoggingForCategories(kLoggingDumpKeyControlBlocks |
|
||||
kLoggingDumpDerivedKeys);
|
||||
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpKeyControlBlocks));
|
||||
ASSERT_FALSE(LogCategoryEnabled(kLoggingTraceUsageTable));
|
||||
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpTraceAll));
|
||||
|
||||
RemoveLoggingForCategories(kLoggingDumpKeyControlBlocks |
|
||||
kLoggingTraceUsageTable);
|
||||
ASSERT_FALSE(LogCategoryEnabled(kLoggingDumpKeyControlBlocks));
|
||||
|
||||
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpDerivedKeys));
|
||||
ASSERT_FALSE(LogCategoryEnabled(kLoggingTraceUsageTable));
|
||||
|
||||
TurnOffLoggingForAllCategories();
|
||||
ASSERT_FALSE(LogCategoryEnabled(kLoggingTraceUsageTable));
|
||||
|
||||
AddLoggingForCategories(kLoggingDumpTraceAll);
|
||||
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpKeyControlBlocks));
|
||||
|
||||
ASSERT_TRUE(LogCategoryEnabled(kLoggingTraceOEMCryptoCalls));
|
||||
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpContentKeys));
|
||||
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpKeyControlBlocks));
|
||||
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpDerivedKeys));
|
||||
ASSERT_TRUE(LogCategoryEnabled(kLoggingTraceNonce));
|
||||
ASSERT_TRUE(LogCategoryEnabled(kLoggingTraceDecryption));
|
||||
ASSERT_TRUE(LogCategoryEnabled(kLoggingTraceUsageTable));
|
||||
ASSERT_TRUE(LogCategoryEnabled(kLoggingTraceDecryptCalls));
|
||||
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpTraceAll));
|
||||
|
||||
RemoveLoggingForCategories(kLoggingDumpKeyControlBlocks);
|
||||
ASSERT_FALSE(LogCategoryEnabled(kLoggingDumpKeyControlBlocks));
|
||||
}
|
||||
@@ -4,20 +4,20 @@ include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
src/keys.cpp \
|
||||
src/oemcrypto_auth_mock.cpp \
|
||||
src/oemcrypto_auth_ref.cpp \
|
||||
src/oemcrypto_engine_device_properties.cpp \
|
||||
src/oemcrypto_engine_mock.cpp \
|
||||
src/oemcrypto_key_mock.cpp \
|
||||
src/oemcrypto_keybox_mock.cpp \
|
||||
src/oemcrypto_engine_ref.cpp \
|
||||
src/oemcrypto_key_ref.cpp \
|
||||
src/oemcrypto_keybox_ref.cpp \
|
||||
src/oemcrypto_keybox_testkey.cpp \
|
||||
src/oemcrypto_logging.cpp \
|
||||
src/oemcrypto_mock.cpp \
|
||||
src/oemcrypto_ref.cpp \
|
||||
src/oemcrypto_nonce_table.cpp \
|
||||
src/oemcrypto_old_usage_table_mock.cpp \
|
||||
src/oemcrypto_old_usage_table_ref.cpp \
|
||||
src/oemcrypto_rsa_key_shared.cpp \
|
||||
src/oemcrypto_session.cpp \
|
||||
src/oemcrypto_session_key_table.cpp \
|
||||
src/oemcrypto_usage_table_mock.cpp \
|
||||
src/oemcrypto_usage_table_ref.cpp \
|
||||
src/wvcrc.cpp \
|
||||
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
@@ -25,7 +25,7 @@ LOCAL_MODULE_TAGS := tests
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LOCAL_PATH)/../include \
|
||||
$(LOCAL_PATH)/src \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libcutils \
|
||||
5
libwvdrmengine/oemcrypto/ref/README.md
Normal file
5
libwvdrmengine/oemcrypto/ref/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Reference OEMCrypto
|
||||
|
||||
This directory contains a testing-only implementation of OEMCrypto. **This
|
||||
implementation is *NOT* suitable for production use and should *NOT* be released
|
||||
on devices.**
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "oem_cert.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
extern const uint32_t kOEMSystemId_Prod = 7346;
|
||||
|
||||
@@ -389,4 +389,4 @@ const uint8_t* kOEMPublicCert = kOEMPublicCert_Prod;
|
||||
const size_t kOEMPrivateKeySize = kOEMPrivateKeySize_Prod;
|
||||
const size_t kOEMPublicCertSize = kOEMPublicCertSize_Prod;
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
// Refer to the following in main modules
|
||||
extern const uint32_t kOEMSystemId;
|
||||
@@ -16,6 +16,6 @@ extern const uint8_t* kOEMPublicCert;
|
||||
extern const size_t kOEMPrivateKeySize;
|
||||
extern const size_t kOEMPublicCertSize;
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
|
||||
#endif // OEM_CERT_H_
|
||||
@@ -2,23 +2,23 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#include "oemcrypto_auth_mock.h"
|
||||
#include "oemcrypto_auth_ref.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "keys.h"
|
||||
#include "log.h"
|
||||
#include "oemcrypto_key_mock.h"
|
||||
#include "oemcrypto_key_ref.h"
|
||||
#include "oemcrypto_logging.h"
|
||||
#include "oemcrypto_rsa_key_shared.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// A 2048 bit RSA key in PKCS#8 PrivateKeyInfo format
|
||||
// This is the RSA Test Key.
|
||||
// This is the RSA Test Key. This key is not derived
|
||||
// from any Widevine authentication root.
|
||||
static const uint8_t kTestRSAPKCS8PrivateKeyInfo2_2048[] = {
|
||||
0x30, 0x82, 0x04, 0xbc, 0x02, 0x01, 0x00, 0x30,
|
||||
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
|
||||
@@ -176,7 +176,7 @@ static const uint8_t kTestRSAPKCS8PrivateKeyInfo2_2048[] = {
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
AuthenticationRoot::AuthenticationRoot(OEMCrypto_ProvisioningMethod method) :
|
||||
provisioning_method_(method),
|
||||
@@ -202,4 +202,4 @@ bool AuthenticationRoot::Validate() {
|
||||
return NO_ERROR == ValidateKeybox();
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,10 +2,10 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#ifndef OEMCRYPTO_AUTH_MOCK_H_
|
||||
#define OEMCRYPTO_AUTH_MOCK_H_
|
||||
#ifndef OEMCRYPTO_AUTH_REF_H_
|
||||
#define OEMCRYPTO_AUTH_REF_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
@@ -13,12 +13,14 @@
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
#include "OEMCryptoCENC.h" // Needed for enums only.
|
||||
#include "oemcrypto_key_mock.h"
|
||||
#include "oemcrypto_keybox_mock.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "oemcrypto_key_ref.h"
|
||||
#include "oemcrypto_keybox_ref.h"
|
||||
#include "oemcrypto_rsa_key_shared.h"
|
||||
#include "wv_cdm_types.h"
|
||||
#include "oemcrypto_scoped_ptr.h"
|
||||
#include "oemcrypto_types.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
class AuthenticationRoot {
|
||||
public:
|
||||
@@ -73,6 +75,6 @@ class AuthenticationRoot {
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(AuthenticationRoot);
|
||||
};
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
|
||||
#endif // OEMCRYPTO_AUTH_MOCK_H_
|
||||
#endif // OEMCRYPTO_AUTH_REF_H_
|
||||
@@ -2,16 +2,16 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
|
||||
#include "oemcrypto_engine_mock.h"
|
||||
#include "oemcrypto_engine_ref.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
CryptoEngine* CryptoEngine::MakeCryptoEngine(
|
||||
std::auto_ptr<wvcdm::FileSystem> file_system) {
|
||||
scoped_ptr<wvcdm::FileSystem> file_system) {
|
||||
return new CryptoEngine(file_system);
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,17 +2,17 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
// This file contains oemcrypto engine properties that would be for a
|
||||
// level 1 device.
|
||||
#include "oemcrypto_engine_mock.h"
|
||||
#include "oemcrypto_engine_ref.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
class L1CryptoEngine : public CryptoEngine {
|
||||
public:
|
||||
explicit L1CryptoEngine(std::auto_ptr<wvcdm::FileSystem> file_system)
|
||||
explicit L1CryptoEngine(scoped_ptr<wvcdm::FileSystem> file_system)
|
||||
: CryptoEngine(file_system) {}
|
||||
|
||||
bool config_local_display_only() { return true; }
|
||||
@@ -31,8 +31,8 @@ class L1CryptoEngine : public CryptoEngine {
|
||||
};
|
||||
|
||||
CryptoEngine* CryptoEngine::MakeCryptoEngine(
|
||||
std::auto_ptr<wvcdm::FileSystem> file_system) {
|
||||
scoped_ptr<wvcdm::FileSystem> file_system) {
|
||||
return new L1CryptoEngine(file_system);
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,20 +2,20 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
// This file contains oemcrypto engine properties that would be for a device
|
||||
// that does not have persistant storage or a keybox.
|
||||
//
|
||||
// Note: We also define it to be L2 for illustration only. Production devices
|
||||
// are rarely level 2.
|
||||
#include "oemcrypto_engine_mock.h"
|
||||
#include "oemcrypto_engine_ref.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
class CertOnlyCryptoEngine : public CryptoEngine {
|
||||
public:
|
||||
explicit CertOnlyCryptoEngine(std::auto_ptr<wvcdm::FileSystem> file_system)
|
||||
explicit CertOnlyCryptoEngine(scoped_ptr<wvcdm::FileSystem> file_system)
|
||||
: CryptoEngine(file_system) {}
|
||||
|
||||
bool config_local_display_only() { return true; }
|
||||
@@ -30,8 +30,8 @@ class CertOnlyCryptoEngine : public CryptoEngine {
|
||||
};
|
||||
|
||||
CryptoEngine* CryptoEngine::MakeCryptoEngine(
|
||||
std::auto_ptr<wvcdm::FileSystem> file_system) {
|
||||
scoped_ptr<wvcdm::FileSystem> file_system) {
|
||||
return new CertOnlyCryptoEngine(file_system);
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,24 +2,24 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
// This file contains oemcrypto engine properties that would be for a
|
||||
// level 2 device that does not have persistant storage or a keybox.
|
||||
// Note: this is for illustration only. Production devices are rarely level 2.
|
||||
|
||||
#include "oemcrypto_engine_mock.h"
|
||||
#include "oemcrypto_engine_ref.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "oem_cert.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
class Prov30CryptoEngine : public CryptoEngine {
|
||||
public:
|
||||
explicit Prov30CryptoEngine(std::auto_ptr<wvcdm::FileSystem> file_system)
|
||||
explicit Prov30CryptoEngine(scoped_ptr<wvcdm::FileSystem> file_system)
|
||||
: CryptoEngine(file_system) {}
|
||||
|
||||
bool config_local_display_only() { return true; }
|
||||
@@ -77,8 +77,8 @@ class Prov30CryptoEngine : public CryptoEngine {
|
||||
};
|
||||
|
||||
CryptoEngine* CryptoEngine::MakeCryptoEngine(
|
||||
std::auto_ptr<wvcdm::FileSystem> file_system) {
|
||||
scoped_ptr<wvcdm::FileSystem> file_system) {
|
||||
return new Prov30CryptoEngine(file_system);
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,9 +2,9 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#include "oemcrypto_engine_mock.h"
|
||||
#include "oemcrypto_engine_ref.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
@@ -17,19 +17,17 @@
|
||||
|
||||
#include "keys.h"
|
||||
#include "log.h"
|
||||
#include "oemcrypto_key_mock.h"
|
||||
#include "oemcrypto_key_ref.h"
|
||||
#include "oemcrypto_rsa_key_shared.h"
|
||||
#include "string_conversions.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
// Note: The class CryptoEngine is configured at compile time by compiling in
|
||||
// different device property files. The methods in this file are generic to
|
||||
// all configurations. See the files oemcrypto_engine_device_properties*.cpp
|
||||
// for methods that are configured for specific configurations.
|
||||
|
||||
CryptoEngine::CryptoEngine(std::auto_ptr<wvcdm::FileSystem> file_system)
|
||||
CryptoEngine::CryptoEngine(scoped_ptr<wvcdm::FileSystem> file_system)
|
||||
: root_of_trust_(config_provisioning_method()),
|
||||
file_system_(file_system),
|
||||
usage_table_(this) {
|
||||
@@ -123,4 +121,4 @@ OEMCryptoResult CryptoEngine::SetDestination(
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,10 +2,10 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#ifndef MOCK_OEMCRYPTO_ENGINE_MOCK_H_
|
||||
#define MOCK_OEMCRYPTO_ENGINE_MOCK_H_
|
||||
#ifndef REF_OEMCRYPTO_ENGINE_REF_H_
|
||||
#define REF_OEMCRYPTO_ENGINE_REF_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
@@ -18,14 +18,15 @@
|
||||
#include "OEMCryptoCENC.h" // Needed for enums only.
|
||||
#include "file_store.h"
|
||||
#include "lock.h"
|
||||
#include "oemcrypto_auth_mock.h"
|
||||
#include "oemcrypto_key_mock.h"
|
||||
#include "oemcrypto_auth_ref.h"
|
||||
#include "oemcrypto_key_ref.h"
|
||||
#include "oemcrypto_rsa_key_shared.h"
|
||||
#include "oemcrypto_scoped_ptr.h"
|
||||
#include "oemcrypto_session.h"
|
||||
#include "oemcrypto_usage_table_mock.h"
|
||||
#include "wv_cdm_types.h"
|
||||
#include "oemcrypto_usage_table_ref.h"
|
||||
#include "oemcrypto_types.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
typedef std::map<SessionId, SessionContext*> ActiveSessions;
|
||||
|
||||
@@ -37,7 +38,7 @@ class CryptoEngine {
|
||||
// NOTE: The caller must instantiate a FileSystem object - ownership
|
||||
// will be transferred to the new CryptoEngine object.
|
||||
static CryptoEngine* MakeCryptoEngine(
|
||||
std::auto_ptr<wvcdm::FileSystem> file_system);
|
||||
scoped_ptr<wvcdm::FileSystem> file_system);
|
||||
|
||||
virtual ~CryptoEngine();
|
||||
|
||||
@@ -82,7 +83,7 @@ class CryptoEngine {
|
||||
size_t GetNumberOfOpenSessions() { return sessions_.size(); }
|
||||
|
||||
size_t GetMaxNumberOfSessions() {
|
||||
// An arbitrary limit for mock implementation.
|
||||
// An arbitrary limit for ref implementation.
|
||||
static const size_t kMaxSupportedOEMCryptoSessions = 64;
|
||||
return kMaxSupportedOEMCryptoSessions;
|
||||
}
|
||||
@@ -170,19 +171,19 @@ class CryptoEngine {
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit CryptoEngine(std::auto_ptr<wvcdm::FileSystem> file_system);
|
||||
explicit CryptoEngine(scoped_ptr<wvcdm::FileSystem> file_system);
|
||||
uint8_t* destination_;
|
||||
|
||||
private:
|
||||
ActiveSessions sessions_;
|
||||
AuthenticationRoot root_of_trust_;
|
||||
wvcdm::Lock session_table_lock_;
|
||||
std::auto_ptr<wvcdm::FileSystem> file_system_;
|
||||
scoped_ptr<wvcdm::FileSystem> file_system_;
|
||||
UsageTable usage_table_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(CryptoEngine);
|
||||
};
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
|
||||
#endif // MOCK_OEMCRYPTO_ENGINE_MOCK_H_
|
||||
#endif // REF_OEMCRYPTO_ENGINE_REF_H_
|
||||
@@ -2,18 +2,18 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#include "oemcrypto_key_mock.h"
|
||||
#include "oemcrypto_key_ref.h"
|
||||
#include "oemcrypto_types.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
#include "log.h"
|
||||
#include "oemcrypto_logging.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
bool KeyControlBlock::Validate() {
|
||||
if (memcmp(verification_, "kctl", 4) && // original verification
|
||||
@@ -45,15 +45,15 @@ uint32_t KeyControlBlock::ExtractField(const std::vector<uint8_t>& str,
|
||||
|
||||
KeyControlBlock::KeyControlBlock(
|
||||
const std::vector<uint8_t>& key_control_string) {
|
||||
if (key_control_string.size() < wvcdm::KEY_CONTROL_SIZE) {
|
||||
if (key_control_string.size() < wvoec::KEY_CONTROL_SIZE) {
|
||||
LOGE("KCB: BAD Size: %d (not %d)", key_control_string.size(),
|
||||
wvcdm::KEY_CONTROL_SIZE);
|
||||
wvoec::KEY_CONTROL_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(verification_, &key_control_string[0], 4);
|
||||
duration_ = ExtractField(key_control_string, 1);
|
||||
nonce_ = ExtractField(key_control_string, 2);
|
||||
duration_ = ExtractField(key_control_string, 1);
|
||||
nonce_ = ExtractField(key_control_string, 2);
|
||||
control_bits_ = ExtractField(key_control_string, 3);
|
||||
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
|
||||
LOGD("KCB:");
|
||||
@@ -63,19 +63,20 @@ KeyControlBlock::KeyControlBlock(
|
||||
LOGD(" magic: %08X", verification());
|
||||
LOGD(" bits: %08X", control_bits());
|
||||
LOGD(" bit kSharedLicense %s.",
|
||||
(control_bits() & kSharedLicense) ? "set" : "unset");
|
||||
(control_bits() & wvoec::kSharedLicense) ? "set" : "unset");
|
||||
LOGD(" bit kControlSRMVersionRequired %s.",
|
||||
(control_bits() & kControlSRMVersionRequired) ? "set" : "unset");
|
||||
(control_bits() & wvoec::kControlSRMVersionRequired) ? "set" : "unset");
|
||||
LOGD(" bit kControlDisableAnalogOutput %s.",
|
||||
(control_bits() & kControlDisableAnalogOutput) ? "set" : "unset");
|
||||
(control_bits() & wvoec::kControlDisableAnalogOutput) ? "set"
|
||||
: "unset");
|
||||
LOGD(" bits kControlSecurityPatchLevel 0x%02x.",
|
||||
(control_bits() & kControlSecurityPatchLevelMask)
|
||||
>> kControlSecurityPatchLevelShift);
|
||||
switch (control_bits() & kControlReplayMask) {
|
||||
case kControlNonceRequired:
|
||||
(control_bits() & wvoec::kControlSecurityPatchLevelMask) >>
|
||||
wvoec::kControlSecurityPatchLevelShift);
|
||||
switch (control_bits() & wvoec::kControlReplayMask) {
|
||||
case wvoec::kControlNonceRequired:
|
||||
LOGD(" bits kControlReplay kControlNonceRequired.");
|
||||
break;
|
||||
case kControlNonceOrEntry:
|
||||
case wvoec::kControlNonceOrEntry:
|
||||
LOGD(" bits kControlReplay kControlNonceOrEntry.");
|
||||
break;
|
||||
default:
|
||||
@@ -83,28 +84,28 @@ KeyControlBlock::KeyControlBlock(
|
||||
break;
|
||||
}
|
||||
LOGD(" bits kControlHDCPVersion 0x%02x.",
|
||||
(control_bits() & kControlHDCPVersionMask)
|
||||
>> kControlHDCPVersionShift);
|
||||
(control_bits() & wvoec::kControlHDCPVersionMask) >>
|
||||
wvoec::kControlHDCPVersionShift);
|
||||
LOGD(" bit kControlAllowEncrypt %s.",
|
||||
(control_bits() & kControlAllowEncrypt) ? "set" : "unset");
|
||||
(control_bits() & wvoec::kControlAllowEncrypt) ? "set" : "unset");
|
||||
LOGD(" bit kControlAllowDecrypt %s.",
|
||||
(control_bits() & kControlAllowDecrypt) ? "set" : "unset");
|
||||
(control_bits() & wvoec::kControlAllowDecrypt) ? "set" : "unset");
|
||||
LOGD(" bit kControlAllowSign %s.",
|
||||
(control_bits() & kControlAllowSign) ? "set" : "unset");
|
||||
(control_bits() & wvoec::kControlAllowSign) ? "set" : "unset");
|
||||
LOGD(" bit kControlAllowVerify %s.",
|
||||
(control_bits() & kControlAllowVerify) ? "set" : "unset");
|
||||
(control_bits() & wvoec::kControlAllowVerify) ? "set" : "unset");
|
||||
LOGD(" bit kControlObserveDataPath %s.",
|
||||
(control_bits() & kControlObserveDataPath) ? "set" : "unset");
|
||||
(control_bits() & wvoec::kControlObserveDataPath) ? "set" : "unset");
|
||||
LOGD(" bit kControlObserveHDCP %s.",
|
||||
(control_bits() & kControlObserveHDCP) ? "set" : "unset");
|
||||
(control_bits() & wvoec::kControlObserveHDCP) ? "set" : "unset");
|
||||
LOGD(" bit kControlObserveCGMS %s.",
|
||||
(control_bits() & kControlObserveCGMS) ? "set" : "unset");
|
||||
(control_bits() & wvoec::kControlObserveCGMS) ? "set" : "unset");
|
||||
LOGD(" bit kControlDataPathSecure %s.",
|
||||
(control_bits() & kControlDataPathSecure) ? "set" : "unset");
|
||||
(control_bits() & wvoec::kControlDataPathSecure) ? "set" : "unset");
|
||||
LOGD(" bit kControlNonceEnabled %s.",
|
||||
(control_bits() & kControlNonceEnabled) ? "set" : "unset");
|
||||
(control_bits() & wvoec::kControlNonceEnabled) ? "set" : "unset");
|
||||
LOGD(" bit kControlHDCPRequired %s.",
|
||||
(control_bits() & kControlHDCPRequired) ? "set" : "unset");
|
||||
(control_bits() & wvoec::kControlHDCPRequired) ? "set" : "unset");
|
||||
uint32_t cgms_bits = control_bits() & 0x3;
|
||||
const char* cgms_values[4] = {"free", "BAD", "once", "never"};
|
||||
LOGD(" CGMS = %s", cgms_values[cgms_bits]);
|
||||
@@ -118,7 +119,7 @@ void Key::UpdateDuration(const KeyControlBlock& control) {
|
||||
|
||||
void KeyControlBlock::RequireLocalDisplay() {
|
||||
// Set all bits to require HDCP Local Display Only.
|
||||
control_bits_ |= kControlHDCPVersionMask;
|
||||
control_bits_ |= wvoec::kControlHDCPVersionMask;
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,43 +2,16 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#ifndef OEMCRYPTO_KEY_MOCK_H_
|
||||
#define OEMCRYPTO_KEY_MOCK_H_
|
||||
#ifndef OEMCRYPTO_KEY_REF_H_
|
||||
#define OEMCRYPTO_KEY_REF_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace wvoec_mock {
|
||||
|
||||
const uint32_t kControlObserveDataPath = (1<<31);
|
||||
const uint32_t kControlObserveHDCP = (1<<30);
|
||||
const uint32_t kControlObserveCGMS = (1<<29);
|
||||
const uint32_t kControlRequireAntiRollbackHardware = (1<<28);
|
||||
const uint32_t kSharedLicense = (1<<23);
|
||||
const uint32_t kControlSRMVersionRequired = (1<<22);
|
||||
const uint32_t kControlDisableAnalogOutput = (1<<21);
|
||||
const uint32_t kControlSecurityPatchLevelShift = 15;
|
||||
const uint32_t kControlSecurityPatchLevelMask =
|
||||
(0x3F<<kControlSecurityPatchLevelShift);
|
||||
const uint32_t kControlReplayMask = (0x03<<13);
|
||||
const uint32_t kControlNonceRequired = (0x01<<13);
|
||||
const uint32_t kControlNonceOrEntry = (0x02<<13);
|
||||
const uint32_t kControlHDCPVersionShift = 9;
|
||||
const uint32_t kControlHDCPVersionMask = (0x0F<<kControlHDCPVersionShift);
|
||||
const uint32_t kControlAllowEncrypt = (1<<8);
|
||||
const uint32_t kControlAllowDecrypt = (1<<7);
|
||||
const uint32_t kControlAllowSign = (1<<6);
|
||||
const uint32_t kControlAllowVerify = (1<<5);
|
||||
const uint32_t kControlDataPathSecure = (1<<4);
|
||||
const uint32_t kControlNonceEnabled = (1<<3);
|
||||
const uint32_t kControlHDCPRequired = (1<<2);
|
||||
const uint32_t kControlCGMSMask = (0x03);
|
||||
const uint32_t kControlCGMSCopyFreely = (0x00);
|
||||
const uint32_t kControlCGMSCopyOnce = (0x02);
|
||||
const uint32_t kControlCGMSCopyNever = (0x03);
|
||||
namespace wvoec_ref {
|
||||
|
||||
class KeyControlBlock {
|
||||
public:
|
||||
@@ -109,6 +82,6 @@ class EntitlementKey : public Key {
|
||||
std::vector<uint8_t> content_key_id_;
|
||||
};
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
|
||||
#endif // OEMCRYPTO_KEY_MOCK_H_
|
||||
#endif // OEMCRYPTO_KEY_REF_H_
|
||||
@@ -2,23 +2,24 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#include "oemcrypto_keybox_mock.h"
|
||||
#include "oemcrypto_keybox_ref.h"
|
||||
|
||||
#include <arpa/inet.h> // needed for ntoh()
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <string>
|
||||
|
||||
#include "log.h"
|
||||
#include "wv_keybox.h"
|
||||
#include "oemcrypto_types.h"
|
||||
#include "wvcrc32.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
namespace {
|
||||
|
||||
const WidevineKeybox kTestKeybox = {
|
||||
const wvoec::WidevineKeybox kTestKeybox = {
|
||||
// Sample keybox used for test vectors
|
||||
{
|
||||
// deviceID
|
||||
@@ -69,7 +70,7 @@ KeyboxError WvKeybox::Validate() {
|
||||
uint32_t crc_stored;
|
||||
uint8_t* crc_stored_bytes = (uint8_t*) &crc_stored;
|
||||
memcpy(crc_stored_bytes, crc_, sizeof(crc_));
|
||||
WidevineKeybox keybox;
|
||||
wvoec::WidevineKeybox keybox;
|
||||
memset(&keybox, 0, sizeof(keybox));
|
||||
memcpy(keybox.device_id_, &device_id_[0], device_id_.size());
|
||||
memcpy(keybox.device_key_, &device_key_[0], sizeof(keybox.device_key_));
|
||||
@@ -91,8 +92,8 @@ bool WvKeybox::InstallKeybox(const uint8_t* buffer, size_t keyBoxLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const WidevineKeybox* keybox
|
||||
= reinterpret_cast<const WidevineKeybox*>(buffer);
|
||||
const wvoec::WidevineKeybox* keybox
|
||||
= reinterpret_cast<const wvoec::WidevineKeybox*>(buffer);
|
||||
size_t device_id_length
|
||||
= strnlen(reinterpret_cast<const char*>(keybox->device_id_), 32);
|
||||
device_id_.assign(keybox->device_id_,
|
||||
@@ -111,4 +112,4 @@ WvTestKeybox::WvTestKeybox() {
|
||||
sizeof(kTestKeybox));
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,14 +2,14 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#ifndef OEMCRYPTO_KEYBOX_MOCK_H_
|
||||
#define OEMCRYPTO_KEYBOX_MOCK_H_
|
||||
#ifndef OEMCRYPTO_KEYBOX_REF_H_
|
||||
#define OEMCRYPTO_KEYBOX_REF_H_
|
||||
|
||||
#include "oemcrypto_key_mock.h"
|
||||
#include "oemcrypto_key_ref.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
const int DEVICE_KEY_LENGTH = 16;
|
||||
typedef uint8_t WvKeyboxKey[DEVICE_KEY_LENGTH];
|
||||
@@ -48,6 +48,6 @@ class WvTestKeybox : public WvKeybox {
|
||||
WvTestKeybox();
|
||||
};
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
|
||||
#endif // OEMCRYPTO_KEYBOX_MOCK_H_
|
||||
#endif // OEMCRYPTO_KEYBOX_REF_H_
|
||||
@@ -4,16 +4,16 @@
|
||||
//
|
||||
// Test keybox.
|
||||
|
||||
#include "oemcrypto_keybox_mock.h"
|
||||
#include "wv_keybox.h"
|
||||
#include "oemcrypto_keybox_ref.h"
|
||||
#include "oemcrypto_types.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
namespace {
|
||||
|
||||
// Note: this is a valid keybox, but it is not accepted by production servers.
|
||||
// However, it is different from the one used for most of the unit tests.
|
||||
const WidevineKeybox kKeybox = {
|
||||
const wvoec::WidevineKeybox kKeybox = {
|
||||
// Sample keybox used for test vectors
|
||||
{
|
||||
// deviceID
|
||||
@@ -53,4 +53,4 @@ bool WvKeybox::Prepare() {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
int logging_category_setting = 0x00;
|
||||
|
||||
@@ -49,7 +49,7 @@ void dump_hex_helper(std::string& buffer, std::string name,
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if (i == 0) {
|
||||
buffer += "\n wvcdm::a2b_hex(\"";
|
||||
buffer += "\n a2b_hex(\"";
|
||||
} else if (i % 32 == 0) {
|
||||
buffer += "\"\n \"";
|
||||
}
|
||||
@@ -103,4 +103,4 @@ void dump_array_part(std::string array, size_t index, std::string name,
|
||||
LOGV(buffer.c_str());
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "log.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
// The constants below represent integers with a single "on" bit that
|
||||
// represents categories of logging This allows users to specify with
|
||||
@@ -62,6 +62,6 @@ void dump_array_part_helper(std::string& buffer, std::string array,
|
||||
void dump_array_part(std::string array, size_t index, std::string name,
|
||||
const uint8_t* vector, size_t length);
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
|
||||
#endif
|
||||
#endif // WVOEC_OEMCRYPTO_LOGGING_H_
|
||||
@@ -2,11 +2,11 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#include "oemcrypto_nonce_table.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
void NonceTable::AddNonce(uint32_t nonce) {
|
||||
int new_slot = -1;
|
||||
@@ -66,4 +66,4 @@ void NonceTable::Flush() {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,14 +2,14 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#ifndef MOCK_OEMCRYPTO_NONCE_TABLE_H_
|
||||
#define MOCK_OEMCRYPTO_NONCE_TABLE_H_
|
||||
#ifndef REF_OEMCRYPTO_NONCE_TABLE_H_
|
||||
#define REF_OEMCRYPTO_NONCE_TABLE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
class NonceTable {
|
||||
public:
|
||||
@@ -35,6 +35,6 @@ class NonceTable {
|
||||
uint32_t nonces_[kTableSize];
|
||||
};
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
|
||||
#endif // MOCK_OEMCRYPTO_NONCE_TABLE_H_
|
||||
#endif // REF_OEMCRYPTO_NONCE_TABLE_H_
|
||||
@@ -2,12 +2,12 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
// This is from the v12 version of oemcrypto usage tables. It is used for
|
||||
// devices that upgrade from v12 to v13 in the field, and need to convert from
|
||||
// the old type of usage table to the new.
|
||||
#include "oemcrypto_old_usage_table_mock.h"
|
||||
#include "oemcrypto_old_usage_table_ref.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@@ -22,14 +22,15 @@
|
||||
|
||||
#include "file_store.h"
|
||||
#include "log.h"
|
||||
#include "oemcrypto_engine_mock.h"
|
||||
#include "oemcrypto_engine_ref.h"
|
||||
#include "oemcrypto_logging.h"
|
||||
#include "properties.h"
|
||||
// TODO(fredgc): Setting the device files base bath is currently broken as
|
||||
// wvcdm::Properties is no longer used by the reference code.
|
||||
//#include "properties.h"
|
||||
#include "pst_report.h"
|
||||
#include "string_conversions.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
OldUsageTableEntry::OldUsageTableEntry(const std::vector<uint8_t> &pst_hash)
|
||||
: pst_hash_(pst_hash),
|
||||
@@ -47,9 +48,9 @@ OldUsageTableEntry::OldUsageTableEntry(const OldStoredUsageEntry *buffer) {
|
||||
time_of_last_decrypt_ = buffer->time_of_last_decrypt;
|
||||
status_ = buffer->status;
|
||||
mac_key_server_.assign(buffer->mac_key_server,
|
||||
buffer->mac_key_server + wvcdm::MAC_KEY_SIZE);
|
||||
buffer->mac_key_server + wvoec::MAC_KEY_SIZE);
|
||||
mac_key_client_.assign(buffer->mac_key_client,
|
||||
buffer->mac_key_client + wvcdm::MAC_KEY_SIZE);
|
||||
buffer->mac_key_client + wvoec::MAC_KEY_SIZE);
|
||||
}
|
||||
|
||||
OldUsageTable::OldUsageTable(CryptoEngine *ce) {
|
||||
@@ -58,16 +59,17 @@ OldUsageTable::OldUsageTable(CryptoEngine *ce) {
|
||||
table_.clear();
|
||||
|
||||
// Load saved table.
|
||||
wvcdm::FileSystem* file_system = ce->file_system();
|
||||
wvcdm::FileSystem *file_system = ce->file_system();
|
||||
wvcdm::File *file;
|
||||
std::string path;
|
||||
// Note: this path is OK for a real implementation, but using security level 1
|
||||
// would be better.
|
||||
if (!wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL3,
|
||||
&path)) {
|
||||
// TODO(fredgc, jfore): Address how this property is presented to the ref.
|
||||
// For now, the path is empty.
|
||||
/*if (!Properties::GetDeviceFilesBasePath(kSecurityLevelL3, &path)) {
|
||||
LOGE("OldUsageTable: Unable to get base path");
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
std::string filename = path + "UsageTable.dat";
|
||||
if (!file_system->Exists(filename)) {
|
||||
if (LogCategoryEnabled(kLoggingTraceUsageTable)) {
|
||||
@@ -119,14 +121,14 @@ OldUsageTable::OldUsageTable(CryptoEngine *ce) {
|
||||
}
|
||||
|
||||
// Next, decrypt the table.
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, encrypted_table->iv, wvcdm::KEY_IV_SIZE);
|
||||
uint8_t iv_buffer[wvoec::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, encrypted_table->iv, wvoec::KEY_IV_SIZE);
|
||||
AES_KEY aes_key;
|
||||
AES_set_decrypt_key(&key[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(&encrypted_buffer[SHA256_DIGEST_LENGTH + wvcdm::KEY_IV_SIZE],
|
||||
&buffer[SHA256_DIGEST_LENGTH + wvcdm::KEY_IV_SIZE],
|
||||
file_size - SHA256_DIGEST_LENGTH - wvcdm::KEY_IV_SIZE,
|
||||
&aes_key, iv_buffer, AES_DECRYPT);
|
||||
AES_cbc_encrypt(&encrypted_buffer[SHA256_DIGEST_LENGTH + wvoec::KEY_IV_SIZE],
|
||||
&buffer[SHA256_DIGEST_LENGTH + wvoec::KEY_IV_SIZE],
|
||||
file_size - SHA256_DIGEST_LENGTH - wvoec::KEY_IV_SIZE, &aes_key,
|
||||
iv_buffer, AES_DECRYPT);
|
||||
|
||||
// Next, read the generation number from a different location.
|
||||
// On a real implementation, you should NOT put the generation number in
|
||||
@@ -176,7 +178,8 @@ OldUsageTableEntry *OldUsageTable::FindEntry(const std::vector<uint8_t> &pst) {
|
||||
return FindEntryLocked(pst);
|
||||
}
|
||||
|
||||
OldUsageTableEntry *OldUsageTable::FindEntryLocked(const std::vector<uint8_t> &pst) {
|
||||
OldUsageTableEntry *OldUsageTable::FindEntryLocked(
|
||||
const std::vector<uint8_t> &pst) {
|
||||
std::vector<uint8_t> pst_hash;
|
||||
if (!ComputeHash(pst, pst_hash)) {
|
||||
LOGE("OldUsageTable: Could not compute hash of pst.");
|
||||
@@ -189,7 +192,8 @@ OldUsageTableEntry *OldUsageTable::FindEntryLocked(const std::vector<uint8_t> &p
|
||||
return it->second;
|
||||
}
|
||||
|
||||
OldUsageTableEntry *OldUsageTable::CreateEntry(const std::vector<uint8_t> &pst) {
|
||||
OldUsageTableEntry *OldUsageTable::CreateEntry(
|
||||
const std::vector<uint8_t> &pst) {
|
||||
std::vector<uint8_t> pst_hash;
|
||||
if (!ComputeHash(pst, pst_hash)) {
|
||||
LOGE("OldUsageTable: Could not compute hash of pst.");
|
||||
@@ -210,15 +214,16 @@ void OldUsageTable::Clear() {
|
||||
}
|
||||
|
||||
void OldUsageTable::DeleteFile(CryptoEngine *ce) {
|
||||
wvcdm::FileSystem* file_system = ce->file_system();
|
||||
wvcdm::FileSystem *file_system = ce->file_system();
|
||||
std::string path;
|
||||
// Note: this path is OK for a real implementation, but using security level 1
|
||||
// would be better.
|
||||
if (!wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL3,
|
||||
&path)) {
|
||||
// TODO(jfore): Address how this property is presented to the ref. For now,
|
||||
// the path is empty.
|
||||
/*if (!Properties::GetDeviceFilesBasePath(kSecurityLevelL3, &path)) {
|
||||
LOGE("OldUsageTable: Unable to get base path");
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
std::string filename = path + "UsageTable.dat";
|
||||
if (file_system->Exists(filename)) {
|
||||
if (!file_system->Remove(filename)) {
|
||||
@@ -228,7 +233,7 @@ void OldUsageTable::DeleteFile(CryptoEngine *ce) {
|
||||
}
|
||||
|
||||
bool OldUsageTable::ComputeHash(const std::vector<uint8_t> &pst,
|
||||
std::vector<uint8_t> &pst_hash) {
|
||||
std::vector<uint8_t> &pst_hash) {
|
||||
// The PST is not fixed size, and we have no promises that it is reasonbly
|
||||
// sized, so we compute a hash of it, and store that instead.
|
||||
pst_hash.resize(SHA256_DIGEST_LENGTH);
|
||||
@@ -239,4 +244,4 @@ bool OldUsageTable::ComputeHash(const std::vector<uint8_t> &pst,
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -1,26 +1,26 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
// This is from the v12 version of oemcrypto usage tables. It is used for
|
||||
// devices that upgrade from v12 to v13 in the field, and need to convert from
|
||||
// the old type of usage table to the new.
|
||||
#ifndef OEMCRYPTO_OLD_USAGE_TABLE_MOCK_H_
|
||||
#define OEMCRYPTO_OLD_USAGE_TABLE_MOCK_H_
|
||||
#ifndef OEMCRYPTO_OLD_USAGE_TABLE_REF_H_
|
||||
#define OEMCRYPTO_OLD_USAGE_TABLE_REF_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "lock.h"
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "lock.h"
|
||||
#include "oemcrypto_types.h"
|
||||
#include "openssl/sha.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
class CryptoEngine;
|
||||
class UsagetTableEntry;
|
||||
@@ -32,8 +32,8 @@ struct OldStoredUsageEntry {
|
||||
int64_t time_of_first_decrypt;
|
||||
int64_t time_of_last_decrypt;
|
||||
enum OEMCrypto_Usage_Entry_Status status;
|
||||
uint8_t mac_key_server[wvcdm::MAC_KEY_SIZE];
|
||||
uint8_t mac_key_client[wvcdm::MAC_KEY_SIZE];
|
||||
uint8_t mac_key_server[wvoec::MAC_KEY_SIZE];
|
||||
uint8_t mac_key_client[wvoec::MAC_KEY_SIZE];
|
||||
};
|
||||
|
||||
typedef union {
|
||||
@@ -43,7 +43,7 @@ typedef union {
|
||||
|
||||
struct OldStoredUsageTable {
|
||||
uint8_t signature[SHA256_DIGEST_LENGTH];
|
||||
uint8_t iv[wvcdm::KEY_IV_SIZE];
|
||||
uint8_t iv[wvoec::KEY_IV_SIZE];
|
||||
int64_t generation;
|
||||
uint64_t count;
|
||||
AlignedOldStoredUsageEntry entries[];
|
||||
@@ -90,6 +90,6 @@ class OldUsageTable {
|
||||
CryptoEngine *ce_;
|
||||
};
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
|
||||
#endif // OEMCRYPTO_OLD_USAGE_TABLE_MOCK_H_
|
||||
#endif // OEMCRYPTO_OLD_USAGE_TABLE_REF_H_
|
||||
@@ -22,12 +22,11 @@
|
||||
#include <vector>
|
||||
#include "file_store.h"
|
||||
#include "log.h"
|
||||
#include "oemcrypto_engine_mock.h"
|
||||
#include "oemcrypto_engine_ref.h"
|
||||
#include "oemcrypto_logging.h"
|
||||
#include "oemcrypto_session.h"
|
||||
#include "oemcrypto_usage_table_mock.h"
|
||||
#include "oemcrypto_usage_table_ref.h"
|
||||
#include "string_conversions.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
namespace {
|
||||
const uint8_t kBakedInCertificateMagicBytes[] = {0xDE, 0xAD, 0xBE, 0xEF};
|
||||
@@ -39,7 +38,7 @@ uint32_t unaligned_dereference_uint32(const void* unaligned_ptr) {
|
||||
uint32_t value;
|
||||
const uint8_t* src = reinterpret_cast<const uint8_t*>(unaligned_ptr);
|
||||
uint8_t* dest = reinterpret_cast<uint8_t*>(&value);
|
||||
for (unsigned long i=0; i < sizeof(value); i++) {
|
||||
for (unsigned long i = 0; i < sizeof(value); i++) {
|
||||
dest[i] = src[i];
|
||||
}
|
||||
return value;
|
||||
@@ -47,14 +46,14 @@ uint32_t unaligned_dereference_uint32(const void* unaligned_ptr) {
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
static CryptoEngine* crypto_engine = NULL;
|
||||
|
||||
typedef struct {
|
||||
uint8_t signature[wvcdm::MAC_KEY_SIZE];
|
||||
uint8_t context[wvcdm::MAC_KEY_SIZE];
|
||||
uint8_t iv[wvcdm::KEY_IV_SIZE];
|
||||
uint8_t signature[wvoec::MAC_KEY_SIZE];
|
||||
uint8_t context[wvoec::MAC_KEY_SIZE];
|
||||
uint8_t iv[wvoec::KEY_IV_SIZE];
|
||||
uint8_t enc_rsa_key[];
|
||||
} WrappedRSAKey;
|
||||
|
||||
@@ -69,7 +68,7 @@ extern "C" OEMCryptoResult OEMCrypto_Initialize(void) {
|
||||
}
|
||||
// NOTE: This requires a compatible Filesystem implementation.
|
||||
// NOTE: Ownership of the FileSystem object is transferred to CryptoEngine
|
||||
std::auto_ptr<wvcdm::FileSystem> fs(new wvcdm::FileSystem());
|
||||
scoped_ptr<wvcdm::FileSystem> fs(new wvcdm::FileSystem());
|
||||
crypto_engine = CryptoEngine::MakeCryptoEngine(fs);
|
||||
|
||||
if (!crypto_engine || !crypto_engine->Initialize()) {
|
||||
@@ -103,8 +102,9 @@ extern "C" OEMCryptoResult OEMCrypto_Terminate(void) {
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session) {
|
||||
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
|
||||
LOGI("-- OEMCryptoResult OEMCrypto_OpenSession"
|
||||
"(OEMCrypto_SESSION *session)\n");
|
||||
LOGI(
|
||||
"-- OEMCryptoResult OEMCrypto_OpenSession"
|
||||
"(OEMCrypto_SESSION *session)\n");
|
||||
}
|
||||
if (!crypto_engine) {
|
||||
LOGE("OEMCrypto_OpenSession: OEMCrypto not initialized.");
|
||||
@@ -118,15 +118,16 @@ extern "C" OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session) {
|
||||
SessionId sid = crypto_engine->CreateSession();
|
||||
*session = (OEMCrypto_SESSION)sid;
|
||||
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
|
||||
LOGD("[OEMCrypto_OpenSession(): SID=%08X]", sid);
|
||||
LOGD("[OEMCrypto_OpenSession(): SID=%08x]", sid);
|
||||
}
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session) {
|
||||
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
|
||||
LOGI("-- OEMCryptoResult OEMCrypto_CloseSession"
|
||||
"(OEMCrypto_SESSION session)\n");
|
||||
LOGI(
|
||||
"-- OEMCryptoResult OEMCrypto_CloseSession"
|
||||
"(OEMCrypto_SESSION session)\n");
|
||||
}
|
||||
if (!crypto_engine) {
|
||||
LOGE("OEMCrypto_CloseSession: OEMCrypto not initialized.");
|
||||
@@ -209,8 +210,9 @@ static uint64_t TimeStamp(void) {
|
||||
extern "C" OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
|
||||
uint32_t* nonce) {
|
||||
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
|
||||
LOGI("-- OEMCryptoResult OEMCrypto_GenerateNonce"
|
||||
"(OEMCrypto_SESSION session,\n");
|
||||
LOGI(
|
||||
"-- OEMCryptoResult OEMCrypto_GenerateNonce"
|
||||
"(OEMCrypto_SESSION session,\n");
|
||||
}
|
||||
if (!crypto_engine) {
|
||||
LOGE("OEMCrypto_GenerateNonce: OEMCrypto not initialized.");
|
||||
@@ -251,7 +253,7 @@ extern "C" OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
|
||||
session_ctx->AddNonce(nonce_value);
|
||||
*nonce = nonce_value;
|
||||
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
|
||||
LOGI("nonce = %08X\n", nonce_value);
|
||||
LOGI("nonce = %08x\n", nonce_value);
|
||||
}
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
@@ -322,23 +324,23 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
|
||||
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
|
||||
dump_hex("message", message, message_length);
|
||||
dump_hex("signature", signature, signature_length);
|
||||
dump_hex("enc_mac_key_iv", enc_mac_key_iv, wvcdm::KEY_IV_SIZE);
|
||||
dump_hex("enc_mac_keys", enc_mac_keys, 2 * wvcdm::MAC_KEY_SIZE);
|
||||
dump_hex("enc_mac_key_iv", enc_mac_key_iv, wvoec::KEY_IV_SIZE);
|
||||
dump_hex("enc_mac_keys", enc_mac_keys, 2 * wvoec::MAC_KEY_SIZE);
|
||||
dump_hex("pst", pst, pst_length);
|
||||
dump_hex("srm_requirement", srm_requirement, wvcdm::KEY_CONTROL_SIZE);
|
||||
dump_hex("srm_requirement", srm_requirement, wvoec::KEY_CONTROL_SIZE);
|
||||
for (size_t i = 0; i < num_keys; i++) {
|
||||
LOGV("key_array[%zu].key_id_length=%zu;\n", i,
|
||||
key_array[i].key_id_length);
|
||||
dump_array_part("key_array", i, "key_id", key_array[i].key_id,
|
||||
key_array[i].key_id_length);
|
||||
dump_array_part("key_array", i, "key_data_iv", key_array[i].key_data_iv,
|
||||
wvcdm::KEY_IV_SIZE);
|
||||
wvoec::KEY_IV_SIZE);
|
||||
dump_array_part("key_array", i, "key_data", key_array[i].key_data,
|
||||
key_array[i].key_data_length);
|
||||
dump_array_part("key_array", i, "key_control_iv",
|
||||
key_array[i].key_control_iv, wvcdm::KEY_IV_SIZE);
|
||||
key_array[i].key_control_iv, wvoec::KEY_IV_SIZE);
|
||||
dump_array_part("key_array", i, "key_control", key_array[i].key_control,
|
||||
wvcdm::KEY_IV_SIZE);
|
||||
wvoec::KEY_IV_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -368,15 +370,15 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
|
||||
}
|
||||
|
||||
// Range check
|
||||
if (!RangeCheck(message, message_length, enc_mac_keys,
|
||||
2 * wvcdm::MAC_KEY_SIZE, true) ||
|
||||
!RangeCheck(message, message_length, enc_mac_key_iv, wvcdm::KEY_IV_SIZE,
|
||||
if (!RangeCheck(message, message_length, enc_mac_keys, 2 * wvoec::MAC_KEY_SIZE,
|
||||
true) ||
|
||||
!RangeCheck(message, message_length, enc_mac_key_iv, wvoec::KEY_IV_SIZE, true) ||
|
||||
!RangeCheck(message, message_length, pst, pst_length, true) ||
|
||||
!RangeCheck(message, message_length, srm_requirement,
|
||||
wvcdm::SRM_REQUIREMENT_SIZE, true)) {
|
||||
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - range "
|
||||
"check.]");
|
||||
wvoec::SRM_REQUIREMENT_SIZE, true)) {
|
||||
LOGE(
|
||||
"[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - range "
|
||||
"check.]");
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
|
||||
@@ -386,13 +388,15 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
|
||||
!RangeCheck(message, message_length, key_array[i].key_data,
|
||||
key_array[i].key_data_length, false) ||
|
||||
!RangeCheck(message, message_length, key_array[i].key_data_iv,
|
||||
wvcdm::KEY_IV_SIZE, false) ||
|
||||
wvoec::KEY_IV_SIZE, false) ||
|
||||
!RangeCheck(message, message_length, key_array[i].key_control,
|
||||
wvcdm::KEY_CONTROL_SIZE, false) ||
|
||||
wvoec::KEY_CONTROL_SIZE, false) ||
|
||||
!RangeCheck(message, message_length, key_array[i].key_control_iv,
|
||||
wvcdm::KEY_IV_SIZE, false)) {
|
||||
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT -range "
|
||||
"check %d]", i);
|
||||
wvoec::KEY_IV_SIZE, false)) {
|
||||
LOGE(
|
||||
"[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT -range "
|
||||
"check %d]",
|
||||
i);
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
}
|
||||
@@ -403,8 +407,7 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
|
||||
OEMCrypto_SESSION session,
|
||||
size_t num_keys,
|
||||
OEMCrypto_SESSION session, size_t num_keys,
|
||||
const OEMCrypto_EntitledContentKeyObject* key_array) {
|
||||
if (num_keys == 0) {
|
||||
LOGE("[OEMCrypto_LoadEntitledContentKeys(): key_array is empty.");
|
||||
@@ -461,9 +464,9 @@ extern "C" OEMCryptoResult OEMCrypto_RefreshKeys(
|
||||
if (!RangeCheck(message, message_length, key_array[i].key_id,
|
||||
key_array[i].key_id_length, true) ||
|
||||
!RangeCheck(message, message_length, key_array[i].key_control,
|
||||
wvcdm::KEY_CONTROL_SIZE, false) ||
|
||||
wvoec::KEY_CONTROL_SIZE, false) ||
|
||||
!RangeCheck(message, message_length, key_array[i].key_control_iv,
|
||||
wvcdm::KEY_IV_SIZE, true)) {
|
||||
wvoec::KEY_IV_SIZE, true)) {
|
||||
LOGE("[OEMCrypto_RefreshKeys(): Range Check %d]", i);
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
@@ -486,12 +489,12 @@ extern "C" OEMCryptoResult OEMCrypto_RefreshKeys(
|
||||
key_id.assign(key_array[i].key_id,
|
||||
key_array[i].key_id + key_array[i].key_id_length);
|
||||
key_control.assign(key_array[i].key_control,
|
||||
key_array[i].key_control + wvcdm::KEY_CONTROL_SIZE);
|
||||
key_array[i].key_control + wvoec::KEY_CONTROL_SIZE);
|
||||
if (key_array[i].key_control_iv == NULL) {
|
||||
key_control_iv.clear();
|
||||
} else {
|
||||
key_control_iv.assign(key_array[i].key_control_iv,
|
||||
key_array[i].key_control_iv + wvcdm::KEY_IV_SIZE);
|
||||
key_array[i].key_control_iv + wvoec::KEY_IV_SIZE);
|
||||
}
|
||||
} else {
|
||||
// key_id could be null if special control key type
|
||||
@@ -499,7 +502,7 @@ extern "C" OEMCryptoResult OEMCrypto_RefreshKeys(
|
||||
key_id.clear();
|
||||
key_control_iv.clear();
|
||||
key_control.assign(key_array[i].key_control,
|
||||
key_array[i].key_control + wvcdm::KEY_CONTROL_SIZE);
|
||||
key_array[i].key_control + wvoec::KEY_CONTROL_SIZE);
|
||||
}
|
||||
|
||||
status = session_ctx->RefreshKey(key_id, key_control, key_control_iv);
|
||||
@@ -531,14 +534,15 @@ extern "C" OEMCryptoResult OEMCrypto_QueryKeyControl(
|
||||
}
|
||||
uint32_t* block = reinterpret_cast<uint32_t*>(key_control_block);
|
||||
if ((key_control_block_length == NULL) ||
|
||||
(*key_control_block_length < wvcdm::KEY_CONTROL_SIZE)) {
|
||||
(*key_control_block_length < wvoec::KEY_CONTROL_SIZE)) {
|
||||
LOGE("[OEMCrypto_QueryKeyControl(): OEMCrypto_ERROR_SHORT_BUFFER]");
|
||||
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||
}
|
||||
*key_control_block_length = wvcdm::KEY_CONTROL_SIZE;
|
||||
*key_control_block_length = wvoec::KEY_CONTROL_SIZE;
|
||||
if (key_id == NULL) {
|
||||
LOGE("[OEMCrypto_QueryKeyControl(): key_id null. "
|
||||
"OEMCrypto_ERROR_UNKNOWN_FAILURE]");
|
||||
LOGE(
|
||||
"[OEMCrypto_QueryKeyControl(): key_id null. "
|
||||
"OEMCrypto_ERROR_UNKNOWN_FAILURE]");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
|
||||
@@ -656,7 +660,7 @@ extern "C" OEMCryptoResult OEMCrypto_CopyBuffer(
|
||||
crypto_engine->SetDestination(out_buffer, data_length, subsample_flags);
|
||||
if (status != OEMCrypto_SUCCESS) return status;
|
||||
if (crypto_engine->destination() != NULL) {
|
||||
memcpy(crypto_engine->destination(), data_addr, data_length);
|
||||
memmove(crypto_engine->destination(), data_addr, data_length);
|
||||
}
|
||||
return crypto_engine->PushDestination(out_buffer, subsample_flags);
|
||||
}
|
||||
@@ -701,8 +705,8 @@ extern "C" OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox,
|
||||
return OEMCrypto_ERROR_WRITE_KEYBOX;
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_LoadTestKeybox(
|
||||
const uint8_t* buffer, size_t length) {
|
||||
extern "C" OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t* buffer,
|
||||
size_t length) {
|
||||
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
|
||||
LOGI("-- OEMCryptoResult OEMCrypto_LoadTestKeybox()\n");
|
||||
}
|
||||
@@ -880,7 +884,7 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
|
||||
dump_hex("encrypted_message_key", encrypted_message_key,
|
||||
encrypted_message_key_length);
|
||||
dump_hex("enc_rsa_key", enc_rsa_key, enc_rsa_key_length);
|
||||
dump_hex("enc_rsa_key_iv", enc_rsa_key_iv, wvcdm::KEY_IV_SIZE);
|
||||
dump_hex("enc_rsa_key_iv", enc_rsa_key_iv, wvoec::KEY_IV_SIZE);
|
||||
}
|
||||
}
|
||||
if (!crypto_engine) {
|
||||
@@ -929,8 +933,9 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
|
||||
|
||||
if (!session_ctx->InstallRSAEncryptedKey(encrypted_message_key,
|
||||
encrypted_message_key_length)) {
|
||||
LOGE("OEMCrypto_RewrapDeviceRSAKey30: "
|
||||
"Error loading encrypted_message_key.");
|
||||
LOGE(
|
||||
"OEMCrypto_RewrapDeviceRSAKey30: "
|
||||
"Error loading encrypted_message_key.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
|
||||
@@ -942,9 +947,10 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
|
||||
}
|
||||
size_t padding = pkcs8_rsa_key[enc_rsa_key_length - 1];
|
||||
if (padding > 16) {
|
||||
LOGE("[OEMCrypto_RewrapDeviceRSAKey30(): "
|
||||
"Encrypted RSA has bad padding: %d]",
|
||||
padding);
|
||||
LOGE(
|
||||
"[OEMCrypto_RewrapDeviceRSAKey30(): "
|
||||
"Encrypted RSA has bad padding: %d]",
|
||||
padding);
|
||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||
}
|
||||
size_t rsa_key_length = enc_rsa_key_length - padding;
|
||||
@@ -984,7 +990,8 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
|
||||
unsigned int sig_length = sizeof(wrapped->signature);
|
||||
if (LogCategoryEnabled(kLoggingDumpDerivedKeys)) {
|
||||
LOGI(("message verified with HMAC and mac_key_server, key = " +
|
||||
wvcdm::b2a_hex(session_ctx->mac_key_server())).c_str());
|
||||
wvcdm::b2a_hex(session_ctx->mac_key_server()))
|
||||
.c_str());
|
||||
}
|
||||
if (!HMAC(EVP_sha256(), &session_ctx->mac_key_server()[0],
|
||||
session_ctx->mac_key_server().size(), wrapped->context,
|
||||
@@ -1007,7 +1014,7 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
|
||||
const uint8_t* signature, size_t signature_length,
|
||||
const uint32_t* unaligned_nonce, const uint8_t* enc_rsa_key,
|
||||
size_t enc_rsa_key_length, const uint8_t* enc_rsa_key_iv,
|
||||
uint8_t* wrapped_rsa_key, size_t* wrapped_rsa_key_length) {
|
||||
uint8_t* wrapped_rsa_key, size_t* wrapped_rsa_key_length) {
|
||||
uint32_t nonce = unaligned_dereference_uint32(unaligned_nonce);
|
||||
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls | kLoggingTraceNonce)) {
|
||||
LOGI("-- OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(%d)\n", session);
|
||||
@@ -1023,7 +1030,7 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
|
||||
}
|
||||
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
|
||||
dump_hex("enc_rsa_key", enc_rsa_key, enc_rsa_key_length);
|
||||
dump_hex("enc_rsa_key_iv", enc_rsa_key_iv, wvcdm::KEY_IV_SIZE);
|
||||
dump_hex("enc_rsa_key_iv", enc_rsa_key_iv, wvoec::KEY_IV_SIZE);
|
||||
}
|
||||
}
|
||||
if (!crypto_engine) {
|
||||
@@ -1072,8 +1079,7 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
|
||||
sizeof(uint32_t), true) ||
|
||||
!RangeCheck(message, message_length, enc_rsa_key, enc_rsa_key_length,
|
||||
true) ||
|
||||
!RangeCheck(message, message_length, enc_rsa_key_iv, wvcdm::KEY_IV_SIZE,
|
||||
true)) {
|
||||
!RangeCheck(message, message_length, enc_rsa_key_iv, wvoec::KEY_IV_SIZE, true)) {
|
||||
LOGE("[OEMCrypto_RewrapDeviceRSAKey(): - range check.]");
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
@@ -1133,7 +1139,8 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
|
||||
unsigned int sig_length = sizeof(wrapped->signature);
|
||||
if (LogCategoryEnabled(kLoggingDumpDerivedKeys)) {
|
||||
LOGI(("message verified with HMAC and mac_key_server, key = " +
|
||||
wvcdm::b2a_hex(session_ctx->mac_key_server())).c_str());
|
||||
wvcdm::b2a_hex(session_ctx->mac_key_server()))
|
||||
.c_str());
|
||||
}
|
||||
if (!HMAC(EVP_sha256(), &session_ctx->mac_key_server()[0],
|
||||
session_ctx->mac_key_server().size(), wrapped->context,
|
||||
@@ -1393,7 +1400,7 @@ extern "C" OEMCryptoResult OEMCrypto_GetHDCPCapability(
|
||||
}
|
||||
|
||||
extern "C" uint32_t OEMCrypto_GetAnalogOutputFlags() {
|
||||
// TODO(b/69867568, fredgc): parameterize this.
|
||||
// TODO(b/69867568, fredgc): parameterize this.
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1463,7 +1470,7 @@ extern "C" OEMCryptoResult OEMCrypto_Generic_Encrypt(
|
||||
algorithm);
|
||||
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
|
||||
dump_hex("in_buffer", in_buffer, buffer_length);
|
||||
dump_hex("iv", iv, wvcdm::KEY_IV_SIZE);
|
||||
dump_hex("iv", iv, wvoec::KEY_IV_SIZE);
|
||||
}
|
||||
}
|
||||
if (!crypto_engine) {
|
||||
@@ -1502,7 +1509,7 @@ extern "C" OEMCryptoResult OEMCrypto_Generic_Decrypt(
|
||||
algorithm);
|
||||
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
|
||||
dump_hex("in_buffer", in_buffer, buffer_length);
|
||||
dump_hex("iv", iv, wvcdm::KEY_IV_SIZE);
|
||||
dump_hex("iv", iv, wvoec::KEY_IV_SIZE);
|
||||
}
|
||||
}
|
||||
if (!crypto_engine) {
|
||||
@@ -1681,9 +1688,10 @@ extern "C" OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
|
||||
return sts;
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_DeleteUsageEntry(
|
||||
OEMCrypto_SESSION, const uint8_t*, size_t, const uint8_t*, size_t,
|
||||
const uint8_t*, size_t) {
|
||||
extern "C" OEMCryptoResult OEMCrypto_DeleteUsageEntry(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;
|
||||
}
|
||||
@@ -1768,8 +1776,7 @@ extern "C" OEMCryptoResult OEMCrypto_RemoveSRM() {
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_CreateUsageTableHeader(
|
||||
uint8_t* header_buffer,
|
||||
size_t* header_buffer_length) {
|
||||
uint8_t* header_buffer, size_t* header_buffer_length) {
|
||||
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
|
||||
LOGI("-- OEMCryptoResult OEMCrypto_CreateUsageTableHeader()\n");
|
||||
}
|
||||
@@ -1781,8 +1788,8 @@ extern "C" OEMCryptoResult OEMCrypto_CreateUsageTableHeader(
|
||||
LOGE("OEMCrypto_CreateUsageTableHeader: Configured without Usage Tables.");
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
return crypto_engine->usage_table()
|
||||
.CreateUsageTableHeader(header_buffer, header_buffer_length);
|
||||
return crypto_engine->usage_table().CreateUsageTableHeader(
|
||||
header_buffer, header_buffer_length);
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_LoadUsageTableHeader(
|
||||
@@ -1943,15 +1950,11 @@ extern "C" OEMCryptoResult OEMCrypto_CopyOldUsageEntry(
|
||||
return session_ctx->CopyOldUsageEntry(pstv);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
OEMCryptoResult OEMCrypto_CreateOldUsageEntry(uint64_t time_since_license_received,
|
||||
uint64_t time_since_first_decrypt,
|
||||
uint64_t time_since_last_decrypt,
|
||||
OEMCrypto_Usage_Entry_Status status,
|
||||
uint8_t *server_mac_key,
|
||||
uint8_t *client_mac_key,
|
||||
const uint8_t* pst,
|
||||
size_t pst_length) {
|
||||
extern "C" OEMCryptoResult OEMCrypto_CreateOldUsageEntry(
|
||||
uint64_t time_since_license_received, uint64_t time_since_first_decrypt,
|
||||
uint64_t time_since_last_decrypt, OEMCrypto_Usage_Entry_Status status,
|
||||
uint8_t* server_mac_key, uint8_t* client_mac_key, const uint8_t* pst,
|
||||
size_t pst_length) {
|
||||
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
|
||||
LOGI("-- OEMCryptoResult OEMCrypto_CreateOldUsageEntry()\n");
|
||||
}
|
||||
@@ -1968,4 +1971,4 @@ OEMCryptoResult OEMCrypto_CreateOldUsageEntry(uint64_t time_since_license_receiv
|
||||
pst_length);
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,7 +2,7 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#include "oemcrypto_rsa_key_shared.h"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "oemcrypto_logging.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
void dump_boringssl_error() {
|
||||
int count = 0;
|
||||
@@ -98,4 +98,4 @@ bool RSA_shared_ptr::LoadPkcs8RsaKey(const uint8_t* buffer, size_t length) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,7 +2,7 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#ifndef OEMCRYPTO_RSA_KEY_SHARED_H_
|
||||
#define OEMCRYPTO_RSA_KEY_SHARED_H_
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
// Shared pointer with specialized destructor. This pointer is only shared
|
||||
// from a CryptoEngine to a Session -- so we don't have to use full reference
|
||||
@@ -37,6 +37,6 @@ class RSA_shared_ptr {
|
||||
// Log errors from BoringSSL.
|
||||
void dump_boringssl_error();
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
|
||||
#endif // OEMCRYPTO_RSA_KEY_SHARED_H_
|
||||
44
libwvdrmengine/oemcrypto/ref/src/oemcrypto_scoped_ptr.h
Normal file
44
libwvdrmengine/oemcrypto/ref/src/oemcrypto_scoped_ptr.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef OEMCRYPTO_SCOPED_PTR_H_
|
||||
#define OEMCRYPTO_SCOPED_PTR_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <memory>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
namespace wvoec_ref {
|
||||
|
||||
// TODO(fredgc, jfore): scoped_ptr may not be the best name for this smart
|
||||
// pointer type. It basically works like auto_ptr which is deprecated.
|
||||
#if __cplusplus < 201103L
|
||||
|
||||
template <typename T>
|
||||
class scoped_ptr {
|
||||
public:
|
||||
explicit scoped_ptr(T* p = NULL) : ptr_(p) {}
|
||||
T* get() const { return ptr_.get(); }
|
||||
|
||||
private:
|
||||
std::auto_ptr<T> ptr_;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template <typename T>
|
||||
class scoped_ptr {
|
||||
public:
|
||||
explicit scoped_ptr(T* p = nullptr) : ptr_(p) {}
|
||||
scoped_ptr(scoped_ptr& r) { ptr_ = std::move(r.ptr_); }
|
||||
T& operator*() const { return *ptr_; }
|
||||
T* operator->() const { return ptr_.get(); }
|
||||
T* get() const { return ptr_.get(); }
|
||||
void reset(T* p = NULL) { ptr_.reset(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<T> ptr_;
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace wvoec_ref
|
||||
|
||||
#endif // OEMCRYPTO_SCOPED_PTR_H_
|
||||
@@ -2,7 +2,7 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#include "oemcrypto_session.h"
|
||||
|
||||
@@ -26,12 +26,13 @@
|
||||
|
||||
#include "keys.h"
|
||||
#include "log.h"
|
||||
#include "oemcrypto_engine_mock.h"
|
||||
#include "oemcrypto_key_mock.h"
|
||||
#include "oemcrypto_engine_ref.h"
|
||||
#include "oemcrypto_key_ref.h"
|
||||
#include "oemcrypto_logging.h"
|
||||
#include "oemcrypto_rsa_key_shared.h"
|
||||
#include "oemcrypto_types.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "string_conversions.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
static const int kPssSaltLength = 20;
|
||||
|
||||
@@ -47,7 +48,7 @@ void ctr128_inc64(uint8_t* counter) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
/***************************************/
|
||||
|
||||
@@ -285,7 +286,7 @@ bool SessionContext::RSADeriveKeys(
|
||||
return false;
|
||||
}
|
||||
session_key_.resize(decrypted_size);
|
||||
if (decrypted_size != static_cast<int>(wvcdm::KEY_SIZE)) {
|
||||
if (decrypted_size != static_cast<int>(wvoec::KEY_SIZE)) {
|
||||
LOGE("[RSADeriveKeys(): error. Session key is wrong size: %d.]",
|
||||
decrypted_size);
|
||||
dump_boringssl_error();
|
||||
@@ -306,7 +307,7 @@ bool SessionContext::GenerateSignature(const uint8_t* message,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mac_key_client_.size() != wvcdm::MAC_KEY_SIZE) {
|
||||
if (mac_key_client_.size() != wvoec::MAC_KEY_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -320,7 +321,7 @@ bool SessionContext::GenerateSignature(const uint8_t* message,
|
||||
if (usage_entry_status_ == kUsageEntryLoaded) {
|
||||
usage_entry_mac_key_client.assign(
|
||||
usage_entry_->mac_key_client(),
|
||||
usage_entry_->mac_key_client() + wvcdm::MAC_KEY_SIZE * sizeof(uint8_t));
|
||||
usage_entry_->mac_key_client() + wvoec::MAC_KEY_SIZE * sizeof(uint8_t));
|
||||
using_usage_entry_mac_key_client =
|
||||
mac_key_client_ == usage_entry_mac_key_client;
|
||||
}
|
||||
@@ -335,7 +336,7 @@ bool SessionContext::GenerateSignature(const uint8_t* message,
|
||||
}
|
||||
|
||||
unsigned int md_len = *signature_length;
|
||||
if (HMAC(EVP_sha256(), &mac_key_client_[0], wvcdm::MAC_KEY_SIZE, message,
|
||||
if (HMAC(EVP_sha256(), &mac_key_client_[0], wvoec::MAC_KEY_SIZE, message,
|
||||
message_length, signature, &md_len)) {
|
||||
*signature_length = md_len;
|
||||
return true;
|
||||
@@ -452,7 +453,7 @@ bool SessionContext::ValidateMessage(const uint8_t* given_message,
|
||||
|
||||
OEMCryptoResult SessionContext::CheckStatusOnline(uint32_t nonce,
|
||||
uint32_t control) {
|
||||
if (!(control & kControlNonceEnabled)) {
|
||||
if (!(control & wvoec::kControlNonceEnabled)) {
|
||||
LOGE("LoadKeys: Server provided Nonce_Required but Nonce_Enabled = 0.");
|
||||
// Server error. Continue, and assume nonce required.
|
||||
}
|
||||
@@ -473,7 +474,7 @@ OEMCryptoResult SessionContext::CheckStatusOnline(uint32_t nonce,
|
||||
|
||||
OEMCryptoResult SessionContext::CheckStatusOffline(uint32_t nonce,
|
||||
uint32_t control) {
|
||||
if (control & kControlNonceEnabled) {
|
||||
if (control & wvoec::kControlNonceEnabled) {
|
||||
LOGE("KCB: Server provided NonceOrEntry but Nonce_Enabled = 1.");
|
||||
// Server error. Continue, and assume nonce required.
|
||||
}
|
||||
@@ -495,17 +496,17 @@ OEMCryptoResult SessionContext::CheckStatusOffline(uint32_t nonce,
|
||||
|
||||
OEMCryptoResult SessionContext::CheckNonceOrEntry(
|
||||
const KeyControlBlock& key_control_block) {
|
||||
switch (key_control_block.control_bits() & kControlReplayMask) {
|
||||
case kControlNonceRequired: // Online license. Nonce always required.
|
||||
switch (key_control_block.control_bits() & wvoec::kControlReplayMask) {
|
||||
case wvoec::kControlNonceRequired: // Online license. Nonce always required.
|
||||
return CheckStatusOnline(key_control_block.nonce(),
|
||||
key_control_block.control_bits());
|
||||
break;
|
||||
case kControlNonceOrEntry: // Offline license. Nonce required on first use.
|
||||
case wvoec::kControlNonceOrEntry: // Offline license. Nonce required on first use.
|
||||
return CheckStatusOffline(key_control_block.nonce(),
|
||||
key_control_block.control_bits());
|
||||
break;
|
||||
default:
|
||||
if ((key_control_block.control_bits() & kControlNonceEnabled) &&
|
||||
if ((key_control_block.control_bits() & wvoec::kControlNonceEnabled) &&
|
||||
(!CheckNonce(key_control_block.nonce()))) {
|
||||
LOGE("LoadKeys: BAD Nonce");
|
||||
return OEMCrypto_ERROR_INVALID_NONCE;
|
||||
@@ -599,15 +600,15 @@ OEMCryptoResult SessionContext::LoadKeys(
|
||||
enc_key_data.assign(key_array[i].key_data,
|
||||
key_array[i].key_data + key_array[i].key_data_length);
|
||||
key_data_iv.assign(key_array[i].key_data_iv,
|
||||
key_array[i].key_data_iv + wvcdm::KEY_IV_SIZE);
|
||||
key_array[i].key_data_iv + wvoec::KEY_IV_SIZE);
|
||||
if (key_array[i].key_control == NULL) {
|
||||
status = OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
break;
|
||||
}
|
||||
key_control.assign(key_array[i].key_control,
|
||||
key_array[i].key_control + wvcdm::KEY_CONTROL_SIZE);
|
||||
key_array[i].key_control + wvoec::KEY_CONTROL_SIZE);
|
||||
key_control_iv.assign(key_array[i].key_control_iv,
|
||||
key_array[i].key_control_iv + wvcdm::KEY_IV_SIZE);
|
||||
key_array[i].key_control_iv + wvoec::KEY_IV_SIZE);
|
||||
|
||||
OEMCryptoResult result =
|
||||
InstallKey(key_id, enc_key_data, key_data_iv, key_control,
|
||||
@@ -624,9 +625,9 @@ OEMCryptoResult SessionContext::LoadKeys(
|
||||
if (enc_mac_keys != NULL) {
|
||||
// V2.1 license protocol: update mac keys after processing license response
|
||||
const std::vector<uint8_t> enc_mac_keys_str = std::vector<uint8_t>(
|
||||
enc_mac_keys, enc_mac_keys + 2 * wvcdm::MAC_KEY_SIZE);
|
||||
enc_mac_keys, enc_mac_keys + 2 * wvoec::MAC_KEY_SIZE);
|
||||
const std::vector<uint8_t> enc_mac_key_iv_str = std::vector<uint8_t>(
|
||||
enc_mac_key_iv, enc_mac_key_iv + wvcdm::KEY_IV_SIZE);
|
||||
enc_mac_key_iv, enc_mac_key_iv + wvoec::KEY_IV_SIZE);
|
||||
|
||||
if (!UpdateMacKeys(enc_mac_keys_str, enc_mac_key_iv_str)) {
|
||||
LOGE("Failed to update mac keys.\n");
|
||||
@@ -763,14 +764,14 @@ OEMCryptoResult SessionContext::InstallKey(
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
if ((key_control_block.control_bits() &
|
||||
kControlRequireAntiRollbackHardware) &&
|
||||
wvoec::kControlRequireAntiRollbackHardware) &&
|
||||
!ce_->config_is_anti_rollback_hw_present()) {
|
||||
LOGE("Anti-rollback hardware is required but hardware not present.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
uint8_t minimum_patch_level =
|
||||
(key_control_block.control_bits() & kControlSecurityPatchLevelMask) >>
|
||||
kControlSecurityPatchLevelShift;
|
||||
(key_control_block.control_bits() & wvoec::kControlSecurityPatchLevelMask) >>
|
||||
wvoec::kControlSecurityPatchLevelShift;
|
||||
if (minimum_patch_level > OEMCrypto_Security_Patch_Level()) {
|
||||
LOGE("[InstallKey(): security patch level: %d. Minimum:%d]",
|
||||
OEMCrypto_Security_Patch_Level(), minimum_patch_level);
|
||||
@@ -781,13 +782,13 @@ OEMCryptoResult SessionContext::InstallKey(
|
||||
LOGE("LoadKeys: Failed Nonce/PST check.");
|
||||
return result;
|
||||
}
|
||||
if (key_control_block.control_bits() & kSharedLicense) {
|
||||
if (key_control_block.control_bits() & wvoec::kSharedLicense) {
|
||||
if (!second_license) {
|
||||
LOGE("LoadKeys: Shared License, but no keys previously loaded.");
|
||||
return OEMCrypto_ERROR_MISSING_MASTER;
|
||||
}
|
||||
}
|
||||
if (key_control_block.control_bits() & kControlSRMVersionRequired) {
|
||||
if (key_control_block.control_bits() & wvoec::kControlSRMVersionRequired) {
|
||||
if (srm_requirements_status_ == NoSRMVersion) {
|
||||
LOGE("[LoadKeys: control bit says SRM version required]");
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
@@ -818,7 +819,7 @@ bool SessionContext::InstallRSAEncryptedKey(
|
||||
return false;
|
||||
}
|
||||
encryption_key_.resize(decrypted_size);
|
||||
if (decrypted_size != static_cast<int>(wvcdm::KEY_SIZE)) {
|
||||
if (decrypted_size != static_cast<int>(wvoec::KEY_SIZE)) {
|
||||
LOGE("[RSADeriveKeys(): error. Session key is wrong size: %d.]",
|
||||
decrypted_size);
|
||||
dump_boringssl_error();
|
||||
@@ -841,7 +842,7 @@ OEMCryptoResult SessionContext::RefreshKey(
|
||||
LOGE("Parse key control error.");
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
if ((key_control_block.control_bits() & kControlNonceEnabled) &&
|
||||
if ((key_control_block.control_bits() & wvoec::kControlNonceEnabled) &&
|
||||
(!CheckNonce(key_control_block.nonce()))) {
|
||||
LOGE("KCB: BAD Nonce");
|
||||
return OEMCrypto_ERROR_INVALID_NONCE;
|
||||
@@ -896,7 +897,7 @@ OEMCryptoResult SessionContext::RefreshKey(
|
||||
}
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
if ((key_control_block.control_bits() & kControlNonceEnabled) &&
|
||||
if ((key_control_block.control_bits() & wvoec::kControlNonceEnabled) &&
|
||||
(!CheckNonce(key_control_block.nonce()))) {
|
||||
LOGE("KCB: BAD Nonce");
|
||||
return OEMCrypto_ERROR_INVALID_NONCE;
|
||||
@@ -910,8 +911,8 @@ bool SessionContext::DecryptRSAKey(const uint8_t* enc_rsa_key,
|
||||
const uint8_t* enc_rsa_key_iv,
|
||||
uint8_t* pkcs8_rsa_key) {
|
||||
// Decrypt rsa key with keybox.
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, enc_rsa_key_iv, wvcdm::KEY_IV_SIZE);
|
||||
uint8_t iv_buffer[wvoec::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, enc_rsa_key_iv, wvoec::KEY_IV_SIZE);
|
||||
AES_KEY aes_key;
|
||||
AES_set_decrypt_key(&encryption_key_[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(enc_rsa_key, pkcs8_rsa_key, enc_rsa_key_length, &aes_key,
|
||||
@@ -924,8 +925,8 @@ bool SessionContext::EncryptRSAKey(const uint8_t* pkcs8_rsa_key,
|
||||
const uint8_t* enc_rsa_key_iv,
|
||||
uint8_t* enc_rsa_key) {
|
||||
// Encrypt rsa key with keybox.
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, enc_rsa_key_iv, wvcdm::KEY_IV_SIZE);
|
||||
uint8_t iv_buffer[wvoec::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, enc_rsa_key_iv, wvoec::KEY_IV_SIZE);
|
||||
AES_KEY aes_key;
|
||||
AES_set_encrypt_key(&encryption_key_[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(pkcs8_rsa_key, enc_rsa_key, enc_rsa_key_length, &aes_key,
|
||||
@@ -960,14 +961,14 @@ OEMCryptoResult SessionContext::CheckKeyUse(const std::string& log_string,
|
||||
LOGE("[%s(): control bit says not allowed.", log_string.c_str());
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if (control.control_bits() & kControlDataPathSecure) {
|
||||
if (control.control_bits() & wvoec::kControlDataPathSecure) {
|
||||
if (!ce_->config_closed_platform() &&
|
||||
buffer_type == OEMCrypto_BufferType_Clear) {
|
||||
LOGE("[%s(): Secure key with insecure buffer]", log_string.c_str());
|
||||
return OEMCrypto_ERROR_DECRYPT_FAILED;
|
||||
}
|
||||
}
|
||||
if (control.control_bits() & kControlReplayMask) {
|
||||
if (control.control_bits() & wvoec::kControlReplayMask) {
|
||||
if (!CheckUsageEntry()) {
|
||||
LOGE("[%s(): usage entry not valid]", log_string.c_str());
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
@@ -982,10 +983,10 @@ OEMCryptoResult SessionContext::CheckKeyUse(const std::string& log_string,
|
||||
if (!ce_->config_local_display_only()) {
|
||||
// Only look at HDCP and Analog restrictions if the display can be
|
||||
// non-local.
|
||||
if (control.control_bits() & kControlHDCPRequired) {
|
||||
if (control.control_bits() & wvoec::kControlHDCPRequired) {
|
||||
uint8_t required_hdcp =
|
||||
(control.control_bits() & kControlHDCPVersionMask) >>
|
||||
kControlHDCPVersionShift;
|
||||
(control.control_bits() & wvoec::kControlHDCPVersionMask) >>
|
||||
wvoec::kControlHDCPVersionShift;
|
||||
if (ce_->srm_blacklisted_device_attached()) {
|
||||
required_hdcp = HDCP_NO_DIGITAL_OUTPUT;
|
||||
}
|
||||
@@ -999,7 +1000,7 @@ OEMCryptoResult SessionContext::CheckKeyUse(const std::string& log_string,
|
||||
}
|
||||
if (!ce_->config_local_display_only() ||
|
||||
buffer_type == OEMCrypto_BufferType_Clear) {
|
||||
if (control.control_bits() & kControlDisableAnalogOutput) {
|
||||
if (control.control_bits() & wvoec::kControlDisableAnalogOutput) {
|
||||
LOGE("[%s(): control bit says disable analog.", log_string.c_str());
|
||||
return OEMCrypto_ERROR_ANALOG_OUTPUT;
|
||||
}
|
||||
@@ -1023,7 +1024,7 @@ OEMCryptoResult SessionContext::Generic_Encrypt(const uint8_t* in_buffer,
|
||||
LOGE("[Generic_Encrypt(): CONTENT_KEY has wrong size: %d", key.size());
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
OEMCryptoResult result = CheckKeyUse("Generic_Encrypt", kControlAllowEncrypt,
|
||||
OEMCryptoResult result = CheckKeyUse("Generic_Encrypt", wvoec::kControlAllowEncrypt,
|
||||
OEMCrypto_BufferType_Clear);
|
||||
if (result != OEMCrypto_SUCCESS) return result;
|
||||
if (algorithm != OEMCrypto_AES_CBC_128_NO_PADDING) {
|
||||
@@ -1040,8 +1041,8 @@ OEMCryptoResult SessionContext::Generic_Encrypt(const uint8_t* in_buffer,
|
||||
LOGE("[Generic_Encrypt(): FAILURE]");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, iv, wvcdm::KEY_IV_SIZE);
|
||||
uint8_t iv_buffer[wvoec::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, iv, wvoec::KEY_IV_SIZE);
|
||||
AES_cbc_encrypt(in_buffer, out_buffer, buffer_length, &aes_key, iv_buffer,
|
||||
AES_ENCRYPT);
|
||||
return OEMCrypto_SUCCESS;
|
||||
@@ -1063,7 +1064,7 @@ OEMCryptoResult SessionContext::Generic_Decrypt(const uint8_t* in_buffer,
|
||||
LOGE("[Generic_Decrypt(): CONTENT_KEY has wrong size.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
OEMCryptoResult result = CheckKeyUse("Generic_Decrypt", kControlAllowDecrypt,
|
||||
OEMCryptoResult result = CheckKeyUse("Generic_Decrypt", wvoec::kControlAllowDecrypt,
|
||||
OEMCrypto_BufferType_Clear);
|
||||
if (result != OEMCrypto_SUCCESS) return result;
|
||||
|
||||
@@ -1081,8 +1082,8 @@ OEMCryptoResult SessionContext::Generic_Decrypt(const uint8_t* in_buffer,
|
||||
LOGE("[Generic_Decrypt(): FAILURE]");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, iv, wvcdm::KEY_IV_SIZE);
|
||||
uint8_t iv_buffer[wvoec::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, iv, wvoec::KEY_IV_SIZE);
|
||||
AES_cbc_encrypt(in_buffer, out_buffer, buffer_length, &aes_key, iv_buffer,
|
||||
AES_DECRYPT);
|
||||
return OEMCrypto_SUCCESS;
|
||||
@@ -1108,7 +1109,7 @@ OEMCryptoResult SessionContext::Generic_Sign(const uint8_t* in_buffer,
|
||||
LOGE("[Generic_Sign(): CONTENT_KEY has wrong size; %d", key.size());
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
OEMCryptoResult result = CheckKeyUse("Generic_Sign", kControlAllowSign,
|
||||
OEMCryptoResult result = CheckKeyUse("Generic_Sign", wvoec::kControlAllowSign,
|
||||
OEMCrypto_BufferType_Clear);
|
||||
if (result != OEMCrypto_SUCCESS) return result;
|
||||
if (algorithm != OEMCrypto_HMAC_SHA256) {
|
||||
@@ -1144,7 +1145,7 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer,
|
||||
LOGE("[Generic_Verify(): CONTENT_KEY has wrong size: %d", key.size());
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
OEMCryptoResult result = CheckKeyUse("Generic_Verify", kControlAllowVerify,
|
||||
OEMCryptoResult result = CheckKeyUse("Generic_Verify", wvoec::kControlAllowVerify,
|
||||
OEMCrypto_BufferType_Clear);
|
||||
if (result != OEMCrypto_SUCCESS) return result;
|
||||
if (algorithm != OEMCrypto_HMAC_SHA256) {
|
||||
@@ -1175,8 +1176,8 @@ bool SessionContext::UpdateMacKeys(const std::vector<uint8_t>& enc_mac_keys,
|
||||
return false;
|
||||
}
|
||||
mac_key_server_ = std::vector<uint8_t>(
|
||||
mac_keys.begin(), mac_keys.begin() + wvcdm::MAC_KEY_SIZE);
|
||||
mac_key_client_ = std::vector<uint8_t>(mac_keys.begin() + wvcdm::MAC_KEY_SIZE,
|
||||
mac_keys.begin(), mac_keys.begin() + wvoec::MAC_KEY_SIZE);
|
||||
mac_key_client_ = std::vector<uint8_t>(mac_keys.begin() + wvoec::MAC_KEY_SIZE,
|
||||
mac_keys.end());
|
||||
if (LogCategoryEnabled(kLoggingDumpDerivedKeys)) {
|
||||
LOGI(("mac_key_client_ has been updated to = " +
|
||||
@@ -1276,10 +1277,10 @@ OEMCryptoResult SessionContext::LoadUsageEntry(
|
||||
// Copy the mac keys to the current session.
|
||||
mac_key_server_ = std::vector<uint8_t>(
|
||||
usage_entry_->mac_key_server(),
|
||||
usage_entry_->mac_key_server() + wvcdm::MAC_KEY_SIZE);
|
||||
usage_entry_->mac_key_server() + wvoec::MAC_KEY_SIZE);
|
||||
mac_key_client_ = std::vector<uint8_t>(
|
||||
usage_entry_->mac_key_client(),
|
||||
usage_entry_->mac_key_client() + wvcdm::MAC_KEY_SIZE);
|
||||
usage_entry_->mac_key_client() + wvoec::MAC_KEY_SIZE);
|
||||
if (LogCategoryEnabled(kLoggingDumpDerivedKeys)) {
|
||||
LOGI(("mac_key_client_ has been updated to = " +
|
||||
wvcdm::b2a_hex(mac_key_client_)).c_str());
|
||||
@@ -1354,8 +1355,8 @@ OEMCryptoResult SessionContext::DecryptCENC(
|
||||
// If the data is clear, we do not need a current key selected.
|
||||
if (!is_encrypted) {
|
||||
if (buffer_type != OEMCrypto_BufferType_Direct) {
|
||||
memcpy(reinterpret_cast<uint8_t*>(clear_data), cipher_data,
|
||||
cipher_data_length);
|
||||
memmove(reinterpret_cast<uint8_t*>(clear_data), cipher_data,
|
||||
cipher_data_length);
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
// For reference implementation, we quietly drop the clear direct video.
|
||||
@@ -1420,7 +1421,7 @@ OEMCryptoResult SessionContext::DecryptCBC(
|
||||
pattern_offset = (pattern_offset + 1) % pattern_length;
|
||||
}
|
||||
if (skip_block || (size < AES_BLOCK_SIZE)) {
|
||||
memcpy(&clear_data[l], &cipher_data[l], size);
|
||||
memmove(&clear_data[l], &cipher_data[l], size);
|
||||
} else {
|
||||
uint8_t aes_output[AES_BLOCK_SIZE];
|
||||
// Save the iv for the next block, in case cipher_data is in the same
|
||||
@@ -1458,7 +1459,7 @@ OEMCryptoResult SessionContext::PatternDecryptCTR(
|
||||
pattern_offset = (pattern_offset + 1) % pattern_length;
|
||||
}
|
||||
if (skip_block) {
|
||||
memcpy(&clear_data[l], &cipher_data[l], size);
|
||||
memmove(&clear_data[l], &cipher_data[l], size);
|
||||
} else {
|
||||
uint8_t aes_output[AES_BLOCK_SIZE];
|
||||
AES_encrypt(iv, aes_output, &aes_key);
|
||||
@@ -1518,22 +1519,12 @@ OEMCryptoResult SessionContext::DecryptCTR(const uint8_t* key_u8,
|
||||
int out_len = 0;
|
||||
|
||||
while (remaining) {
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_CIPHER_CTX ctx_struct;
|
||||
EVP_CIPHER_CTX* evp_cipher_ctx = &ctx_struct;
|
||||
EVP_CIPHER_CTX_init(evp_cipher_ctx);
|
||||
#else
|
||||
EVP_CIPHER_CTX* evp_cipher_ctx = EVP_CIPHER_CTX_new();
|
||||
#endif
|
||||
EVP_CIPHER_CTX_set_padding(evp_cipher_ctx, 0);
|
||||
if (!EVP_DecryptInit_ex(evp_cipher_ctx, EVP_aes_128_ctr(), NULL, key_u8,
|
||||
aes_iv_u8)) {
|
||||
LOGE("[DecryptCTR(): EVP_INIT ERROR]");
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_CIPHER_CTX_cleanup(evp_cipher_ctx);
|
||||
#else
|
||||
EVP_CIPHER_CTX_free(evp_cipher_ctx);
|
||||
#endif
|
||||
return OEMCrypto_ERROR_DECRYPT_FAILED;
|
||||
}
|
||||
|
||||
@@ -1553,11 +1544,7 @@ OEMCryptoResult SessionContext::DecryptCTR(const uint8_t* key_u8,
|
||||
if (!EVP_DecryptUpdate(evp_cipher_ctx, &clear_data[l], &out_len,
|
||||
&cipher_data[l], decrypt_length)) {
|
||||
LOGE("[DecryptCTR(): EVP_UPDATE_ERROR]");
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_CIPHER_CTX_cleanup(evp_cipher_ctx);
|
||||
#else
|
||||
EVP_CIPHER_CTX_free(evp_cipher_ctx);
|
||||
#endif
|
||||
return OEMCrypto_ERROR_DECRYPT_FAILED;
|
||||
}
|
||||
l += decrypt_length;
|
||||
@@ -1568,18 +1555,10 @@ OEMCryptoResult SessionContext::DecryptCTR(const uint8_t* key_u8,
|
||||
&clear_data[cipher_data_length - remaining],
|
||||
&final)) {
|
||||
LOGE("[DecryptCTR(): EVP_FINAL_ERROR]");
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_CIPHER_CTX_cleanup(evp_cipher_ctx);
|
||||
#else
|
||||
EVP_CIPHER_CTX_free(evp_cipher_ctx);
|
||||
#endif
|
||||
return OEMCrypto_ERROR_DECRYPT_FAILED;
|
||||
}
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_CIPHER_CTX_cleanup(evp_cipher_ctx);
|
||||
#else
|
||||
EVP_CIPHER_CTX_free(evp_cipher_ctx);
|
||||
#endif
|
||||
|
||||
// If remaining is not zero, reset the iv before the second pass.
|
||||
if (remaining) {
|
||||
@@ -1590,4 +1569,4 @@ OEMCryptoResult SessionContext::DecryptCTR(const uint8_t* key_u8,
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,10 +2,10 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#ifndef MOCK_OEMCRYPTO_SESSION_H_
|
||||
#define MOCK_OEMCRYPTO_SESSION_H_
|
||||
#ifndef REF_OEMCRYPTO_SESSION_H_
|
||||
#define REF_OEMCRYPTO_SESSION_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
@@ -15,17 +15,15 @@
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
#include "OEMCryptoCENC.h" // Needed for enums only.
|
||||
#include "file_store.h"
|
||||
#include "lock.h"
|
||||
#include "oemcrypto_auth_mock.h"
|
||||
#include "oemcrypto_key_mock.h"
|
||||
#include "oemcrypto_auth_ref.h"
|
||||
#include "oemcrypto_key_ref.h"
|
||||
#include "oemcrypto_nonce_table.h"
|
||||
#include "oemcrypto_rsa_key_shared.h"
|
||||
#include "oemcrypto_session_key_table.h"
|
||||
#include "oemcrypto_usage_table_mock.h"
|
||||
#include "wv_cdm_types.h"
|
||||
#include "oemcrypto_usage_table_ref.h"
|
||||
#include "oemcrypto_types.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
class CryptoEngine;
|
||||
typedef uint32_t SessionId;
|
||||
@@ -245,6 +243,6 @@ class SessionContext {
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(SessionContext);
|
||||
};
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
|
||||
#endif // MOCK_OEMCRYPTO_SESSION_H_
|
||||
#endif // REF_OEMCRYPTO_SESSION_H_
|
||||
@@ -2,14 +2,14 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#include "oemcrypto_session_key_table.h"
|
||||
|
||||
#include "keys.h"
|
||||
#include "log.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
SessionKeyTable::~SessionKeyTable() {
|
||||
for (KeyMap::iterator i = keys_.begin(); i != keys_.end(); ++i) {
|
||||
@@ -116,4 +116,4 @@ bool EntitlementKeyTable::GetEntitlementKey(
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,19 +2,20 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#ifndef MOCK_OEMCRYPTO_SESSION_KEY_TABLE_H_
|
||||
#define MOCK_OEMCRYPTO_SESSION_KEY_TABLE_H_
|
||||
#ifndef REF_OEMCRYPTO_SESSION_KEY_TABLE_H_
|
||||
#define REF_OEMCRYPTO_SESSION_KEY_TABLE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "oemcrypto_key_mock.h"
|
||||
#include "wv_cdm_types.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "oemcrypto_key_ref.h"
|
||||
#include "oemcrypto_types.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
class SessionContext;
|
||||
class CryptoEngine;
|
||||
@@ -65,6 +66,6 @@ class EntitlementKeyTable {
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(EntitlementKeyTable);
|
||||
};
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
|
||||
#endif // MOCK_OEMCRYPTO_SESSION_KEY_TABLE_H_
|
||||
#endif // REF_OEMCRYPTO_SESSION_KEY_TABLE_H_
|
||||
@@ -2,9 +2,9 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#include "oemcrypto_usage_table_mock.h"
|
||||
#include "oemcrypto_usage_table_ref.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@@ -19,15 +19,16 @@
|
||||
|
||||
#include "file_store.h"
|
||||
#include "log.h"
|
||||
#include "oemcrypto_engine_mock.h"
|
||||
#include "oemcrypto_engine_ref.h"
|
||||
#include "oemcrypto_logging.h"
|
||||
#include "oemcrypto_old_usage_table_mock.h"
|
||||
#include "properties.h"
|
||||
#include "oemcrypto_old_usage_table_ref.h"
|
||||
// TODO(fredgc): Setting the device files base bath is currently broken as
|
||||
// wvcdm::Properties is no longer used by the reference code.
|
||||
//#include "properties.h"
|
||||
#include "pst_report.h"
|
||||
#include "string_conversions.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
namespace {
|
||||
const size_t kMagicLength = 8;
|
||||
const char* kEntryVerification = "USEENTRY";
|
||||
@@ -84,19 +85,19 @@ bool UsageTableEntry::VerifyPST(const uint8_t* pst, size_t pst_length) {
|
||||
|
||||
bool UsageTableEntry::VerifyMacKeys(const std::vector<uint8_t>& server,
|
||||
const std::vector<uint8_t>& client) {
|
||||
return (server.size() == wvcdm::MAC_KEY_SIZE) &&
|
||||
(client.size() == wvcdm::MAC_KEY_SIZE) &&
|
||||
(0 == memcmp(&server[0], data_.mac_key_server, wvcdm::MAC_KEY_SIZE)) &&
|
||||
(0 == memcmp(&client[0], data_.mac_key_client, wvcdm::MAC_KEY_SIZE));
|
||||
return (server.size() == wvoec::MAC_KEY_SIZE) &&
|
||||
(client.size() == wvoec::MAC_KEY_SIZE) &&
|
||||
(0 == memcmp(&server[0], data_.mac_key_server, wvoec::MAC_KEY_SIZE)) &&
|
||||
(0 == memcmp(&client[0], data_.mac_key_client, wvoec::MAC_KEY_SIZE));
|
||||
}
|
||||
|
||||
bool UsageTableEntry::SetMacKeys(const std::vector<uint8_t>& server,
|
||||
const std::vector<uint8_t>& client) {
|
||||
if ((server.size() != wvcdm::MAC_KEY_SIZE) ||
|
||||
(client.size() != wvcdm::MAC_KEY_SIZE))
|
||||
if ((server.size() != wvoec::MAC_KEY_SIZE) ||
|
||||
(client.size() != wvoec::MAC_KEY_SIZE))
|
||||
return false;
|
||||
memcpy(data_.mac_key_server, &server[0], wvcdm::MAC_KEY_SIZE);
|
||||
memcpy(data_.mac_key_client, &client[0], wvcdm::MAC_KEY_SIZE);
|
||||
memcpy(data_.mac_key_server, &server[0], wvoec::MAC_KEY_SIZE);
|
||||
memcpy(data_.mac_key_client, &client[0], wvoec::MAC_KEY_SIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -130,13 +131,12 @@ OEMCryptoResult UsageTableEntry::ReportUsage(const std::vector<uint8_t>& pst,
|
||||
if (recent_decrypt_) return OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE;
|
||||
if (pst.size() == 0 || pst.size() > kMaxPSTLength ||
|
||||
pst.size() != data_.pst_length) {
|
||||
LOGE("ReportUsage: bad pst length = %d, should be %d.",
|
||||
pst.size(), data_.pst_length);
|
||||
LOGE("ReportUsage: bad pst length = %d, should be %d.", pst.size(),
|
||||
data_.pst_length);
|
||||
return OEMCrypto_ERROR_WRONG_PST;
|
||||
}
|
||||
if (memcmp(&pst[0], data_.pst, data_.pst_length)) {
|
||||
LOGE("ReportUsage: wrong pst %s, should be %s.",
|
||||
wvcdm::b2a_hex(pst).c_str(),
|
||||
LOGE("ReportUsage: wrong pst %s, should be %s.", wvcdm::b2a_hex(pst).c_str(),
|
||||
wvcdm::HexEncode(data_.pst, data_.pst_length).c_str());
|
||||
return OEMCrypto_ERROR_WRONG_PST;
|
||||
}
|
||||
@@ -163,12 +163,13 @@ OEMCryptoResult UsageTableEntry::ReportUsage(const std::vector<uint8_t>& pst,
|
||||
if (LogCategoryEnabled(kLoggingDumpDerivedKeys)) {
|
||||
std::vector<uint8_t> mac_key_client(
|
||||
data_.mac_key_client,
|
||||
data_.mac_key_client + wvcdm::MAC_KEY_SIZE * sizeof(uint8_t));
|
||||
data_.mac_key_client + wvoec::MAC_KEY_SIZE * sizeof(uint8_t));
|
||||
LOGI(("message signed with HMAC and data_.mac_key_client, "
|
||||
"mac_key_client = " +
|
||||
wvcdm::b2a_hex(mac_key_client)).c_str());
|
||||
wvcdm::b2a_hex(mac_key_client))
|
||||
.c_str());
|
||||
}
|
||||
if (!HMAC(EVP_sha1(), data_.mac_key_client, wvcdm::MAC_KEY_SIZE,
|
||||
if (!HMAC(EVP_sha1(), data_.mac_key_client, wvoec::MAC_KEY_SIZE,
|
||||
buffer + SHA_DIGEST_LENGTH, length_needed - SHA_DIGEST_LENGTH,
|
||||
pst_report.signature(), &md_len)) {
|
||||
LOGE("ReportUsage: could not compute signature.");
|
||||
@@ -209,9 +210,9 @@ OEMCryptoResult UsageTableEntry::SaveData(CryptoEngine* ce,
|
||||
const std::vector<uint8_t>& key = ce->DeviceRootKey(override_to_real);
|
||||
|
||||
// Encrypt the entry.
|
||||
RAND_bytes(encrypted->iv, wvcdm::KEY_IV_SIZE);
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE]; // working iv buffer.
|
||||
memcpy(iv_buffer, encrypted->iv, wvcdm::KEY_IV_SIZE);
|
||||
RAND_bytes(encrypted->iv, wvoec::KEY_IV_SIZE);
|
||||
uint8_t iv_buffer[wvoec::KEY_IV_SIZE]; // working iv buffer.
|
||||
memcpy(iv_buffer, encrypted->iv, wvoec::KEY_IV_SIZE);
|
||||
AES_KEY aes_key;
|
||||
AES_set_encrypt_key(&key[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(
|
||||
@@ -265,8 +266,8 @@ OEMCryptoResult UsageTableEntry::LoadData(CryptoEngine* ce, uint32_t index,
|
||||
}
|
||||
|
||||
// Next, decrypt the entry.
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, encrypted->iv, wvcdm::KEY_IV_SIZE);
|
||||
uint8_t iv_buffer[wvoec::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, encrypted->iv, wvoec::KEY_IV_SIZE);
|
||||
AES_KEY aes_key;
|
||||
AES_set_decrypt_key(&key[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(&buffer[kEncryptionOffset], &clear_buffer[kEncryptionOffset],
|
||||
@@ -279,7 +280,8 @@ OEMCryptoResult UsageTableEntry::LoadData(CryptoEngine* ce, uint32_t index,
|
||||
wvcdm::HexEncode(clear->verification, kMagicLength).c_str(),
|
||||
clear->verification,
|
||||
wvcdm::HexEncode(reinterpret_cast<const uint8_t*>(kEntryVerification),
|
||||
kMagicLength).c_str(),
|
||||
kMagicLength)
|
||||
.c_str(),
|
||||
reinterpret_cast<const uint8_t*>(kEntryVerification));
|
||||
return OEMCrypto_ERROR_BAD_MAGIC;
|
||||
}
|
||||
@@ -306,23 +308,23 @@ OEMCryptoResult UsageTableEntry::CopyOldUsageEntry(
|
||||
data_.time_of_first_decrypt = old_entry->time_of_first_decrypt_;
|
||||
data_.time_of_last_decrypt = old_entry->time_of_last_decrypt_;
|
||||
data_.status = old_entry->status_;
|
||||
if (old_entry->mac_key_server_.size() != wvcdm::MAC_KEY_SIZE) {
|
||||
if (old_entry->mac_key_server_.size() != wvoec::MAC_KEY_SIZE) {
|
||||
LOGE("CopyOldEntry: Old entry has bad server mac key.");
|
||||
} else {
|
||||
memcpy(data_.mac_key_server, &(old_entry->mac_key_server_[0]),
|
||||
wvcdm::MAC_KEY_SIZE);
|
||||
wvoec::MAC_KEY_SIZE);
|
||||
}
|
||||
if (old_entry->mac_key_client_.size() != wvcdm::MAC_KEY_SIZE) {
|
||||
if (old_entry->mac_key_client_.size() != wvoec::MAC_KEY_SIZE) {
|
||||
LOGE("CopyOldEntry: Old entry has bad client mac key.");
|
||||
} else {
|
||||
memcpy(data_.mac_key_client, &(old_entry->mac_key_client_[0]),
|
||||
wvcdm::MAC_KEY_SIZE);
|
||||
wvoec::MAC_KEY_SIZE);
|
||||
if (LogCategoryEnabled(kLoggingDumpDerivedKeys)) {
|
||||
std::vector<uint8_t> mac_key_client(
|
||||
data_.mac_key_client,
|
||||
data_.mac_key_client + wvcdm::MAC_KEY_SIZE * sizeof(uint8_t));
|
||||
LOGI(("data_.mac_key_client has changed to = " +
|
||||
wvcdm::b2a_hex(mac_key_client)).c_str());
|
||||
data_.mac_key_client + wvoec::MAC_KEY_SIZE * sizeof(uint8_t));
|
||||
LOGI(("data_.mac_key_client has changed to = " +
|
||||
wvcdm::b2a_hex(mac_key_client)).c_str());
|
||||
}
|
||||
}
|
||||
if (pst.size() > kMaxPSTLength) {
|
||||
@@ -336,12 +338,11 @@ OEMCryptoResult UsageTableEntry::CopyOldUsageEntry(
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
size_t UsageTableEntry::SignedEntrySize() {
|
||||
size_t base = sizeof(SignedEntryBlock);
|
||||
// round up to make even number of blocks:
|
||||
size_t blocks = (base - 1) / wvcdm::KEY_IV_SIZE + 1;
|
||||
return blocks * wvcdm::KEY_IV_SIZE;
|
||||
size_t blocks = (base - 1) / wvoec::KEY_IV_SIZE + 1;
|
||||
return blocks * wvoec::KEY_IV_SIZE;
|
||||
}
|
||||
|
||||
UsageTable::~UsageTable() {
|
||||
@@ -354,8 +355,8 @@ UsageTable::~UsageTable() {
|
||||
size_t UsageTable::SignedHeaderSize(size_t count) {
|
||||
size_t base = sizeof(SignedHeaderBlock) + count * sizeof(int64_t);
|
||||
// round up to make even number of blocks:
|
||||
size_t blocks = (base - 1) / wvcdm::KEY_IV_SIZE + 1;
|
||||
return blocks * wvcdm::KEY_IV_SIZE;
|
||||
size_t blocks = (base - 1) / wvoec::KEY_IV_SIZE + 1;
|
||||
return blocks * wvoec::KEY_IV_SIZE;
|
||||
}
|
||||
|
||||
OEMCryptoResult UsageTable::UpdateUsageEntry(SessionContext* session,
|
||||
@@ -503,9 +504,9 @@ OEMCryptoResult UsageTable::SaveUsageTableHeader(uint8_t* signed_buffer,
|
||||
const std::vector<uint8_t>& key = ce_->DeviceRootKey(override_to_real);
|
||||
|
||||
// Encrypt the entry.
|
||||
RAND_bytes(encrypted->iv, wvcdm::KEY_IV_SIZE);
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE]; // working iv buffer.
|
||||
memcpy(iv_buffer, encrypted->iv, wvcdm::KEY_IV_SIZE);
|
||||
RAND_bytes(encrypted->iv, wvoec::KEY_IV_SIZE);
|
||||
uint8_t iv_buffer[wvoec::KEY_IV_SIZE]; // working iv buffer.
|
||||
memcpy(iv_buffer, encrypted->iv, wvoec::KEY_IV_SIZE);
|
||||
AES_KEY aes_key;
|
||||
AES_set_encrypt_key(&key[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(
|
||||
@@ -558,8 +559,8 @@ OEMCryptoResult UsageTable::LoadUsageTableHeader(
|
||||
}
|
||||
|
||||
// Next, decrypt the entry.
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, encrypted->iv, wvcdm::KEY_IV_SIZE);
|
||||
uint8_t iv_buffer[wvoec::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, encrypted->iv, wvoec::KEY_IV_SIZE);
|
||||
AES_KEY aes_key;
|
||||
AES_set_decrypt_key(&key[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(&buffer[kEncryptionOffset], &clear_buffer[kEncryptionOffset],
|
||||
@@ -572,7 +573,8 @@ OEMCryptoResult UsageTable::LoadUsageTableHeader(
|
||||
wvcdm::HexEncode(clear->verification, kMagicLength).c_str(),
|
||||
clear->verification,
|
||||
wvcdm::HexEncode(reinterpret_cast<const uint8_t*>(kHeaderVerification),
|
||||
kMagicLength).c_str(),
|
||||
kMagicLength)
|
||||
.c_str(),
|
||||
reinterpret_cast<const uint8_t*>(kHeaderVerification));
|
||||
return OEMCrypto_ERROR_BAD_MAGIC;
|
||||
}
|
||||
@@ -641,11 +643,13 @@ bool UsageTable::SaveGenerationNumber() {
|
||||
std::string path;
|
||||
// Note: this path is OK for a real implementation, but using security level 1
|
||||
// would be better.
|
||||
if (!wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL3,
|
||||
// TODO(jfore, rfrias): Address how this property is presented to the ref.
|
||||
// For now, the path is empty.
|
||||
/*if (!Properties::GetDeviceFilesBasePath(kSecurityLevelL3,
|
||||
&path)) {
|
||||
LOGE("UsageTable: Unable to get base path");
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
// On a real implementation, you should NOT put the generation number in
|
||||
// a file in user space. It should be stored in secure memory.
|
||||
std::string filename = path + "GenerationNumber.dat";
|
||||
@@ -666,16 +670,17 @@ bool UsageTable::LoadGenerationNumber(bool or_make_new_one) {
|
||||
std::string path;
|
||||
// Note: this path is OK for a real implementation, but using security level 1
|
||||
// would be better.
|
||||
if (!wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL3,
|
||||
// TODO(jfore, rfrias): Address how this property is presented to the ref.
|
||||
// For now, the path is empty.
|
||||
/*if (!Properties::GetDeviceFilesBasePath(kSecurityLevelL3,
|
||||
&path)) {
|
||||
LOGE("UsageTable: Unable to get base path");
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
// On a real implementation, you should NOT put the generation number in
|
||||
// a file in user space. It should be stored in secure memory.
|
||||
std::string filename = path + "GenerationNumber.dat";
|
||||
wvcdm::File* file = file_system->Open(filename,
|
||||
wvcdm::FileSystem::kReadOnly);
|
||||
wvcdm::File* file = file_system->Open(filename, wvcdm::FileSystem::kReadOnly);
|
||||
if (!file) {
|
||||
if (or_make_new_one) {
|
||||
RAND_bytes(reinterpret_cast<uint8_t*>(&master_generation_number_),
|
||||
@@ -702,7 +707,7 @@ OEMCryptoResult UsageTable::CreateUsageTableHeader(
|
||||
*header_buffer_length = signed_header_size;
|
||||
if (!LoadGenerationNumber(true)) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
// Make sure there are no entries that are currently tied to an open session.
|
||||
for (size_t i=0; i < sessions_.size(); ++i) {
|
||||
for (size_t i = 0; i < sessions_.size(); ++i) {
|
||||
if (sessions_[i] != NULL) {
|
||||
LOGE("CreateUsageTableHeader: index %d used by session.", i);
|
||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
@@ -736,8 +741,8 @@ OEMCryptoResult UsageTable::CreateOldUsageEntry(
|
||||
uint8_t* server_mac_key, uint8_t* client_mac_key, const uint8_t* pst,
|
||||
size_t pst_length) {
|
||||
if (!old_table_) old_table_ = new OldUsageTable(ce_);
|
||||
std::vector<uint8_t> pstv(pst, pst+pst_length);
|
||||
OldUsageTableEntry *old_entry = old_table_->CreateEntry(pstv);
|
||||
std::vector<uint8_t> pstv(pst, pst + pst_length);
|
||||
OldUsageTableEntry* old_entry = old_table_->CreateEntry(pstv);
|
||||
|
||||
int64_t now = time(NULL);
|
||||
old_entry->time_of_license_received_ = now - time_since_license_received;
|
||||
@@ -745,10 +750,10 @@ OEMCryptoResult UsageTable::CreateOldUsageEntry(
|
||||
old_entry->time_of_last_decrypt_ = now - time_since_last_decrypt;
|
||||
old_entry->status_ = status;
|
||||
old_entry->mac_key_server_.assign(server_mac_key,
|
||||
server_mac_key + wvcdm::MAC_KEY_SIZE);
|
||||
server_mac_key + wvoec::MAC_KEY_SIZE);
|
||||
old_entry->mac_key_client_.assign(client_mac_key,
|
||||
client_mac_key + wvcdm::MAC_KEY_SIZE);
|
||||
client_mac_key + wvoec::MAC_KEY_SIZE);
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
@@ -2,10 +2,10 @@
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// Mock implementation of OEMCrypto APIs
|
||||
// Ref implementation of OEMCrypto APIs
|
||||
//
|
||||
#ifndef OEMCRYPTO_USAGE_TABLE_MOCK_H_
|
||||
#define OEMCRYPTO_USAGE_TABLE_MOCK_H_
|
||||
#ifndef OEMCRYPTO_USAGE_TABLE_REF_H_
|
||||
#define OEMCRYPTO_USAGE_TABLE_REF_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
@@ -13,12 +13,10 @@
|
||||
#include <vector>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "file_store.h"
|
||||
#include "lock.h"
|
||||
#include "openssl/sha.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
#include "oemcrypto_types.h"
|
||||
|
||||
namespace wvoec_mock {
|
||||
namespace wvoec_ref {
|
||||
|
||||
class SessionContext;
|
||||
class CryptoEngine;
|
||||
@@ -34,8 +32,8 @@ struct StoredUsageEntry {
|
||||
int64_t time_of_first_decrypt;
|
||||
int64_t time_of_last_decrypt;
|
||||
enum OEMCrypto_Usage_Entry_Status status;
|
||||
uint8_t mac_key_server[wvcdm::MAC_KEY_SIZE];
|
||||
uint8_t mac_key_client[wvcdm::MAC_KEY_SIZE];
|
||||
uint8_t mac_key_server[wvoec::MAC_KEY_SIZE];
|
||||
uint8_t mac_key_client[wvoec::MAC_KEY_SIZE];
|
||||
uint32_t index;
|
||||
uint8_t pst[kMaxPSTLength+1]; // add 1 for padding.
|
||||
uint8_t pst_length;
|
||||
@@ -134,6 +132,6 @@ class UsageTable {
|
||||
OldUsageTable *old_table_;
|
||||
};
|
||||
|
||||
} // namespace wvoec_mock
|
||||
} // namespace wvoec_ref
|
||||
|
||||
#endif // OEMCRYPTO_USAGE_TABLE_MOCK_H_
|
||||
#endif // OEMCRYPTO_USAGE_TABLE_REF_H_
|
||||
@@ -2,6 +2,9 @@ LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
|
||||
LOCAL_MODULE:=oemcrypto_test
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ LOCAL_C_INCLUDES += \
|
||||
$(LOCAL_PATH)/../include \
|
||||
$(LOCAL_PATH)/../mock/src \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/util/include \
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
libcdm \
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "wv_keybox.h"
|
||||
#include "oemcrypto_types.h"
|
||||
|
||||
namespace wvoec {
|
||||
|
||||
|
||||
@@ -26,14 +26,12 @@
|
||||
#include <vector>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "log.h"
|
||||
#include "oec_device_features.h"
|
||||
#include "oec_test_data.h"
|
||||
#include "oemcrypto_key_mock.h"
|
||||
#include "oemcrypto_types.h"
|
||||
#include "string_conversions.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
#include "wv_cdm_types.h"
|
||||
#include "wv_keybox.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -102,9 +100,9 @@ Session::Session()
|
||||
: open_(false),
|
||||
forced_session_id_(false),
|
||||
session_id_(0),
|
||||
mac_key_server_(wvcdm::MAC_KEY_SIZE),
|
||||
mac_key_client_(wvcdm::MAC_KEY_SIZE),
|
||||
enc_key_(wvcdm::KEY_SIZE),
|
||||
mac_key_server_(MAC_KEY_SIZE),
|
||||
mac_key_client_(MAC_KEY_SIZE),
|
||||
enc_key_(KEY_SIZE),
|
||||
public_rsa_(0),
|
||||
message_size_(sizeof(MessageData)),
|
||||
// Most tests only use 4 keys. Other tests will explicitly call
|
||||
@@ -187,7 +185,7 @@ void Session::DeriveKey(const uint8_t* key, const vector<uint8_t>& context,
|
||||
CMAC_CTX* cmac_ctx = CMAC_CTX_new();
|
||||
ASSERT_NE(static_cast<void*>(NULL), cmac_ctx);
|
||||
|
||||
ASSERT_EQ(1, CMAC_Init(cmac_ctx, key, wvcdm::KEY_SIZE, cipher, 0));
|
||||
ASSERT_EQ(1, CMAC_Init(cmac_ctx, key, KEY_SIZE, cipher, 0));
|
||||
|
||||
std::vector<uint8_t> message;
|
||||
message.push_back(counter);
|
||||
@@ -223,7 +221,7 @@ void Session::DeriveKeys(const uint8_t* master_key,
|
||||
}
|
||||
|
||||
void Session::GenerateDerivedKeysFromKeybox(
|
||||
const wvoec_mock::WidevineKeybox& keybox) {
|
||||
const wvoec::WidevineKeybox& keybox) {
|
||||
GenerateNonce();
|
||||
vector<uint8_t> mac_context;
|
||||
vector<uint8_t> enc_context;
|
||||
@@ -269,9 +267,9 @@ void Session::LoadTestKeys(const std::string& pst, bool new_mac_keys) {
|
||||
key_array_, pst_ptr, pst.length(), NULL,
|
||||
OEMCrypto_ContentLicense));
|
||||
// Update new generated keys.
|
||||
memcpy(&mac_key_server_[0], license_.mac_keys, wvcdm::MAC_KEY_SIZE);
|
||||
memcpy(&mac_key_client_[0], license_.mac_keys + wvcdm::MAC_KEY_SIZE,
|
||||
wvcdm::MAC_KEY_SIZE);
|
||||
memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE);
|
||||
memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE,
|
||||
MAC_KEY_SIZE);
|
||||
} else {
|
||||
ASSERT_EQ(
|
||||
OEMCrypto_SUCCESS,
|
||||
@@ -299,9 +297,9 @@ void Session::LoadEnitlementTestKeys(const std::string& pst,
|
||||
key_array_, pst_ptr, pst.length(), NULL,
|
||||
OEMCrypto_EntitlementLicense));
|
||||
// Update new generated keys.
|
||||
memcpy(&mac_key_server_[0], license_.mac_keys, wvcdm::MAC_KEY_SIZE);
|
||||
memcpy(&mac_key_client_[0], license_.mac_keys + wvcdm::MAC_KEY_SIZE,
|
||||
wvcdm::MAC_KEY_SIZE);
|
||||
memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE);
|
||||
memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE,
|
||||
MAC_KEY_SIZE);
|
||||
} else {
|
||||
ASSERT_EQ(
|
||||
expected_sts,
|
||||
@@ -479,7 +477,7 @@ void Session::FillSimpleMessage(uint32_t duration, uint32_t control,
|
||||
memset(license_.keys[i].key_id, i, license_.keys[i].key_id_length);
|
||||
EXPECT_EQ(1, GetRandBytes(license_.keys[i].key_data,
|
||||
sizeof(license_.keys[i].key_data)));
|
||||
license_.keys[i].key_data_length = wvcdm::KEY_SIZE;
|
||||
license_.keys[i].key_data_length = KEY_SIZE;
|
||||
EXPECT_EQ(1, GetRandBytes(license_.keys[i].key_iv,
|
||||
sizeof(license_.keys[i].key_iv)));
|
||||
EXPECT_EQ(1, GetRandBytes(license_.keys[i].control_iv,
|
||||
@@ -493,14 +491,14 @@ void Session::FillSimpleMessage(uint32_t duration, uint32_t control,
|
||||
} else if (global_features.api_version == 12) {
|
||||
// For version 12, we require OEMCrypto to handle kc12 for all licenses.
|
||||
memcpy(license_.keys[i].control.verification, "kc12", 4);
|
||||
} else if (control & wvoec_mock::kControlSecurityPatchLevelMask) {
|
||||
} else if (control & wvoec::kControlSecurityPatchLevelMask) {
|
||||
// For versions before 12, we require the special key control block only
|
||||
// when there are newer features present.
|
||||
memcpy(license_.keys[i].control.verification, "kc11", 4);
|
||||
} else if (control & wvoec_mock::kControlRequireAntiRollbackHardware) {
|
||||
} else if (control & wvoec::kControlRequireAntiRollbackHardware) {
|
||||
memcpy(license_.keys[i].control.verification, "kc10", 4);
|
||||
} else if (control & (wvoec_mock::kControlHDCPVersionMask |
|
||||
wvoec_mock::kControlReplayMask)) {
|
||||
} else if (control & (wvoec::kControlHDCPVersionMask |
|
||||
wvoec::kControlReplayMask)) {
|
||||
memcpy(license_.keys[i].control.verification, "kc09", 4);
|
||||
} else {
|
||||
memcpy(license_.keys[i].control.verification, "kctl", 4);
|
||||
@@ -526,7 +524,7 @@ void Session::FillSimpleEntitlementMessage(
|
||||
memset(license_.keys[i].key_id, i, license_.keys[i].key_id_length);
|
||||
EXPECT_EQ(1, GetRandBytes(license_.keys[i].key_data,
|
||||
sizeof(license_.keys[i].key_data)));
|
||||
license_.keys[i].key_data_length = wvcdm::KEY_SIZE * 2; // AES-256 keys
|
||||
license_.keys[i].key_data_length = KEY_SIZE * 2; // AES-256 keys
|
||||
EXPECT_EQ(1, GetRandBytes(license_.keys[i].key_iv,
|
||||
sizeof(license_.keys[i].key_iv)));
|
||||
EXPECT_EQ(1, GetRandBytes(license_.keys[i].control_iv,
|
||||
@@ -540,14 +538,14 @@ void Session::FillSimpleEntitlementMessage(
|
||||
} else if (global_features.api_version == 12) {
|
||||
// For version 12, we require OEMCrypto to handle kc12 for all licenses.
|
||||
memcpy(license_.keys[i].control.verification, "kc12", 4);
|
||||
} else if (control & wvoec_mock::kControlSecurityPatchLevelMask) {
|
||||
} else if (control & wvoec::kControlSecurityPatchLevelMask) {
|
||||
// For versions before 12, we require the special key control block only
|
||||
// when there are newer features present.
|
||||
memcpy(license_.keys[i].control.verification, "kc11", 4);
|
||||
} else if (control & wvoec_mock::kControlRequireAntiRollbackHardware) {
|
||||
} else if (control & wvoec::kControlRequireAntiRollbackHardware) {
|
||||
memcpy(license_.keys[i].control.verification, "kc10", 4);
|
||||
} else if (control & (wvoec_mock::kControlHDCPVersionMask |
|
||||
wvoec_mock::kControlReplayMask)) {
|
||||
} else if (control & (wvoec::kControlHDCPVersionMask |
|
||||
wvoec::kControlReplayMask)) {
|
||||
memcpy(license_.keys[i].control.verification, "kc09", 4);
|
||||
} else {
|
||||
memcpy(license_.keys[i].control.verification, "kctl", 4);
|
||||
@@ -591,21 +589,21 @@ void Session::EncryptAndSign() {
|
||||
encrypted_license() = license_;
|
||||
|
||||
uint8_t iv_buffer[16];
|
||||
memcpy(iv_buffer, &license_.mac_key_iv[0], wvcdm::KEY_IV_SIZE);
|
||||
memcpy(iv_buffer, &license_.mac_key_iv[0], KEY_IV_SIZE);
|
||||
AES_KEY aes_key;
|
||||
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(&license_.mac_keys[0], &encrypted_license().mac_keys[0],
|
||||
2 * wvcdm::MAC_KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
|
||||
2 * MAC_KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
|
||||
|
||||
for (unsigned int i = 0; i < num_keys_; i++) {
|
||||
memcpy(iv_buffer, &license_.keys[i].control_iv[0], wvcdm::KEY_IV_SIZE);
|
||||
memcpy(iv_buffer, &license_.keys[i].control_iv[0], KEY_IV_SIZE);
|
||||
AES_set_encrypt_key(&license_.keys[i].key_data[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(
|
||||
reinterpret_cast<const uint8_t*>(&license_.keys[i].control),
|
||||
reinterpret_cast<uint8_t*>(&encrypted_license().keys[i].control),
|
||||
wvcdm::KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
|
||||
KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
|
||||
|
||||
memcpy(iv_buffer, &license_.keys[i].key_iv[0], wvcdm::KEY_IV_SIZE);
|
||||
memcpy(iv_buffer, &license_.keys[i].key_iv[0], KEY_IV_SIZE);
|
||||
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(
|
||||
&license_.keys[i].key_data[0], &encrypted_license().keys[i].key_data[0],
|
||||
@@ -620,14 +618,14 @@ void Session::EncryptAndSign() {
|
||||
void Session::EncryptProvisioningMessage(
|
||||
RSAPrivateKeyMessage* data, RSAPrivateKeyMessage* encrypted,
|
||||
const vector<uint8_t>& encryption_key) {
|
||||
ASSERT_EQ(encryption_key.size(), wvcdm::KEY_SIZE);
|
||||
ASSERT_EQ(encryption_key.size(), KEY_SIZE);
|
||||
*encrypted = *data;
|
||||
size_t padding = wvcdm::KEY_SIZE - (data->rsa_key_length % wvcdm::KEY_SIZE);
|
||||
size_t padding = KEY_SIZE - (data->rsa_key_length % KEY_SIZE);
|
||||
memset(data->rsa_key + data->rsa_key_length, static_cast<uint8_t>(padding),
|
||||
padding);
|
||||
encrypted->rsa_key_length = data->rsa_key_length + padding;
|
||||
uint8_t iv_buffer[16];
|
||||
memcpy(iv_buffer, &data->rsa_key_iv[0], wvcdm::KEY_IV_SIZE);
|
||||
memcpy(iv_buffer, &data->rsa_key_iv[0], KEY_IV_SIZE);
|
||||
AES_KEY aes_key;
|
||||
AES_set_encrypt_key(&encryption_key[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(&data->rsa_key[0], &encrypted->rsa_key[0],
|
||||
@@ -740,8 +738,8 @@ void Session::TestDecryptCTR(bool select_key_first,
|
||||
for (size_t i = 0; i < unencryptedData.size(); i++)
|
||||
unencryptedData[i] = i % 256;
|
||||
EXPECT_EQ(1, GetRandBytes(&unencryptedData[0], unencryptedData.size()));
|
||||
vector<uint8_t> encryptionIv(wvcdm::KEY_IV_SIZE);
|
||||
EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], wvcdm::KEY_IV_SIZE));
|
||||
vector<uint8_t> encryptionIv(KEY_IV_SIZE);
|
||||
EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], KEY_IV_SIZE));
|
||||
vector<uint8_t> encryptedData(unencryptedData.size());
|
||||
EncryptCTR(unencryptedData, license_.keys[key_index].key_data,
|
||||
&encryptionIv[0], &encryptedData);
|
||||
@@ -893,7 +891,7 @@ void Session::MakeRSACertificate(struct RSAPrivateKeyMessage* encrypted,
|
||||
memcpy(message.rsa_key, rsa_key.data(), rsa_key.size());
|
||||
message.rsa_key_length = rsa_key.size();
|
||||
}
|
||||
EXPECT_EQ(1, GetRandBytes(message.rsa_key_iv, wvcdm::KEY_IV_SIZE));
|
||||
EXPECT_EQ(1, GetRandBytes(message.rsa_key_iv, KEY_IV_SIZE));
|
||||
message.nonce = nonce_;
|
||||
|
||||
EncryptProvisioningMessage(&message, encrypted, *encryption_key);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user