MockDrmCryptoPlugin.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. /*
  2. * Copyright (C) 2013 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. //#define LOG_NDEBUG 0
  17. #define LOG_TAG "MockDrmCryptoPlugin"
  18. #include <utils/Log.h>
  19. #include "media/drm/DrmAPI.h"
  20. #include "MockDrmCryptoPlugin.h"
  21. #include "media/stagefright/MediaErrors.h"
  22. using namespace android;
  23. // Shared library entry point
  24. DrmFactory *createDrmFactory()
  25. {
  26. return new MockDrmFactory();
  27. }
  28. // Shared library entry point
  29. CryptoFactory *createCryptoFactory()
  30. {
  31. return new MockCryptoFactory();
  32. }
  33. const uint8_t mock_uuid[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  34. 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
  35. namespace android {
  36. // MockDrmFactory
  37. bool MockDrmFactory::isCryptoSchemeSupported(const uint8_t uuid[16])
  38. {
  39. return (!memcmp(uuid, mock_uuid, sizeof(mock_uuid)));
  40. }
  41. bool MockDrmFactory::isContentTypeSupported(const String8 &mimeType)
  42. {
  43. if (mimeType != "video/mp4") {
  44. return false;
  45. }
  46. return true;
  47. }
  48. status_t MockDrmFactory::createDrmPlugin(const uint8_t /* uuid */[16],
  49. DrmPlugin **plugin)
  50. {
  51. *plugin = new MockDrmPlugin();
  52. return OK;
  53. }
  54. // MockCryptoFactory
  55. bool MockCryptoFactory::isCryptoSchemeSupported(const uint8_t uuid[16]) const
  56. {
  57. return (!memcmp(uuid, mock_uuid, sizeof(mock_uuid)));
  58. }
  59. status_t MockCryptoFactory::createPlugin(const uint8_t /* uuid */[16],
  60. const void * /* data */,
  61. size_t /* size */, CryptoPlugin **plugin)
  62. {
  63. *plugin = new MockCryptoPlugin();
  64. return OK;
  65. }
  66. // MockDrmPlugin methods
  67. status_t MockDrmPlugin::openSession(Vector<uint8_t> &sessionId)
  68. {
  69. const size_t kSessionIdSize = 8;
  70. Mutex::Autolock lock(mLock);
  71. for (size_t i = 0; i < kSessionIdSize / sizeof(long); i++) {
  72. long r = random();
  73. sessionId.appendArray((uint8_t *)&r, sizeof(long));
  74. }
  75. mSessions.add(sessionId);
  76. ALOGD("MockDrmPlugin::openSession() -> %s", vectorToString(sessionId).string());
  77. return OK;
  78. }
  79. status_t MockDrmPlugin::closeSession(Vector<uint8_t> const &sessionId)
  80. {
  81. Mutex::Autolock lock(mLock);
  82. ALOGD("MockDrmPlugin::closeSession(%s)", vectorToString(sessionId).string());
  83. ssize_t index = findSession(sessionId);
  84. if (index == kNotFound) {
  85. ALOGD("Invalid sessionId");
  86. return BAD_VALUE;
  87. }
  88. mSessions.removeAt(index);
  89. return OK;
  90. }
  91. status_t MockDrmPlugin::getKeyRequest(Vector<uint8_t> const &sessionId,
  92. Vector<uint8_t> const &initData,
  93. String8 const &mimeType, KeyType keyType,
  94. KeyedVector<String8, String8> const &optionalParameters,
  95. Vector<uint8_t> &request, String8 &defaultUrl,
  96. KeyRequestType *keyRequestType)
  97. {
  98. Mutex::Autolock lock(mLock);
  99. ALOGD("MockDrmPlugin::getKeyRequest(sessionId=%s, initData=%s, mimeType=%s"
  100. ", keyType=%d, optionalParameters=%s))",
  101. vectorToString(sessionId).string(), vectorToString(initData).string(), mimeType.string(),
  102. keyType, stringMapToString(optionalParameters).string());
  103. ssize_t index = findSession(sessionId);
  104. if (index == kNotFound) {
  105. ALOGD("Invalid sessionId");
  106. return BAD_VALUE;
  107. }
  108. // Properties used in mock test, set by mock plugin and verifed cts test app
  109. // byte[] initData -> mock-initdata
  110. // string mimeType -> mock-mimetype
  111. // string keyType -> mock-keytype
  112. // string optionalParameters -> mock-optparams formatted as {key1,value1},{key2,value2}
  113. mByteArrayProperties.add(String8("mock-initdata"), initData);
  114. mStringProperties.add(String8("mock-mimetype"), mimeType);
  115. String8 keyTypeStr;
  116. keyTypeStr.appendFormat("%d", (int)keyType);
  117. mStringProperties.add(String8("mock-keytype"), keyTypeStr);
  118. String8 params;
  119. for (size_t i = 0; i < optionalParameters.size(); i++) {
  120. params.appendFormat("%s{%s,%s}", i ? "," : "",
  121. optionalParameters.keyAt(i).string(),
  122. optionalParameters.valueAt(i).string());
  123. }
  124. mStringProperties.add(String8("mock-optparams"), params);
  125. // Properties used in mock test, set by cts test app returned from mock plugin
  126. // byte[] mock-request -> request
  127. // string mock-default-url -> defaultUrl
  128. // string mock-keyRequestType -> keyRequestType
  129. index = mByteArrayProperties.indexOfKey(String8("mock-request"));
  130. if (index < 0) {
  131. ALOGD("Missing 'mock-request' parameter for mock");
  132. return BAD_VALUE;
  133. } else {
  134. request = mByteArrayProperties.valueAt(index);
  135. }
  136. index = mStringProperties.indexOfKey(String8("mock-defaultUrl"));
  137. if (index < 0) {
  138. ALOGD("Missing 'mock-defaultUrl' parameter for mock");
  139. return BAD_VALUE;
  140. } else {
  141. defaultUrl = mStringProperties.valueAt(index);
  142. }
  143. index = mStringProperties.indexOfKey(String8("mock-keyRequestType"));
  144. if (index < 0) {
  145. ALOGD("Missing 'mock-keyRequestType' parameter for mock");
  146. return BAD_VALUE;
  147. } else {
  148. *keyRequestType = static_cast<KeyRequestType>(
  149. atoi(mStringProperties.valueAt(index).string()));
  150. }
  151. return OK;
  152. }
  153. status_t MockDrmPlugin::provideKeyResponse(Vector<uint8_t> const &sessionId,
  154. Vector<uint8_t> const &response,
  155. Vector<uint8_t> &keySetId)
  156. {
  157. Mutex::Autolock lock(mLock);
  158. ALOGD("MockDrmPlugin::provideKeyResponse(sessionId=%s, response=%s)",
  159. vectorToString(sessionId).string(), vectorToString(response).string());
  160. ssize_t index = findSession(sessionId);
  161. if (index == kNotFound) {
  162. ALOGD("Invalid sessionId");
  163. return BAD_VALUE;
  164. }
  165. if (response.size() == 0) {
  166. return BAD_VALUE;
  167. }
  168. // Properties used in mock test, set by mock plugin and verifed cts test app
  169. // byte[] response -> mock-response
  170. mByteArrayProperties.add(String8("mock-response"), response);
  171. const size_t kKeySetIdSize = 8;
  172. for (size_t i = 0; i < kKeySetIdSize / sizeof(long); i++) {
  173. long r = random();
  174. keySetId.appendArray((uint8_t *)&r, sizeof(long));
  175. }
  176. mKeySets.add(keySetId);
  177. return OK;
  178. }
  179. status_t MockDrmPlugin::removeKeys(Vector<uint8_t> const &keySetId)
  180. {
  181. Mutex::Autolock lock(mLock);
  182. ALOGD("MockDrmPlugin::removeKeys(keySetId=%s)",
  183. vectorToString(keySetId).string());
  184. ssize_t index = findKeySet(keySetId);
  185. if (index == kNotFound) {
  186. ALOGD("Invalid keySetId");
  187. return BAD_VALUE;
  188. }
  189. mKeySets.removeAt(index);
  190. return OK;
  191. }
  192. status_t MockDrmPlugin::restoreKeys(Vector<uint8_t> const &sessionId,
  193. Vector<uint8_t> const &keySetId)
  194. {
  195. Mutex::Autolock lock(mLock);
  196. ALOGD("MockDrmPlugin::restoreKeys(sessionId=%s, keySetId=%s)",
  197. vectorToString(sessionId).string(),
  198. vectorToString(keySetId).string());
  199. ssize_t index = findSession(sessionId);
  200. if (index == kNotFound) {
  201. ALOGD("Invalid sessionId");
  202. return BAD_VALUE;
  203. }
  204. index = findKeySet(keySetId);
  205. if (index == kNotFound) {
  206. ALOGD("Invalid keySetId");
  207. return BAD_VALUE;
  208. }
  209. return OK;
  210. }
  211. status_t MockDrmPlugin::queryKeyStatus(Vector<uint8_t> const &sessionId,
  212. KeyedVector<String8, String8> &infoMap) const
  213. {
  214. ALOGD("MockDrmPlugin::queryKeyStatus(sessionId=%s)",
  215. vectorToString(sessionId).string());
  216. ssize_t index = findSession(sessionId);
  217. if (index == kNotFound) {
  218. ALOGD("Invalid sessionId");
  219. return BAD_VALUE;
  220. }
  221. infoMap.add(String8("purchaseDuration"), String8("1000"));
  222. infoMap.add(String8("licenseDuration"), String8("100"));
  223. return OK;
  224. }
  225. status_t MockDrmPlugin::getProvisionRequest(String8 const & /* certType */,
  226. String8 const & /* certAuthority */,
  227. Vector<uint8_t> &request,
  228. String8 &defaultUrl)
  229. {
  230. Mutex::Autolock lock(mLock);
  231. ALOGD("MockDrmPlugin::getProvisionRequest()");
  232. // Properties used in mock test, set by cts test app returned from mock plugin
  233. // byte[] mock-request -> request
  234. // string mock-default-url -> defaultUrl
  235. ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-request"));
  236. if (index < 0) {
  237. ALOGD("Missing 'mock-request' parameter for mock");
  238. return BAD_VALUE;
  239. } else {
  240. request = mByteArrayProperties.valueAt(index);
  241. }
  242. index = mStringProperties.indexOfKey(String8("mock-defaultUrl"));
  243. if (index < 0) {
  244. ALOGD("Missing 'mock-defaultUrl' parameter for mock");
  245. return BAD_VALUE;
  246. } else {
  247. defaultUrl = mStringProperties.valueAt(index);
  248. }
  249. return OK;
  250. }
  251. status_t MockDrmPlugin::provideProvisionResponse(Vector<uint8_t> const &response,
  252. Vector<uint8_t> & /* certificate */,
  253. Vector<uint8_t> & /* wrappedKey */)
  254. {
  255. Mutex::Autolock lock(mLock);
  256. ALOGD("MockDrmPlugin::provideProvisionResponse(%s)",
  257. vectorToString(response).string());
  258. // Properties used in mock test, set by mock plugin and verifed cts test app
  259. // byte[] response -> mock-response
  260. mByteArrayProperties.add(String8("mock-response"), response);
  261. return OK;
  262. }
  263. status_t MockDrmPlugin::getSecureStop(Vector<uint8_t> const & /* ssid */,
  264. Vector<uint8_t> & secureStop)
  265. {
  266. Mutex::Autolock lock(mLock);
  267. ALOGD("MockDrmPlugin::getSecureStop()");
  268. // Properties used in mock test, set by cts test app returned from mock plugin
  269. // byte[] mock-secure-stop -> first secure stop in list
  270. ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop"));
  271. if (index < 0) {
  272. ALOGD("Missing 'mock-secure-stop' parameter for mock");
  273. return BAD_VALUE;
  274. } else {
  275. secureStop = mByteArrayProperties.valueAt(index);
  276. }
  277. return OK;
  278. }
  279. status_t MockDrmPlugin::getSecureStops(List<Vector<uint8_t> > &secureStops)
  280. {
  281. Mutex::Autolock lock(mLock);
  282. ALOGD("MockDrmPlugin::getSecureStops()");
  283. // Properties used in mock test, set by cts test app returned from mock plugin
  284. // byte[] mock-secure-stop1 -> first secure stop in list
  285. // byte[] mock-secure-stop2 -> second secure stop in list
  286. Vector<uint8_t> ss1, ss2;
  287. ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop1"));
  288. if (index < 0) {
  289. ALOGD("Missing 'mock-secure-stop1' parameter for mock");
  290. return BAD_VALUE;
  291. } else {
  292. ss1 = mByteArrayProperties.valueAt(index);
  293. }
  294. index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop2"));
  295. if (index < 0) {
  296. ALOGD("Missing 'mock-secure-stop2' parameter for mock");
  297. return BAD_VALUE;
  298. } else {
  299. ss2 = mByteArrayProperties.valueAt(index);
  300. }
  301. secureStops.push_back(ss1);
  302. secureStops.push_back(ss2);
  303. return OK;
  304. }
  305. status_t MockDrmPlugin::releaseSecureStops(Vector<uint8_t> const &ssRelease)
  306. {
  307. Mutex::Autolock lock(mLock);
  308. ALOGD("MockDrmPlugin::releaseSecureStops(%s)",
  309. vectorToString(ssRelease).string());
  310. // Properties used in mock test, set by mock plugin and verifed cts test app
  311. // byte[] secure-stop-release -> mock-ssrelease
  312. mByteArrayProperties.add(String8("mock-ssrelease"), ssRelease);
  313. return OK;
  314. }
  315. status_t MockDrmPlugin::releaseAllSecureStops()
  316. {
  317. Mutex::Autolock lock(mLock);
  318. ALOGD("MockDrmPlugin::releaseAllSecureStops()");
  319. return OK;
  320. }
  321. status_t MockDrmPlugin::getPropertyString(String8 const &name, String8 &value) const
  322. {
  323. ALOGD("MockDrmPlugin::getPropertyString(name=%s)", name.string());
  324. ssize_t index = mStringProperties.indexOfKey(name);
  325. if (index < 0) {
  326. ALOGD("no property for '%s'", name.string());
  327. return BAD_VALUE;
  328. }
  329. value = mStringProperties.valueAt(index);
  330. return OK;
  331. }
  332. status_t MockDrmPlugin::getPropertyByteArray(String8 const &name,
  333. Vector<uint8_t> &value) const
  334. {
  335. ALOGD("MockDrmPlugin::getPropertyByteArray(name=%s)", name.string());
  336. ssize_t index = mByteArrayProperties.indexOfKey(name);
  337. if (index < 0) {
  338. ALOGD("no property for '%s'", name.string());
  339. return BAD_VALUE;
  340. }
  341. value = mByteArrayProperties.valueAt(index);
  342. return OK;
  343. }
  344. status_t MockDrmPlugin::setPropertyString(String8 const &name,
  345. String8 const &value)
  346. {
  347. Mutex::Autolock lock(mLock);
  348. ALOGD("MockDrmPlugin::setPropertyString(name=%s, value=%s)",
  349. name.string(), value.string());
  350. if (name == "mock-send-event") {
  351. unsigned code, extra;
  352. sscanf(value.string(), "%d %d", &code, &extra);
  353. DrmPlugin::EventType eventType = (DrmPlugin::EventType)code;
  354. Vector<uint8_t> const *pSessionId = NULL;
  355. ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-event-session-id"));
  356. if (index >= 0) {
  357. pSessionId = &mByteArrayProperties[index];
  358. }
  359. Vector<uint8_t> const *pData = NULL;
  360. index = mByteArrayProperties.indexOfKey(String8("mock-event-data"));
  361. if (index >= 0) {
  362. pData = &mByteArrayProperties[index];
  363. }
  364. ALOGD("sending event from mock drm plugin: %d %d %s %s",
  365. (int)code, extra, pSessionId ? vectorToString(*pSessionId) : "{}",
  366. pData ? vectorToString(*pData) : "{}");
  367. sendEvent(eventType, extra, pSessionId, pData);
  368. } else if (name == "mock-send-expiration-update") {
  369. int64_t expiryTimeMS;
  370. sscanf(value.string(), "%jd", &expiryTimeMS);
  371. Vector<uint8_t> const *pSessionId = NULL;
  372. ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-event-session-id"));
  373. if (index >= 0) {
  374. pSessionId = &mByteArrayProperties[index];
  375. }
  376. ALOGD("sending expiration-update from mock drm plugin: %jd %s",
  377. expiryTimeMS, pSessionId ? vectorToString(*pSessionId) : "{}");
  378. sendExpirationUpdate(pSessionId, expiryTimeMS);
  379. } else if (name == "mock-send-keys-change") {
  380. Vector<uint8_t> const *pSessionId = NULL;
  381. ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-event-session-id"));
  382. if (index >= 0) {
  383. pSessionId = &mByteArrayProperties[index];
  384. }
  385. ALOGD("sending keys-change from mock drm plugin: %s",
  386. pSessionId ? vectorToString(*pSessionId) : "{}");
  387. Vector<DrmPlugin::KeyStatus> keyStatusList;
  388. DrmPlugin::KeyStatus keyStatus;
  389. uint8_t keyId1[] = {'k', 'e', 'y', '1'};
  390. keyStatus.mKeyId.clear();
  391. keyStatus.mKeyId.appendArray(keyId1, sizeof(keyId1));
  392. keyStatus.mType = DrmPlugin::kKeyStatusType_Usable;
  393. keyStatusList.add(keyStatus);
  394. uint8_t keyId2[] = {'k', 'e', 'y', '2'};
  395. keyStatus.mKeyId.clear();
  396. keyStatus.mKeyId.appendArray(keyId2, sizeof(keyId2));
  397. keyStatus.mType = DrmPlugin::kKeyStatusType_Expired;
  398. keyStatusList.add(keyStatus);
  399. uint8_t keyId3[] = {'k', 'e', 'y', '3'};
  400. keyStatus.mKeyId.clear();
  401. keyStatus.mKeyId.appendArray(keyId3, sizeof(keyId3));
  402. keyStatus.mType = DrmPlugin::kKeyStatusType_OutputNotAllowed;
  403. keyStatusList.add(keyStatus);
  404. uint8_t keyId4[] = {'k', 'e', 'y', '4'};
  405. keyStatus.mKeyId.clear();
  406. keyStatus.mKeyId.appendArray(keyId4, sizeof(keyId4));
  407. keyStatus.mType = DrmPlugin::kKeyStatusType_StatusPending;
  408. keyStatusList.add(keyStatus);
  409. uint8_t keyId5[] = {'k', 'e', 'y', '5'};
  410. keyStatus.mKeyId.clear();
  411. keyStatus.mKeyId.appendArray(keyId5, sizeof(keyId5));
  412. keyStatus.mType = DrmPlugin::kKeyStatusType_InternalError;
  413. keyStatusList.add(keyStatus);
  414. sendKeysChange(pSessionId, &keyStatusList, true);
  415. } else {
  416. mStringProperties.add(name, value);
  417. }
  418. return OK;
  419. }
  420. status_t MockDrmPlugin::setPropertyByteArray(String8 const &name,
  421. Vector<uint8_t> const &value)
  422. {
  423. Mutex::Autolock lock(mLock);
  424. ALOGD("MockDrmPlugin::setPropertyByteArray(name=%s, value=%s)",
  425. name.string(), vectorToString(value).string());
  426. mByteArrayProperties.add(name, value);
  427. return OK;
  428. }
  429. status_t MockDrmPlugin::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
  430. String8 const &algorithm)
  431. {
  432. Mutex::Autolock lock(mLock);
  433. ALOGD("MockDrmPlugin::setCipherAlgorithm(sessionId=%s, algorithm=%s)",
  434. vectorToString(sessionId).string(), algorithm.string());
  435. ssize_t index = findSession(sessionId);
  436. if (index == kNotFound) {
  437. ALOGD("Invalid sessionId");
  438. return BAD_VALUE;
  439. }
  440. if (algorithm == "AES/CBC/NoPadding") {
  441. return OK;
  442. }
  443. return BAD_VALUE;
  444. }
  445. status_t MockDrmPlugin::setMacAlgorithm(Vector<uint8_t> const &sessionId,
  446. String8 const &algorithm)
  447. {
  448. Mutex::Autolock lock(mLock);
  449. ALOGD("MockDrmPlugin::setMacAlgorithm(sessionId=%s, algorithm=%s)",
  450. vectorToString(sessionId).string(), algorithm.string());
  451. ssize_t index = findSession(sessionId);
  452. if (index == kNotFound) {
  453. ALOGD("Invalid sessionId");
  454. return BAD_VALUE;
  455. }
  456. if (algorithm == "HmacSHA256") {
  457. return OK;
  458. }
  459. return BAD_VALUE;
  460. }
  461. status_t MockDrmPlugin::encrypt(Vector<uint8_t> const &sessionId,
  462. Vector<uint8_t> const &keyId,
  463. Vector<uint8_t> const &input,
  464. Vector<uint8_t> const &iv,
  465. Vector<uint8_t> &output)
  466. {
  467. Mutex::Autolock lock(mLock);
  468. ALOGD("MockDrmPlugin::encrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)",
  469. vectorToString(sessionId).string(),
  470. vectorToString(keyId).string(),
  471. vectorToString(input).string(),
  472. vectorToString(iv).string());
  473. ssize_t index = findSession(sessionId);
  474. if (index == kNotFound) {
  475. ALOGD("Invalid sessionId");
  476. return BAD_VALUE;
  477. }
  478. // Properties used in mock test, set by mock plugin and verifed cts test app
  479. // byte[] keyId -> mock-keyid
  480. // byte[] input -> mock-input
  481. // byte[] iv -> mock-iv
  482. mByteArrayProperties.add(String8("mock-keyid"), keyId);
  483. mByteArrayProperties.add(String8("mock-input"), input);
  484. mByteArrayProperties.add(String8("mock-iv"), iv);
  485. // Properties used in mock test, set by cts test app returned from mock plugin
  486. // byte[] mock-output -> output
  487. index = mByteArrayProperties.indexOfKey(String8("mock-output"));
  488. if (index < 0) {
  489. ALOGD("Missing 'mock-request' parameter for mock");
  490. return BAD_VALUE;
  491. } else {
  492. output = mByteArrayProperties.valueAt(index);
  493. }
  494. return OK;
  495. }
  496. status_t MockDrmPlugin::decrypt(Vector<uint8_t> const &sessionId,
  497. Vector<uint8_t> const &keyId,
  498. Vector<uint8_t> const &input,
  499. Vector<uint8_t> const &iv,
  500. Vector<uint8_t> &output)
  501. {
  502. Mutex::Autolock lock(mLock);
  503. ALOGD("MockDrmPlugin::decrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)",
  504. vectorToString(sessionId).string(),
  505. vectorToString(keyId).string(),
  506. vectorToString(input).string(),
  507. vectorToString(iv).string());
  508. ssize_t index = findSession(sessionId);
  509. if (index == kNotFound) {
  510. ALOGD("Invalid sessionId");
  511. return BAD_VALUE;
  512. }
  513. // Properties used in mock test, set by mock plugin and verifed cts test app
  514. // byte[] keyId -> mock-keyid
  515. // byte[] input -> mock-input
  516. // byte[] iv -> mock-iv
  517. mByteArrayProperties.add(String8("mock-keyid"), keyId);
  518. mByteArrayProperties.add(String8("mock-input"), input);
  519. mByteArrayProperties.add(String8("mock-iv"), iv);
  520. // Properties used in mock test, set by cts test app returned from mock plugin
  521. // byte[] mock-output -> output
  522. index = mByteArrayProperties.indexOfKey(String8("mock-output"));
  523. if (index < 0) {
  524. ALOGD("Missing 'mock-request' parameter for mock");
  525. return BAD_VALUE;
  526. } else {
  527. output = mByteArrayProperties.valueAt(index);
  528. }
  529. return OK;
  530. }
  531. status_t MockDrmPlugin::sign(Vector<uint8_t> const &sessionId,
  532. Vector<uint8_t> const &keyId,
  533. Vector<uint8_t> const &message,
  534. Vector<uint8_t> &signature)
  535. {
  536. Mutex::Autolock lock(mLock);
  537. ALOGD("MockDrmPlugin::sign(sessionId=%s, keyId=%s, message=%s)",
  538. vectorToString(sessionId).string(),
  539. vectorToString(keyId).string(),
  540. vectorToString(message).string());
  541. ssize_t index = findSession(sessionId);
  542. if (index == kNotFound) {
  543. ALOGD("Invalid sessionId");
  544. return BAD_VALUE;
  545. }
  546. // Properties used in mock test, set by mock plugin and verifed cts test app
  547. // byte[] keyId -> mock-keyid
  548. // byte[] message -> mock-message
  549. mByteArrayProperties.add(String8("mock-keyid"), keyId);
  550. mByteArrayProperties.add(String8("mock-message"), message);
  551. // Properties used in mock test, set by cts test app returned from mock plugin
  552. // byte[] mock-signature -> signature
  553. index = mByteArrayProperties.indexOfKey(String8("mock-signature"));
  554. if (index < 0) {
  555. ALOGD("Missing 'mock-request' parameter for mock");
  556. return BAD_VALUE;
  557. } else {
  558. signature = mByteArrayProperties.valueAt(index);
  559. }
  560. return OK;
  561. }
  562. status_t MockDrmPlugin::verify(Vector<uint8_t> const &sessionId,
  563. Vector<uint8_t> const &keyId,
  564. Vector<uint8_t> const &message,
  565. Vector<uint8_t> const &signature,
  566. bool &match)
  567. {
  568. Mutex::Autolock lock(mLock);
  569. ALOGD("MockDrmPlugin::verify(sessionId=%s, keyId=%s, message=%s, signature=%s)",
  570. vectorToString(sessionId).string(),
  571. vectorToString(keyId).string(),
  572. vectorToString(message).string(),
  573. vectorToString(signature).string());
  574. ssize_t index = findSession(sessionId);
  575. if (index == kNotFound) {
  576. ALOGD("Invalid sessionId");
  577. return BAD_VALUE;
  578. }
  579. // Properties used in mock test, set by mock plugin and verifed cts test app
  580. // byte[] keyId -> mock-keyid
  581. // byte[] message -> mock-message
  582. // byte[] signature -> mock-signature
  583. mByteArrayProperties.add(String8("mock-keyid"), keyId);
  584. mByteArrayProperties.add(String8("mock-message"), message);
  585. mByteArrayProperties.add(String8("mock-signature"), signature);
  586. // Properties used in mock test, set by cts test app returned from mock plugin
  587. // String mock-match "1" or "0" -> match
  588. index = mStringProperties.indexOfKey(String8("mock-match"));
  589. if (index < 0) {
  590. ALOGD("Missing 'mock-request' parameter for mock");
  591. return BAD_VALUE;
  592. } else {
  593. match = atol(mStringProperties.valueAt(index).string());
  594. }
  595. return OK;
  596. }
  597. status_t MockDrmPlugin::signRSA(Vector<uint8_t> const &sessionId,
  598. String8 const &algorithm,
  599. Vector<uint8_t> const &message,
  600. Vector<uint8_t> const &wrappedKey,
  601. Vector<uint8_t> &signature)
  602. {
  603. Mutex::Autolock lock(mLock);
  604. ALOGD("MockDrmPlugin::signRSA(sessionId=%s, algorithm=%s, keyId=%s, "
  605. "message=%s, signature=%s)",
  606. vectorToString(sessionId).string(),
  607. algorithm.string(),
  608. vectorToString(message).string(),
  609. vectorToString(wrappedKey).string(),
  610. vectorToString(signature).string());
  611. // Properties used in mock test, set by mock plugin and verifed cts test app
  612. // byte[] wrappedKey -> mock-wrappedkey
  613. // byte[] message -> mock-message
  614. // byte[] signature -> mock-signature
  615. mByteArrayProperties.add(String8("mock-sessionid"), sessionId);
  616. mStringProperties.add(String8("mock-algorithm"), algorithm);
  617. mByteArrayProperties.add(String8("mock-message"), message);
  618. mByteArrayProperties.add(String8("mock-wrappedkey"), wrappedKey);
  619. mByteArrayProperties.add(String8("mock-signature"), signature);
  620. return OK;
  621. }
  622. ssize_t MockDrmPlugin::findSession(Vector<uint8_t> const &sessionId) const
  623. {
  624. ALOGD("findSession: nsessions=%zu, size=%zu", mSessions.size(), sessionId.size());
  625. for (size_t i = 0; i < mSessions.size(); ++i) {
  626. if (memcmp(mSessions[i].array(), sessionId.array(), sessionId.size()) == 0) {
  627. return i;
  628. }
  629. }
  630. return kNotFound;
  631. }
  632. ssize_t MockDrmPlugin::findKeySet(Vector<uint8_t> const &keySetId) const
  633. {
  634. ALOGD("findKeySet: nkeySets=%zu, size=%zu", mKeySets.size(), keySetId.size());
  635. for (size_t i = 0; i < mKeySets.size(); ++i) {
  636. if (memcmp(mKeySets[i].array(), keySetId.array(), keySetId.size()) == 0) {
  637. return i;
  638. }
  639. }
  640. return kNotFound;
  641. }
  642. // Conversion utilities
  643. String8 MockDrmPlugin::vectorToString(Vector<uint8_t> const &vector) const
  644. {
  645. return arrayToString(vector.array(), vector.size());
  646. }
  647. String8 MockDrmPlugin::arrayToString(uint8_t const *array, size_t len) const
  648. {
  649. String8 result("{ ");
  650. for (size_t i = 0; i < len; i++) {
  651. result.appendFormat("0x%02x ", array[i]);
  652. }
  653. result += "}";
  654. return result;
  655. }
  656. String8 MockDrmPlugin::stringMapToString(const KeyedVector<String8, String8>& map) const
  657. {
  658. String8 result("{ ");
  659. for (size_t i = 0; i < map.size(); i++) {
  660. result.appendFormat("%s{name=%s, value=%s}", i > 0 ? ", " : "",
  661. map.keyAt(i).string(), map.valueAt(i).string());
  662. }
  663. return result + " }";
  664. }
  665. bool operator<(Vector<uint8_t> const &lhs, Vector<uint8_t> const &rhs) {
  666. return lhs.size() < rhs.size() || (memcmp(lhs.array(), rhs.array(), lhs.size()) < 0);
  667. }
  668. //
  669. // Crypto Plugin
  670. //
  671. bool MockCryptoPlugin::requiresSecureDecoderComponent(const char *mime) const
  672. {
  673. ALOGD("MockCryptoPlugin::requiresSecureDecoderComponent(mime=%s)", mime);
  674. return false;
  675. }
  676. ssize_t
  677. MockCryptoPlugin::decrypt(bool secure, const uint8_t key[DECRYPT_KEY_SIZE],
  678. const uint8_t iv[DECRYPT_KEY_SIZE], Mode mode,
  679. const Pattern &pattern, const void *srcPtr,
  680. const SubSample *subSamples, size_t numSubSamples,
  681. void *dstPtr, AString * /* errorDetailMsg */)
  682. {
  683. ALOGD("MockCryptoPlugin::decrypt(secure=%d, key=%s, iv=%s, mode=%d, "
  684. "pattern:{encryptBlocks=%d, skipBlocks=%d} src=%p, "
  685. "subSamples=%s, dst=%p)",
  686. (int)secure,
  687. arrayToString(key, DECRYPT_KEY_SIZE).string(),
  688. arrayToString(iv, DECRYPT_KEY_SIZE).string(),
  689. (int)mode, pattern.mEncryptBlocks, pattern.mSkipBlocks, srcPtr,
  690. subSamplesToString(subSamples, numSubSamples).string(),
  691. dstPtr);
  692. return OK;
  693. }
  694. // Conversion utilities
  695. String8 MockCryptoPlugin::arrayToString(uint8_t const *array, size_t len) const
  696. {
  697. String8 result("{ ");
  698. for (size_t i = 0; i < len; i++) {
  699. result.appendFormat("0x%02x ", array[i]);
  700. }
  701. result += "}";
  702. return result;
  703. }
  704. String8 MockCryptoPlugin::subSamplesToString(SubSample const *subSamples,
  705. size_t numSubSamples) const
  706. {
  707. String8 result;
  708. for (size_t i = 0; i < numSubSamples; i++) {
  709. result.appendFormat("[%zu] {clear:%u, encrypted:%u} ", i,
  710. subSamples[i].mNumBytesOfClearData,
  711. subSamples[i].mNumBytesOfEncryptedData);
  712. }
  713. return result;
  714. }
  715. };