IDrm.cpp revision 68b15554f6dca3b056eac517fe5fa2fd4ee80a33
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
27namespace android {
28
29enum {
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};
59
60struct BpDrm : public BpInterface<IDrm> {
61    BpDrm(const sp<IBinder> &impl)
62        : BpInterface<IDrm>(impl) {
63    }
64
65    virtual status_t initCheck() const {
66        Parcel data, reply;
67        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
68        remote()->transact(INIT_CHECK, data, &reply);
69
70        return reply.readInt32();
71    }
72
73    virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
74        Parcel data, reply;
75        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
76        data.write(uuid, 16);
77        data.writeString8(mimeType);
78        remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
79
80        return reply.readInt32() != 0;
81    }
82
83    virtual status_t createPlugin(const uint8_t uuid[16]) {
84        Parcel data, reply;
85        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
86        data.write(uuid, 16);
87
88        remote()->transact(CREATE_PLUGIN, data, &reply);
89
90        return reply.readInt32();
91    }
92
93    virtual status_t destroyPlugin() {
94        Parcel data, reply;
95        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
96        remote()->transact(DESTROY_PLUGIN, data, &reply);
97
98        return reply.readInt32();
99    }
100
101    virtual status_t openSession(Vector<uint8_t> &sessionId) {
102        Parcel data, reply;
103        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
104
105        remote()->transact(OPEN_SESSION, data, &reply);
106        readVector(reply, sessionId);
107
108        return reply.readInt32();
109    }
110
111    virtual status_t closeSession(Vector<uint8_t> const &sessionId) {
112        Parcel data, reply;
113        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
114
115        writeVector(data, sessionId);
116        remote()->transact(CLOSE_SESSION, data, &reply);
117
118        return reply.readInt32();
119    }
120
121    virtual status_t
122        getKeyRequest(Vector<uint8_t> const &sessionId,
123                      Vector<uint8_t> const &initData,
124                      String8 const &mimeType, DrmPlugin::KeyType keyType,
125                      KeyedVector<String8, String8> const &optionalParameters,
126                      Vector<uint8_t> &request, String8 &defaultUrl) {
127        Parcel data, reply;
128        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
129
130        writeVector(data, sessionId);
131        writeVector(data, initData);
132        data.writeString8(mimeType);
133        data.writeInt32((uint32_t)keyType);
134
135        data.writeInt32(optionalParameters.size());
136        for (size_t i = 0; i < optionalParameters.size(); ++i) {
137            data.writeString8(optionalParameters.keyAt(i));
138            data.writeString8(optionalParameters.valueAt(i));
139        }
140        remote()->transact(GET_KEY_REQUEST, data, &reply);
141
142        readVector(reply, request);
143        defaultUrl = reply.readString8();
144
145        return reply.readInt32();
146    }
147
148    virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
149                                        Vector<uint8_t> const &response,
150                                        Vector<uint8_t> &keySetId) {
151        Parcel data, reply;
152        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
153        writeVector(data, sessionId);
154        writeVector(data, response);
155        remote()->transact(PROVIDE_KEY_RESPONSE, data, &reply);
156        readVector(reply, keySetId);
157
158        return reply.readInt32();
159    }
160
161    virtual status_t removeKeys(Vector<uint8_t> const &keySetId) {
162        Parcel data, reply;
163        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
164
165        writeVector(data, keySetId);
166        remote()->transact(REMOVE_KEYS, data, &reply);
167
168        return reply.readInt32();
169    }
170
171    virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
172                                 Vector<uint8_t> const &keySetId) {
173        Parcel data, reply;
174        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
175
176        writeVector(data, sessionId);
177        writeVector(data, keySetId);
178        remote()->transact(RESTORE_KEYS, data, &reply);
179
180        return reply.readInt32();
181    }
182
183    virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
184                                        KeyedVector<String8, String8> &infoMap) const {
185        Parcel data, reply;
186        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
187
188        writeVector(data, sessionId);
189        remote()->transact(QUERY_KEY_STATUS, data, &reply);
190
191        infoMap.clear();
192        size_t count = reply.readInt32();
193        for (size_t i = 0; i < count; i++) {
194            String8 key = reply.readString8();
195            String8 value = reply.readString8();
196            infoMap.add(key, value);
197        }
198        return reply.readInt32();
199    }
200
201    virtual status_t getProvisionRequest(String8 const &certType,
202                                         String8 const &certAuthority,
203                                         Vector<uint8_t> &request,
204                                         String8 &defaultUrl) {
205        Parcel data, reply;
206        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
207
208        data.writeString8(certType);
209        data.writeString8(certAuthority);
210        remote()->transact(GET_PROVISION_REQUEST, data, &reply);
211
212        readVector(reply, request);
213        defaultUrl = reply.readString8();
214
215        return reply.readInt32();
216    }
217
218    virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
219                                              Vector<uint8_t> &certificate,
220                                              Vector<uint8_t> &wrappedKey) {
221        Parcel data, reply;
222        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
223
224        writeVector(data, response);
225        remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
226
227        readVector(reply, certificate);
228        readVector(reply, wrappedKey);
229
230        return reply.readInt32();
231    }
232
233    virtual status_t unprovisionDevice() {
234        Parcel data, reply;
235        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
236
237        remote()->transact(UNPROVISION_DEVICE, data, &reply);
238
239        return reply.readInt32();
240    }
241
242    virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) {
243        Parcel data, reply;
244        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
245
246        remote()->transact(GET_SECURE_STOPS, data, &reply);
247
248        secureStops.clear();
249        uint32_t count = reply.readInt32();
250        for (size_t i = 0; i < count; i++) {
251            Vector<uint8_t> secureStop;
252            readVector(reply, secureStop);
253            secureStops.push_back(secureStop);
254        }
255        return reply.readInt32();
256    }
257
258    virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) {
259        Parcel data, reply;
260        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
261
262        writeVector(data, ssRelease);
263        remote()->transact(RELEASE_SECURE_STOPS, data, &reply);
264
265        return reply.readInt32();
266    }
267
268    virtual status_t getPropertyString(String8 const &name, String8 &value) const {
269        Parcel data, reply;
270        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
271
272        data.writeString8(name);
273        remote()->transact(GET_PROPERTY_STRING, data, &reply);
274
275        value = reply.readString8();
276        return reply.readInt32();
277    }
278
279    virtual status_t getPropertyByteArray(String8 const &name, Vector<uint8_t> &value) const {
280        Parcel data, reply;
281        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
282
283        data.writeString8(name);
284        remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply);
285
286        readVector(reply, value);
287        return reply.readInt32();
288    }
289
290    virtual status_t setPropertyString(String8 const &name, String8 const &value) const {
291        Parcel data, reply;
292        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
293
294        data.writeString8(name);
295        data.writeString8(value);
296        remote()->transact(SET_PROPERTY_STRING, data, &reply);
297
298        return reply.readInt32();
299    }
300
301    virtual status_t setPropertyByteArray(String8 const &name,
302                                          Vector<uint8_t> const &value) const {
303        Parcel data, reply;
304        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
305
306        data.writeString8(name);
307        writeVector(data, value);
308        remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply);
309
310        return reply.readInt32();
311    }
312
313
314    virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
315                                        String8 const &algorithm) {
316        Parcel data, reply;
317        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
318
319        writeVector(data, sessionId);
320        data.writeString8(algorithm);
321        remote()->transact(SET_CIPHER_ALGORITHM, data, &reply);
322        return reply.readInt32();
323    }
324
325    virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
326                                     String8 const &algorithm) {
327        Parcel data, reply;
328        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
329
330        writeVector(data, sessionId);
331        data.writeString8(algorithm);
332        remote()->transact(SET_MAC_ALGORITHM, data, &reply);
333        return reply.readInt32();
334    }
335
336    virtual status_t encrypt(Vector<uint8_t> const &sessionId,
337                             Vector<uint8_t> const &keyId,
338                             Vector<uint8_t> const &input,
339                             Vector<uint8_t> const &iv,
340                             Vector<uint8_t> &output) {
341        Parcel data, reply;
342        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
343
344        writeVector(data, sessionId);
345        writeVector(data, keyId);
346        writeVector(data, input);
347        writeVector(data, iv);
348
349        remote()->transact(ENCRYPT, data, &reply);
350        readVector(reply, output);
351
352        return reply.readInt32();
353    }
354
355    virtual status_t decrypt(Vector<uint8_t> const &sessionId,
356                             Vector<uint8_t> const &keyId,
357                             Vector<uint8_t> const &input,
358                             Vector<uint8_t> const &iv,
359                             Vector<uint8_t> &output) {
360        Parcel data, reply;
361        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
362
363        writeVector(data, sessionId);
364        writeVector(data, keyId);
365        writeVector(data, input);
366        writeVector(data, iv);
367
368        remote()->transact(DECRYPT, data, &reply);
369        readVector(reply, output);
370
371        return reply.readInt32();
372    }
373
374    virtual status_t sign(Vector<uint8_t> const &sessionId,
375                          Vector<uint8_t> const &keyId,
376                          Vector<uint8_t> const &message,
377                          Vector<uint8_t> &signature) {
378        Parcel data, reply;
379        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
380
381        writeVector(data, sessionId);
382        writeVector(data, keyId);
383        writeVector(data, message);
384
385        remote()->transact(SIGN, data, &reply);
386        readVector(reply, signature);
387
388        return reply.readInt32();
389    }
390
391    virtual status_t verify(Vector<uint8_t> const &sessionId,
392                            Vector<uint8_t> const &keyId,
393                            Vector<uint8_t> const &message,
394                            Vector<uint8_t> const &signature,
395                            bool &match) {
396        Parcel data, reply;
397        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
398
399        writeVector(data, sessionId);
400        writeVector(data, keyId);
401        writeVector(data, message);
402        writeVector(data, signature);
403
404        remote()->transact(VERIFY, data, &reply);
405        match = (bool)reply.readInt32();
406        return reply.readInt32();
407    }
408
409    virtual status_t signRSA(Vector<uint8_t> const &sessionId,
410                             String8 const &algorithm,
411                             Vector<uint8_t> const &message,
412                             Vector<uint8_t> const &wrappedKey,
413                             Vector<uint8_t> &signature) {
414        Parcel data, reply;
415        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
416
417        writeVector(data, sessionId);
418        data.writeString8(algorithm);
419        writeVector(data, message);
420        writeVector(data, wrappedKey);
421
422        remote()->transact(SIGN_RSA, data, &reply);
423        readVector(reply, signature);
424
425        return reply.readInt32();
426    }
427
428    virtual status_t setListener(const sp<IDrmClient>& listener) {
429        Parcel data, reply;
430        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
431        data.writeStrongBinder(listener->asBinder());
432        remote()->transact(SET_LISTENER, data, &reply);
433        return reply.readInt32();
434    }
435
436private:
437    void readVector(Parcel &reply, Vector<uint8_t> &vector) const {
438        uint32_t size = reply.readInt32();
439        vector.insertAt((size_t)0, size);
440        reply.read(vector.editArray(), size);
441    }
442
443    void writeVector(Parcel &data, Vector<uint8_t> const &vector) const {
444        data.writeInt32(vector.size());
445        data.write(vector.array(), vector.size());
446    }
447
448    DISALLOW_EVIL_CONSTRUCTORS(BpDrm);
449};
450
451IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm");
452
453////////////////////////////////////////////////////////////////////////////////
454
455void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
456    uint32_t size = data.readInt32();
457    vector.insertAt((size_t)0, size);
458    data.read(vector.editArray(), size);
459}
460
461void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
462    reply->writeInt32(vector.size());
463    reply->write(vector.array(), vector.size());
464}
465
466status_t BnDrm::onTransact(
467    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
468    switch (code) {
469        case INIT_CHECK:
470        {
471            CHECK_INTERFACE(IDrm, data, reply);
472            reply->writeInt32(initCheck());
473            return OK;
474        }
475
476        case IS_CRYPTO_SUPPORTED:
477        {
478            CHECK_INTERFACE(IDrm, data, reply);
479            uint8_t uuid[16];
480            data.read(uuid, sizeof(uuid));
481            String8 mimeType = data.readString8();
482            reply->writeInt32(isCryptoSchemeSupported(uuid, mimeType));
483
484            return OK;
485        }
486
487        case CREATE_PLUGIN:
488        {
489            CHECK_INTERFACE(IDrm, data, reply);
490            uint8_t uuid[16];
491            data.read(uuid, sizeof(uuid));
492            reply->writeInt32(createPlugin(uuid));
493            return OK;
494        }
495
496        case DESTROY_PLUGIN:
497        {
498            CHECK_INTERFACE(IDrm, data, reply);
499            reply->writeInt32(destroyPlugin());
500            return OK;
501        }
502
503        case OPEN_SESSION:
504        {
505            CHECK_INTERFACE(IDrm, data, reply);
506            Vector<uint8_t> sessionId;
507            status_t result = openSession(sessionId);
508            writeVector(reply, sessionId);
509            reply->writeInt32(result);
510            return OK;
511        }
512
513        case CLOSE_SESSION:
514        {
515            CHECK_INTERFACE(IDrm, data, reply);
516            Vector<uint8_t> sessionId;
517            readVector(data, sessionId);
518            reply->writeInt32(closeSession(sessionId));
519            return OK;
520        }
521
522        case GET_KEY_REQUEST:
523        {
524            CHECK_INTERFACE(IDrm, data, reply);
525            Vector<uint8_t> sessionId, initData;
526
527            readVector(data, sessionId);
528            readVector(data, initData);
529            String8 mimeType = data.readString8();
530            DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)data.readInt32();
531
532            KeyedVector<String8, String8> optionalParameters;
533            uint32_t count = data.readInt32();
534            for (size_t i = 0; i < count; ++i) {
535                String8 key, value;
536                key = data.readString8();
537                value = data.readString8();
538                optionalParameters.add(key, value);
539            }
540
541            Vector<uint8_t> request;
542            String8 defaultUrl;
543
544            status_t result = getKeyRequest(sessionId, initData,
545                                            mimeType, keyType,
546                                            optionalParameters,
547                                            request, defaultUrl);
548            writeVector(reply, request);
549            reply->writeString8(defaultUrl);
550            reply->writeInt32(result);
551            return OK;
552        }
553
554        case PROVIDE_KEY_RESPONSE:
555        {
556            CHECK_INTERFACE(IDrm, data, reply);
557            Vector<uint8_t> sessionId, response, keySetId;
558            readVector(data, sessionId);
559            readVector(data, response);
560            uint32_t result = provideKeyResponse(sessionId, response, keySetId);
561            writeVector(reply, keySetId);
562            reply->writeInt32(result);
563            return OK;
564        }
565
566        case REMOVE_KEYS:
567        {
568            CHECK_INTERFACE(IDrm, data, reply);
569            Vector<uint8_t> keySetId;
570            readVector(data, keySetId);
571            reply->writeInt32(removeKeys(keySetId));
572            return OK;
573        }
574
575        case RESTORE_KEYS:
576        {
577            CHECK_INTERFACE(IDrm, data, reply);
578            Vector<uint8_t> sessionId, keySetId;
579            readVector(data, sessionId);
580            readVector(data, keySetId);
581            reply->writeInt32(restoreKeys(sessionId, keySetId));
582            return OK;
583        }
584
585        case QUERY_KEY_STATUS:
586        {
587            CHECK_INTERFACE(IDrm, data, reply);
588            Vector<uint8_t> sessionId;
589            readVector(data, sessionId);
590            KeyedVector<String8, String8> infoMap;
591            status_t result = queryKeyStatus(sessionId, infoMap);
592            size_t count = infoMap.size();
593            reply->writeInt32(count);
594            for (size_t i = 0; i < count; ++i) {
595                reply->writeString8(infoMap.keyAt(i));
596                reply->writeString8(infoMap.valueAt(i));
597            }
598            reply->writeInt32(result);
599            return OK;
600        }
601
602        case GET_PROVISION_REQUEST:
603        {
604            CHECK_INTERFACE(IDrm, data, reply);
605            String8 certType = data.readString8();
606            String8 certAuthority = data.readString8();
607
608            Vector<uint8_t> request;
609            String8 defaultUrl;
610            status_t result = getProvisionRequest(certType, certAuthority,
611                                                  request, defaultUrl);
612            writeVector(reply, request);
613            reply->writeString8(defaultUrl);
614            reply->writeInt32(result);
615            return OK;
616        }
617
618        case PROVIDE_PROVISION_RESPONSE:
619        {
620            CHECK_INTERFACE(IDrm, data, reply);
621            Vector<uint8_t> response;
622            Vector<uint8_t> certificate;
623            Vector<uint8_t> wrappedKey;
624            readVector(data, response);
625            status_t result = provideProvisionResponse(response, certificate, wrappedKey);
626            writeVector(reply, certificate);
627            writeVector(reply, wrappedKey);
628            reply->writeInt32(result);
629            return OK;
630        }
631
632        case UNPROVISION_DEVICE:
633        {
634            CHECK_INTERFACE(IDrm, data, reply);
635            status_t result = unprovisionDevice();
636            reply->writeInt32(result);
637            return OK;
638        }
639
640        case GET_SECURE_STOPS:
641        {
642            CHECK_INTERFACE(IDrm, data, reply);
643            List<Vector<uint8_t> > secureStops;
644            status_t result = getSecureStops(secureStops);
645            size_t count = secureStops.size();
646            reply->writeInt32(count);
647            List<Vector<uint8_t> >::iterator iter = secureStops.begin();
648            while(iter != secureStops.end()) {
649                size_t size = iter->size();
650                reply->writeInt32(size);
651                reply->write(iter->array(), iter->size());
652                iter++;
653            }
654            reply->writeInt32(result);
655            return OK;
656        }
657
658        case RELEASE_SECURE_STOPS:
659        {
660            CHECK_INTERFACE(IDrm, data, reply);
661            Vector<uint8_t> ssRelease;
662            readVector(data, ssRelease);
663            reply->writeInt32(releaseSecureStops(ssRelease));
664            return OK;
665        }
666
667        case GET_PROPERTY_STRING:
668        {
669            CHECK_INTERFACE(IDrm, data, reply);
670            String8 name = data.readString8();
671            String8 value;
672            status_t result = getPropertyString(name, value);
673            reply->writeString8(value);
674            reply->writeInt32(result);
675            return OK;
676        }
677
678        case GET_PROPERTY_BYTE_ARRAY:
679        {
680            CHECK_INTERFACE(IDrm, data, reply);
681            String8 name = data.readString8();
682            Vector<uint8_t> value;
683            status_t result = getPropertyByteArray(name, value);
684            writeVector(reply, value);
685            reply->writeInt32(result);
686            return OK;
687        }
688
689        case SET_PROPERTY_STRING:
690        {
691            CHECK_INTERFACE(IDrm, data, reply);
692            String8 name = data.readString8();
693            String8 value = data.readString8();
694            reply->writeInt32(setPropertyString(name, value));
695            return OK;
696        }
697
698        case SET_PROPERTY_BYTE_ARRAY:
699        {
700            CHECK_INTERFACE(IDrm, data, reply);
701            String8 name = data.readString8();
702            Vector<uint8_t> value;
703            readVector(data, value);
704            reply->writeInt32(setPropertyByteArray(name, value));
705            return OK;
706        }
707
708        case SET_CIPHER_ALGORITHM:
709        {
710            CHECK_INTERFACE(IDrm, data, reply);
711            Vector<uint8_t> sessionId;
712            readVector(data, sessionId);
713            String8 algorithm = data.readString8();
714            reply->writeInt32(setCipherAlgorithm(sessionId, algorithm));
715            return OK;
716        }
717
718        case SET_MAC_ALGORITHM:
719        {
720            CHECK_INTERFACE(IDrm, data, reply);
721            Vector<uint8_t> sessionId;
722            readVector(data, sessionId);
723            String8 algorithm = data.readString8();
724            reply->writeInt32(setMacAlgorithm(sessionId, algorithm));
725            return OK;
726        }
727
728        case ENCRYPT:
729        {
730            CHECK_INTERFACE(IDrm, data, reply);
731            Vector<uint8_t> sessionId, keyId, input, iv, output;
732            readVector(data, sessionId);
733            readVector(data, keyId);
734            readVector(data, input);
735            readVector(data, iv);
736            uint32_t result = encrypt(sessionId, keyId, input, iv, output);
737            writeVector(reply, output);
738            reply->writeInt32(result);
739            return OK;
740        }
741
742        case DECRYPT:
743        {
744            CHECK_INTERFACE(IDrm, data, reply);
745            Vector<uint8_t> sessionId, keyId, input, iv, output;
746            readVector(data, sessionId);
747            readVector(data, keyId);
748            readVector(data, input);
749            readVector(data, iv);
750            uint32_t result = decrypt(sessionId, keyId, input, iv, output);
751            writeVector(reply, output);
752            reply->writeInt32(result);
753            return OK;
754        }
755
756        case SIGN:
757        {
758            CHECK_INTERFACE(IDrm, data, reply);
759            Vector<uint8_t> sessionId, keyId, message, signature;
760            readVector(data, sessionId);
761            readVector(data, keyId);
762            readVector(data, message);
763            uint32_t result = sign(sessionId, keyId, message, signature);
764            writeVector(reply, signature);
765            reply->writeInt32(result);
766            return OK;
767        }
768
769        case VERIFY:
770        {
771            CHECK_INTERFACE(IDrm, data, reply);
772            Vector<uint8_t> sessionId, keyId, message, signature;
773            readVector(data, sessionId);
774            readVector(data, keyId);
775            readVector(data, message);
776            readVector(data, signature);
777            bool match;
778            uint32_t result = verify(sessionId, keyId, message, signature, match);
779            reply->writeInt32(match);
780            reply->writeInt32(result);
781            return OK;
782        }
783
784        case SIGN_RSA:
785        {
786            CHECK_INTERFACE(IDrm, data, reply);
787            Vector<uint8_t> sessionId, message, wrappedKey, signature;
788            readVector(data, sessionId);
789            String8 algorithm = data.readString8();
790            readVector(data, message);
791            readVector(data, wrappedKey);
792            uint32_t result = signRSA(sessionId, algorithm, message, wrappedKey, signature);
793            writeVector(reply, signature);
794            reply->writeInt32(result);
795            return OK;
796        }
797
798    case SET_LISTENER: {
799        CHECK_INTERFACE(IDrm, data, reply);
800        sp<IDrmClient> listener =
801            interface_cast<IDrmClient>(data.readStrongBinder());
802        reply->writeInt32(setListener(listener));
803        return NO_ERROR;
804    } break;
805
806    default:
807        return BBinder::onTransact(code, data, reply, flags);
808    }
809}
810
811}  // namespace android
812
813