Merge "DRM Pluging uses CDM core's generic crypto API." into udc-dev
This commit is contained in:
@@ -194,36 +194,44 @@ class WVDrmPlugin : public ::aidl::android::hardware::drm::BnDrmPlugin,
|
|||||||
// is cleared right before plugin is destructed.
|
// is cleared right before plugin is destructed.
|
||||||
wvutil::LoggingUidSetter mLoggingUidSetter;
|
wvutil::LoggingUidSetter mLoggingUidSetter;
|
||||||
|
|
||||||
struct CryptoSession {
|
class SessionInfo {
|
||||||
public:
|
public:
|
||||||
CryptoSession()
|
SessionInfo() {}
|
||||||
: mOecSessionId(-1),
|
|
||||||
mCipherAlgorithm(kInvalidCryptoAlgorithm),
|
|
||||||
mMacAlgorithm(kInvalidCryptoAlgorithm) {}
|
|
||||||
|
|
||||||
CryptoSession(OEMCrypto_SESSION sessionId)
|
SessionInfo(OEMCrypto_SESSION sessionId) : mOecSessionId(sessionId) {}
|
||||||
: mOecSessionId(sessionId),
|
|
||||||
mCipherAlgorithm(kInvalidCryptoAlgorithm),
|
|
||||||
mMacAlgorithm(kInvalidCryptoAlgorithm) {}
|
|
||||||
|
|
||||||
OEMCrypto_SESSION oecSessionId() const { return mOecSessionId; }
|
OEMCrypto_SESSION oecSessionId() const { return mOecSessionId; }
|
||||||
|
|
||||||
OEMCrypto_Algorithm cipherAlgorithm() const { return mCipherAlgorithm; }
|
wvcdm::CdmEncryptionAlgorithm getEncryptionAlgorithm() const {
|
||||||
|
return mEncryptionAlgorithm;
|
||||||
void setCipherAlgorithm(OEMCrypto_Algorithm newAlgorithm) {
|
|
||||||
mCipherAlgorithm = newAlgorithm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCrypto_Algorithm macAlgorithm() const { return mMacAlgorithm; }
|
bool hasEncryptionAlgorithm() const {
|
||||||
|
return mEncryptionAlgorithm != wvcdm::kEncryptionAlgorithmUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
void setMacAlgorithm(OEMCrypto_Algorithm newAlgorithm) {
|
void setEncryptionAlgorithm(wvcdm::CdmEncryptionAlgorithm newAlgorithm) {
|
||||||
mMacAlgorithm = newAlgorithm;
|
mEncryptionAlgorithm = newAlgorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
wvcdm::CdmSigningAlgorithm getSigningAlgorithm() const {
|
||||||
|
return mSigningAlgorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasSigningAlgorithm() const {
|
||||||
|
return mSigningAlgorithm != wvcdm::kSigningAlgorithmUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSigningAlgorithm(wvcdm::CdmSigningAlgorithm newAlgorithm) {
|
||||||
|
mSigningAlgorithm = newAlgorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OEMCrypto_SESSION mOecSessionId;
|
OEMCrypto_SESSION mOecSessionId = -1;
|
||||||
OEMCrypto_Algorithm mCipherAlgorithm;
|
wvcdm::CdmEncryptionAlgorithm mEncryptionAlgorithm =
|
||||||
OEMCrypto_Algorithm mMacAlgorithm;
|
wvcdm::kEncryptionAlgorithmUnknown;
|
||||||
|
wvcdm::CdmSigningAlgorithm mSigningAlgorithm =
|
||||||
|
wvcdm::kSigningAlgorithmUnknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WVClientPropertySet : public wvcdm::CdmClientPropertySet {
|
class WVClientPropertySet : public wvcdm::CdmClientPropertySet {
|
||||||
@@ -397,24 +405,33 @@ class WVDrmPlugin : public ::aidl::android::hardware::drm::BnDrmPlugin,
|
|||||||
android::Mutex mLock;
|
android::Mutex mLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CryptoSessionMap {
|
class SessionInfoMap {
|
||||||
public:
|
public:
|
||||||
std::map<CdmSessionId, std::shared_ptr<CryptoSession>> clear() {
|
void clear() {
|
||||||
std::unique_lock<std::mutex> auto_lock(mLock);
|
std::unique_lock<std::mutex> auto_lock(mLock);
|
||||||
auto copy = mMap;
|
|
||||||
mMap.clear();
|
mMap.clear();
|
||||||
return copy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<CryptoSession> get(const CdmSessionId& sid) {
|
std::vector<CdmSessionId> getKeysAndClear() {
|
||||||
std::unique_lock<std::mutex> auto_lock(mLock);
|
std::unique_lock<std::mutex> auto_lock(mLock);
|
||||||
if (mMap.count(sid)) {
|
std::vector<CdmSessionId> keys;
|
||||||
return mMap[sid];
|
for (const auto pair : mMap) {
|
||||||
|
keys.push_back(pair.first);
|
||||||
|
}
|
||||||
|
mMap.clear();
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<SessionInfo> get(const CdmSessionId& sid) const {
|
||||||
|
std::unique_lock<std::mutex> auto_lock(mLock);
|
||||||
|
const auto it = mMap.find(sid);
|
||||||
|
if (it != mMap.end()) {
|
||||||
|
return it->second;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() {
|
bool empty() const {
|
||||||
std::unique_lock<std::mutex> auto_lock(mLock);
|
std::unique_lock<std::mutex> auto_lock(mLock);
|
||||||
return mMap.empty();
|
return mMap.empty();
|
||||||
}
|
}
|
||||||
@@ -426,17 +443,17 @@ class WVDrmPlugin : public ::aidl::android::hardware::drm::BnDrmPlugin,
|
|||||||
|
|
||||||
void insert(const CdmSessionId& sid, OEMCrypto_SESSION osid) {
|
void insert(const CdmSessionId& sid, OEMCrypto_SESSION osid) {
|
||||||
std::unique_lock<std::mutex> auto_lock(mLock);
|
std::unique_lock<std::mutex> auto_lock(mLock);
|
||||||
mMap[sid] = std::make_shared<CryptoSession>(osid);
|
mMap[sid] = std::make_shared<SessionInfo>(osid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex mLock;
|
mutable std::mutex mLock;
|
||||||
std::map<CdmSessionId, std::shared_ptr<CryptoSession>> mMap;
|
std::map<CdmSessionId, std::shared_ptr<SessionInfo>> mMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
android::sp<wvcdm::WvContentDecryptionModule> const mCDM;
|
android::sp<wvcdm::WvContentDecryptionModule> const mCDM;
|
||||||
WVGenericCryptoInterface* mCrypto;
|
WVGenericCryptoInterface* mCrypto;
|
||||||
CryptoSessionMap mCryptoSessions;
|
SessionInfoMap mSessionInfoMap;
|
||||||
std::shared_ptr<::aidl::android::hardware::drm::IDrmPluginListener> mListener;
|
std::shared_ptr<::aidl::android::hardware::drm::IDrmPluginListener> mListener;
|
||||||
|
|
||||||
std::string mProvisioningServiceCertificate;
|
std::string mProvisioningServiceCertificate;
|
||||||
|
|||||||
@@ -21,48 +21,6 @@ class WVGenericCryptoInterface {
|
|||||||
WVGenericCryptoInterface() {}
|
WVGenericCryptoInterface() {}
|
||||||
virtual ~WVGenericCryptoInterface() {}
|
virtual ~WVGenericCryptoInterface() {}
|
||||||
|
|
||||||
virtual OEMCryptoResult selectKey(const OEMCrypto_SESSION session,
|
|
||||||
const uint8_t* key_id,
|
|
||||||
size_t key_id_length) {
|
|
||||||
return OEMCrypto_SelectKey(session, key_id, key_id_length,
|
|
||||||
OEMCrypto_CipherMode_CBCS);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual OEMCryptoResult encrypt(OEMCrypto_SESSION session,
|
|
||||||
const uint8_t* in_buffer,
|
|
||||||
size_t buffer_length, const uint8_t* iv,
|
|
||||||
OEMCrypto_Algorithm algorithm,
|
|
||||||
uint8_t* out_buffer) {
|
|
||||||
return OEMCrypto_Generic_Encrypt_V17(session, in_buffer, buffer_length, iv,
|
|
||||||
algorithm, out_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual OEMCryptoResult decrypt(OEMCrypto_SESSION session,
|
|
||||||
const uint8_t* in_buffer,
|
|
||||||
size_t buffer_length, const uint8_t* iv,
|
|
||||||
OEMCrypto_Algorithm algorithm,
|
|
||||||
uint8_t* out_buffer) {
|
|
||||||
return OEMCrypto_Generic_Decrypt_V17(session, in_buffer, buffer_length, iv,
|
|
||||||
algorithm, out_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual OEMCryptoResult sign(OEMCrypto_SESSION session,
|
|
||||||
const uint8_t* in_buffer, size_t buffer_length,
|
|
||||||
OEMCrypto_Algorithm algorithm,
|
|
||||||
uint8_t* signature, size_t* signature_length) {
|
|
||||||
return OEMCrypto_Generic_Sign_V17(session, in_buffer, buffer_length, algorithm,
|
|
||||||
signature, signature_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual OEMCryptoResult verify(OEMCrypto_SESSION session,
|
|
||||||
const uint8_t* in_buffer, size_t buffer_length,
|
|
||||||
OEMCrypto_Algorithm algorithm,
|
|
||||||
const uint8_t* signature,
|
|
||||||
size_t signature_length) {
|
|
||||||
return OEMCrypto_Generic_Verify_V17(session, in_buffer, buffer_length,
|
|
||||||
algorithm, signature, signature_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual OEMCryptoResult signRSA(const uint8_t* wrapped_rsa_key,
|
virtual OEMCryptoResult signRSA(const uint8_t* wrapped_rsa_key,
|
||||||
size_t wrapped_rsa_key_length,
|
size_t wrapped_rsa_key_length,
|
||||||
const uint8_t* message, size_t message_length,
|
const uint8_t* message, size_t message_length,
|
||||||
@@ -76,15 +34,6 @@ class WVGenericCryptoInterface {
|
|||||||
wrapped_rsa_key, wrapped_rsa_key_length);
|
wrapped_rsa_key, wrapped_rsa_key_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual OEMCryptoResult generateRSASignature(
|
|
||||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
|
||||||
uint8_t* signature, size_t* signature_length,
|
|
||||||
RSA_Padding_Scheme padding_scheme) {
|
|
||||||
return OEMCrypto_GenerateRSASignature(session, message, message_length,
|
|
||||||
signature, signature_length,
|
|
||||||
padding_scheme);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_EVIL_CONSTRUCTORS(WVGenericCryptoInterface);
|
DISALLOW_EVIL_CONSTRUCTORS(WVGenericCryptoInterface);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -162,7 +162,6 @@ WVDrmPlugin::WVDrmPlugin(const android::sp<WvContentDecryptionModule>& cdm,
|
|||||||
: mCdmIdentifierBuilder(useSpoid, *this, appPackageName),
|
: mCdmIdentifierBuilder(useSpoid, *this, appPackageName),
|
||||||
mCDM(cdm),
|
mCDM(cdm),
|
||||||
mCrypto(crypto),
|
mCrypto(crypto),
|
||||||
mCryptoSessions(),
|
|
||||||
mAppPackageName(appPackageName) {
|
mAppPackageName(appPackageName) {
|
||||||
Terminator::Register(this);
|
Terminator::Register(this);
|
||||||
}
|
}
|
||||||
@@ -174,17 +173,14 @@ WVDrmPlugin::~WVDrmPlugin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WVDrmPlugin::Close() {
|
void WVDrmPlugin::Close() {
|
||||||
typedef std::map<CdmSessionId, std::shared_ptr<CryptoSession>>::iterator mapIterator;
|
const auto sessionKeys = mSessionInfoMap.getKeysAndClear();
|
||||||
auto cryptoSessions = mCryptoSessions.clear();
|
for (const auto& sessionKey : sessionKeys) {
|
||||||
for (mapIterator iter = cryptoSessions.begin();
|
const CdmResponseType res = mCDM->CloseSession(sessionKey);
|
||||||
iter != cryptoSessions.end(); ++iter) {
|
|
||||||
CdmResponseType res = mCDM->CloseSession(iter->first);
|
|
||||||
if (!isCdmResponseTypeSuccess(res)) {
|
if (!isCdmResponseTypeSuccess(res)) {
|
||||||
ALOGE("Failed to close session while destroying WVDrmPlugin");
|
ALOGE("Failed to close session while destroying WVDrmPlugin: sid = %s",
|
||||||
|
sessionKey.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// clear local copy of cryptoSessions map
|
|
||||||
cryptoSessions.clear();
|
|
||||||
|
|
||||||
if (mCdmIdentifierBuilder.is_sealed()) {
|
if (mCdmIdentifierBuilder.is_sealed()) {
|
||||||
CdmIdentifier identifier;
|
CdmIdentifier identifier;
|
||||||
@@ -219,15 +215,15 @@ WvStatus WVDrmPlugin::openSessionCommon(vector<uint8_t>& sessionId) {
|
|||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
// Construct a CryptoSession
|
// Construct a SessionInfo
|
||||||
CdmQueryMap info;
|
CdmQueryMap info;
|
||||||
res = mCDM->QueryOemCryptoSessionId(cdmSessionId, &info);
|
res = mCDM->QueryOemCryptoSessionId(cdmSessionId, &info);
|
||||||
|
|
||||||
if (isCdmResponseTypeSuccess(res) &&
|
if (isCdmResponseTypeSuccess(res) &&
|
||||||
info.count(wvcdm::QUERY_KEY_OEMCRYPTO_SESSION_ID)) {
|
info.count(wvcdm::QUERY_KEY_OEMCRYPTO_SESSION_ID)) {
|
||||||
OEMCrypto_SESSION oecSessionId =
|
const OEMCrypto_SESSION oecSessionId =
|
||||||
std::stoul(info[wvcdm::QUERY_KEY_OEMCRYPTO_SESSION_ID]);
|
std::stoul(info[wvcdm::QUERY_KEY_OEMCRYPTO_SESSION_ID]);
|
||||||
mCryptoSessions.insert(cdmSessionId, oecSessionId);
|
mSessionInfoMap.insert(cdmSessionId, oecSessionId);
|
||||||
success = true;
|
success = true;
|
||||||
} else {
|
} else {
|
||||||
ALOGE("Unable to query key control info.");
|
ALOGE("Unable to query key control info.");
|
||||||
@@ -325,7 +321,7 @@ SecurityLevel WVDrmPlugin::mapSecurityLevel(const std::string& level) {
|
|||||||
}
|
}
|
||||||
CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
||||||
CdmResponseType res = mCDM->CloseSession(cdmSessionId);
|
CdmResponseType res = mCDM->CloseSession(cdmSessionId);
|
||||||
mCryptoSessions.erase(cdmSessionId);
|
mSessionInfoMap.erase(cdmSessionId);
|
||||||
if (!isCdmResponseTypeSuccess(res)) {
|
if (!isCdmResponseTypeSuccess(res)) {
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
||||||
}
|
}
|
||||||
@@ -1223,7 +1219,7 @@ Status WVDrmPlugin::unprovisionDevice() {
|
|||||||
std::string _value(in_value.c_str());
|
std::string _value(in_value.c_str());
|
||||||
|
|
||||||
if (name == "securityLevel") {
|
if (name == "securityLevel") {
|
||||||
if (mCryptoSessions.empty()) {
|
if (mSessionInfoMap.empty()) {
|
||||||
if (_value == wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3.c_str()) {
|
if (_value == wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3.c_str()) {
|
||||||
mPropertySet.set_security_level(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3);
|
mPropertySet.set_security_level(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3);
|
||||||
} else if (_value == wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1.c_str()) {
|
} else if (_value == wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1.c_str()) {
|
||||||
@@ -1263,7 +1259,7 @@ Status WVDrmPlugin::unprovisionDevice() {
|
|||||||
return toNdkScopedAStatus(Status::BAD_VALUE);
|
return toNdkScopedAStatus(Status::BAD_VALUE);
|
||||||
}
|
}
|
||||||
} else if (name == "sessionSharing") {
|
} else if (name == "sessionSharing") {
|
||||||
if (mCryptoSessions.empty()) {
|
if (mSessionInfoMap.empty()) {
|
||||||
if (_value == kEnable) {
|
if (_value == kEnable) {
|
||||||
mPropertySet.set_is_session_sharing_enabled(true);
|
mPropertySet.set_is_session_sharing_enabled(true);
|
||||||
} else if (_value == kDisable) {
|
} else if (_value == kDisable) {
|
||||||
@@ -1278,7 +1274,7 @@ Status WVDrmPlugin::unprovisionDevice() {
|
|||||||
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
||||||
}
|
}
|
||||||
} else if (name == "appId") {
|
} else if (name == "appId") {
|
||||||
if (mCryptoSessions.empty()) {
|
if (mSessionInfoMap.empty()) {
|
||||||
mPropertySet.set_app_id(_value.c_str());
|
mPropertySet.set_app_id(_value.c_str());
|
||||||
} else {
|
} else {
|
||||||
ALOGE("App tried to set the application id while sessions are opened.");
|
ALOGE("App tried to set the application id while sessions are opened.");
|
||||||
@@ -1286,7 +1282,7 @@ Status WVDrmPlugin::unprovisionDevice() {
|
|||||||
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
||||||
}
|
}
|
||||||
} else if (name == "origin") {
|
} else if (name == "origin") {
|
||||||
if (!mCryptoSessions.empty()) {
|
if (!mSessionInfoMap.empty()) {
|
||||||
ALOGE("App tried to set the origin while sessions are opened.");
|
ALOGE("App tried to set the origin while sessions are opened.");
|
||||||
ALOGW("Returns UNKNOWN error for legacy status kErrorSessionIsOpen");
|
ALOGW("Returns UNKNOWN error for legacy status kErrorSessionIsOpen");
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
||||||
@@ -1408,46 +1404,42 @@ Status WVDrmPlugin::unprovisionDevice() {
|
|||||||
|
|
||||||
::ndk::ScopedAStatus WVDrmPlugin::setCipherAlgorithm(
|
::ndk::ScopedAStatus WVDrmPlugin::setCipherAlgorithm(
|
||||||
const vector<uint8_t>& in_sessionId, const std::string& in_algorithm) {
|
const vector<uint8_t>& in_sessionId, const std::string& in_algorithm) {
|
||||||
if (in_sessionId.size() == 0 || in_algorithm.size() == 0) {
|
if (in_sessionId.empty() || in_algorithm.empty()) {
|
||||||
return toNdkScopedAStatus(Status::BAD_VALUE);
|
return toNdkScopedAStatus(Status::BAD_VALUE);
|
||||||
}
|
}
|
||||||
std::string algo(in_algorithm.c_str());
|
const std::string algo(in_algorithm.c_str());
|
||||||
|
|
||||||
CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
const CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
||||||
shared_ptr<CryptoSession> cryptoSession = mCryptoSessions.get(cdmSessionId);
|
shared_ptr<SessionInfo> sessionInfo = mSessionInfoMap.get(cdmSessionId);
|
||||||
if (cryptoSession == nullptr) {
|
if (!sessionInfo) {
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (algo == "AES/CBC/NoPadding") {
|
if (algo == "AES/CBC/NoPadding") {
|
||||||
cryptoSession->setCipherAlgorithm(OEMCrypto_AES_CBC_128_NO_PADDING);
|
sessionInfo->setEncryptionAlgorithm(wvcdm::kEncryptionAlgorithmAesCbc128);
|
||||||
} else {
|
return toNdkScopedAStatus(Status::OK);
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
|
|
||||||
}
|
}
|
||||||
|
return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
|
||||||
return toNdkScopedAStatus(Status::OK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::ndk::ScopedAStatus WVDrmPlugin::setMacAlgorithm(
|
::ndk::ScopedAStatus WVDrmPlugin::setMacAlgorithm(
|
||||||
const vector<uint8_t>& in_sessionId, const std::string& in_algorithm) {
|
const vector<uint8_t>& in_sessionId, const std::string& in_algorithm) {
|
||||||
if (in_sessionId.size() == 0 || in_algorithm.size() == 0) {
|
if (in_sessionId.empty() || in_algorithm.empty()) {
|
||||||
return toNdkScopedAStatus(Status::BAD_VALUE);
|
return toNdkScopedAStatus(Status::BAD_VALUE);
|
||||||
}
|
}
|
||||||
std::string algo(in_algorithm.c_str());
|
const std::string algo(in_algorithm.c_str());
|
||||||
|
|
||||||
CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
const CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
||||||
shared_ptr<CryptoSession> cryptoSession = mCryptoSessions.get(cdmSessionId);
|
shared_ptr<SessionInfo> sessionInfo = mSessionInfoMap.get(cdmSessionId);
|
||||||
if (cryptoSession == nullptr) {
|
if (!sessionInfo) {
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (algo == "HmacSHA256") {
|
if (algo == "HmacSHA256") {
|
||||||
cryptoSession->setMacAlgorithm(OEMCrypto_HMAC_SHA256);
|
sessionInfo->setSigningAlgorithm(wvcdm::kSigningAlgorithmHmacSha256);
|
||||||
} else {
|
return toNdkScopedAStatus(Status::OK);
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
|
|
||||||
}
|
}
|
||||||
|
return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
|
||||||
return toNdkScopedAStatus(Status::OK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::ndk::ScopedAStatus WVDrmPlugin::encrypt(const vector<uint8_t>& in_sessionId,
|
::ndk::ScopedAStatus WVDrmPlugin::encrypt(const vector<uint8_t>& in_sessionId,
|
||||||
@@ -1455,43 +1447,32 @@ Status WVDrmPlugin::unprovisionDevice() {
|
|||||||
const vector<uint8_t>& in_input,
|
const vector<uint8_t>& in_input,
|
||||||
const vector<uint8_t>& in_iv,
|
const vector<uint8_t>& in_iv,
|
||||||
vector<uint8_t>* _aidl_return) {
|
vector<uint8_t>* _aidl_return) {
|
||||||
vector<uint8_t> output;
|
_aidl_return->clear();
|
||||||
|
const CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
||||||
*_aidl_return = output;
|
shared_ptr<SessionInfo> sessionInfo = mSessionInfoMap.get(cdmSessionId);
|
||||||
CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
if (!sessionInfo) {
|
||||||
const shared_ptr<CryptoSession> cryptoSession = mCryptoSessions.get(cdmSessionId);
|
|
||||||
if (cryptoSession == nullptr) {
|
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cryptoSession->cipherAlgorithm() == kInvalidCryptoAlgorithm) {
|
if (!sessionInfo->hasEncryptionAlgorithm()) {
|
||||||
ALOGW("Returns UNKNOWN error for legacy status NO_INIT");
|
ALOGW("Encryption algorithm not set");
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult res = mCrypto->selectKey(cryptoSession->oecSessionId(),
|
std::string output;
|
||||||
in_keyId.data(), in_keyId.size());
|
const CdmResponseType result = mCDM->GenericEncrypt(
|
||||||
|
cdmSessionId, KeyId(in_keyId.begin(), in_keyId.end()),
|
||||||
|
std::string(in_input.begin(), in_input.end()),
|
||||||
|
std::string(in_iv.begin(), in_iv.end()),
|
||||||
|
sessionInfo->getEncryptionAlgorithm(), &output);
|
||||||
|
|
||||||
if (res != OEMCrypto_SUCCESS) {
|
if (!result.IsOk()) {
|
||||||
ALOGE("OEMCrypto_SelectKey failed with %u", res);
|
ALOGE("Generic encryption failed: %s", result.ToString().c_str());
|
||||||
return toNdkScopedAStatus(mapAndNotifyOfOEMCryptoResult(in_sessionId, res));
|
return toNdkScopedAStatus(
|
||||||
|
mapAndNotifyOfCdmResponseType(in_sessionId, result));
|
||||||
}
|
}
|
||||||
|
_aidl_return->assign(output.begin(), output.end());
|
||||||
output.resize(in_input.size());
|
return toNdkScopedAStatus(Status::OK);
|
||||||
|
|
||||||
Status status = Status::OK;
|
|
||||||
res = mCrypto->encrypt(cryptoSession->oecSessionId(), in_input.data(),
|
|
||||||
in_input.size(), in_iv.data(),
|
|
||||||
cryptoSession->cipherAlgorithm(), output.data());
|
|
||||||
|
|
||||||
*_aidl_return = output;
|
|
||||||
if (res == OEMCrypto_SUCCESS) {
|
|
||||||
status = Status::OK;
|
|
||||||
} else {
|
|
||||||
ALOGE("OEMCrypto_Generic_Encrypt failed with %u", res);
|
|
||||||
status = mapAndNotifyOfOEMCryptoResult(in_sessionId, res);
|
|
||||||
}
|
|
||||||
return toNdkScopedAStatus(status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::ndk::ScopedAStatus WVDrmPlugin::decrypt(const vector<uint8_t>& in_sessionId,
|
::ndk::ScopedAStatus WVDrmPlugin::decrypt(const vector<uint8_t>& in_sessionId,
|
||||||
@@ -1499,105 +1480,63 @@ Status WVDrmPlugin::unprovisionDevice() {
|
|||||||
const vector<uint8_t>& in_input,
|
const vector<uint8_t>& in_input,
|
||||||
const vector<uint8_t>& in_iv,
|
const vector<uint8_t>& in_iv,
|
||||||
vector<uint8_t>* _aidl_return) {
|
vector<uint8_t>* _aidl_return) {
|
||||||
vector<uint8_t> output;
|
_aidl_return->clear();
|
||||||
*_aidl_return = output;
|
const CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
||||||
|
shared_ptr<SessionInfo> sessionInfo = mSessionInfoMap.get(cdmSessionId);
|
||||||
CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
if (!sessionInfo) {
|
||||||
const shared_ptr<CryptoSession> cryptoSession = mCryptoSessions.get(cdmSessionId);
|
|
||||||
if (cryptoSession == nullptr) {
|
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cryptoSession->cipherAlgorithm() == kInvalidCryptoAlgorithm) {
|
if (!sessionInfo->hasEncryptionAlgorithm()) {
|
||||||
ALOGW("Returns UNKNOWN error for legacy status NO_INIT");
|
ALOGW("Encryption algorithm not set");
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult res = mCrypto->selectKey(cryptoSession->oecSessionId(),
|
std::string output;
|
||||||
in_keyId.data(), in_keyId.size());
|
const CdmResponseType result = mCDM->GenericDecrypt(
|
||||||
|
cdmSessionId, KeyId(in_keyId.begin(), in_keyId.end()),
|
||||||
|
std::string(in_input.begin(), in_input.end()),
|
||||||
|
std::string(in_iv.begin(), in_iv.end()),
|
||||||
|
sessionInfo->getEncryptionAlgorithm(), &output);
|
||||||
|
|
||||||
if (res != OEMCrypto_SUCCESS) {
|
if (!result.IsOk()) {
|
||||||
ALOGE("OEMCrypto_SelectKey failed with %u", res);
|
ALOGE("Generic decryption failed: %s", result.ToString().c_str());
|
||||||
return toNdkScopedAStatus(mapAndNotifyOfOEMCryptoResult(in_sessionId, res));
|
return toNdkScopedAStatus(
|
||||||
|
mapAndNotifyOfCdmResponseType(in_sessionId, result));
|
||||||
}
|
}
|
||||||
|
_aidl_return->assign(output.begin(), output.end());
|
||||||
output.resize(in_input.size());
|
return toNdkScopedAStatus(Status::OK);
|
||||||
|
|
||||||
Status status = Status::OK;
|
|
||||||
res = mCrypto->decrypt(cryptoSession->oecSessionId(), in_input.data(),
|
|
||||||
in_input.size(), in_iv.data(),
|
|
||||||
cryptoSession->cipherAlgorithm(), output.data());
|
|
||||||
|
|
||||||
*_aidl_return = output;
|
|
||||||
if (res == OEMCrypto_SUCCESS) {
|
|
||||||
status = Status::OK;
|
|
||||||
} else {
|
|
||||||
ALOGE("OEMCrypto_Generic_Decrypt failed with %u", res);
|
|
||||||
status = mapAndNotifyOfOEMCryptoResult(in_sessionId, res);
|
|
||||||
}
|
|
||||||
return toNdkScopedAStatus(status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::ndk::ScopedAStatus WVDrmPlugin::sign(const vector<uint8_t>& in_sessionId,
|
::ndk::ScopedAStatus WVDrmPlugin::sign(const vector<uint8_t>& in_sessionId,
|
||||||
const vector<uint8_t>& in_keyId,
|
const vector<uint8_t>& in_keyId,
|
||||||
const vector<uint8_t>& in_message,
|
const vector<uint8_t>& in_message,
|
||||||
vector<uint8_t>* _aidl_return) {
|
vector<uint8_t>* _aidl_return) {
|
||||||
vector<uint8_t> signature;
|
_aidl_return->clear();
|
||||||
*_aidl_return = signature;
|
const CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
||||||
|
shared_ptr<SessionInfo> sessionInfo = mSessionInfoMap.get(cdmSessionId);
|
||||||
CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
if (!sessionInfo) {
|
||||||
const shared_ptr<CryptoSession> cryptoSession = mCryptoSessions.get(cdmSessionId);
|
|
||||||
if (cryptoSession == nullptr) {
|
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cryptoSession->macAlgorithm() == kInvalidCryptoAlgorithm) {
|
if (!sessionInfo->hasSigningAlgorithm()) {
|
||||||
ALOGW("Returns UNKNOWN error for legacy status NO_INIT");
|
ALOGW("Signing algorithm not set");
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult res = mCrypto->selectKey(cryptoSession->oecSessionId(),
|
std::string signature;
|
||||||
in_keyId.data(), in_keyId.size());
|
const CdmResponseType result =
|
||||||
|
mCDM->GenericSign(cdmSessionId, KeyId(in_keyId.begin(), in_keyId.end()),
|
||||||
|
std::string(in_message.begin(), in_message.end()),
|
||||||
|
sessionInfo->getSigningAlgorithm(), &signature);
|
||||||
|
|
||||||
if (res != OEMCrypto_SUCCESS) {
|
if (!result.IsOk()) {
|
||||||
ALOGE("OEMCrypto_SelectKey failed with %u", res);
|
ALOGE("Generic signature failed: %s", result.ToString().c_str());
|
||||||
return toNdkScopedAStatus(mapAndNotifyOfOEMCryptoResult(in_sessionId, res));
|
return toNdkScopedAStatus(
|
||||||
|
mapAndNotifyOfCdmResponseType(in_sessionId, result));
|
||||||
}
|
}
|
||||||
|
_aidl_return->assign(signature.begin(), signature.end());
|
||||||
size_t signatureSize = 0;
|
return toNdkScopedAStatus(Status::OK);
|
||||||
|
|
||||||
res = mCrypto->sign(cryptoSession->oecSessionId(), in_message.data(),
|
|
||||||
in_message.size(), cryptoSession->macAlgorithm(), nullptr,
|
|
||||||
&signatureSize);
|
|
||||||
|
|
||||||
Status status = Status::OK;
|
|
||||||
if (res != OEMCrypto_ERROR_SHORT_BUFFER) {
|
|
||||||
ALOGE(
|
|
||||||
"OEMCrypto_Generic_Sign failed with %u when requesting signature "
|
|
||||||
"size",
|
|
||||||
res);
|
|
||||||
if (res != OEMCrypto_SUCCESS) {
|
|
||||||
status = mapAndNotifyOfOEMCryptoResult(in_sessionId, res);
|
|
||||||
} else {
|
|
||||||
status = Status::ERROR_DRM_UNKNOWN;
|
|
||||||
}
|
|
||||||
return toNdkScopedAStatus(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
signature.resize(signatureSize);
|
|
||||||
|
|
||||||
res = mCrypto->sign(cryptoSession->oecSessionId(), in_message.data(),
|
|
||||||
in_message.size(), cryptoSession->macAlgorithm(),
|
|
||||||
signature.data(), &signatureSize);
|
|
||||||
|
|
||||||
*_aidl_return = signature;
|
|
||||||
if (res == OEMCrypto_SUCCESS) {
|
|
||||||
status = Status::OK;
|
|
||||||
} else {
|
|
||||||
ALOGE("OEMCrypto_Generic_Sign failed with %u", res);
|
|
||||||
status = mapAndNotifyOfOEMCryptoResult(in_sessionId, res);
|
|
||||||
}
|
|
||||||
return toNdkScopedAStatus(status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::ndk::ScopedAStatus WVDrmPlugin::verify(const vector<uint8_t>& in_sessionId,
|
::ndk::ScopedAStatus WVDrmPlugin::verify(const vector<uint8_t>& in_sessionId,
|
||||||
@@ -1605,46 +1544,38 @@ Status WVDrmPlugin::unprovisionDevice() {
|
|||||||
const vector<uint8_t>& in_message,
|
const vector<uint8_t>& in_message,
|
||||||
const vector<uint8_t>& in_signature,
|
const vector<uint8_t>& in_signature,
|
||||||
bool* _aidl_return) {
|
bool* _aidl_return) {
|
||||||
bool match = false;
|
*_aidl_return = false;
|
||||||
*_aidl_return = match;
|
const CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
||||||
|
shared_ptr<SessionInfo> sessionInfo = mSessionInfoMap.get(cdmSessionId);
|
||||||
CdmSessionId cdmSessionId(in_sessionId.begin(), in_sessionId.end());
|
if (!sessionInfo) {
|
||||||
const shared_ptr<CryptoSession> cryptoSession = mCryptoSessions.get(cdmSessionId);
|
|
||||||
if (cryptoSession == nullptr) {
|
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cryptoSession->macAlgorithm() == kInvalidCryptoAlgorithm) {
|
if (!sessionInfo->hasSigningAlgorithm()) {
|
||||||
ALOGW("Returns UNKNOWN error for legacy status NO_INIT");
|
ALOGW("Signing algorithm not set");
|
||||||
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult res = mCrypto->selectKey(cryptoSession->oecSessionId(),
|
const CdmResponseType result = mCDM->GenericVerify(
|
||||||
in_keyId.data(), in_keyId.size());
|
cdmSessionId, KeyId(in_keyId.begin(), in_keyId.end()),
|
||||||
|
std::string(in_message.begin(), in_message.end()),
|
||||||
|
sessionInfo->getSigningAlgorithm(),
|
||||||
|
std::string(in_signature.begin(), in_signature.end()));
|
||||||
|
|
||||||
if (res != OEMCrypto_SUCCESS) {
|
if (result.IsOk()) {
|
||||||
ALOGE("OEMCrypto_SelectKey failed with %u", res);
|
*_aidl_return = true;
|
||||||
return toNdkScopedAStatus(mapAndNotifyOfOEMCryptoResult(in_sessionId, res));
|
return toNdkScopedAStatus(Status::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = mCrypto->verify(cryptoSession->oecSessionId(), in_message.data(),
|
if (result == wvcdm::UNKNOWN_ERROR &&
|
||||||
in_message.size(), cryptoSession->macAlgorithm(),
|
result.oemc_result() == OEMCrypto_ERROR_SIGNATURE_FAILURE) {
|
||||||
in_signature.data(), in_signature.size());
|
// TODO(b/279245250): Use a better error code.
|
||||||
|
return toNdkScopedAStatus(Status::OK);
|
||||||
Status status = Status::OK;
|
|
||||||
if (res == OEMCrypto_SUCCESS) {
|
|
||||||
match = true;
|
|
||||||
status = Status::OK;
|
|
||||||
} else if (res == OEMCrypto_ERROR_SIGNATURE_FAILURE) {
|
|
||||||
match = false;
|
|
||||||
status = Status::OK;
|
|
||||||
} else {
|
|
||||||
ALOGE("OEMCrypto_Generic_Verify failed with %u", res);
|
|
||||||
match = false;
|
|
||||||
status = mapAndNotifyOfOEMCryptoResult(in_sessionId, res);
|
|
||||||
}
|
}
|
||||||
*_aidl_return = match;
|
|
||||||
return toNdkScopedAStatus(status);
|
ALOGE("Generic verify failed: %s", result.ToString().c_str());
|
||||||
|
return toNdkScopedAStatus(
|
||||||
|
mapAndNotifyOfCdmResponseType(in_sessionId, result));
|
||||||
}
|
}
|
||||||
|
|
||||||
::ndk::ScopedAStatus WVDrmPlugin::signRSA(const vector<uint8_t>& in_sessionId,
|
::ndk::ScopedAStatus WVDrmPlugin::signRSA(const vector<uint8_t>& in_sessionId,
|
||||||
|
|||||||
@@ -265,40 +265,28 @@ class MockCDM : public WvContentDecryptionModule {
|
|||||||
(const CdmIdentifier &, wvcdm::RequestedSecurityLevel,
|
(const CdmIdentifier &, wvcdm::RequestedSecurityLevel,
|
||||||
const std::string &, const std::string &),
|
const std::string &, const std::string &),
|
||||||
(override));
|
(override));
|
||||||
|
|
||||||
|
// Generic crypto API.
|
||||||
|
MOCK_METHOD(CdmResponseType, GenericEncrypt,
|
||||||
|
(const CdmSessionId &, const wvcdm::KeyId &, const std::string &,
|
||||||
|
const std::string &, wvcdm::CdmEncryptionAlgorithm,
|
||||||
|
std::string *));
|
||||||
|
MOCK_METHOD(CdmResponseType, GenericDecrypt,
|
||||||
|
(const CdmSessionId &, const wvcdm::KeyId &, const std::string &,
|
||||||
|
const std::string &, wvcdm::CdmEncryptionAlgorithm,
|
||||||
|
std::string *));
|
||||||
|
MOCK_METHOD(CdmResponseType, GenericSign,
|
||||||
|
(const CdmSessionId &, const wvcdm::KeyId &, const std::string &,
|
||||||
|
wvcdm::CdmSigningAlgorithm, std::string *));
|
||||||
|
MOCK_METHOD(CdmResponseType, GenericVerify,
|
||||||
|
(const CdmSessionId &, const wvcdm::KeyId &, const std::string &,
|
||||||
|
wvcdm::CdmSigningAlgorithm, const std::string &));
|
||||||
};
|
};
|
||||||
|
|
||||||
class MockCrypto : public WVGenericCryptoInterface {
|
class MockCrypto : public WVGenericCryptoInterface {
|
||||||
public:
|
public:
|
||||||
MOCK_METHOD(OEMCryptoResult, selectKey,
|
MOCK_METHOD(OEMCryptoResult, loadDeviceRSAKey,
|
||||||
(const OEMCrypto_SESSION, const uint8_t *, size_t), (override));
|
(OEMCrypto_SESSION, const uint8_t *, size_t), (override));
|
||||||
|
|
||||||
MOCK_METHOD(OEMCryptoResult, encrypt,
|
|
||||||
(OEMCrypto_SESSION, const uint8_t *, size_t, const uint8_t *,
|
|
||||||
OEMCrypto_Algorithm, uint8_t *),
|
|
||||||
(override));
|
|
||||||
|
|
||||||
MOCK_METHOD(OEMCryptoResult, decrypt,
|
|
||||||
(OEMCrypto_SESSION, const uint8_t *, size_t, const uint8_t *,
|
|
||||||
OEMCrypto_Algorithm, uint8_t *),
|
|
||||||
(override));
|
|
||||||
|
|
||||||
MOCK_METHOD(OEMCryptoResult, sign,
|
|
||||||
(OEMCrypto_SESSION, const uint8_t *, size_t, OEMCrypto_Algorithm,
|
|
||||||
uint8_t *, size_t *),
|
|
||||||
(override));
|
|
||||||
|
|
||||||
MOCK_METHOD(OEMCryptoResult, verify,
|
|
||||||
(OEMCrypto_SESSION, const uint8_t *, size_t, OEMCrypto_Algorithm,
|
|
||||||
const uint8_t *, size_t),
|
|
||||||
(override));
|
|
||||||
|
|
||||||
MOCK_METHOD(OEMCryptoResult, loadDeviceRSAKey,
|
|
||||||
(OEMCrypto_SESSION, const uint8_t *, size_t), (override));
|
|
||||||
|
|
||||||
MOCK_METHOD(OEMCryptoResult, generateRSASignature,
|
|
||||||
(OEMCrypto_SESSION, const uint8_t *, size_t, uint8_t *, size_t *,
|
|
||||||
RSA_Padding_Scheme),
|
|
||||||
(override));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
@@ -1904,19 +1892,6 @@ TEST_F(WVDrmPluginHalTest, CallsGenericEncrypt) {
|
|||||||
iv.assign(ivRaw, ivRaw + KEY_IV_SIZE);
|
iv.assign(ivRaw, ivRaw + KEY_IV_SIZE);
|
||||||
std::vector<uint8_t> output;
|
std::vector<uint8_t> output;
|
||||||
|
|
||||||
{
|
|
||||||
InSequence calls;
|
|
||||||
|
|
||||||
EXPECT_CALL(mCrypto, selectKey(4, _, KEY_ID_SIZE))
|
|
||||||
.With(Args<1, 2>(ElementsAreArray(keyIdRaw, KEY_ID_SIZE)))
|
|
||||||
.Times(1);
|
|
||||||
|
|
||||||
EXPECT_CALL(mCrypto, encrypt(4, _, kDataSize, IsIV(ivRaw),
|
|
||||||
OEMCrypto_AES_CBC_128_NO_PADDING, _))
|
|
||||||
.With(Args<1, 2>(ElementsAreArray(inputRaw, kDataSize)))
|
|
||||||
.Times(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide expected behavior to support session creation
|
// Provide expected behavior to support session creation
|
||||||
EXPECT_CALL(*mCdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
|
EXPECT_CALL(*mCdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
|
||||||
.Times(AtLeast(1))
|
.Times(AtLeast(1))
|
||||||
@@ -1927,6 +1902,11 @@ TEST_F(WVDrmPluginHalTest, CallsGenericEncrypt) {
|
|||||||
.Times(AtLeast(1))
|
.Times(AtLeast(1))
|
||||||
.WillRepeatedly(Invoke(setSessionIdOnMap<4>));
|
.WillRepeatedly(Invoke(setSessionIdOnMap<4>));
|
||||||
|
|
||||||
|
EXPECT_CALL(*mCdm,
|
||||||
|
GenericEncrypt(mCdmSessionId, _, _, _,
|
||||||
|
wvcdm::kEncryptionAlgorithmAesCbc128, NotNull()))
|
||||||
|
.WillOnce(testing::Return(CdmResponseType(wvcdm::NO_ERROR)));
|
||||||
|
|
||||||
EXPECT_CALL(*mCdm, CloseSession(_)).Times(AtLeast(0));
|
EXPECT_CALL(*mCdm, CloseSession(_)).Times(AtLeast(0));
|
||||||
|
|
||||||
SessionId sessionId;
|
SessionId sessionId;
|
||||||
@@ -1962,19 +1942,6 @@ TEST_F(WVDrmPluginHalTest, CallsGenericDecrypt) {
|
|||||||
iv.assign(ivRaw, ivRaw + KEY_IV_SIZE);
|
iv.assign(ivRaw, ivRaw + KEY_IV_SIZE);
|
||||||
std::vector<uint8_t> output;
|
std::vector<uint8_t> output;
|
||||||
|
|
||||||
{
|
|
||||||
InSequence calls;
|
|
||||||
|
|
||||||
EXPECT_CALL(mCrypto, selectKey(4, _, KEY_ID_SIZE))
|
|
||||||
.With(Args<1, 2>(ElementsAreArray(keyIdRaw, KEY_ID_SIZE)))
|
|
||||||
.Times(1);
|
|
||||||
|
|
||||||
EXPECT_CALL(mCrypto, decrypt(4, _, kDataSize, IsIV(ivRaw),
|
|
||||||
OEMCrypto_AES_CBC_128_NO_PADDING, _))
|
|
||||||
.With(Args<1, 2>(ElementsAreArray(inputRaw, kDataSize)))
|
|
||||||
.Times(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide expected behavior to support session creation
|
// Provide expected behavior to support session creation
|
||||||
EXPECT_CALL(*mCdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
|
EXPECT_CALL(*mCdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
|
||||||
.Times(AtLeast(1))
|
.Times(AtLeast(1))
|
||||||
@@ -1985,6 +1952,11 @@ TEST_F(WVDrmPluginHalTest, CallsGenericDecrypt) {
|
|||||||
.Times(AtLeast(1))
|
.Times(AtLeast(1))
|
||||||
.WillRepeatedly(Invoke(setSessionIdOnMap<4>));
|
.WillRepeatedly(Invoke(setSessionIdOnMap<4>));
|
||||||
|
|
||||||
|
EXPECT_CALL(*mCdm,
|
||||||
|
GenericDecrypt(mCdmSessionId, _, _, _,
|
||||||
|
wvcdm::kEncryptionAlgorithmAesCbc128, NotNull()))
|
||||||
|
.WillOnce(testing::Return(CdmResponseType(wvcdm::NO_ERROR)));
|
||||||
|
|
||||||
EXPECT_CALL(*mCdm, CloseSession(_)).Times(AtLeast(0));
|
EXPECT_CALL(*mCdm, CloseSession(_)).Times(AtLeast(0));
|
||||||
|
|
||||||
SessionId sessionId;
|
SessionId sessionId;
|
||||||
@@ -2014,26 +1986,6 @@ TEST_F(WVDrmPluginHalTest, CallsGenericSign) {
|
|||||||
keyId.assign(keyIdRaw, keyIdRaw + KEY_ID_SIZE);
|
keyId.assign(keyIdRaw, keyIdRaw + KEY_ID_SIZE);
|
||||||
std::vector<uint8_t> message;
|
std::vector<uint8_t> message;
|
||||||
message.assign(messageRaw, messageRaw + kDataSize);
|
message.assign(messageRaw, messageRaw + kDataSize);
|
||||||
std::vector<uint8_t> signature;
|
|
||||||
|
|
||||||
{
|
|
||||||
InSequence calls;
|
|
||||||
|
|
||||||
EXPECT_CALL(mCrypto, selectKey(4, _, KEY_ID_SIZE))
|
|
||||||
.With(Args<1, 2>(ElementsAreArray(keyIdRaw, KEY_ID_SIZE)))
|
|
||||||
.Times(1);
|
|
||||||
|
|
||||||
EXPECT_CALL(mCrypto,
|
|
||||||
sign(4, _, kDataSize, OEMCrypto_HMAC_SHA256, _, Pointee(0)))
|
|
||||||
.With(Args<1, 2>(ElementsAreArray(messageRaw, kDataSize)))
|
|
||||||
.WillOnce(DoAll(SetArgPointee<5>(64),
|
|
||||||
testing::Return(OEMCrypto_ERROR_SHORT_BUFFER)));
|
|
||||||
|
|
||||||
EXPECT_CALL(mCrypto,
|
|
||||||
sign(4, _, kDataSize, OEMCrypto_HMAC_SHA256, _, Pointee(64)))
|
|
||||||
.With(Args<1, 2>(ElementsAreArray(messageRaw, kDataSize)))
|
|
||||||
.Times(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide expected behavior to support session creation
|
// Provide expected behavior to support session creation
|
||||||
EXPECT_CALL(*mCdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
|
EXPECT_CALL(*mCdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
|
||||||
@@ -2045,6 +1997,12 @@ TEST_F(WVDrmPluginHalTest, CallsGenericSign) {
|
|||||||
.Times(AtLeast(1))
|
.Times(AtLeast(1))
|
||||||
.WillRepeatedly(Invoke(setSessionIdOnMap<4>));
|
.WillRepeatedly(Invoke(setSessionIdOnMap<4>));
|
||||||
|
|
||||||
|
const std::string kFakeSign = "super secure signature generated";
|
||||||
|
EXPECT_CALL(*mCdm, GenericSign(mCdmSessionId, _, _,
|
||||||
|
wvcdm::kSigningAlgorithmHmacSha256, NotNull()))
|
||||||
|
.WillOnce(DoAll(SetArgPointee<4>(kFakeSign),
|
||||||
|
testing::Return(CdmResponseType(wvcdm::NO_ERROR))));
|
||||||
|
|
||||||
EXPECT_CALL(*mCdm, CloseSession(_)).Times(AtLeast(0));
|
EXPECT_CALL(*mCdm, CloseSession(_)).Times(AtLeast(0));
|
||||||
|
|
||||||
SessionId sessionId;
|
SessionId sessionId;
|
||||||
@@ -2054,9 +2012,12 @@ TEST_F(WVDrmPluginHalTest, CallsGenericSign) {
|
|||||||
ret = mPlugin->setMacAlgorithm(sessionId, std::string("HmacSHA256"));
|
ret = mPlugin->setMacAlgorithm(sessionId, std::string("HmacSHA256"));
|
||||||
EXPECT_TRUE(ret.isOk());
|
EXPECT_TRUE(ret.isOk());
|
||||||
|
|
||||||
|
std::vector<uint8_t> signature;
|
||||||
ret = mPlugin->sign(sessionId, keyId, message, &signature);
|
ret = mPlugin->sign(sessionId, keyId, message, &signature);
|
||||||
EXPECT_TRUE(ret.isOk());
|
EXPECT_TRUE(ret.isOk());
|
||||||
ASSERT_NE(0u, signature.size());
|
|
||||||
|
const std::vector<uint8_t> kFakeSignVec(kFakeSign.begin(), kFakeSign.end());
|
||||||
|
ASSERT_EQ(signature, kFakeSignVec);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WVDrmPluginHalTest, CallsGenericVerify) {
|
TEST_F(WVDrmPluginHalTest, CallsGenericVerify) {
|
||||||
@@ -2080,29 +2041,9 @@ TEST_F(WVDrmPluginHalTest, CallsGenericVerify) {
|
|||||||
std::vector<uint8_t> signature;
|
std::vector<uint8_t> signature;
|
||||||
signature.assign(signatureRaw, signatureRaw + kSignatureSize);
|
signature.assign(signatureRaw, signatureRaw + kSignatureSize);
|
||||||
|
|
||||||
{
|
const wvcdm::CdmResponseType kSignatureOkResponse(wvcdm::NO_ERROR);
|
||||||
InSequence calls;
|
const wvcdm::CdmResponseType kSignatureBadResponse(
|
||||||
|
wvcdm::UNKNOWN_ERROR, OEMCrypto_ERROR_SIGNATURE_FAILURE, "GenericVerify");
|
||||||
EXPECT_CALL(mCrypto, selectKey(4, _, KEY_ID_SIZE))
|
|
||||||
.With(Args<1, 2>(ElementsAreArray(keyIdRaw, KEY_ID_SIZE)))
|
|
||||||
.Times(1);
|
|
||||||
|
|
||||||
EXPECT_CALL(mCrypto, verify(4, _, kDataSize, OEMCrypto_HMAC_SHA256, _,
|
|
||||||
kSignatureSize))
|
|
||||||
.With(AllOf(Args<1, 2>(ElementsAreArray(messageRaw, kDataSize)),
|
|
||||||
Args<4, 5>(ElementsAreArray(signatureRaw, kSignatureSize))))
|
|
||||||
.WillOnce(testing::Return(OEMCrypto_SUCCESS));
|
|
||||||
|
|
||||||
EXPECT_CALL(mCrypto, selectKey(4, _, KEY_ID_SIZE))
|
|
||||||
.With(Args<1, 2>(ElementsAreArray(keyIdRaw, KEY_ID_SIZE)))
|
|
||||||
.Times(1);
|
|
||||||
|
|
||||||
EXPECT_CALL(mCrypto, verify(4, _, kDataSize, OEMCrypto_HMAC_SHA256, _,
|
|
||||||
kSignatureSize))
|
|
||||||
.With(AllOf(Args<1, 2>(ElementsAreArray(messageRaw, kDataSize)),
|
|
||||||
Args<4, 5>(ElementsAreArray(signatureRaw, kSignatureSize))))
|
|
||||||
.WillOnce(testing::Return(OEMCrypto_ERROR_SIGNATURE_FAILURE));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide expected behavior to support session creation
|
// Provide expected behavior to support session creation
|
||||||
EXPECT_CALL(*mCdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
|
EXPECT_CALL(*mCdm, OpenSession(StrEq("com.widevine"), _, _, _, _))
|
||||||
@@ -2114,6 +2055,11 @@ TEST_F(WVDrmPluginHalTest, CallsGenericVerify) {
|
|||||||
.Times(AtLeast(1))
|
.Times(AtLeast(1))
|
||||||
.WillRepeatedly(Invoke(setSessionIdOnMap<4>));
|
.WillRepeatedly(Invoke(setSessionIdOnMap<4>));
|
||||||
|
|
||||||
|
EXPECT_CALL(*mCdm, GenericVerify(mCdmSessionId, _, _,
|
||||||
|
wvcdm::kSigningAlgorithmHmacSha256, _))
|
||||||
|
.WillOnce(testing::Return(kSignatureOkResponse))
|
||||||
|
.WillOnce(testing::Return(kSignatureBadResponse));
|
||||||
|
|
||||||
EXPECT_CALL(*mCdm, CloseSession(_)).Times(AtLeast(0));
|
EXPECT_CALL(*mCdm, CloseSession(_)).Times(AtLeast(0));
|
||||||
|
|
||||||
SessionId sessionId;
|
SessionId sessionId;
|
||||||
|
|||||||
Reference in New Issue
Block a user