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