OEMCrypto and OPK v17.5
This commit is contained in:
32
CHANGELOG.md
32
CHANGELOG.md
@@ -2,6 +2,37 @@
|
||||
|
||||
[TOC]
|
||||
|
||||
## [Version 17.5][v17.5]
|
||||
|
||||
This release is mostly testing-focused, including new tests that provide
|
||||
stricter enforcement of the existing OEMCrypto specification.
|
||||
|
||||
This release of OPK fixes a rare but possible null dereference bug.
|
||||
|
||||
### Tests
|
||||
|
||||
- Added new tests to better validate the behavior of
|
||||
`OEMCrypto_BuildInformation()`
|
||||
- Verifies output length is set correctly
|
||||
- Verifies content is ASCII text without trailing null bytes
|
||||
- Removed OEMCryptoLicenseTest.RejectCbc1API16
|
||||
- Fixed erroneous failures on devices with low TEE memory caused by sending an
|
||||
output buffer to decrypt that was much larger than necessary
|
||||
|
||||
### API
|
||||
|
||||
- Clarified the expected handling of the pattern (0,0) in cbcs mode. For more
|
||||
information, please check the [OEMCrypto v17 Delta Document][delta-17].
|
||||
|
||||
### OPK
|
||||
|
||||
- Fixed a potential null dereference in `OPK_DispatchMessage()` if the allocator
|
||||
runs out of memory
|
||||
- Fixed incorrect behavior of `OEMCrypto_RemoveEntitledKeySession()` when the
|
||||
session is already closed
|
||||
|
||||
[delta-17]: https://developers.google.com/widevine/drm/client/oemcrypto/v17/delta
|
||||
|
||||
## [Version 17.4][v17.4]
|
||||
|
||||
This is a minor release that includes a few security fixes.
|
||||
@@ -289,3 +320,4 @@ Public release for OEMCrypto API and ODK library version 16.4.
|
||||
[v17.2.1]: https://widevine-partner.googlesource.com/oemcrypto/+/refs/tags/v17.2.1
|
||||
[v17.3]: https://widevine-partner.googlesource.com/oemcrypto/+/refs/tags/v17.3
|
||||
[v17.4]: https://widevine-partner.googlesource.com/oemcrypto/+/refs/tags/v17.4
|
||||
[v17.5]: https://widevine-partner.googlesource.com/oemcrypto/+/refs/tags/v17.5
|
||||
|
||||
BIN
docs/Widevine_Open_Source_License_Terms.pdf
Normal file
BIN
docs/Widevine_Open_Source_License_Terms.pdf
Normal file
Binary file not shown.
@@ -3,7 +3,7 @@
|
||||
// License Agreement.
|
||||
|
||||
/**
|
||||
* @mainpage OEMCrypto API v17.4
|
||||
* @mainpage OEMCrypto API v17.5
|
||||
*
|
||||
* OEMCrypto is the low level library implemented by the OEM to provide key and
|
||||
* content protection, usually in a separate secure memory or process space. The
|
||||
@@ -2495,10 +2495,20 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session,
|
||||
* usually be non-zero. This mode allows devices to decrypt FMP4 HLS content,
|
||||
* SAMPLE-AES HLS content, as well as content using the DASH 'cbcs' scheme.
|
||||
*
|
||||
* The skip field of OEMCrypto_CENCEncryptPatternDesc may also be zero. If
|
||||
* the skip field is zero, then patterns are not in use and all crypto blocks
|
||||
* in the encrypted part of the subsample are encrypted. It is not valid for
|
||||
* the encrypt field to be zero.
|
||||
* The skip field of OEMCrypto_CENCEncryptPatternDesc may be zero. If the skip
|
||||
* field is zero, then patterns are not in use and all crypto blocks in the
|
||||
* encrypted part of the subsample are encrypted, except for any partial crypto
|
||||
* blocks at the end. The most common pattern with a skip field of zero is
|
||||
* (10,0), but all patterns with a skip field of zero are functionally the same.
|
||||
*
|
||||
* If the skip field of OEMCrypto_CENCEncryptPatternDesc is zero, the encrypt
|
||||
* field may also be zero. This pattern sometimes appears in content,
|
||||
* particularly in audio tracks. This (0,0) pattern should be treated as
|
||||
* equivalent to the pattern (10,0). e.g. All complete crypto blocks should be
|
||||
* decrypted.
|
||||
*
|
||||
* It is not valid for the encrypt field of OEMCrypto_CENCEncryptPatternDesc to
|
||||
* be zero if the skip field is non-zero.
|
||||
*
|
||||
* The length of a crypto block in AES-128 is 16 bytes. In the 'cbcs' scheme,
|
||||
* if the encrypted part of a subsample has a length that is not a multiple
|
||||
|
||||
@@ -25,9 +25,9 @@ struct CoreMessageFeatures {
|
||||
|
||||
// This is the published version of the ODK Core Message library. The default
|
||||
// behavior is for the server to restrict messages to at most this version
|
||||
// number. The default is 17.4.
|
||||
// number. The default is 17.5.
|
||||
uint32_t maximum_major_version = 17;
|
||||
uint32_t maximum_minor_version = 4;
|
||||
uint32_t maximum_minor_version = 5;
|
||||
|
||||
bool operator==(const CoreMessageFeatures &other) const;
|
||||
bool operator!=(const CoreMessageFeatures &other) const {
|
||||
|
||||
@@ -16,10 +16,10 @@ extern "C" {
|
||||
|
||||
/* The version of this library. */
|
||||
#define ODK_MAJOR_VERSION 17
|
||||
#define ODK_MINOR_VERSION 4
|
||||
#define ODK_MINOR_VERSION 5
|
||||
|
||||
/* ODK Version string. Date changed automatically on each release. */
|
||||
#define ODK_RELEASE_DATE "ODK v17.4 2024-06-04"
|
||||
#define ODK_RELEASE_DATE "ODK v17.5 2024-09-04"
|
||||
|
||||
/* The lowest version number for an ODK message. */
|
||||
#define ODK_FIRST_VERSION 16
|
||||
|
||||
@@ -23,7 +23,7 @@ CoreMessageFeatures CoreMessageFeatures::DefaultFeatures(
|
||||
features.maximum_minor_version = 5; // 16.5
|
||||
break;
|
||||
case 17:
|
||||
features.maximum_minor_version = 4; // 17.4
|
||||
features.maximum_minor_version = 5; // 17.5
|
||||
break;
|
||||
default:
|
||||
features.maximum_minor_version = 0;
|
||||
|
||||
@@ -274,7 +274,7 @@ OEMCryptoResult ODK_InitializeSessionValues(ODK_TimerLimits* timer_limits,
|
||||
nonce_values->api_minor_version = 5;
|
||||
break;
|
||||
case 17:
|
||||
nonce_values->api_minor_version = 4;
|
||||
nonce_values->api_minor_version = 5;
|
||||
break;
|
||||
case 18:
|
||||
nonce_values->api_minor_version = 3;
|
||||
|
||||
@@ -875,6 +875,7 @@ std::vector<VersionParameters> TestCases() {
|
||||
{17, 17, 2, 17, 2},
|
||||
{17, 17, 3, 17, 3},
|
||||
{17, 17, 4, 17, 4},
|
||||
{17, 17, 5, 17, 5},
|
||||
};
|
||||
return test_cases;
|
||||
}
|
||||
|
||||
@@ -3243,7 +3243,13 @@ OEMCryptoResult OEMCrypto_RemoveEntitledKeySession(
|
||||
OEMCryptoEntitledKeySession* key_session_context = NULL;
|
||||
OEMCryptoResult result =
|
||||
GetSessionContext(key_session, &session_context, &key_session_context);
|
||||
if (result != OEMCrypto_SUCCESS) return result;
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
// In case that the entitlement session is closed prior to the entitled key
|
||||
// session, the result of OPKI_GetSession() will not be OEMCrypto_SUCCESS,
|
||||
// and that's ok. This entitled key session should already be released when
|
||||
// its entitlement session was closed. Just return success here.
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
ABORT_IF(session_context == NULL,
|
||||
"Failed to get the entitlement session context.");
|
||||
ABORT_IF(key_session_context == NULL,
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
// version bumps to v17.1, the first released OPK implementation would be
|
||||
// v17.1.0
|
||||
#define API_MAJOR_VERSION 17
|
||||
#define API_MINOR_VERSION 4
|
||||
#define API_MINOR_VERSION 5
|
||||
#define OPK_PATCH_VERSION 0
|
||||
|
||||
#endif /* OEMCRYPTO_TA_OEMCRYPTO_API_MACROS_H_ */
|
||||
|
||||
@@ -67,10 +67,9 @@ ODK_MessageStatus Tuner_DispatchMessage(ODK_Message* request,
|
||||
OEMCrypto_CENCEncryptPatternDesc* pattern =
|
||||
(OEMCrypto_CENCEncryptPatternDesc*)OPK_VarAlloc(
|
||||
sizeof(OEMCrypto_CENCEncryptPatternDesc));
|
||||
if (!pattern) goto handle_out_of_memory;
|
||||
OPK_Init_OEMCrypto_CENCEncryptPatternDesc(
|
||||
(OEMCrypto_CENCEncryptPatternDesc*)pattern);
|
||||
// OPK_Unpack_DecryptCENC_Request(request, &session, &samples,
|
||||
// &samples_length, &pattern);
|
||||
OPK_Unpack_TunerHal_Decrypt_Request(request, &key_token,
|
||||
&key_token_length, &key_parity,
|
||||
&samples, &samples_length, &pattern);
|
||||
@@ -90,6 +89,12 @@ handle_invalid_request:
|
||||
LOGE("invalid request");
|
||||
*response = CreateEmptyMessage();
|
||||
return MESSAGE_STATUS_OK;
|
||||
|
||||
handle_out_of_memory:
|
||||
LOGE("out of memory");
|
||||
ODK_Message_SetStatus(request, MESSAGE_STATUS_OUT_OF_MEMORY);
|
||||
*response = CreateEmptyMessage();
|
||||
return MESSAGE_STATUS_OK;
|
||||
}
|
||||
|
||||
void OPK_Unpack_TunerHal_Decrypt_Request(
|
||||
|
||||
@@ -331,12 +331,14 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
size_t message_length;
|
||||
OPK_Init_size_t((size_t*)&message_length);
|
||||
size_t* signature_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (signature_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(signature_length);
|
||||
OEMCrypto_SESSION session;
|
||||
OPK_Init_uint32_t((uint32_t*)&session);
|
||||
uint8_t* message;
|
||||
OPK_InitPointer((uint8_t**)&message);
|
||||
size_t* core_message_size = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (core_message_size == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(core_message_size);
|
||||
uint8_t* signature;
|
||||
OPK_InitPointer((uint8_t**)&signature);
|
||||
@@ -360,12 +362,14 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
size_t message_length;
|
||||
OPK_Init_size_t((size_t*)&message_length);
|
||||
size_t* signature_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (signature_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(signature_length);
|
||||
OEMCrypto_SESSION session;
|
||||
OPK_Init_uint32_t((uint32_t*)&session);
|
||||
uint8_t* message;
|
||||
OPK_InitPointer((uint8_t**)&message);
|
||||
size_t* core_message_size = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (core_message_size == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(core_message_size);
|
||||
uint8_t* signature;
|
||||
OPK_InitPointer((uint8_t**)&signature);
|
||||
@@ -469,6 +473,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
OEMCrypto_KeyRefreshObject* key_array =
|
||||
(OEMCrypto_KeyRefreshObject*)OPK_VarAlloc(
|
||||
sizeof(OEMCrypto_KeyRefreshObject));
|
||||
if (key_array == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_OEMCrypto_KeyRefreshObject(
|
||||
(OEMCrypto_KeyRefreshObject*)key_array);
|
||||
OPK_Unpack_RefreshKeys_Request(request, &session, &message,
|
||||
@@ -516,6 +521,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
size_t content_key_id_length;
|
||||
OPK_Init_size_t((size_t*)&content_key_id_length);
|
||||
size_t* key_control_block_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (key_control_block_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(key_control_block_length);
|
||||
OEMCrypto_SESSION session;
|
||||
OPK_Init_uint32_t((uint32_t*)&session);
|
||||
@@ -610,13 +616,20 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
}
|
||||
case 120: /* OEMCrypto_LoadCasECMKeys */
|
||||
{
|
||||
if (!Handle_OEMCrypto_LoadCasECMKeys(request, response))
|
||||
goto handle_invalid_request;
|
||||
ODK_MessageStatus status = MESSAGE_STATUS_OK;
|
||||
if (!Handle_OEMCrypto_LoadCasECMKeys(request, response, &status)) {
|
||||
if (status == MESSAGE_STATUS_OUT_OF_MEMORY) {
|
||||
goto handle_out_of_memory;
|
||||
} else {
|
||||
goto handle_invalid_request;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 130: /* OEMCrypto_GetOEMKeyToken */
|
||||
{
|
||||
size_t* key_token_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (key_token_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(key_token_length);
|
||||
OEMCrypto_SESSION key_session;
|
||||
OPK_Init_uint32_t((uint32_t*)&key_session);
|
||||
@@ -665,6 +678,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
OEMCrypto_CENCEncryptPatternDesc* pattern =
|
||||
(OEMCrypto_CENCEncryptPatternDesc*)OPK_VarAlloc(
|
||||
sizeof(OEMCrypto_CENCEncryptPatternDesc));
|
||||
if (pattern == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_OEMCrypto_CENCEncryptPatternDesc(
|
||||
(OEMCrypto_CENCEncryptPatternDesc*)pattern);
|
||||
OPK_Unpack_DecryptCENC_Request(request, &session, &samples,
|
||||
@@ -687,6 +701,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
OEMCrypto_DestBufferDesc* out_buffer_descriptor =
|
||||
(OEMCrypto_DestBufferDesc*)OPK_VarAlloc(
|
||||
sizeof(OEMCrypto_DestBufferDesc));
|
||||
if (out_buffer_descriptor == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_OEMCrypto_DestBufferDesc(
|
||||
(OEMCrypto_DestBufferDesc*)out_buffer_descriptor);
|
||||
uint8_t subsample_flags;
|
||||
@@ -761,6 +776,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
size_t buffer_length;
|
||||
OPK_Init_size_t((size_t*)&buffer_length);
|
||||
size_t* signature_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (signature_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(signature_length);
|
||||
OEMCrypto_SESSION session;
|
||||
OPK_Init_uint32_t((uint32_t*)&session);
|
||||
@@ -815,6 +831,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
OPK_Init_size_t((size_t*)&keybox_or_cert_length);
|
||||
size_t* wrapped_keybox_or_cert_length =
|
||||
(size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (wrapped_keybox_or_cert_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(wrapped_keybox_or_cert_length);
|
||||
size_t transport_key_length;
|
||||
OPK_Init_size_t((size_t*)&transport_key_length);
|
||||
@@ -881,6 +898,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
case 7: /* OEMCrypto_GetDeviceID */
|
||||
{
|
||||
size_t* device_id_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (device_id_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(device_id_length);
|
||||
uint8_t* device_id;
|
||||
OPK_InitPointer((uint8_t**)&device_id);
|
||||
@@ -898,9 +916,11 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
{
|
||||
size_t* wrapped_private_key_length =
|
||||
(size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (wrapped_private_key_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(wrapped_private_key_length);
|
||||
uint8_t* clear_private_key_bytes =
|
||||
(uint8_t*)OPK_VarAlloc(sizeof(uint8_t));
|
||||
if (clear_private_key_bytes == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_uint8_t((uint8_t*)clear_private_key_bytes);
|
||||
size_t clear_private_key_length;
|
||||
OPK_Init_size_t((size_t*)&clear_private_key_length);
|
||||
@@ -923,6 +943,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
case 4: /* OEMCrypto_GetKeyData */
|
||||
{
|
||||
size_t* key_data_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (key_data_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(key_data_length);
|
||||
uint8_t* key_data;
|
||||
OPK_InitPointer((uint8_t**)&key_data);
|
||||
@@ -967,6 +988,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
case 104: /* OEMCrypto_GetOEMPublicCertificate */
|
||||
{
|
||||
size_t* public_cert_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (public_cert_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(public_cert_length);
|
||||
uint8_t* public_cert;
|
||||
OPK_InitPointer((uint8_t**)&public_cert);
|
||||
@@ -1023,6 +1045,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
case 125: /* OEMCrypto_BuildInformation */
|
||||
{
|
||||
size_t* buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (buffer_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(buffer_length);
|
||||
char* buffer;
|
||||
OPK_InitPointer((uint8_t**)&buffer);
|
||||
@@ -1221,6 +1244,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
OPK_Init_size_t((size_t*)&signature_length);
|
||||
size_t* wrapped_private_key_length =
|
||||
(size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (wrapped_private_key_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(wrapped_private_key_length);
|
||||
OEMCrypto_SESSION session;
|
||||
OPK_Init_uint32_t((uint32_t*)&session);
|
||||
@@ -1285,6 +1309,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
size_t message_length;
|
||||
OPK_Init_size_t((size_t*)&message_length);
|
||||
size_t* signature_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (signature_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(signature_length);
|
||||
OEMCrypto_SESSION session;
|
||||
OPK_Init_uint32_t((uint32_t*)&session);
|
||||
@@ -1313,12 +1338,14 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
size_t message_length;
|
||||
OPK_Init_size_t((size_t*)&message_length);
|
||||
size_t* signature_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (signature_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(signature_length);
|
||||
OEMCrypto_SESSION session;
|
||||
OPK_Init_uint32_t((uint32_t*)&session);
|
||||
uint8_t* message;
|
||||
OPK_InitPointer((uint8_t**)&message);
|
||||
size_t* core_message_size = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (core_message_size == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(core_message_size);
|
||||
uint8_t* signature;
|
||||
OPK_InitPointer((uint8_t**)&signature);
|
||||
@@ -1340,6 +1367,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
case 61: /* OEMCrypto_CreateUsageTableHeader */
|
||||
{
|
||||
size_t* header_buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (header_buffer_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(header_buffer_length);
|
||||
uint8_t* header_buffer;
|
||||
OPK_InitPointer((uint8_t**)&header_buffer);
|
||||
@@ -1427,8 +1455,10 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
case 65: /* OEMCrypto_UpdateUsageEntry */
|
||||
{
|
||||
size_t* header_buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (header_buffer_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(header_buffer_length);
|
||||
size_t* entry_buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (entry_buffer_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(entry_buffer_length);
|
||||
OEMCrypto_SESSION session;
|
||||
OPK_Init_uint32_t((uint32_t*)&session);
|
||||
@@ -1474,6 +1504,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
size_t pst_length;
|
||||
OPK_Init_size_t((size_t*)&pst_length);
|
||||
size_t* buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (buffer_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(buffer_length);
|
||||
OEMCrypto_SESSION session;
|
||||
OPK_Init_uint32_t((uint32_t*)&session);
|
||||
@@ -1510,6 +1541,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
case 67: /* OEMCrypto_ShrinkUsageTableHeader */
|
||||
{
|
||||
size_t* header_buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (header_buffer_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(header_buffer_length);
|
||||
uint32_t new_entry_count;
|
||||
OPK_Init_uint32_t((uint32_t*)&new_entry_count);
|
||||
@@ -1530,9 +1562,11 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
case 116: /* OEMCrypto_GetBootCertificateChain */
|
||||
{
|
||||
size_t* bcc_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (bcc_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(bcc_length);
|
||||
size_t* additional_signature_length =
|
||||
(size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (additional_signature_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(additional_signature_length);
|
||||
uint8_t* bcc;
|
||||
OPK_InitPointer((uint8_t**)&bcc);
|
||||
@@ -1555,12 +1589,15 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
case 117: /* OEMCrypto_GenerateCertificateKeyPair */
|
||||
{
|
||||
size_t* public_key_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (public_key_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(public_key_length);
|
||||
size_t* public_key_signature_length =
|
||||
(size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (public_key_signature_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(public_key_signature_length);
|
||||
size_t* wrapped_private_key_length =
|
||||
(size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (wrapped_private_key_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(wrapped_private_key_length);
|
||||
OEMCrypto_SESSION session;
|
||||
OPK_Init_uint32_t((uint32_t*)&session);
|
||||
@@ -1690,6 +1727,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
OEMCrypto_DestBufferDesc* output_descriptor =
|
||||
(OEMCrypto_DestBufferDesc*)OPK_VarAlloc(
|
||||
sizeof(OEMCrypto_DestBufferDesc));
|
||||
if (output_descriptor == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_OEMCrypto_DestBufferDesc(output_descriptor);
|
||||
int secure_fd;
|
||||
OPK_Init_int((int*)&secure_fd);
|
||||
@@ -1707,8 +1745,10 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
case 115: /* OEMCrypto_OPK_SerializationVersion */
|
||||
{
|
||||
uint32_t* ree_major = (uint32_t*)OPK_VarAlloc(sizeof(uint32_t));
|
||||
if (ree_major == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_uint32_t(ree_major);
|
||||
uint32_t* ree_minor = (uint32_t*)OPK_VarAlloc(sizeof(uint32_t));
|
||||
if (ree_minor == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_uint32_t(ree_minor);
|
||||
uint32_t* tee_major;
|
||||
OPK_InitPointer((uint8_t**)&tee_major);
|
||||
@@ -1729,6 +1769,7 @@ ODK_MessageStatus OPK_DispatchMessage(ODK_Message* request,
|
||||
case 113: /* OEMCrypto_GenerateOTARequest */
|
||||
{
|
||||
size_t* buffer_length = (size_t*)OPK_VarAlloc(sizeof(size_t));
|
||||
if (buffer_length == NULL) goto handle_out_of_memory;
|
||||
OPK_Init_size_t(buffer_length);
|
||||
OEMCrypto_SESSION session;
|
||||
OPK_Init_uint32_t((uint32_t*)&session);
|
||||
@@ -1778,4 +1819,10 @@ handle_invalid_request:
|
||||
LOGE("invalid request");
|
||||
*response = CreateEmptyMessage();
|
||||
return MESSAGE_STATUS_OK;
|
||||
|
||||
handle_out_of_memory:
|
||||
LOGE("out of memory");
|
||||
ODK_Message_SetStatus(request, MESSAGE_STATUS_OUT_OF_MEMORY);
|
||||
*response = CreateEmptyMessage();
|
||||
return MESSAGE_STATUS_OK;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@ void OPK_Init_OEMCrypto_EntitledContentKeyObject(
|
||||
OEMCrypto_EntitledContentKeyObject* obj);
|
||||
|
||||
bool Handle_OEMCrypto_LoadCasECMKeys(ODK_Message* request,
|
||||
ODK_Message* response) {
|
||||
ODK_Message* response,
|
||||
ODK_MessageStatus* status) {
|
||||
size_t message_length;
|
||||
OPK_Init_size_t((size_t*)&message_length);
|
||||
OEMCrypto_SESSION session;
|
||||
@@ -28,11 +29,19 @@ bool Handle_OEMCrypto_LoadCasECMKeys(ODK_Message* request,
|
||||
OEMCrypto_EntitledContentKeyObject* even_key =
|
||||
(OEMCrypto_EntitledContentKeyObject*)OPK_VarAlloc(
|
||||
sizeof(OEMCrypto_EntitledContentKeyObject));
|
||||
if (!even_key) {
|
||||
*status = MESSAGE_STATUS_OUT_OF_MEMORY;
|
||||
return false;
|
||||
}
|
||||
OPK_Init_OEMCrypto_EntitledContentKeyObject(
|
||||
(OEMCrypto_EntitledContentKeyObject*)even_key);
|
||||
OEMCrypto_EntitledContentKeyObject* odd_key =
|
||||
(OEMCrypto_EntitledContentKeyObject*)OPK_VarAlloc(
|
||||
sizeof(OEMCrypto_EntitledContentKeyObject));
|
||||
if (!odd_key) {
|
||||
*status = MESSAGE_STATUS_OUT_OF_MEMORY;
|
||||
return false;
|
||||
}
|
||||
OPK_Init_OEMCrypto_EntitledContentKeyObject(
|
||||
(OEMCrypto_EntitledContentKeyObject*)odd_key);
|
||||
OPK_Unpack_LoadCasECMKeys_Request(request, &session, &message,
|
||||
@@ -44,5 +53,6 @@ bool Handle_OEMCrypto_LoadCasECMKeys(ODK_Message* request,
|
||||
result = OEMCrypto_LoadCasECMKeys(session, message, message_length, even_key,
|
||||
odd_key);
|
||||
*response = OPK_Pack_LoadCasECMKeys_Response(result);
|
||||
*status = MESSAGE_STATUS_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@ extern "C" {
|
||||
#include "odk_message.h"
|
||||
|
||||
bool Handle_OEMCrypto_LoadCasECMKeys(ODK_Message* request,
|
||||
ODK_Message* response);
|
||||
ODK_Message* response,
|
||||
ODK_MessageStatus* status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
||||
@@ -17,7 +17,6 @@ void advance_dest_buffer(OEMCrypto_DestBufferDesc* dest_buffer, size_t bytes) {
|
||||
switch (dest_buffer->type) {
|
||||
case OEMCrypto_BufferType_Clear:
|
||||
dest_buffer->buffer.clear.clear_buffer += bytes;
|
||||
dest_buffer->buffer.clear.clear_buffer_length -= bytes;
|
||||
break;
|
||||
|
||||
case OEMCrypto_BufferType_Secure:
|
||||
@@ -96,6 +95,11 @@ OEMCryptoResult DecryptFallbackChain::DecryptSample(
|
||||
const size_t length =
|
||||
subsample.num_bytes_clear + subsample.num_bytes_encrypted;
|
||||
fake_sample.buffers.input_data_length = length;
|
||||
if (fake_sample.buffers.output_descriptor.type ==
|
||||
OEMCrypto_BufferType_Clear) {
|
||||
fake_sample.buffers.output_descriptor.buffer.clear.clear_buffer_length =
|
||||
length;
|
||||
}
|
||||
fake_sample.subsamples = &subsample;
|
||||
fake_sample.subsamples_length = 1;
|
||||
|
||||
@@ -138,6 +142,11 @@ OEMCryptoResult DecryptFallbackChain::DecryptSubsample(
|
||||
|
||||
if (subsample.num_bytes_clear > 0) {
|
||||
fake_sample.buffers.input_data_length = subsample.num_bytes_clear;
|
||||
if (fake_sample.buffers.output_descriptor.type ==
|
||||
OEMCrypto_BufferType_Clear) {
|
||||
fake_sample.buffers.output_descriptor.buffer.clear.clear_buffer_length =
|
||||
subsample.num_bytes_clear;
|
||||
}
|
||||
fake_subsample.num_bytes_clear = subsample.num_bytes_clear;
|
||||
fake_subsample.num_bytes_encrypted = 0;
|
||||
fake_subsample.block_offset = 0;
|
||||
@@ -160,6 +169,11 @@ OEMCryptoResult DecryptFallbackChain::DecryptSubsample(
|
||||
|
||||
if (subsample.num_bytes_encrypted > 0) {
|
||||
fake_sample.buffers.input_data_length = subsample.num_bytes_encrypted;
|
||||
if (fake_sample.buffers.output_descriptor.type ==
|
||||
OEMCrypto_BufferType_Clear) {
|
||||
fake_sample.buffers.output_descriptor.buffer.clear.clear_buffer_length =
|
||||
subsample.num_bytes_encrypted;
|
||||
}
|
||||
fake_subsample.num_bytes_clear = 0;
|
||||
fake_subsample.num_bytes_encrypted = subsample.num_bytes_encrypted;
|
||||
fake_subsample.block_offset = subsample.block_offset;
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "log.h"
|
||||
#include "oec_test_data.h"
|
||||
#include "string_conversions.h"
|
||||
#include "test_sleep.h"
|
||||
|
||||
namespace wvoec {
|
||||
@@ -58,6 +60,12 @@ void DeviceFeatures::Initialize() {
|
||||
loads_certificate = false;
|
||||
}
|
||||
printf("loads_certificate = %s.\n", loads_certificate ? "true" : "false");
|
||||
if (rsa_test_key().empty()) {
|
||||
set_rsa_test_key(
|
||||
std::vector<uint8_t>(kTestRSAPKCS8PrivateKeyInfo2_2048,
|
||||
kTestRSAPKCS8PrivateKeyInfo2_2048 +
|
||||
sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048)));
|
||||
}
|
||||
generic_crypto =
|
||||
(OEMCrypto_ERROR_NOT_IMPLEMENTED !=
|
||||
OEMCrypto_Generic_Encrypt(session, buffer, 0, iv,
|
||||
@@ -113,6 +121,9 @@ void DeviceFeatures::Initialize() {
|
||||
case LOAD_TEST_RSA_KEY:
|
||||
printf("LOAD_TEST_RSA_KEY: Call LoadTestRSAKey before deriving keys.\n");
|
||||
break;
|
||||
case PRELOADED_RSA_KEY:
|
||||
printf("PRELOADED_RSA_KEY: Device has test RSA key baked in.\n");
|
||||
break;
|
||||
case TEST_PROVISION_30:
|
||||
printf("TEST_PROVISION_30: Device provisioned with OEM Cert.\n");
|
||||
break;
|
||||
@@ -181,9 +192,10 @@ void DeviceFeatures::PickDerivedKey() {
|
||||
derive_key_method = TEST_PROVISION_30;
|
||||
return;
|
||||
case OEMCrypto_DrmCertificate:
|
||||
if (OEMCrypto_ERROR_NOT_IMPLEMENTED != OEMCrypto_LoadTestRSAKey()) {
|
||||
derive_key_method = LOAD_TEST_RSA_KEY;
|
||||
}
|
||||
derive_key_method =
|
||||
(OEMCrypto_ERROR_NOT_IMPLEMENTED == OEMCrypto_LoadTestRSAKey())
|
||||
? PRELOADED_RSA_KEY
|
||||
: LOAD_TEST_RSA_KEY;
|
||||
return;
|
||||
case OEMCrypto_Keybox:
|
||||
// Fall through to api_version < 12 case.
|
||||
|
||||
@@ -38,6 +38,7 @@ class DeviceFeatures {
|
||||
LOAD_TEST_RSA_KEY, // Call LoadTestRSAKey before deriving keys.
|
||||
TEST_PROVISION_30, // Device has OEM Certificate installed.
|
||||
TEST_PROVISION_40, // Device has Boot Certificate Chain installed.
|
||||
PRELOADED_RSA_KEY, // Device has test RSA key baked in.
|
||||
};
|
||||
|
||||
enum DeriveMethod derive_key_method;
|
||||
@@ -69,6 +70,16 @@ class DeviceFeatures {
|
||||
// Get a list of output types that should be tested.
|
||||
const std::vector<OutputType>& GetOutputTypes();
|
||||
|
||||
// If the device has a baked in cert, then this is the public key that should
|
||||
// be used for testing.
|
||||
const std::vector<uint8_t>& rsa_test_key() const { return rsa_test_key_; };
|
||||
void set_rsa_test_key(const std::vector<uint8_t>& rsa_test_key) {
|
||||
rsa_test_key_ = rsa_test_key;
|
||||
}
|
||||
void set_rsa_test_key(std::vector<uint8_t>&& rsa_test_key) {
|
||||
rsa_test_key_ = std::move(rsa_test_key);
|
||||
}
|
||||
|
||||
private:
|
||||
// Decide which method should be used to derive session keys, based on
|
||||
// supported featuers.
|
||||
@@ -81,6 +92,7 @@ class DeviceFeatures {
|
||||
// A list of possible output types.
|
||||
std::vector<OutputType> output_types_;
|
||||
bool initialized_ = false;
|
||||
std::vector<uint8_t> rsa_test_key_;
|
||||
};
|
||||
|
||||
// There is one global set of features for the version of OEMCrypto being
|
||||
|
||||
@@ -1771,10 +1771,9 @@ void Session::LoadOEMCert(bool verify_cert) {
|
||||
|
||||
void Session::SetTestRsaPublicKey() {
|
||||
public_ec_.reset();
|
||||
public_rsa_ = util::RsaPublicKey::LoadPrivateKeyInfo(
|
||||
kTestRSAPKCS8PrivateKeyInfo2_2048,
|
||||
sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048));
|
||||
ASSERT_TRUE(public_rsa_) << "Could not parse test RSA public key #2";
|
||||
public_rsa_ =
|
||||
util::RsaPublicKey::LoadPrivateKeyInfo(global_features.rsa_test_key());
|
||||
ASSERT_TRUE(public_rsa_) << "Could not parse test RSA public key";
|
||||
}
|
||||
|
||||
void Session::SetPublicKeyFromPrivateKeyInfo(OEMCrypto_PrivateKeyType key_type,
|
||||
|
||||
@@ -63,6 +63,9 @@ void SessionUtil::EnsureTestKeys() {
|
||||
case DeviceFeatures::TEST_PROVISION_30:
|
||||
// Can use oem certificate to install test rsa key.
|
||||
break;
|
||||
case DeviceFeatures::PRELOADED_RSA_KEY:
|
||||
// There is already a key.
|
||||
break;
|
||||
case wvoec::DeviceFeatures::TEST_PROVISION_40:
|
||||
// OEM certificate is retrieved from the server.
|
||||
break;
|
||||
|
||||
@@ -292,7 +292,7 @@ TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) {
|
||||
*/
|
||||
TEST_F(OEMCryptoClientTest, VersionNumber) {
|
||||
const std::string log_message =
|
||||
"OEMCrypto unit tests for API 17.4. Tests last updated 2024-06-04";
|
||||
"OEMCrypto unit tests for API 17.5. Tests last updated 2024-09-04";
|
||||
cout << " " << log_message << "\n";
|
||||
cout << " "
|
||||
<< "These tests are part of Android T."
|
||||
@@ -301,7 +301,7 @@ TEST_F(OEMCryptoClientTest, VersionNumber) {
|
||||
// If any of the following fail, then it is time to update the log message
|
||||
// above.
|
||||
EXPECT_EQ(ODK_MAJOR_VERSION, 17);
|
||||
EXPECT_EQ(ODK_MINOR_VERSION, 4);
|
||||
EXPECT_EQ(ODK_MINOR_VERSION, 5);
|
||||
EXPECT_EQ(kCurrentAPI, 17u);
|
||||
OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel();
|
||||
EXPECT_GT(level, OEMCrypto_Level_Unknown);
|
||||
@@ -548,6 +548,118 @@ TEST_F(OEMCryptoClientTest, CheckNullBuildInformationAPI17) {
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies that OEMCrypto_BuildInformation() is behaving as expected
|
||||
// by assigning appropriate values to the build info size.
|
||||
TEST_F(OEMCryptoClientTest, CheckBuildInformation_OutputLengthAPI17) {
|
||||
constexpr size_t kZero = 0;
|
||||
constexpr char kNullChar = '\0';
|
||||
|
||||
// Allocating single byte to avoid potential null dereference.
|
||||
std::string build_info(1, kNullChar);
|
||||
size_t build_info_length = 0;
|
||||
|
||||
OEMCryptoResult result =
|
||||
OEMCrypto_BuildInformation(&build_info[0], &build_info_length);
|
||||
|
||||
ASSERT_EQ(result, OEMCrypto_ERROR_SHORT_BUFFER);
|
||||
ASSERT_GT(build_info_length, kZero)
|
||||
<< "Signaling ERROR_SHORT_BUFFER should have assigned a length";
|
||||
|
||||
// Force a ERROR_SHORT_BUFFER using a non-zero value.
|
||||
// Note: It is assumed that vendors will provide more than a single
|
||||
// character of info.
|
||||
const size_t second_attempt_length =
|
||||
(build_info_length >= 2) ? build_info_length / 2 : 1;
|
||||
build_info.assign(second_attempt_length, kNullChar);
|
||||
build_info_length = build_info.size();
|
||||
|
||||
result = OEMCrypto_BuildInformation(&build_info[0], &build_info_length);
|
||||
ASSERT_EQ(result, OEMCrypto_ERROR_SHORT_BUFFER)
|
||||
<< "second_attempt_length = " << second_attempt_length
|
||||
<< ", build_info_length" << build_info_length;
|
||||
// OEM specified build info length should be larger than the
|
||||
// original length if returning ERROR_SHORT_BUFFER.
|
||||
ASSERT_GT(build_info_length, second_attempt_length);
|
||||
|
||||
// Final attempt with a buffer large enough buffer, padding to
|
||||
// ensure the caller truncates.
|
||||
constexpr size_t kBufferPadSize = 42;
|
||||
const size_t expected_length = build_info_length;
|
||||
const size_t final_attempt_length = expected_length + kBufferPadSize;
|
||||
build_info.assign(final_attempt_length, kNullChar);
|
||||
build_info_length = build_info.size();
|
||||
|
||||
result = OEMCrypto_BuildInformation(&build_info[0], &build_info_length);
|
||||
|
||||
ASSERT_EQ(result, OEMCrypto_SUCCESS)
|
||||
<< "final_attempt_length = " << final_attempt_length
|
||||
<< ", expected_length = " << expected_length
|
||||
<< ", build_info_length = " << build_info_length;
|
||||
// Ensure not empty.
|
||||
ASSERT_GT(build_info_length, kZero) << "Build info cannot be empty";
|
||||
// Ensure it was truncated down from the padded length.
|
||||
ASSERT_LT(build_info_length, final_attempt_length)
|
||||
<< "Should have truncated from oversized buffer: expected_length = "
|
||||
<< expected_length;
|
||||
// Ensure the real length is within the size originally specified.
|
||||
// OK if final length is smaller than estimated length.
|
||||
ASSERT_LE(build_info_length, expected_length);
|
||||
}
|
||||
|
||||
// Verifies that OEMCrypto_BuildInformation() is behaving as expected
|
||||
// by checking the resulting contents.
|
||||
TEST_F(OEMCryptoClientTest, CheckBuildInformation_OutputContentAPI17) {
|
||||
constexpr size_t kZero = 0;
|
||||
constexpr char kNullChar = '\0';
|
||||
|
||||
// Allocating single byte to avoid potential null dereference.
|
||||
std::string build_info(1, kNullChar);
|
||||
size_t build_info_length = 0;
|
||||
OEMCryptoResult result =
|
||||
OEMCrypto_BuildInformation(&build_info[0], &build_info_length);
|
||||
ASSERT_EQ(result, OEMCrypto_ERROR_SHORT_BUFFER);
|
||||
ASSERT_GT(build_info_length, kZero)
|
||||
<< "Signaling ERROR_SHORT_BUFFER should have assigned a length";
|
||||
|
||||
// Expect successful acquisition of build information.
|
||||
const size_t expected_length = build_info_length;
|
||||
build_info.assign(expected_length, kNullChar);
|
||||
result = OEMCrypto_BuildInformation(&build_info[0], &build_info_length);
|
||||
ASSERT_EQ(result, OEMCrypto_SUCCESS)
|
||||
<< "expected_length = " << expected_length
|
||||
<< ", build_info_length = " << build_info_length;
|
||||
// Ensure not empty.
|
||||
ASSERT_GT(build_info_length, kZero) << "Build info cannot be empty";
|
||||
// Ensure the real length is within the size originally specified.
|
||||
ASSERT_LE(build_info_length, expected_length)
|
||||
<< "Cannot specify success if buffer was too small";
|
||||
build_info.resize(build_info_length);
|
||||
|
||||
// Ensure there isn't a trailing null byte.
|
||||
ASSERT_NE(build_info.back(), kNullChar)
|
||||
<< "Build info must not contain trailing null byte";
|
||||
|
||||
// Ensure all build info characters are printable, or a limited
|
||||
// set of white space characters (case of JSON build info).
|
||||
const auto is_valid_build_info_white_space = [](const char& ch) -> bool {
|
||||
constexpr char kSpace = ' ';
|
||||
constexpr char kLineFeed = '\n';
|
||||
constexpr char kTab = '\t';
|
||||
return ch == kLineFeed || ch == kTab || ch == kSpace;
|
||||
};
|
||||
const auto is_valid_build_info_char = [&](const char& ch) -> bool {
|
||||
return ::isprint(ch) || is_valid_build_info_white_space(ch);
|
||||
};
|
||||
ASSERT_TRUE(std::all_of(build_info.begin(), build_info.end(),
|
||||
is_valid_build_info_char))
|
||||
<< "Build info is not printable: " << wvutil::b2a_hex(build_info);
|
||||
|
||||
// Ensure build info isn't just white space.
|
||||
ASSERT_FALSE(std::all_of(build_info.begin(), build_info.end(),
|
||||
is_valid_build_info_white_space))
|
||||
<< "Build info is just white space: " << wvutil::b2a_hex(build_info);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoClientTest, CheckMaxNumberOfSessionsAPI10) {
|
||||
size_t sessions_count;
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS,
|
||||
@@ -3258,10 +3370,15 @@ TEST_P(OEMCryptoLicenseTest,
|
||||
// Close the OEMCrypto session.
|
||||
session_.close();
|
||||
// All entitled key sessions associated with the OEMCrypto session should
|
||||
// already be been destroyed,
|
||||
// already be destroyed.
|
||||
OEMCryptoResult sts = OEMCrypto_RemoveEntitledKeySession(key_session_id_1);
|
||||
// For v17, there is a discrepancy in the L3 and OPK implementation for when
|
||||
// the entitlement session is closed prior to the entitled key session. This
|
||||
// is because it is difficult to update L3 for Android T. To accommodate this,
|
||||
// we accept both error codes and OEMCrypto_SUCCESS.
|
||||
EXPECT_TRUE(sts == OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION ||
|
||||
sts == OEMCrypto_ERROR_INVALID_SESSION);
|
||||
sts == OEMCrypto_ERROR_INVALID_SESSION ||
|
||||
sts == OEMCrypto_SUCCESS);
|
||||
// Open a new session just for OEMCryptoLicenseTest TearDown.
|
||||
session_.open();
|
||||
}
|
||||
@@ -3496,36 +3613,6 @@ TEST_P(OEMCryptoLicenseTest, RejectCensAPI16) {
|
||||
EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts);
|
||||
}
|
||||
|
||||
// 'cbc1' mode is no longer supported in v16
|
||||
TEST_P(OEMCryptoLicenseTest, RejectCbc1API16) {
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
|
||||
|
||||
OEMCryptoResult sts;
|
||||
sts = OEMCrypto_SelectKey(
|
||||
session_.session_id(), session_.license().keys[0].key_id,
|
||||
session_.license().keys[0].key_id_length, OEMCrypto_CipherMode_CBCS);
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
|
||||
vector<uint8_t> in_buffer(256);
|
||||
vector<uint8_t> out_buffer(in_buffer.size());
|
||||
OEMCrypto_SampleDescription sample_description;
|
||||
OEMCrypto_SubSampleDescription subsample_description;
|
||||
|
||||
GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description,
|
||||
&subsample_description);
|
||||
|
||||
// Create a zero pattern to indicate this is 'cbc1'
|
||||
OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0};
|
||||
|
||||
// Try to decrypt the data
|
||||
sts = OEMCrypto_DecryptCENC(session_.session_id(), &sample_description, 1,
|
||||
&pattern);
|
||||
EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts);
|
||||
}
|
||||
|
||||
TEST_P(OEMCryptoLicenseTest, RejectCbcsWithBlockOffset) {
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
|
||||
@@ -9637,7 +9724,7 @@ TEST_P(OEMCryptoUsageTableDefragTest, MoveUsageEntries) {
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
FailReloadLicense(&entries[3], OEMCrypto_ERROR_UNKNOWN_FAILURE));
|
||||
}
|
||||
|
||||
|
||||
TEST_P(OEMCryptoUsageTableDefragTest, MakeAndMoveEntry) {
|
||||
// 1. Make an entry then close.
|
||||
LicenseWithUsageEntry entry;
|
||||
|
||||
Reference in New Issue
Block a user