summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdwin Wong <edwinwong@google.com>2017-10-06 18:21:06 -0700
committerMSe <mse1969@posteo.de>2018-01-10 21:51:24 +0100
commit7659a838bdf18762217c986035ff673a71213028 (patch)
tree13bb0329bd1dbc9bfd4efd04db8ac39c0b2a2b2b
parent75123a0af4b4882bba5bc7ec3872b5ad45ff58fe (diff)
downloadframeworks_av-7659a838bdf18762217c986035ff673a71213028.tar.gz
frameworks_av-7659a838bdf18762217c986035ff673a71213028.tar.bz2
frameworks_av-7659a838bdf18762217c986035ff673a71213028.zip
Validate decryption key length to decrypt function.
Cherry picked from http://go/ag/3038278. AesCtrDecryptor::decrypt() doesn't check whether the size of "key" is equal to 16 bytes, which may lead to an OOB read problem in the context of mediadrmserver. Add DecryptsWithEmptyKey and DecryptsWithKeyTooLong unit tests. Test: ClearKeyDrmUnitTest adb shell LD_LIBRARY_PATH="/vendor/lib/mediadrm" /data/nativetest/ClearKeyDrmUnitTest/ClearKeyDrmUnitTest bug: 63982768 Change-Id: I1f22c9df2b051972b2c532608b7f203e3ce77926 (cherry picked from commit 379b672b189aa72ce0103b485019022f3e292c36) CVE-2017-13201
-rw-r--r--drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp5
-rw-r--r--drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h1
-rw-r--r--drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp63
3 files changed, 68 insertions, 1 deletions
diff --git a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp b/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp
index 01f8d65702..f7106b275e 100644
--- a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp
+++ b/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp
@@ -36,6 +36,11 @@ android::status_t AesCtrDecryptor::decrypt(const android::Vector<uint8_t>& key,
uint8_t previousEncryptedCounter[kBlockSize];
memset(previousEncryptedCounter, 0, kBlockSize);
+ if (key.size() != kBlockSize || (sizeof(Iv) / sizeof(uint8_t)) != kBlockSize) {
+ android_errorWriteLog(0x534e4554, "63982768");
+ return android::ERROR_DRM_DECRYPT;
+ }
+
size_t offset = 0;
AES_KEY opensslKey;
AES_set_encrypt_key(key.array(), kBlockBitCount, &opensslKey);
diff --git a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h b/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h
index b416266ddf..edb84458a7 100644
--- a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h
+++ b/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h
@@ -18,6 +18,7 @@
#define CLEARKEY_AES_CTR_DECRYPTOR_H_
#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/MediaErrors.h>
#include <Utils.h>
#include <utils/Errors.h>
#include <utils/Vector.h>
diff --git a/drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp b/drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp
index 039e40226b..5db8290a91 100644
--- a/drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp
+++ b/drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp
@@ -34,7 +34,7 @@ class AesCtrDecryptorTest : public ::testing::Test {
uint8_t* destination, const SubSample* subSamples,
size_t numSubSamples, size_t* bytesDecryptedOut) {
Vector<uint8_t> keyVector;
- keyVector.appendArray(key, kBlockSize);
+ keyVector.appendArray(key, sizeof(key) / sizeof(uint8_t));
AesCtrDecryptor decryptor;
return decryptor.decrypt(keyVector, iv, source, destination, subSamples,
@@ -57,6 +57,67 @@ class AesCtrDecryptorTest : public ::testing::Test {
}
};
+TEST_F(AesCtrDecryptorTest, DecryptsWithEmptyKey) {
+ const size_t kTotalSize = 64;
+ const size_t kNumSubsamples = 1;
+
+ // Test vectors from NIST-800-38A
+ Iv iv = {
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+ };
+
+ uint8_t source[kTotalSize] = { 0 };
+ uint8_t destination[kTotalSize] = { 0 };
+ SubSample subSamples[kNumSubsamples] = {
+ {0, 64}
+ };
+
+ size_t bytesDecrypted = 0;
+ Vector<uint8_t> keyVector;
+ keyVector.clear();
+
+ AesCtrDecryptor decryptor;
+ ASSERT_EQ(android::ERROR_DRM_DECRYPT, decryptor.decrypt(keyVector, iv,
+ &source[0], &destination[0],
+ &subSamples[0], kNumSubsamples, &bytesDecrypted));
+ ASSERT_EQ(0u, bytesDecrypted);
+}
+
+TEST_F(AesCtrDecryptorTest, DecryptsWithKeyTooLong) {
+ const size_t kTotalSize = 64;
+ const size_t kNumSubsamples = 1;
+
+ // Test vectors from NIST-800-38A
+ uint8_t key[kBlockSize * 2] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
+ };
+
+ Iv iv = {
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+ };
+
+ uint8_t source[kTotalSize] = { 0 };
+ uint8_t destination[kTotalSize] = { 0 };
+ SubSample subSamples[kNumSubsamples] = {
+ {0, 64}
+ };
+
+ size_t bytesDecrypted = 0;
+ Vector<uint8_t> keyVector;
+ keyVector.appendArray(key, sizeof(key) / sizeof(uint8_t));
+
+ AesCtrDecryptor decryptor;
+ ASSERT_EQ(android::ERROR_DRM_DECRYPT, decryptor.decrypt(keyVector, iv,
+ &source[0], &destination[0],
+ &subSamples[0], kNumSubsamples, &bytesDecrypted));
+ ASSERT_EQ(0u, bytesDecrypted);
+}
+
TEST_F(AesCtrDecryptorTest, DecryptsContiguousEncryptedBlock) {
const size_t kTotalSize = 64;
const size_t kNumSubsamples = 1;