OEMCrypto v11 Documentation and Headers

Merge from widevine repo of http://go/wvgerrit/16186

These are the OEMCrypto v11 documents and header files. I have updated
just enough code so that existing unit tests pass.  New unit tests,
the reference implementation, and the level 3 implementation are in
future CLs.

Change-Id: I9bbf1909e047f63a5877320a2d06740a3c4a3e32
This commit is contained in:
Fred Gylys-Colwell
2015-12-09 13:51:18 -08:00
parent a99825b7aa
commit 0dc746a380
10 changed files with 251 additions and 73 deletions

View File

@@ -34,6 +34,7 @@ OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(SecurityLevel level,
size_t* count);
OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(SecurityLevel level,
size_t* maximum);
uint8_t OEMCrypto_Security_Patch_Level(SecurityLevel level);
} // namespace wvcdm
#endif // WVCDM_CORE_OEMCRYPTO_ADAPTER_H_

View File

@@ -683,10 +683,11 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) {
}
}
}
sts = OEMCrypto_DecryptCTR(
// TODO(rfrias): add encrypt pattern parameter.
sts = OEMCrypto_DecryptCENC(
oec_session_id_, params.encrypt_buffer, params.encrypt_length,
params.is_encrypted, &(*params.iv).front(), params.block_offset,
&buffer_descriptor, params.subsample_flags);
&buffer_descriptor, NULL, params.subsample_flags);
}
switch (sts) {

View File

@@ -30,6 +30,17 @@ using wvcdm::kLevel3;
namespace {
// TODO(fredgc): rename to _V10 after removing from level3.h.
typedef struct {
const uint8_t* key_id;
size_t key_id_length;
const uint8_t* key_data_iv;
const uint8_t* key_data;
size_t key_data_length;
const uint8_t* key_control_iv;
const uint8_t* key_control;
} OEMCrypto_KeyObject_TODO;
typedef OEMCryptoResult (*L1_Initialize_t)(void);
typedef OEMCryptoResult (*L1_Terminate_t)(void);
typedef OEMCryptoResult (*L1_OpenSession_t)(OEMCrypto_SESSION* session);
@@ -51,6 +62,12 @@ typedef OEMCryptoResult (*L1_LoadKeys_t)(
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
const OEMCrypto_KeyObject* key_array, const uint8_t* pst,
size_t pst_length);
typedef OEMCryptoResult (*L1_LoadKeys_V10_t)(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
const OEMCrypto_KeyObject_V10* key_array, const uint8_t* pst,
size_t pst_length);
typedef OEMCryptoResult (*L1_LoadKeys_V8_t)(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length,
@@ -66,10 +83,15 @@ typedef OEMCryptoResult (*L1_QueryKeyControl_t)(
typedef OEMCryptoResult (*L1_SelectKey_t)(const OEMCrypto_SESSION session,
const uint8_t* key_id,
size_t key_id_length);
typedef OEMCryptoResult (*L1_DecryptCTR_t)(
typedef OEMCryptoResult (*L1_DecryptCTR_V10_t)(
OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length,
bool is_encrypted, const uint8_t* iv, size_t offset,
const OEMCrypto_DestBufferDesc* out_buffer, uint8_t subsample_flags);
typedef OEMCryptoResult (*L1_DecryptCENC_t)(
OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length,
bool is_encrypted, const uint8_t* iv, size_t offset,
const OEMCrypto_DestBufferDesc* out_buffer,
const OEMCrypto_PatternDesc* pattern, uint8_t subsample_flags);
typedef OEMCryptoResult (*L1_CopyBuffer_t)(const uint8_t* data_addr,
size_t data_length,
OEMCrypto_DestBufferDesc* out_buffer,
@@ -113,6 +135,7 @@ typedef OEMCryptoResult (*L1_DeriveKeysFromSessionKey_t)(
size_t mac_key_context_length, const uint8_t* enc_key_context,
size_t enc_key_context_length);
typedef uint32_t (*L1_APIVersion_t)();
typedef uint8_t (*L1_SecurityPatchLevel_t)();
typedef const char* (*L1_SecurityLevel_t)();
typedef OEMCryptoResult (*L1_GetHDCPCapability_V9_t)(uint8_t* current,
uint8_t* maximum);
@@ -169,7 +192,8 @@ struct FunctionPointers {
L1_RefreshKeys_t RefreshKeys;
L1_QueryKeyControl_t QueryKeyControl;
L1_SelectKey_t SelectKey;
L1_DecryptCTR_t DecryptCTR;
L1_DecryptCTR_V10_t DecryptCTR_V10;
L1_DecryptCENC_t DecryptCENC;
L1_CopyBuffer_t CopyBuffer;
L1_WrapKeybox_t WrapKeybox;
L1_InstallKeybox_t InstallKeybox;
@@ -184,6 +208,7 @@ struct FunctionPointers {
L1_GenerateRSASignature_t GenerateRSASignature;
L1_DeriveKeysFromSessionKey_t DeriveKeysFromSessionKey;
L1_APIVersion_t APIVersion;
L1_SecurityPatchLevel_t SecurityPatchLevel;
L1_SecurityLevel_t SecurityLevel;
L1_GetHDCPCapability_t GetHDCPCapability;
L1_SupportsUsageTable_t SupportsUsageTable;
@@ -204,6 +229,7 @@ struct FunctionPointers {
L1_LoadKeys_V8_t LoadKeys_V8;
L1_GenerateRSASignature_V8_t GenerateRSASignature_V8;
L1_GetHDCPCapability_V9_t GetHDCPCapability_V9;
L1_LoadKeys_V10_t LoadKeys_V10;
};
struct LevelSession {
@@ -277,7 +303,6 @@ class Adapter {
LOOKUP(GenerateSignature, OEMCrypto_GenerateSignature);
LOOKUP(RefreshKeys, OEMCrypto_RefreshKeys);
LOOKUP(SelectKey, OEMCrypto_SelectKey);
LOOKUP(DecryptCTR, OEMCrypto_DecryptCTR);
LOOKUP(InstallKeybox, OEMCrypto_InstallKeybox);
LOOKUP(IsKeyboxValid, OEMCrypto_IsKeyboxValid);
LOOKUP(GetDeviceID, OEMCrypto_GetDeviceID);
@@ -333,6 +358,14 @@ class Adapter {
LOOKUP(GetNumberOfOpenSessions, OEMCrypto_GetNumberOfOpenSessions);
LOOKUP(GetMaxNumberOfSessions, OEMCrypto_GetMaxNumberOfSessions);
LOOKUP(ForceDeleteUsageEntry, OEMCrypto_ForceDeleteUsageEntry);
if (level1_.version == 10) {
LOOKUP(LoadKeys_V10, OEMCrypto_LoadKeys_V10);
LOOKUP(DecryptCTR_V10, OEMCrypto_DecryptCTR_V10);
} else {
LOOKUP(LoadKeys, OEMCrypto_LoadKeys);
LOOKUP(DecryptCENC, OEMCrypto_DecryptCENC);
LOOKUP(SecurityPatchLevel, OEMCrypto_Security_Patch_Level);
}
}
}
if (OEMCrypto_SUCCESS == level1_.IsKeyboxValid()) {
@@ -387,11 +420,11 @@ class Adapter {
level3_.GenerateDerivedKeys = Level3_GenerateDerivedKeys;
level3_.GenerateNonce = Level3_GenerateNonce;
level3_.GenerateSignature = Level3_GenerateSignature;
level3_.LoadKeys = Level3_LoadKeys;
level3_.LoadKeys_V10 = Level3_LoadKeys;
level3_.RefreshKeys = Level3_RefreshKeys;
level3_.QueryKeyControl = Level3_QueryKeyControl;
level3_.SelectKey = Level3_SelectKey;
level3_.DecryptCTR = Level3_DecryptCTR;
level3_.DecryptCTR_V10 = Level3_DecryptCTR;
level3_.CopyBuffer = Level3_CopyBuffer;
level3_.WrapKeybox = Level3_WrapKeybox;
level3_.InstallKeybox = Level3_InstallKeybox;
@@ -572,6 +605,14 @@ uint32_t OEMCrypto_APIVersion(SecurityLevel level) {
return fcn->APIVersion();
}
uint8_t OEMCrypto_Security_Patch_Level(SecurityLevel level) {
if (!kAdapter) return 0;
const FunctionPointers* fcn = kAdapter->get(level);
if (!fcn) return 0;
if (fcn->version < 10) return 0;
return fcn->SecurityPatchLevel();
}
const char* OEMCrypto_SecurityLevel(SecurityLevel level) {
if (!kAdapter) return "";
const FunctionPointers* fcn = kAdapter->get(level);
@@ -705,6 +746,25 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
return pair.fcn->LoadKeys_V8(pair.session, message, message_length,
signature, signature_length, enc_mac_key_iv,
enc_mac_key, num_keys, key_array);
} else if (pair.fcn->version < 11) {
std::vector<OEMCrypto_KeyObject_V10> key_array_v10(num_keys);
for(int i=0; i< num_keys; i++) {
key_array_v10[i].key_id = key_array[i].key_id;
key_array_v10[i].key_id_length = key_array[i].key_id_length;
key_array_v10[i].key_data_iv = key_array[i].key_data_iv;
key_array_v10[i].key_data = key_array[i].key_data;
key_array_v10[i].key_data_length = key_array[i].key_data_length;
key_array_v10[i].key_control_iv = key_array[i].key_control_iv;
key_array_v10[i].key_control = key_array[i].key_control;
if (key_array[i].cipher_mode == OEMCrypto_CipherMode_CBC) {
LOGE("CBC Mode not supported.");
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
}
return pair.fcn->LoadKeys_V10(pair.session, message, message_length,
signature,
signature_length, enc_mac_key_iv, enc_mac_key,
num_keys, &key_array_v10[0], pst, pst_length);
} else {
return pair.fcn->LoadKeys(pair.session, message, message_length, signature,
signature_length, enc_mac_key_iv, enc_mac_key,
@@ -743,16 +803,23 @@ extern "C" OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,
return pair.fcn->SelectKey(pair.session, key_id, key_id_length);
}
extern "C" OEMCryptoResult OEMCrypto_DecryptCTR(
extern "C" OEMCryptoResult OEMCrypto_DecryptCENC(
OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length,
bool is_encrypted, const uint8_t* iv, size_t offset,
OEMCrypto_DestBufferDesc* out_buffer, uint8_t subsample_flags) {
OEMCrypto_DestBufferDesc* out_buffer, const OEMCrypto_PatternDesc* pattern,
uint8_t subsample_flags) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
return pair.fcn->DecryptCTR(pair.session, data_addr, data_length,
is_encrypted, iv, offset, out_buffer,
subsample_flags);
if (pair.fcn->version < 11) {
return pair.fcn->DecryptCTR_V10(pair.session, data_addr, data_length,
is_encrypted, iv, offset, out_buffer,
subsample_flags);
} else {
return pair.fcn->DecryptCENC(pair.session, data_addr, data_length,
is_encrypted, iv, offset, out_buffer, pattern,
subsample_flags);
}
}
extern "C" OEMCryptoResult OEMCrypto_CopyBuffer(

View File

@@ -121,6 +121,14 @@ typedef struct {
} buffer;
} OEMCrypto_DestBufferDesc;
/** OEMCryptoCipherMode is used in LoadKeys to prepare a key for either CTR
* decryption or CBC decryption.
*/
typedef enum OEMCryptoCipherMode {
OEMCrypto_CipherMode_CTR,
OEMCrypto_CipherMode_CBC,
} OEMCryptoCipherMode;
/*
* OEMCrypto_KeyObject
* Points to the relevant fields for a content key. The fields are extracted
@@ -137,6 +145,8 @@ typedef struct {
* key_control field.
* key_control - the key control block. It is encrypted (AES-128-CBC) with
* the content key from the key_data field.
* cipher_mode - whether the key should be prepared for CTR mode or CBC mode
* when used in later calls to DecryptCENC.
*
* The memory for the OEMCrypto_KeyObject fields is allocated and freed
* by the caller of OEMCrypto_LoadKeys().
@@ -149,6 +159,7 @@ typedef struct {
size_t key_data_length;
const uint8_t* key_control_iv;
const uint8_t* key_control;
OEMCryptoCipherMode cipher_mode;
} OEMCrypto_KeyObject;
/*
@@ -188,11 +199,21 @@ typedef enum OEMCrypto_Algorithm {
} OEMCrypto_Algorithm;
/*
* Flags indicating data endpoints in OEMCrypto_DecryptCTR.
* Flags indicating data endpoints in OEMCrypto_DecryptCENC.
*/
#define OEMCrypto_FirstSubsample 1
#define OEMCrypto_LastSubsample 2
/* OEMCrypto_PatternDesc
* This is used in OEMCrypto_DecryptCENC to indicate the encrypt/skip pattern
* used, as specified in the CENC standard.
*/
typedef struct {
size_t encrypt; // number of 16 byte blocks to decrypt.
size_t skip; // number of 16 byte blocks to leave in clear.
size_t offset; // offset into the pattern in blocks for this call.
} OEMCrypto_PatternDesc;
/*
* OEMCrypto_Usage_Entry_Status.
* Valid values for status in the usage table.
@@ -284,7 +305,7 @@ typedef enum OEMCrypto_HDCP_Capability {
#define OEMCrypto_ReportUsage _oecc32
#define OEMCrypto_DeleteUsageEntry _oecc33
#define OEMCrypto_DeleteUsageTable _oecc34
#define OEMCrypto_LoadKeys _oecc35
#define OEMCrypto_LoadKeys_v10 _oecc35
#define OEMCrypto_GenerateRSASignature _oecc36
#define OEMCrypto_GetMaxNumberOfSessions _oecc37
#define OEMCrypto_GetNumberOfOpenSessions _oecc38
@@ -295,6 +316,9 @@ typedef enum OEMCrypto_HDCP_Capability {
#define OEMCrypto_ForceDeleteUsageEntry _oecc43
#define OEMCrypto_GetHDCPCapability _oecc44
#define OEMCrypto_LoadTestRSAKey _oecc45
#define OEMCrypto_Security_Patch_Level _oecc46
#define OEMCrypto_LoadKeys _oecc47
#define OEMCrypto_DecryptCENC _oecc48
/*
@@ -565,10 +589,12 @@ OEMCryptoResult OEMCrypto_GenerateSignature(
* the previous call to OEMCrypto_GenerateNonce().
*
* This sessions elapsed time clock is started at 0. The clock will be used
* in OEMCrypto_DecryptCTR().
* in OEMCrypto_DecryptCENC().
*
* NOTE: OEMCrypto_GenerateDerivedKeys() must be called first to establish the
* mac_key and encrypt_key.
* NOTE: The calling software must have previously established the mac_keys
* and encrypt_key with a call to OEMCrypto_GenerateDerivedKeys(),
* OEMCrypto_DeriveKeysFromSessionKey(), or a previous call to
* OEMCrypto_LoadKeys().
*
* Refer to document "Widevine Modular DRM Security Integration Guide for
* CENC" for details.
@@ -604,9 +630,15 @@ OEMCryptoResult OEMCrypto_GenerateSignature(
* the cache. Note that all the key control blocks in a particular call shall
* have the same nonce value.
*
* 6. If the key control block has a nonzero Replay_Control, then the
* 6. If any key control block has the Require_AntiRollback_Hardware bit set,
* and the device does not protect the usage table from rollback, then do not
* load the keys and return OEMCrypto_ERROR_UNKNOWN_FAILURE.
*
* 7. If the key control block has a nonzero Replay_Control, then the
* verification described below is also performed.
*
* 8. If num_keys == 0, then return OEMCrypto_ERROR_INVALID_CONTEXT.
*
* Usage Table and Provider Session Token (pst):
*
* If a key control block has a nonzero value for Replay_Control, then all keys
@@ -652,6 +684,10 @@ OEMCryptoResult OEMCrypto_GenerateSignature(
* Devices that do not support the Usage Table will return
* OEMCrypto_ERROR_INVALID_CONTEXT if the Replay_Control is nonzero.
*
* Note: If LoadKeys creates a new entry in the usage table, OEMCrypto will
* increment the Usage Tables generation number, and then sign, encrypt, and
* save the Usage Table.
*
* Parameters:
* session (in) - crypto session identifier.
* message (in) - pointer to memory containing message to be verified.
@@ -681,7 +717,7 @@ OEMCryptoResult OEMCrypto_GenerateSignature(
* OEMCrypto_ERROR_UNKNOWN_FAILURE
*
* Version:
* This method changed in API version 9.
* This method changed in API version 11.
*/
OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,
const uint8_t* message,
@@ -714,7 +750,7 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,
* first to establish the mac_key[server].
*
* This sessions elapsed time clock is reset to 0 when this function is called.
* The elapsed time clock is used in OEMCrypto_DecryptCTR().
* The elapsed time clock is used in OEMCrypto_DecryptCENC().
*
* This function does not add keys to the key table. It is only used to update a
* key control block license duration. Refer to the License Signing and
@@ -849,7 +885,7 @@ OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session,
*
* Description:
* Select a content key and install it in the hardware key ladder for
* subsequent decryption operations (OEMCrypto_DecryptCTR()) for this session.
* subsequent decryption operations (OEMCrypto_DecryptCENC()) for this session.
* The specified key must have been previously "installed" via
* OEMCrypto_LoadKeys() or OEMCrypto_RefreshKeys().
*
@@ -864,7 +900,7 @@ OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session,
* permission flags and timers based on the key's control block.
*
* Step 3: use the latched content key to decrypt (AES-128-CTR) buffers passed in
* via OEMCrypto_DecryptCTR(). If the key is 256 bits it will be used for
* via OEMCrypto_DecryptCENC(). If the key is 256 bits it will be used for
* OEMCrypto_Generic_Sign or OEMCrypto_Generic_Verify as specified in the key
* control block. Continue to use this key until OEMCrypto_SelectKey() is called
* again, or until OEMCrypto_CloseSession() is called.
@@ -898,15 +934,17 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session,
size_t key_id_length);
/*
* OEMCrypto_DecryptCTR
* OEMCrypto_DecryptCENC
*
* Description:
* Decrypts (AES-128-CTR) or copies the payload in the buffer referenced by the
* data_addr parameter into the buffer referenced by the out_buffer parameter,
* using the session context indicated by the session parameter. If is_encrypted
* is true, the content key associated with the session is latched in the active
* hardware key ladder and is used for the decryption operation. If is_encrypted
* is false, the data is simply copied.
* Decrypts or copies the payload in the buffer referenced by the *data_addr
* parameter into the buffer referenced by the out_buffer parameter, using
* the session context indicated by the session parameter. Decryption mode
* is AES-128-CTR or AES-128-CBC depending on the value of cipher_mode set in
* the OEMCrypto_KeyObject passed in to OEMCrypto_LoadKeys. If is_encrypted
* is true, the content key associated with the session is latched in the
* active hardware key ladder and is used for the decryption operation. If
* is_encrypted is false, the data is simply copied.
*
* After decryption, the data_length bytes are copied to the location described
* by out_buffer. This could be one of
@@ -921,13 +959,13 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session,
* the decoder and rendered.
*
* NOTES:
* IV points to the counter value to be used for the initial
* encrypted block of the input buffer. The IV length is the AES
* block size. For subsequent encrypted AES blocks the IV is
* calculated by incrementing the lower 64 bits (byte 8-15) of the
* IV value used for the previous block. The counter rolls over to
* zero when it reaches its maximum value (0xFFFFFFFFFFFFFFFF).
* The upper 64 bits (byte 0-7) of the IV do not change.
* For CTR mode, IV points to the counter value to be used for the initial
* encrypted block of the input buffer. The IV length is the AES block
* size. For subsequent encrypted AES blocks the IV is calculated by
* incrementing the lower 64 bits (byte 8-15) of the IV value used for the
* previous block. The counter rolls over to zero when it reaches its maximum
* value (0xFFFFFFFFFFFFFFFF). The upper 64 bits (byte 0-7) of the IV do not
* change.
*
* This method may be called several times before the decrypted data is used.
* For this reason, the parameter subsample_flags may be used to optimize
@@ -938,7 +976,7 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session,
* OEMCrypto_LastSubsample has been set. If an implementation decrypts data
* immediately, it may ignore subsample_flags.
*
* If the destination buffer is secure, an offset may be specified. DecryptCTR
* If the destination buffer is secure, an offset may be specified. DecryptCENC
* begins storing data out_buffer->secure.offset bytes after the beginning of the
* secure buffer.
*
@@ -946,6 +984,13 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session,
* time_of_last_decrypt. If the status of the entry is "unused", then change the
* status to "active" and set the time_of_first_decrypt.
*
* The decryption mode, either OEMCrypto_CipherMode_CTR or
* OEMCrypto_CipherMode_CBC, was specified in the call to OEMCrypto_LoadKeys.
* The encryption pattern is specified in by the parameter pattern. A
* description of partial encryption patterns can be found in the document
* Draft International Standard ISO/IEC DIS 23001-7. Search for the codes
* "cenc", "cbc1", "cens" or "cbcs".
*
*
* Verification:
* The following checks should be performed if is_encrypted is true. If any
@@ -992,9 +1037,12 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session,
* decryption block start address and data_addr are discarded
* after decryption. It does not adjust the beginning of the
* source or destination data. This parameter satisfies
* 0 <= block_offset < 16.
* 0 <= block_offset < 16. This paramater is only used
* for CTR mode.
* out_buffer (in) - A caller-owned descriptor that specifies the handling of the
* decrypted byte stream. See OEMCrypto_DestbufferDesc for details.
* pattern (in) - A caller-owned structure indicating the encrypt/skip
* pattern as specified in the CENC standard.
* subsample_flags (in) - bitwise flags indicating if this is the first, middle,
* or last subsample in a chunk of data.
* 0 = neither first nor last subsample,
@@ -1018,16 +1066,18 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session,
* OEMCrypto_ERROR_UNKNOWN_FAILURE
*
* Version:
* This method changed in API version 9.
* This method changed in API version 11.
* This method changed its name in API version 11.
*/
OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
const uint8_t *data_addr,
size_t data_length,
bool is_encrypted,
const uint8_t *iv,
size_t block_offset,
OEMCrypto_DestBufferDesc* out_buffer,
uint8_t subsample_flags);
OEMCryptoResult OEMCrypto_DecryptCENC(OEMCrypto_SESSION session,
const uint8_t *data_addr,
size_t data_length,
bool is_encrypted,
const uint8_t *iv,
size_t block_offset,
OEMCrypto_DestBufferDesc* out_buffer,
const OEMCrypto_PatternDesc* pattern,
uint8_t subsample_flags);
/*
@@ -1037,9 +1087,9 @@ OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
* Copies the payload in the buffer referenced by the *data_addr parameter into
* the buffer referenced by the out_buffer parameter. The data is simply
* copied. The definition of OEMCrypto_DestBufferDesc and subsample_flags are
* the same as in OEMCrypto_DecryptCTR, above.
* the same as in OEMCrypto_DecryptCENC, above.
*
* The main difference between this and DecryptCTR is that this function does
* The main difference between this and DecryptCENC is that this function does
* not need an open session, and it may be called concurrently with other
* session functions on a multithreaded system. In particular, an application
* will use this to copy the clear leader of a video to a secure buffer while
@@ -1648,9 +1698,6 @@ OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(OEMCrypto_SESSION session,
* There is no plan to introduce forward-compatibility. Applications will reject
* a library with a newer version of the API.
*
* The version specified in this document is 9. Any OEM that returns this
* version number guarantees it passes all unit tests associated this version.
*
* Parameters:
* none
*
@@ -1665,6 +1712,28 @@ OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(OEMCrypto_SESSION session,
*/
uint32_t OEMCrypto_APIVersion();
/**
* OEMCrypto_Security_Patch_Level()
*
* Description:
* This function returns the current patch level of the software running in
* the trusted environment. The patch level is defined by the OEM, and is
* only incremented when a security update has been added.
*
* Parameters:
* none
*
* Returns:
* The OEM defined version number.
*
* Threading:
* This function may be called simultaneously with any other functions.
*
* Version:
* This method was introduced in API version 11.
*/
uint8_t OEMCrypto_Security_Patch_Level();
/*
* OEMCrypto_SecurityLevel()
*

View File

@@ -77,6 +77,17 @@ OEMCryptoResult Level3_GenerateSignature(OEMCrypto_SESSION session,
size_t message_length,
uint8_t* signature,
size_t* signature_length);
// TODO(fredgc): move this to oemcrypto_adapter_dynamic.cpp
typedef struct {
const uint8_t* key_id;
size_t key_id_length;
const uint8_t* key_data_iv;
const uint8_t* key_data;
size_t key_data_length;
const uint8_t* key_control_iv;
const uint8_t* key_control;
} OEMCrypto_KeyObject_V10;
OEMCryptoResult Level3_LoadKeys(OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
@@ -85,7 +96,7 @@ OEMCryptoResult Level3_LoadKeys(OEMCrypto_SESSION session,
const uint8_t* enc_mac_key_iv,
const uint8_t* enc_mac_key,
size_t num_keys,
const OEMCrypto_KeyObject* key_array,
const OEMCrypto_KeyObject_V10* key_array,
const uint8_t* pst,
size_t pst_length);
OEMCryptoResult Level3_RefreshKeys(OEMCrypto_SESSION session,

View File

@@ -596,14 +596,15 @@ OEMCryptoResult SetDestination(OEMCrypto_DestBufferDesc* out_buffer,
}
extern "C"
OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
const uint8_t* data_addr,
size_t data_length,
bool is_encrypted,
const uint8_t* iv,
size_t block_offset,
OEMCrypto_DestBufferDesc* out_buffer,
uint8_t subsample_flags) {
OEMCryptoResult OEMCrypto_DecryptCENC(OEMCrypto_SESSION session,
const uint8_t* data_addr,
size_t data_length,
bool is_encrypted,
const uint8_t* iv,
size_t block_offset,
OEMCrypto_DestBufferDesc* out_buffer,
const OEMCrypto_PatternDesc* pattern,
uint8_t subsample_flags) {
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_DecryptCTR"
"(OEMCrypto_SESSION session,\n");
@@ -1207,7 +1208,13 @@ OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
extern "C"
uint32_t OEMCrypto_APIVersion() {
return 10;
// TODO(fredgc): Implement new API.
return 11;
}
extern "C"
uint8_t OEMCrypto_Security_Patch_Level() {
return 0;
}
extern "C"

View File

@@ -828,6 +828,7 @@ class Session {
key_array[i].key_control_iv = data.keys[i].control_iv;
key_array[i].key_control =
reinterpret_cast<const uint8_t*>(&data.keys[i].control);
key_array[i].cipher_mode = OEMCrypto_CipherMode_CTR;
}
}
@@ -887,10 +888,14 @@ class Session {
destBuffer.type = OEMCrypto_BufferType_Clear;
destBuffer.buffer.clear.address = outputBuffer.data();
destBuffer.buffer.clear.max_length = outputBuffer.size();
OEMCrypto_PatternDesc pattern;
pattern.encrypt = 1; // TODO(fredgc): test other values.
pattern.skip = 0;
pattern.offset = 0;
// Decrypt the data
sts = OEMCrypto_DecryptCTR(
sts = OEMCrypto_DecryptCENC(
session_id(), &encryptedData[0], encryptedData.size(), true,
&encryptionIv[0], 0, &destBuffer,
&encryptionIv[0], 0, &destBuffer, &pattern,
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample);
// We only have a few errors that we test are reported.
if (expected_result == OEMCrypto_SUCCESS) { // No error.
@@ -1283,7 +1288,7 @@ TEST_F(OEMCryptoClientTest, VersionNumber) {
cout << " OEMCrypto does not support usage tables." << endl;
}
ASSERT_GE(version, 8u);
ASSERT_LE(version, 10u);
ASSERT_LE(version, 11u);
}
const char* HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value) {
@@ -2259,6 +2264,10 @@ TEST_F(OEMCryptoSessionTests, DecryptPerformance) {
OEMCrypto_DestBufferDesc destBuffer;
destBuffer.type = OEMCrypto_BufferType_Clear;
destBuffer.buffer.clear.address = &output[0];
OEMCrypto_PatternDesc pattern;
pattern.encrypt = 1; // TODO(fredgc): test other values.
pattern.skip = 0;
pattern.offset = 0;
const char* level = OEMCrypto_SecurityLevel();
const int n = 10;
@@ -2278,9 +2287,9 @@ TEST_F(OEMCryptoSessionTests, DecryptPerformance) {
size_t total = 0;
do {
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_DecryptCTR(
OEMCrypto_DecryptCENC(
s.session_id(), &input[0], length, true,
&encryptionIv[0], 0, &destBuffer,
&encryptionIv[0], 0, &destBuffer, &pattern,
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample));
count++;
total += length;
@@ -2377,6 +2386,11 @@ class OEMCryptoSessionTestsDecryptEdgeCases : public OEMCryptoSessionTests {
s.license().keys[0].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
OEMCrypto_PatternDesc pattern;
pattern.encrypt = 1; // TODO(fredgc): test other values.
pattern.skip = 0;
pattern.offset = 0;
// We decrypt three subsamples. each with a block offset.
vector<uint8_t> outputBuffer(total_size, 0xaa);
size_t buffer_offset = 0;
@@ -2395,9 +2409,9 @@ class OEMCryptoSessionTestsDecryptEdgeCases : public OEMCryptoSessionTests {
memcpy(aes_iv, &encryptionIv[0], AES_BLOCK_SIZE);
size_t iv_increment = buffer_offset / AES_BLOCK_SIZE;
ctr128_inc64(iv_increment, aes_iv);
sts = OEMCrypto_DecryptCTR(
sts = OEMCrypto_DecryptCENC(
s.session_id(), &encryptedData[buffer_offset], subsample_size[i],
true, aes_iv, block_offset, &destBuffer, subsample_flags);
true, aes_iv, block_offset, &destBuffer, &pattern, subsample_flags);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
buffer_offset += subsample_size[i];
}
@@ -2531,11 +2545,15 @@ TEST_F(OEMCryptoSessionTests, DecryptUnencrypted) {
destBuffer.type = OEMCrypto_BufferType_Clear;
destBuffer.buffer.clear.address = &outputBuffer[0];
destBuffer.buffer.clear.max_length = outputBuffer.size();
OEMCrypto_PatternDesc pattern;
pattern.encrypt = 1; // TODO(fredgc): test other values.
pattern.skip = 0;
pattern.offset = 0;
// Decrypt the data
sts = OEMCrypto_DecryptCTR(
sts = OEMCrypto_DecryptCENC(
s.session_id(), &unencryptedData[0], unencryptedData.size(), false,
&encryptionIv[0], 0, &destBuffer,
&encryptionIv[0], 0, &destBuffer, &pattern,
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
ASSERT_EQ(unencryptedData, outputBuffer);
@@ -2566,11 +2584,15 @@ TEST_F(OEMCryptoSessionTests, DecryptUnencryptedNoKey) {
destBuffer.type = OEMCrypto_BufferType_Clear;
destBuffer.buffer.clear.address = &outputBuffer[0];
destBuffer.buffer.clear.max_length = outputBuffer.size();
OEMCrypto_PatternDesc pattern;
pattern.encrypt = 1; // TODO(fredgc): test other values.
pattern.skip = 0;
pattern.offset = 0;
// Decrypt the data
sts = OEMCrypto_DecryptCTR(
sts = OEMCrypto_DecryptCENC(
s.session_id(), &unencryptedData[0], unencryptedData.size(), false,
&encryptionIv[0], 0, &destBuffer,
&encryptionIv[0], 0, &destBuffer, &pattern,
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
ASSERT_EQ(unencryptedData, outputBuffer);