Migration from jb-mr2 to master for Widevine CDM

Android development of the widevine CDM has been done
on the jb-mr2 branch of the cdm code base.  This CL
contains a merge of that jb-mr2 work to CDM master, and
also reflects the evolution of the common Modular DRM
code base since jb-mr2 branched.

Change-Id: I1d7e1a12d092c00044a4298261146cb97808d4ef
This commit is contained in:
Jeff Tinker
2013-07-29 17:29:07 -07:00
parent edb987db07
commit 0190f99fb3
68 changed files with 4754 additions and 3601 deletions

View File

@@ -10,7 +10,9 @@
namespace wvcdm {
void log_write(LogPriority level, const char* fmt, ...) {
void InitLogging(int argc, const char* const* argv) {}
void Log(const char* file, int line, LogPriority level, const char* fmt, ...) {
va_list ap;
char buf[LOG_BUF_SIZE];
va_start(ap, fmt);

View File

@@ -17,14 +17,23 @@ typedef enum {
LOG_VERBOSE
} LogPriority;
void log_write(LogPriority priority, const char* fmt, ...);
// Required to enable/disable verbose logging (LOGV) in Chromium. In Chromium,
// verbose logging level is controlled using command line switches --v (global)
// or --vmodule (per module). This function calls logging::InitLogging to
// initialize logging, which should have already been included in most Chromium
// based binaries. However, it is typically not included by default in
// unittests, in particular, the unittests in CDM core need to call InitLogging
// to be able to control verbose logging in command line.
void InitLogging(int argc, const char* const* argv);
void Log(const char* file, int line, LogPriority level, const char* fmt, ...);
// Log APIs
#define LOGE(...) ((void)log_write(wvcdm::LOG_ERROR, __VA_ARGS__))
#define LOGW(...) ((void)log_write(wvcdm::LOG_WARN, __VA_ARGS__))
#define LOGI(...) ((void)log_write(wvcdm::LOG_INFO, __VA_ARGS__))
#define LOGD(...) ((void)log_write(wvcdm::LOG_DEBUG, __VA_ARGS__))
#define LOGV(...) ((void)log_write(wvcdm::LOG_VERBOSE, __VA_ARGS__))
#define LOGE(...) Log(__FILE__, __LINE__, wvcdm::LOG_ERROR, __VA_ARGS__)
#define LOGW(...) Log(__FILE__, __LINE__, wvcdm::LOG_WARN, __VA_ARGS__)
#define LOGI(...) Log(__FILE__, __LINE__, wvcdm::LOG_INFO, __VA_ARGS__)
#define LOGD(...) Log(__FILE__, __LINE__, wvcdm::LOG_DEBUG, __VA_ARGS__)
#define LOGV(...) Log(__FILE__, __LINE__, wvcdm::LOG_VERBOSE, __VA_ARGS__)
}; // namespace wvcdm

View File

@@ -16,7 +16,6 @@
namespace wvoec_mock {
bool KeyControlBlock::Validate() {
valid_ = false;
if (0x6b63746c != verification_) { // kctl.
LOGE("KCB: BAD verification string: %08X (not %08X)", verification_,
@@ -35,7 +34,6 @@ bool KeyControlBlock::Validate() {
LOGW("KCB: CGMS setting set for refresh.");
}
}
valid_ = true;
return valid_;
}

View File

@@ -135,7 +135,7 @@ OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_GenerateNonce(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_GenerateNonce(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
@@ -172,7 +172,7 @@ OEMCryptoResult OEMCrypto_GenerateDerivedKeys(OEMCrypto_SESSION session,
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
@@ -227,7 +227,7 @@ OEMCryptoResult OEMCrypto_GenerateSignature(
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_GenerateSignature(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_GenerateSignature(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
@@ -292,7 +292,7 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_LoadKeys(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_LoadKeys(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
@@ -393,7 +393,7 @@ OEMCryptoResult OEMCrypto_RefreshKeys(OEMCrypto_SESSION session,
size_t num_keys,
const OEMCrypto_KeyRefreshObject* key_array) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_RefreshKeys(num_keys=%d)\n", num_keys);
printf("-- OEMCryptoResult OEMCrypto_RefreshKeys(num_keys=%zu)\n", num_keys);
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
@@ -403,7 +403,7 @@ OEMCryptoResult OEMCrypto_RefreshKeys(OEMCrypto_SESSION session,
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_RefreshKeys(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_RefreshKeys(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
@@ -491,7 +491,7 @@ OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_SelectKey(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_SelectKey(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
@@ -527,8 +527,9 @@ OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
break;
case OEMCrypto_BufferType_Secure:
buffer_type = kBufferTypeSecure;
destination = ((uint8_t*)out_buffer->buffer.secure.handle
+ out_buffer->buffer.secure.offset);
destination =
reinterpret_cast<uint8_t*>(out_buffer->buffer.secure.handle)
+ out_buffer->buffer.secure.offset;
max_length = out_buffer->buffer.secure.max_length;
break;
default:
@@ -552,7 +553,7 @@ OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_DecryptCTR(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_DecryptCTR(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
@@ -562,7 +563,7 @@ OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
if (!crypto_engine->DecryptCTR(session_ctx, iv, (int)block_offset,
if (!crypto_engine->DecryptCTR(session_ctx, iv, block_offset,
data_addr, data_length, is_encrypted,
destination, buffer_type)) {
LOGE("[OEMCrypto_DecryptCTR(): OEMCrypto_ERROR_DECRYPT_FAILED]");
@@ -718,7 +719,7 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_RewrapDeviceRSAKey(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_RewrapDeviceRSAKey(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (message == NULL || message_length == 0 || signature == NULL
@@ -753,7 +754,7 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
result = OEMCrypto_ERROR_INVALID_RSA_KEY;
}
size_t padding = pkcs8_rsa_key[enc_rsa_key_length - 1];
if( result == OEMCrypto_SUCCESS) {
if (result == OEMCrypto_SUCCESS) {
if (padding > 16) {
LOGE("[RewrapRSAKey(): Encrypted RSA has bad padding: %d]", padding);
result = OEMCrypto_ERROR_INVALID_RSA_KEY;
@@ -761,19 +762,19 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
}
size_t rsa_key_length = enc_rsa_key_length - padding;
// verify signature, verify RSA key, and load it.
if( result == OEMCrypto_SUCCESS) {
if (result == OEMCrypto_SUCCESS) {
if (!session_ctx->LoadRSAKey(pkcs8_rsa_key, rsa_key_length,
message, message_length,
signature, signature_length)) {
result = OEMCrypto_ERROR_SIGNATURE_FAILURE;
// return OEMCrypto_ERROR_INVALID_RSA_KEY;
// return OEMCrypto_ERROR_INVALID_RSA_KEY;
}
}
// Now we generate a wrapped keybox.
WrappedRSAKey* wrapped = reinterpret_cast<WrappedRSAKey*>(wrapped_rsa_key);
// Pick a random context and IV for generating keys.
if( result == OEMCrypto_SUCCESS) {
if (result == OEMCrypto_SUCCESS) {
if (!RAND_bytes(wrapped->context, sizeof(wrapped->context))) {
result = OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
@@ -784,7 +785,7 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
const std::vector<uint8_t> context(wrapped->context,
wrapped->context + sizeof(wrapped->context));
// Generate mac and encryption keys for encrypting the signature.
if( result == OEMCrypto_SUCCESS) {
if (result == OEMCrypto_SUCCESS) {
if (!session_ctx->DeriveKeys(crypto_engine->keybox().device_key().value(),
context, context)) {
result = OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -792,7 +793,7 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
}
// Encrypt rsa key with keybox.
if( result == OEMCrypto_SUCCESS) {
if (result == OEMCrypto_SUCCESS) {
if (!session_ctx->EncryptRSAKey(pkcs8_rsa_key, enc_rsa_key_length,
wrapped->iv, wrapped->enc_rsa_key)) {
result = OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -802,8 +803,8 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
// The wrapped keybox must be signed with the same key we verify with. I'll
// pick the server key, so I don't have to modify LoadRSAKey.
if( result == OEMCrypto_SUCCESS) {
size_t sig_length = sizeof(wrapped->signature);
if (result == OEMCrypto_SUCCESS) {
unsigned int sig_length = sizeof(wrapped->signature);
if (!HMAC(EVP_sha256(), &session_ctx->mac_key_server()[0],
SHA256_DIGEST_LENGTH, wrapped->context,
buffer_size - sizeof(wrapped->signature), wrapped->signature,
@@ -844,7 +845,7 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session,
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_LoadDeviceRSAKey(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_LoadDeviceRSAKey(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
const std::vector<uint8_t> context(wrapped->context,
@@ -864,7 +865,7 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session,
result = OEMCrypto_ERROR_INVALID_RSA_KEY;
}
size_t padding = pkcs8_rsa_key[enc_rsa_key_length - 1];
if( result == OEMCrypto_SUCCESS) {
if (result == OEMCrypto_SUCCESS) {
if (padding > 16) {
LOGE("[LoadDeviceRSAKey(): Encrypted RSA has bad padding: %d]", padding);
result = OEMCrypto_ERROR_INVALID_RSA_KEY;
@@ -872,7 +873,7 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session,
}
size_t rsa_key_length = enc_rsa_key_length - padding;
// verify signature.
if( result == OEMCrypto_SUCCESS) {
if (result == OEMCrypto_SUCCESS) {
if (!session_ctx->LoadRSAKey(pkcs8_rsa_key, rsa_key_length,
wrapped->context,
wrapped_rsa_key_length - sizeof(wrapped->signature),
@@ -908,7 +909,7 @@ OEMCryptoResult OEMCrypto_GenerateRSASignature(OEMCrypto_SESSION session,
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_GenerateRSASignature(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_GenerateRSASignature(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
@@ -938,13 +939,13 @@ OEMCryptoResult OEMCrypto_GenerateRSASignature(OEMCrypto_SESSION session,
extern "C"
OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
OEMCrypto_SESSION session,
const uint8_t* enc_session_key,
size_t enc_session_key_length,
const uint8_t* mac_key_context,
size_t mac_key_context_length,
const uint8_t* enc_key_context,
size_t enc_key_context_length) {
OEMCrypto_SESSION session,
const uint8_t* enc_session_key,
size_t enc_session_key_length,
const uint8_t* mac_key_context,
size_t mac_key_context_length,
const uint8_t* enc_key_context,
size_t enc_key_context_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(\n");
dump_hex("enc_session_key", enc_session_key, enc_session_key_length);
@@ -958,7 +959,7 @@ OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
@@ -1008,7 +1009,7 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session,
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_Generic_Enrypt(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_Generic_Enrypt(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (in_buffer == NULL || buffer_length == 0 ||
@@ -1037,7 +1038,7 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt(OEMCrypto_SESSION session,
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_Generic_Decrypt(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_Generic_Decrypt(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (!session_ctx->Generic_Decrypt(in_buffer, buffer_length, iv, algorithm,
@@ -1065,7 +1066,7 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session,
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_Generic_Sign(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_Generic_Sign(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (*signature_length < SHA256_DIGEST_LENGTH) {
@@ -1096,7 +1097,7 @@ OEMCryptoResult OEMCrypto_Generic_Verify(OEMCrypto_SESSION session,
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_Generic_Verify(): ERROR_NO_INVALID_SESSION]");
LOGE("[OEMCrypto_Generic_Verify(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (signature_length != SHA256_DIGEST_LENGTH) {