bool ClearKeyDecryptionManager::IsExpectingKeyForKeyId(const KeyId& aKeyId) const { CK_LOGD("ClearKeyDecryptionManager::IsExpectingKeyForId %08x...", *(uint32_t*)&aKeyId[0]); const auto& decryptor = mDecryptors.find(aKeyId); return decryptor != mDecryptors.end() && !decryptor->second->HasKey(); }
bool ClearKeyDecryptionManager::HasKeyForKeyId(const KeyId& aKeyId) const { CK_LOGD("ClearKeyDecryptionManager::HasKeyForKeyId"); const auto& decryptor = mDecryptors.find(aKeyId); return decryptor != mDecryptors.end() && decryptor->second->HasKey(); }
GMPErr ClearKeyDecryptor::Decrypt(uint8_t* aBuffer, uint32_t aBufferSize, const CryptoMetaData& aMetadata) { CK_LOGD("ClearKeyDecryptor::Decrypt"); // If the sample is split up into multiple encrypted subsamples, we need to // stitch them into one continuous buffer for decryption. std::vector<uint8_t> tmp(aBufferSize); if (aMetadata.NumSubsamples()) { // Take all encrypted parts of subsamples and stitch them into one // continuous encrypted buffer. uint8_t* data = aBuffer; uint8_t* iter = &tmp[0]; for (size_t i = 0; i < aMetadata.NumSubsamples(); i++) { data += aMetadata.mClearBytes[i]; uint32_t cipherBytes = aMetadata.mCipherBytes[i]; if (data + cipherBytes > aBuffer + aBufferSize) { // Trying to read past the end of the buffer! return GMPCryptoErr; } memcpy(iter, data, cipherBytes); data += cipherBytes; iter += cipherBytes; } tmp.resize((size_t)(iter - &tmp[0])); } else { memcpy(&tmp[0], aBuffer, aBufferSize); } assert(aMetadata.mIV.size() == 8 || aMetadata.mIV.size() == 16); std::vector<uint8_t> iv(aMetadata.mIV); iv.insert(iv.end(), CLEARKEY_KEY_LEN - aMetadata.mIV.size(), 0); ClearKeyUtils::DecryptAES(mKey, tmp, iv); if (aMetadata.NumSubsamples()) { // Take the decrypted buffer, split up into subsamples, and insert those // subsamples back into their original position in the original buffer. uint8_t* data = aBuffer; uint8_t* iter = &tmp[0]; for (size_t i = 0; i < aMetadata.NumSubsamples(); i++) { data += aMetadata.mClearBytes[i]; uint32_t cipherBytes = aMetadata.mCipherBytes[i]; memcpy(data, iter, cipherBytes); data += cipherBytes; iter += cipherBytes; } } else { memcpy(aBuffer, &tmp[0], aBufferSize); } return GMPNoErr; }
void ClearKeyDecryptionManager::InitKey(KeyId aKeyId, Key aKey) { CK_LOGD("ClearKeyDecryptionManager::InitKey %08x...", *(uint32_t*)&aKeyId[0]); if (IsExpectingKeyForKeyId(aKeyId)) { mDecryptors[aKeyId]->InitKey(aKey); } }
void ClearKeyDecryptionManager::ExpectKeyId(KeyId aKeyId) { CK_LOGD("ClearKeyDecryptionManager::ExpectKeyId %08x...", *(uint32_t*)&aKeyId[0]); if (!HasSeenKeyId(aKeyId)) { mDecryptors[aKeyId] = new ClearKeyDecryptor(); } mDecryptors[aKeyId]->AddRef(); }
GMPErr ClearKeyDecryptor::Decrypt(uint8_t* aBuffer, uint32_t aBufferSize, const GMPEncryptedBufferMetadata* aMetadata) { CK_LOGD("ClearKeyDecryptor::Decrypt"); // If the sample is split up into multiple encrypted subsamples, we need to // stitch them into one continuous buffer for decryption. std::vector<uint8_t> tmp(aBufferSize); if (aMetadata->NumSubsamples()) { // Take all encrypted parts of subsamples and stitch them into one // continuous encrypted buffer. unsigned char* data = aBuffer; unsigned char* iter = &tmp[0]; for (size_t i = 0; i < aMetadata->NumSubsamples(); i++) { data += aMetadata->ClearBytes()[i]; uint32_t cipherBytes = aMetadata->CipherBytes()[i]; memcpy(iter, data, cipherBytes); data += cipherBytes; iter += cipherBytes; } tmp.resize((size_t)(iter - &tmp[0])); } else { memcpy(&tmp[0], aBuffer, aBufferSize); } MOZ_ASSERT(aMetadata->IVSize() == 8 || aMetadata->IVSize() == 16); std::vector<uint8_t> iv(aMetadata->IV(), aMetadata->IV() + aMetadata->IVSize()); iv.insert(iv.end(), CLEARKEY_KEY_LEN - aMetadata->IVSize(), 0); ClearKeyUtils::DecryptAES(mKey, tmp, iv); if (aMetadata->NumSubsamples()) { // Take the decrypted buffer, split up into subsamples, and insert those // subsamples back into their original position in the original buffer. unsigned char* data = aBuffer; unsigned char* iter = &tmp[0]; for (size_t i = 0; i < aMetadata->NumSubsamples(); i++) { data += aMetadata->ClearBytes()[i]; uint32_t cipherBytes = aMetadata->CipherBytes()[i]; memcpy(data, iter, cipherBytes); data += cipherBytes; iter += cipherBytes; } } else { memcpy(aBuffer, &tmp[0], aBufferSize); } return GMPNoErr; }
void ClearKeyDecryptionManager::ReleaseKeyId(KeyId aKeyId) { CK_LOGD("ClearKeyDecryptionManager::ReleaseKeyId"); assert(HasSeenKeyId(aKeyId)); ClearKeyDecryptor* decryptor = mDecryptors[aKeyId]; if (!decryptor->Release()) { mDecryptors.erase(aKeyId); } }
GMPErr ClearKeyDecryptionManager::Decrypt(uint8_t* aBuffer, uint32_t aBufferSize, const CryptoMetaData& aMetadata) { CK_LOGD("ClearKeyDecryptionManager::Decrypt"); if (!HasKeyForKeyId(aMetadata.mKeyId)) { return GMPNoKeyErr; } return mDecryptors[aMetadata.mKeyId]->Decrypt(aBuffer, aBufferSize, aMetadata); }
ClearKeyDecryptionManager::~ClearKeyDecryptionManager() { CK_LOGD("ClearKeyDecryptionManager::~ClearKeyDecryptionManager"); sInstance = nullptr; for (auto it = mDecryptors.begin(); it != mDecryptors.end(); it++) { it->second->Release(); } mDecryptors.clear(); }
void ClearKeyDecryptionManager::ReleaseKeyId(KeyId aKeyId) { CK_LOGD("ClearKeyDecryptionManager::ReleaseKeyId"); MOZ_ASSERT(HasKeyForKeyId(aKeyId)); ClearKeyDecryptor* decryptor = mDecryptors[aKeyId]; if (!decryptor->Release()) { mDecryptors.erase(aKeyId); } }
GMPErr ClearKeyDecryptionManager::Decrypt(uint8_t* aBuffer, uint32_t aBufferSize, const GMPEncryptedBufferMetadata* aMetadata) { CK_LOGD("ClearKeyDecryptionManager::Decrypt"); KeyId keyId(aMetadata->KeyId(), aMetadata->KeyId() + aMetadata->KeyIdSize()); if (!HasKeyForKeyId(keyId)) { return GMPNoKeyErr; } return mDecryptors[keyId]->Decrypt(aBuffer, aBufferSize, aMetadata); }
GMP_EXPORT GMPErr GMPGetAPI(const char* aApiName, void* aHostAPI, void** aPluginAPI) { CK_LOGD("ClearKey GMPGetAPI |%s|", aApiName); assert(!*aPluginAPI); if (!strcmp(aApiName, GMP_API_DECRYPTOR)) { *aPluginAPI = new ClearKeySessionManager(); } #if defined(ENABLE_WMF) else if (wmf::EnsureLibs()) { if (!strcmp(aApiName, GMP_API_AUDIO_DECODER)) { *aPluginAPI = new AudioDecoder(static_cast<GMPAudioHost*>(aHostAPI)); } else if (!strcmp(aApiName, GMP_API_VIDEO_DECODER)) { *aPluginAPI = new VideoDecoder(static_cast<GMPVideoHost*>(aHostAPI)); } } #endif else { CK_LOGE("GMPGetAPI couldn't resolve API name |%s|\n", aApiName); } return *aPluginAPI ? GMPNoErr : GMPNotImplementedErr; }
bool ClearKeyDecryptionManager::HasSeenKeyId(const KeyId& aKeyId) const { CK_LOGD("ClearKeyDecryptionManager::SeenKeyId %s", mDecryptors.find(aKeyId) != mDecryptors.end() ? "t" : "f"); return mDecryptors.find(aKeyId) != mDecryptors.end(); }
ClearKeyDecryptionManager::ClearKeyDecryptionManager() { CK_LOGD("ClearKeyDecryptionManager::ClearKeyDecryptionManager"); }
GMP_EXPORT GMPErr GMPShutdown(void) { CK_LOGD("ClearKey GMPShutdown"); return GMPNoErr; }
ClearKeyDecryptor::~ClearKeyDecryptor() { CK_LOGD("ClearKeyDecryptor dtor; key = %08x...", *(uint32_t*)&mKey[0]); }
ClearKeyDecryptor::ClearKeyDecryptor() { CK_LOGD("ClearKeyDecryptor ctor"); }