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);
}
예제 #12
0
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");
}
예제 #15
0
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");
}