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 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "IDrm"
19 #include <utils/Log.h>
20 
21 #include <binder/Parcel.h>
22 #include <media/IDrm.h>
23 #include <media/stagefright/MediaErrors.h>
24 #include <media/stagefright/foundation/ADebug.h>
25 #include <media/stagefright/foundation/AString.h>
26 
27 namespace android {
28 
29 enum {
30     INIT_CHECK = IBinder::FIRST_CALL_TRANSACTION,
31     IS_CRYPTO_SUPPORTED,
32     CREATE_PLUGIN,
33     DESTROY_PLUGIN,
34     OPEN_SESSION,
35     CLOSE_SESSION,
36     GET_KEY_REQUEST,
37     PROVIDE_KEY_RESPONSE,
38     REMOVE_KEYS,
39     RESTORE_KEYS,
40     QUERY_KEY_STATUS,
41     GET_PROVISION_REQUEST,
42     PROVIDE_PROVISION_RESPONSE,
43     GET_SECURE_STOPS,
44     RELEASE_SECURE_STOPS,
45     GET_PROPERTY_STRING,
46     GET_PROPERTY_BYTE_ARRAY,
47     SET_PROPERTY_STRING,
48     SET_PROPERTY_BYTE_ARRAY,
49     SET_CIPHER_ALGORITHM,
50     SET_MAC_ALGORITHM,
51     ENCRYPT,
52     DECRYPT,
53     SIGN,
54     SIGN_RSA,
55     VERIFY,
56     SET_LISTENER,
57     UNPROVISION_DEVICE,
58     GET_SECURE_STOP,
59     RELEASE_ALL_SECURE_STOPS
60 };
61 
62 struct BpDrm : public BpInterface<IDrm> {
BpDrmandroid::BpDrm63     BpDrm(const sp<IBinder> &impl)
64         : BpInterface<IDrm>(impl) {
65     }
66 
initCheckandroid::BpDrm67     virtual status_t initCheck() const {
68         Parcel data, reply;
69         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
70         status_t status = remote()->transact(INIT_CHECK, data, &reply);
71         if (status != OK) {
72             return status;
73         }
74 
75         return reply.readInt32();
76     }
77 
isCryptoSchemeSupportedandroid::BpDrm78     virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
79         Parcel data, reply;
80         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
81         data.write(uuid, 16);
82         data.writeString8(mimeType);
83         status_t status = remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
84         if (status != OK) {
85             ALOGE("isCryptoSchemeSupported: binder call failed: %d", status);
86             return false;
87         }
88 
89         return reply.readInt32() != 0;
90     }
91 
createPluginandroid::BpDrm92     virtual status_t createPlugin(const uint8_t uuid[16]) {
93         Parcel data, reply;
94         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
95         data.write(uuid, 16);
96 
97         status_t status = remote()->transact(CREATE_PLUGIN, data, &reply);
98         if (status != OK) {
99             return status;
100         }
101 
102         return reply.readInt32();
103     }
104 
destroyPluginandroid::BpDrm105     virtual status_t destroyPlugin() {
106         Parcel data, reply;
107         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
108         status_t status = remote()->transact(DESTROY_PLUGIN, data, &reply);
109         if (status != OK) {
110             return status;
111         }
112 
113         return reply.readInt32();
114     }
115 
openSessionandroid::BpDrm116     virtual status_t openSession(Vector<uint8_t> &sessionId) {
117         Parcel data, reply;
118         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
119 
120         status_t status = remote()->transact(OPEN_SESSION, data, &reply);
121         if (status != OK) {
122             return status;
123         }
124         readVector(reply, sessionId);
125 
126         return reply.readInt32();
127     }
128 
closeSessionandroid::BpDrm129     virtual status_t closeSession(Vector<uint8_t> const &sessionId) {
130         Parcel data, reply;
131         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
132 
133         writeVector(data, sessionId);
134         status_t status = remote()->transact(CLOSE_SESSION, data, &reply);
135         if (status != OK) {
136             return status;
137         }
138 
139         return reply.readInt32();
140     }
141 
142     virtual status_t
getKeyRequestandroid::BpDrm143         getKeyRequest(Vector<uint8_t> const &sessionId,
144                       Vector<uint8_t> const &initData,
145                       String8 const &mimeType, DrmPlugin::KeyType keyType,
146                       KeyedVector<String8, String8> const &optionalParameters,
147                       Vector<uint8_t> &request, String8 &defaultUrl,
148                       DrmPlugin::KeyRequestType *keyRequestType) {
149         Parcel data, reply;
150         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
151 
152         writeVector(data, sessionId);
153         writeVector(data, initData);
154         data.writeString8(mimeType);
155         data.writeInt32((uint32_t)keyType);
156 
157         data.writeInt32(optionalParameters.size());
158         for (size_t i = 0; i < optionalParameters.size(); ++i) {
159             data.writeString8(optionalParameters.keyAt(i));
160             data.writeString8(optionalParameters.valueAt(i));
161         }
162 
163         status_t status = remote()->transact(GET_KEY_REQUEST, data, &reply);
164         if (status != OK) {
165             return status;
166         }
167 
168         readVector(reply, request);
169         defaultUrl = reply.readString8();
170         *keyRequestType = static_cast<DrmPlugin::KeyRequestType>(reply.readInt32());
171 
172         return reply.readInt32();
173     }
174 
provideKeyResponseandroid::BpDrm175     virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
176                                         Vector<uint8_t> const &response,
177                                         Vector<uint8_t> &keySetId) {
178         Parcel data, reply;
179         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
180         writeVector(data, sessionId);
181         writeVector(data, response);
182 
183         status_t status = remote()->transact(PROVIDE_KEY_RESPONSE, data, &reply);
184         if (status != OK) {
185             return status;
186         }
187 
188         readVector(reply, keySetId);
189 
190         return reply.readInt32();
191     }
192 
removeKeysandroid::BpDrm193     virtual status_t removeKeys(Vector<uint8_t> const &keySetId) {
194         Parcel data, reply;
195         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
196 
197         writeVector(data, keySetId);
198         status_t status = remote()->transact(REMOVE_KEYS, data, &reply);
199         if (status != OK) {
200             return status;
201         }
202 
203         return reply.readInt32();
204     }
205 
restoreKeysandroid::BpDrm206     virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
207                                  Vector<uint8_t> const &keySetId) {
208         Parcel data, reply;
209         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
210 
211         writeVector(data, sessionId);
212         writeVector(data, keySetId);
213         status_t status = remote()->transact(RESTORE_KEYS, data, &reply);
214         if (status != OK) {
215             return status;
216         }
217 
218         return reply.readInt32();
219     }
220 
queryKeyStatusandroid::BpDrm221     virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
222                                         KeyedVector<String8, String8> &infoMap) const {
223         Parcel data, reply;
224         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
225 
226         writeVector(data, sessionId);
227         status_t status = remote()->transact(QUERY_KEY_STATUS, data, &reply);
228         if (status != OK) {
229             return status;
230         }
231 
232         infoMap.clear();
233         size_t count = reply.readInt32();
234         for (size_t i = 0; i < count; i++) {
235             String8 key = reply.readString8();
236             String8 value = reply.readString8();
237             infoMap.add(key, value);
238         }
239         return reply.readInt32();
240     }
241 
getProvisionRequestandroid::BpDrm242     virtual status_t getProvisionRequest(String8 const &certType,
243                                          String8 const &certAuthority,
244                                          Vector<uint8_t> &request,
245                                          String8 &defaultUrl) {
246         Parcel data, reply;
247         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
248 
249         data.writeString8(certType);
250         data.writeString8(certAuthority);
251         status_t status = remote()->transact(GET_PROVISION_REQUEST, data, &reply);
252         if (status != OK) {
253             return status;
254         }
255 
256         readVector(reply, request);
257         defaultUrl = reply.readString8();
258 
259         return reply.readInt32();
260     }
261 
provideProvisionResponseandroid::BpDrm262     virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
263                                               Vector<uint8_t> &certificate,
264                                               Vector<uint8_t> &wrappedKey) {
265         Parcel data, reply;
266         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
267 
268         writeVector(data, response);
269         status_t status = remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
270         if (status != OK) {
271             return status;
272         }
273 
274         readVector(reply, certificate);
275         readVector(reply, wrappedKey);
276 
277         return reply.readInt32();
278     }
279 
unprovisionDeviceandroid::BpDrm280     virtual status_t unprovisionDevice() {
281         Parcel data, reply;
282         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
283 
284         status_t status = remote()->transact(UNPROVISION_DEVICE, data, &reply);
285         if (status != OK) {
286             return status;
287         }
288 
289         return reply.readInt32();
290     }
291 
getSecureStopsandroid::BpDrm292     virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) {
293         Parcel data, reply;
294         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
295 
296         status_t status = remote()->transact(GET_SECURE_STOPS, data, &reply);
297         if (status != OK) {
298             return status;
299         }
300 
301         secureStops.clear();
302         uint32_t count = reply.readInt32();
303         for (size_t i = 0; i < count; i++) {
304             Vector<uint8_t> secureStop;
305             readVector(reply, secureStop);
306             secureStops.push_back(secureStop);
307         }
308         return reply.readInt32();
309     }
310 
getSecureStopandroid::BpDrm311     virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
312         Parcel data, reply;
313         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
314 
315         writeVector(data, ssid);
316         status_t status = remote()->transact(GET_SECURE_STOP, data, &reply);
317         if (status != OK) {
318             return status;
319         }
320 
321         readVector(reply, secureStop);
322         return reply.readInt32();
323     }
324 
releaseSecureStopsandroid::BpDrm325     virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) {
326         Parcel data, reply;
327         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
328 
329         writeVector(data, ssRelease);
330         status_t status = remote()->transact(RELEASE_SECURE_STOPS, data, &reply);
331         if (status != OK) {
332             return status;
333         }
334 
335         return reply.readInt32();
336     }
337 
releaseAllSecureStopsandroid::BpDrm338     virtual status_t releaseAllSecureStops() {
339         Parcel data, reply;
340         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
341 
342         status_t status = remote()->transact(RELEASE_ALL_SECURE_STOPS, data, &reply);
343         if (status != OK) {
344             return status;
345         }
346 
347         return reply.readInt32();
348     }
349 
getPropertyStringandroid::BpDrm350     virtual status_t getPropertyString(String8 const &name, String8 &value) const {
351         Parcel data, reply;
352         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
353 
354         data.writeString8(name);
355         status_t status = remote()->transact(GET_PROPERTY_STRING, data, &reply);
356         if (status != OK) {
357             return status;
358         }
359 
360         value = reply.readString8();
361         return reply.readInt32();
362     }
363 
getPropertyByteArrayandroid::BpDrm364     virtual status_t getPropertyByteArray(String8 const &name, Vector<uint8_t> &value) const {
365         Parcel data, reply;
366         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
367 
368         data.writeString8(name);
369         status_t status = remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply);
370         if (status != OK) {
371             return status;
372         }
373 
374         readVector(reply, value);
375         return reply.readInt32();
376     }
377 
setPropertyStringandroid::BpDrm378     virtual status_t setPropertyString(String8 const &name, String8 const &value) const {
379         Parcel data, reply;
380         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
381 
382         data.writeString8(name);
383         data.writeString8(value);
384         status_t status = remote()->transact(SET_PROPERTY_STRING, data, &reply);
385         if (status != OK) {
386             return status;
387         }
388 
389         return reply.readInt32();
390     }
391 
setPropertyByteArrayandroid::BpDrm392     virtual status_t setPropertyByteArray(String8 const &name,
393                                           Vector<uint8_t> const &value) const {
394         Parcel data, reply;
395         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
396 
397         data.writeString8(name);
398         writeVector(data, value);
399         status_t status = remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply);
400         if (status != OK) {
401             return status;
402         }
403 
404         return reply.readInt32();
405     }
406 
407 
setCipherAlgorithmandroid::BpDrm408     virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
409                                         String8 const &algorithm) {
410         Parcel data, reply;
411         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
412 
413         writeVector(data, sessionId);
414         data.writeString8(algorithm);
415         status_t status = remote()->transact(SET_CIPHER_ALGORITHM, data, &reply);
416         if (status != OK) {
417             return status;
418         }
419         return reply.readInt32();
420     }
421 
setMacAlgorithmandroid::BpDrm422     virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
423                                      String8 const &algorithm) {
424         Parcel data, reply;
425         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
426 
427         writeVector(data, sessionId);
428         data.writeString8(algorithm);
429         status_t status = remote()->transact(SET_MAC_ALGORITHM, data, &reply);
430         if (status != OK) {
431             return status;
432         }
433         return reply.readInt32();
434     }
435 
encryptandroid::BpDrm436     virtual status_t encrypt(Vector<uint8_t> const &sessionId,
437                              Vector<uint8_t> const &keyId,
438                              Vector<uint8_t> const &input,
439                              Vector<uint8_t> const &iv,
440                              Vector<uint8_t> &output) {
441         Parcel data, reply;
442         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
443 
444         writeVector(data, sessionId);
445         writeVector(data, keyId);
446         writeVector(data, input);
447         writeVector(data, iv);
448 
449         status_t status = remote()->transact(ENCRYPT, data, &reply);
450         if (status != OK) {
451             return status;
452         }
453         readVector(reply, output);
454 
455         return reply.readInt32();
456     }
457 
decryptandroid::BpDrm458     virtual status_t decrypt(Vector<uint8_t> const &sessionId,
459                              Vector<uint8_t> const &keyId,
460                              Vector<uint8_t> const &input,
461                              Vector<uint8_t> const &iv,
462                              Vector<uint8_t> &output) {
463         Parcel data, reply;
464         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
465 
466         writeVector(data, sessionId);
467         writeVector(data, keyId);
468         writeVector(data, input);
469         writeVector(data, iv);
470 
471         status_t status = remote()->transact(DECRYPT, data, &reply);
472         if (status != OK) {
473             return status;
474         }
475         readVector(reply, output);
476 
477         return reply.readInt32();
478     }
479 
signandroid::BpDrm480     virtual status_t sign(Vector<uint8_t> const &sessionId,
481                           Vector<uint8_t> const &keyId,
482                           Vector<uint8_t> const &message,
483                           Vector<uint8_t> &signature) {
484         Parcel data, reply;
485         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
486 
487         writeVector(data, sessionId);
488         writeVector(data, keyId);
489         writeVector(data, message);
490 
491         status_t status = remote()->transact(SIGN, data, &reply);
492         if (status != OK) {
493             return status;
494         }
495         readVector(reply, signature);
496 
497         return reply.readInt32();
498     }
499 
verifyandroid::BpDrm500     virtual status_t verify(Vector<uint8_t> const &sessionId,
501                             Vector<uint8_t> const &keyId,
502                             Vector<uint8_t> const &message,
503                             Vector<uint8_t> const &signature,
504                             bool &match) {
505         Parcel data, reply;
506         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
507 
508         writeVector(data, sessionId);
509         writeVector(data, keyId);
510         writeVector(data, message);
511         writeVector(data, signature);
512 
513         status_t status = remote()->transact(VERIFY, data, &reply);
514         if (status != OK) {
515             return status;
516         }
517         match = (bool)reply.readInt32();
518         return reply.readInt32();
519     }
520 
signRSAandroid::BpDrm521     virtual status_t signRSA(Vector<uint8_t> const &sessionId,
522                              String8 const &algorithm,
523                              Vector<uint8_t> const &message,
524                              Vector<uint8_t> const &wrappedKey,
525                              Vector<uint8_t> &signature) {
526         Parcel data, reply;
527         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
528 
529         writeVector(data, sessionId);
530         data.writeString8(algorithm);
531         writeVector(data, message);
532         writeVector(data, wrappedKey);
533 
534         status_t status = remote()->transact(SIGN_RSA, data, &reply);
535         if (status != OK) {
536             return status;
537         }
538         readVector(reply, signature);
539 
540         return reply.readInt32();
541     }
542 
setListenerandroid::BpDrm543     virtual status_t setListener(const sp<IDrmClient>& listener) {
544         Parcel data, reply;
545         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
546         data.writeStrongBinder(IInterface::asBinder(listener));
547         status_t status = remote()->transact(SET_LISTENER, data, &reply);
548         if (status != OK) {
549             return status;
550         }
551         return reply.readInt32();
552     }
553 
554 private:
readVectorandroid::BpDrm555     void readVector(Parcel &reply, Vector<uint8_t> &vector) const {
556         uint32_t size = reply.readInt32();
557         vector.insertAt((size_t)0, size);
558         reply.read(vector.editArray(), size);
559     }
560 
writeVectorandroid::BpDrm561     void writeVector(Parcel &data, Vector<uint8_t> const &vector) const {
562         data.writeInt32(vector.size());
563         data.write(vector.array(), vector.size());
564     }
565 
566     DISALLOW_EVIL_CONSTRUCTORS(BpDrm);
567 };
568 
569 IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm");
570 
571 ////////////////////////////////////////////////////////////////////////////////
572 
readVector(const Parcel & data,Vector<uint8_t> & vector) const573 void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
574     uint32_t size = data.readInt32();
575     vector.insertAt((size_t)0, size);
576     data.read(vector.editArray(), size);
577 }
578 
writeVector(Parcel * reply,Vector<uint8_t> const & vector) const579 void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
580     reply->writeInt32(vector.size());
581     reply->write(vector.array(), vector.size());
582 }
583 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)584 status_t BnDrm::onTransact(
585     uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
586     switch (code) {
587         case INIT_CHECK:
588         {
589             CHECK_INTERFACE(IDrm, data, reply);
590             reply->writeInt32(initCheck());
591             return OK;
592         }
593 
594         case IS_CRYPTO_SUPPORTED:
595         {
596             CHECK_INTERFACE(IDrm, data, reply);
597             uint8_t uuid[16];
598             data.read(uuid, sizeof(uuid));
599             String8 mimeType = data.readString8();
600             reply->writeInt32(isCryptoSchemeSupported(uuid, mimeType));
601 
602             return OK;
603         }
604 
605         case CREATE_PLUGIN:
606         {
607             CHECK_INTERFACE(IDrm, data, reply);
608             uint8_t uuid[16];
609             data.read(uuid, sizeof(uuid));
610             reply->writeInt32(createPlugin(uuid));
611             return OK;
612         }
613 
614         case DESTROY_PLUGIN:
615         {
616             CHECK_INTERFACE(IDrm, data, reply);
617             reply->writeInt32(destroyPlugin());
618             return OK;
619         }
620 
621         case OPEN_SESSION:
622         {
623             CHECK_INTERFACE(IDrm, data, reply);
624             Vector<uint8_t> sessionId;
625             status_t result = openSession(sessionId);
626             writeVector(reply, sessionId);
627             reply->writeInt32(result);
628             return OK;
629         }
630 
631         case CLOSE_SESSION:
632         {
633             CHECK_INTERFACE(IDrm, data, reply);
634             Vector<uint8_t> sessionId;
635             readVector(data, sessionId);
636             reply->writeInt32(closeSession(sessionId));
637             return OK;
638         }
639 
640         case GET_KEY_REQUEST:
641         {
642             CHECK_INTERFACE(IDrm, data, reply);
643             Vector<uint8_t> sessionId, initData;
644 
645             readVector(data, sessionId);
646             readVector(data, initData);
647             String8 mimeType = data.readString8();
648             DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)data.readInt32();
649 
650             KeyedVector<String8, String8> optionalParameters;
651             uint32_t count = data.readInt32();
652             for (size_t i = 0; i < count; ++i) {
653                 String8 key, value;
654                 key = data.readString8();
655                 value = data.readString8();
656                 optionalParameters.add(key, value);
657             }
658 
659             Vector<uint8_t> request;
660             String8 defaultUrl;
661             DrmPlugin::KeyRequestType keyRequestType;
662 
663             status_t result = getKeyRequest(sessionId, initData, mimeType,
664                     keyType, optionalParameters, request, defaultUrl,
665                     &keyRequestType);
666 
667             writeVector(reply, request);
668             reply->writeString8(defaultUrl);
669             reply->writeInt32(static_cast<int32_t>(keyRequestType));
670             reply->writeInt32(result);
671             return OK;
672         }
673 
674         case PROVIDE_KEY_RESPONSE:
675         {
676             CHECK_INTERFACE(IDrm, data, reply);
677             Vector<uint8_t> sessionId, response, keySetId;
678             readVector(data, sessionId);
679             readVector(data, response);
680             uint32_t result = provideKeyResponse(sessionId, response, keySetId);
681             writeVector(reply, keySetId);
682             reply->writeInt32(result);
683             return OK;
684         }
685 
686         case REMOVE_KEYS:
687         {
688             CHECK_INTERFACE(IDrm, data, reply);
689             Vector<uint8_t> keySetId;
690             readVector(data, keySetId);
691             reply->writeInt32(removeKeys(keySetId));
692             return OK;
693         }
694 
695         case RESTORE_KEYS:
696         {
697             CHECK_INTERFACE(IDrm, data, reply);
698             Vector<uint8_t> sessionId, keySetId;
699             readVector(data, sessionId);
700             readVector(data, keySetId);
701             reply->writeInt32(restoreKeys(sessionId, keySetId));
702             return OK;
703         }
704 
705         case QUERY_KEY_STATUS:
706         {
707             CHECK_INTERFACE(IDrm, data, reply);
708             Vector<uint8_t> sessionId;
709             readVector(data, sessionId);
710             KeyedVector<String8, String8> infoMap;
711             status_t result = queryKeyStatus(sessionId, infoMap);
712             size_t count = infoMap.size();
713             reply->writeInt32(count);
714             for (size_t i = 0; i < count; ++i) {
715                 reply->writeString8(infoMap.keyAt(i));
716                 reply->writeString8(infoMap.valueAt(i));
717             }
718             reply->writeInt32(result);
719             return OK;
720         }
721 
722         case GET_PROVISION_REQUEST:
723         {
724             CHECK_INTERFACE(IDrm, data, reply);
725             String8 certType = data.readString8();
726             String8 certAuthority = data.readString8();
727 
728             Vector<uint8_t> request;
729             String8 defaultUrl;
730             status_t result = getProvisionRequest(certType, certAuthority,
731                                                   request, defaultUrl);
732             writeVector(reply, request);
733             reply->writeString8(defaultUrl);
734             reply->writeInt32(result);
735             return OK;
736         }
737 
738         case PROVIDE_PROVISION_RESPONSE:
739         {
740             CHECK_INTERFACE(IDrm, data, reply);
741             Vector<uint8_t> response;
742             Vector<uint8_t> certificate;
743             Vector<uint8_t> wrappedKey;
744             readVector(data, response);
745             status_t result = provideProvisionResponse(response, certificate, wrappedKey);
746             writeVector(reply, certificate);
747             writeVector(reply, wrappedKey);
748             reply->writeInt32(result);
749             return OK;
750         }
751 
752         case UNPROVISION_DEVICE:
753         {
754             CHECK_INTERFACE(IDrm, data, reply);
755             status_t result = unprovisionDevice();
756             reply->writeInt32(result);
757             return OK;
758         }
759 
760         case GET_SECURE_STOPS:
761         {
762             CHECK_INTERFACE(IDrm, data, reply);
763             List<Vector<uint8_t> > secureStops;
764             status_t result = getSecureStops(secureStops);
765             size_t count = secureStops.size();
766             reply->writeInt32(count);
767             List<Vector<uint8_t> >::iterator iter = secureStops.begin();
768             while(iter != secureStops.end()) {
769                 size_t size = iter->size();
770                 reply->writeInt32(size);
771                 reply->write(iter->array(), iter->size());
772                 iter++;
773             }
774             reply->writeInt32(result);
775             return OK;
776         }
777 
778         case GET_SECURE_STOP:
779         {
780             CHECK_INTERFACE(IDrm, data, reply);
781             Vector<uint8_t> ssid, secureStop;
782             readVector(data, ssid);
783             status_t result = getSecureStop(ssid, secureStop);
784             writeVector(reply, secureStop);
785             reply->writeInt32(result);
786             return OK;
787         }
788 
789         case RELEASE_SECURE_STOPS:
790         {
791             CHECK_INTERFACE(IDrm, data, reply);
792             Vector<uint8_t> ssRelease;
793             readVector(data, ssRelease);
794             reply->writeInt32(releaseSecureStops(ssRelease));
795             return OK;
796         }
797 
798         case RELEASE_ALL_SECURE_STOPS:
799         {
800             CHECK_INTERFACE(IDrm, data, reply);
801             reply->writeInt32(releaseAllSecureStops());
802             return OK;
803         }
804 
805         case GET_PROPERTY_STRING:
806         {
807             CHECK_INTERFACE(IDrm, data, reply);
808             String8 name = data.readString8();
809             String8 value;
810             status_t result = getPropertyString(name, value);
811             reply->writeString8(value);
812             reply->writeInt32(result);
813             return OK;
814         }
815 
816         case GET_PROPERTY_BYTE_ARRAY:
817         {
818             CHECK_INTERFACE(IDrm, data, reply);
819             String8 name = data.readString8();
820             Vector<uint8_t> value;
821             status_t result = getPropertyByteArray(name, value);
822             writeVector(reply, value);
823             reply->writeInt32(result);
824             return OK;
825         }
826 
827         case SET_PROPERTY_STRING:
828         {
829             CHECK_INTERFACE(IDrm, data, reply);
830             String8 name = data.readString8();
831             String8 value = data.readString8();
832             reply->writeInt32(setPropertyString(name, value));
833             return OK;
834         }
835 
836         case SET_PROPERTY_BYTE_ARRAY:
837         {
838             CHECK_INTERFACE(IDrm, data, reply);
839             String8 name = data.readString8();
840             Vector<uint8_t> value;
841             readVector(data, value);
842             reply->writeInt32(setPropertyByteArray(name, value));
843             return OK;
844         }
845 
846         case SET_CIPHER_ALGORITHM:
847         {
848             CHECK_INTERFACE(IDrm, data, reply);
849             Vector<uint8_t> sessionId;
850             readVector(data, sessionId);
851             String8 algorithm = data.readString8();
852             reply->writeInt32(setCipherAlgorithm(sessionId, algorithm));
853             return OK;
854         }
855 
856         case SET_MAC_ALGORITHM:
857         {
858             CHECK_INTERFACE(IDrm, data, reply);
859             Vector<uint8_t> sessionId;
860             readVector(data, sessionId);
861             String8 algorithm = data.readString8();
862             reply->writeInt32(setMacAlgorithm(sessionId, algorithm));
863             return OK;
864         }
865 
866         case ENCRYPT:
867         {
868             CHECK_INTERFACE(IDrm, data, reply);
869             Vector<uint8_t> sessionId, keyId, input, iv, output;
870             readVector(data, sessionId);
871             readVector(data, keyId);
872             readVector(data, input);
873             readVector(data, iv);
874             uint32_t result = encrypt(sessionId, keyId, input, iv, output);
875             writeVector(reply, output);
876             reply->writeInt32(result);
877             return OK;
878         }
879 
880         case DECRYPT:
881         {
882             CHECK_INTERFACE(IDrm, data, reply);
883             Vector<uint8_t> sessionId, keyId, input, iv, output;
884             readVector(data, sessionId);
885             readVector(data, keyId);
886             readVector(data, input);
887             readVector(data, iv);
888             uint32_t result = decrypt(sessionId, keyId, input, iv, output);
889             writeVector(reply, output);
890             reply->writeInt32(result);
891             return OK;
892         }
893 
894         case SIGN:
895         {
896             CHECK_INTERFACE(IDrm, data, reply);
897             Vector<uint8_t> sessionId, keyId, message, signature;
898             readVector(data, sessionId);
899             readVector(data, keyId);
900             readVector(data, message);
901             uint32_t result = sign(sessionId, keyId, message, signature);
902             writeVector(reply, signature);
903             reply->writeInt32(result);
904             return OK;
905         }
906 
907         case VERIFY:
908         {
909             CHECK_INTERFACE(IDrm, data, reply);
910             Vector<uint8_t> sessionId, keyId, message, signature;
911             readVector(data, sessionId);
912             readVector(data, keyId);
913             readVector(data, message);
914             readVector(data, signature);
915             bool match;
916             uint32_t result = verify(sessionId, keyId, message, signature, match);
917             reply->writeInt32(match);
918             reply->writeInt32(result);
919             return OK;
920         }
921 
922         case SIGN_RSA:
923         {
924             CHECK_INTERFACE(IDrm, data, reply);
925             Vector<uint8_t> sessionId, message, wrappedKey, signature;
926             readVector(data, sessionId);
927             String8 algorithm = data.readString8();
928             readVector(data, message);
929             readVector(data, wrappedKey);
930             uint32_t result = signRSA(sessionId, algorithm, message, wrappedKey, signature);
931             writeVector(reply, signature);
932             reply->writeInt32(result);
933             return OK;
934         }
935 
936     case SET_LISTENER: {
937         CHECK_INTERFACE(IDrm, data, reply);
938         sp<IDrmClient> listener =
939             interface_cast<IDrmClient>(data.readStrongBinder());
940         reply->writeInt32(setListener(listener));
941         return NO_ERROR;
942     } break;
943 
944     default:
945         return BBinder::onTransact(code, data, reply, flags);
946     }
947 }
948 
949 }  // namespace android
950