1 /*
2  * Copyright (C) 2016 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_TAG "android.hardware.drm@1.0-impl"
17 
18 #include <utils/KeyedVector.h>
19 #include <utils/String8.h>
20 
21 #include "DrmPlugin.h"
22 #include "TypeConvert.h"
23 
24 namespace android {
25 namespace hardware {
26 namespace drm {
27 namespace V1_0 {
28 namespace implementation {
29 
30     // Methods from ::android::hardware::drm::V1_0::IDrmPlugin follow.
31 
openSession(openSession_cb _hidl_cb)32     Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) {
33         Vector<uint8_t> legacySessionId;
34         status_t status = mLegacyPlugin->openSession(legacySessionId);
35         _hidl_cb(toStatus(status), toHidlVec(legacySessionId));
36         return Void();
37     }
38 
closeSession(const hidl_vec<uint8_t> & sessionId)39     Return<Status> DrmPlugin::closeSession(const hidl_vec<uint8_t>& sessionId) {
40         return toStatus(mLegacyPlugin->closeSession(toVector(sessionId)));
41     }
42 
getKeyRequest(const hidl_vec<uint8_t> & scope,const hidl_vec<uint8_t> & initData,const hidl_string & mimeType,KeyType keyType,const hidl_vec<KeyValue> & optionalParameters,getKeyRequest_cb _hidl_cb)43     Return<void> DrmPlugin::getKeyRequest(const hidl_vec<uint8_t>& scope,
44             const hidl_vec<uint8_t>& initData, const hidl_string& mimeType,
45             KeyType keyType, const hidl_vec<KeyValue>& optionalParameters,
46             getKeyRequest_cb _hidl_cb) {
47 
48         status_t status = android::OK;
49 
50         android::DrmPlugin::KeyType legacyKeyType;
51         switch(keyType) {
52         case KeyType::OFFLINE:
53             legacyKeyType = android::DrmPlugin::kKeyType_Offline;
54             break;
55         case KeyType::STREAMING:
56             legacyKeyType = android::DrmPlugin::kKeyType_Streaming;
57             break;
58         case KeyType::RELEASE:
59             legacyKeyType = android::DrmPlugin::kKeyType_Release;
60             break;
61         default:
62             status = android::BAD_VALUE;
63             break;
64         }
65 
66         Vector<uint8_t> legacyRequest;
67         KeyRequestType requestType = KeyRequestType::UNKNOWN;
68         String8 defaultUrl;
69 
70         if (status == android::OK) {
71             android::KeyedVector<String8, String8> legacyOptionalParameters;
72             for (size_t i = 0; i < optionalParameters.size(); i++) {
73                 legacyOptionalParameters.add(String8(optionalParameters[i].key.c_str()),
74                         String8(optionalParameters[i].value.c_str()));
75             }
76 
77             android::DrmPlugin::KeyRequestType legacyRequestType =
78                     android::DrmPlugin::kKeyRequestType_Unknown;
79 
80             status = mLegacyPlugin->getKeyRequest(toVector(scope),
81                     toVector(initData), String8(mimeType.c_str()), legacyKeyType,
82                     legacyOptionalParameters, legacyRequest, defaultUrl,
83                     &legacyRequestType);
84 
85             switch(legacyRequestType) {
86             case android::DrmPlugin::kKeyRequestType_Initial:
87                 requestType = KeyRequestType::INITIAL;
88                 break;
89             case android::DrmPlugin::kKeyRequestType_Renewal:
90                 requestType = KeyRequestType::RENEWAL;
91                 break;
92             case android::DrmPlugin::kKeyRequestType_Release:
93                 requestType = KeyRequestType::RELEASE;
94                 break;
95             case android::DrmPlugin::kKeyRequestType_Unknown:
96             default:
97                 requestType = KeyRequestType::UNKNOWN;
98                 break;
99             }
100         }
101         _hidl_cb(toStatus(status), toHidlVec(legacyRequest), requestType,
102                  defaultUrl.string());
103         return Void();
104     }
105 
provideKeyResponse(const hidl_vec<uint8_t> & scope,const hidl_vec<uint8_t> & response,provideKeyResponse_cb _hidl_cb)106     Return<void> DrmPlugin::provideKeyResponse(const hidl_vec<uint8_t>& scope,
107             const hidl_vec<uint8_t>& response, provideKeyResponse_cb _hidl_cb) {
108 
109         Vector<uint8_t> keySetId;
110         status_t status = mLegacyPlugin->provideKeyResponse(toVector(scope),
111                 toVector(response), keySetId);
112         _hidl_cb(toStatus(status), toHidlVec(keySetId));
113         return Void();
114     }
115 
removeKeys(const hidl_vec<uint8_t> & sessionId)116     Return<Status> DrmPlugin::removeKeys(const hidl_vec<uint8_t>& sessionId) {
117         return toStatus(mLegacyPlugin->removeKeys(toVector(sessionId)));
118     }
119 
restoreKeys(const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & keySetId)120     Return<Status> DrmPlugin::restoreKeys(const hidl_vec<uint8_t>& sessionId,
121             const hidl_vec<uint8_t>& keySetId) {
122         status_t legacyStatus = mLegacyPlugin->restoreKeys(toVector(sessionId),
123                 toVector(keySetId));
124         return toStatus(legacyStatus);
125     }
126 
queryKeyStatus(const hidl_vec<uint8_t> & sessionId,queryKeyStatus_cb _hidl_cb)127     Return<void> DrmPlugin::queryKeyStatus(const hidl_vec<uint8_t>& sessionId,
128             queryKeyStatus_cb _hidl_cb) {
129 
130         android::KeyedVector<String8, String8> legacyInfoMap;
131         status_t status = mLegacyPlugin->queryKeyStatus(toVector(sessionId),
132                 legacyInfoMap);
133 
134         Vector<KeyValue> infoMapVec;
135         for (size_t i = 0; i < legacyInfoMap.size(); i++) {
136             KeyValue keyValuePair;
137             keyValuePair.key = String8(legacyInfoMap.keyAt(i));
138             keyValuePair.value = String8(legacyInfoMap.valueAt(i));
139             infoMapVec.push_back(keyValuePair);
140         }
141         _hidl_cb(toStatus(status), toHidlVec(infoMapVec));
142         return Void();
143     }
144 
getProvisionRequest(const hidl_string & certificateType,const hidl_string & certificateAuthority,getProvisionRequest_cb _hidl_cb)145     Return<void> DrmPlugin::getProvisionRequest(
146             const hidl_string& certificateType,
147             const hidl_string& certificateAuthority,
148             getProvisionRequest_cb _hidl_cb) {
149 
150         Vector<uint8_t> legacyRequest;
151         String8 legacyDefaultUrl;
152         status_t status = mLegacyPlugin->getProvisionRequest(
153                 String8(certificateType.c_str()), String8(certificateAuthority.c_str()),
154                 legacyRequest, legacyDefaultUrl);
155 
156         _hidl_cb(toStatus(status), toHidlVec(legacyRequest),
157                 hidl_string(legacyDefaultUrl));
158         return Void();
159     }
160 
provideProvisionResponse(const hidl_vec<uint8_t> & response,provideProvisionResponse_cb _hidl_cb)161     Return<void> DrmPlugin::provideProvisionResponse(
162             const hidl_vec<uint8_t>& response,
163             provideProvisionResponse_cb _hidl_cb) {
164 
165         Vector<uint8_t> certificate;
166         Vector<uint8_t> wrappedKey;
167 
168         status_t legacyStatus = mLegacyPlugin->provideProvisionResponse(
169                 toVector(response), certificate, wrappedKey);
170 
171         _hidl_cb(toStatus(legacyStatus), toHidlVec(certificate),
172                 toHidlVec(wrappedKey));
173         return Void();
174     }
175 
getSecureStops(getSecureStops_cb _hidl_cb)176     Return<void> DrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) {
177         List<Vector<uint8_t> > legacySecureStops;
178         status_t status = mLegacyPlugin->getSecureStops(legacySecureStops);
179 
180         Vector<SecureStop> secureStopsVec;
181         List<Vector<uint8_t> >::iterator iter = legacySecureStops.begin();
182 
183         while (iter != legacySecureStops.end()) {
184             SecureStop secureStop;
185             secureStop.opaqueData = toHidlVec(*iter++);
186             secureStopsVec.push_back(secureStop);
187         }
188 
189         _hidl_cb(toStatus(status), toHidlVec(secureStopsVec));
190         return Void();
191     }
192 
getSecureStop(const hidl_vec<uint8_t> & secureStopId,getSecureStop_cb _hidl_cb)193     Return<void> DrmPlugin::getSecureStop(const hidl_vec<uint8_t>& secureStopId,
194             getSecureStop_cb _hidl_cb) {
195 
196         Vector<uint8_t> legacySecureStop;
197         status_t status = mLegacyPlugin->getSecureStop(toVector(secureStopId),
198                 legacySecureStop);
199 
200         SecureStop secureStop;
201         secureStop.opaqueData = toHidlVec(legacySecureStop);
202         _hidl_cb(toStatus(status), secureStop);
203         return Void();
204     }
205 
releaseAllSecureStops()206     Return<Status> DrmPlugin::releaseAllSecureStops() {
207         return toStatus(mLegacyPlugin->releaseAllSecureStops());
208     }
209 
releaseSecureStop(const hidl_vec<uint8_t> & secureStopId)210     Return<Status> DrmPlugin::releaseSecureStop(
211             const hidl_vec<uint8_t>& secureStopId) {
212         status_t legacyStatus =
213             mLegacyPlugin->releaseSecureStops(toVector(secureStopId));
214         return toStatus(legacyStatus);
215     }
216 
getPropertyString(const hidl_string & propertyName,getPropertyString_cb _hidl_cb)217     Return<void> DrmPlugin::getPropertyString(const hidl_string& propertyName,
218             getPropertyString_cb _hidl_cb) {
219         String8 legacyValue;
220         status_t status = mLegacyPlugin->getPropertyString(
221                 String8(propertyName.c_str()), legacyValue);
222         _hidl_cb(toStatus(status), legacyValue.string());
223         return Void();
224     }
225 
getPropertyByteArray(const hidl_string & propertyName,getPropertyByteArray_cb _hidl_cb)226     Return<void> DrmPlugin::getPropertyByteArray(const hidl_string& propertyName,
227             getPropertyByteArray_cb _hidl_cb) {
228         Vector<uint8_t> legacyValue;
229         status_t status = mLegacyPlugin->getPropertyByteArray(
230                 String8(propertyName.c_str()), legacyValue);
231         _hidl_cb(toStatus(status), toHidlVec(legacyValue));
232         return Void();
233     }
234 
setPropertyString(const hidl_string & propertyName,const hidl_string & value)235     Return<Status> DrmPlugin::setPropertyString(const hidl_string& propertyName,
236             const hidl_string& value) {
237         status_t legacyStatus =
238             mLegacyPlugin->setPropertyString(String8(propertyName.c_str()),
239                     String8(value.c_str()));
240         return toStatus(legacyStatus);
241     }
242 
setPropertyByteArray(const hidl_string & propertyName,const hidl_vec<uint8_t> & value)243     Return<Status> DrmPlugin::setPropertyByteArray(
244             const hidl_string& propertyName, const hidl_vec<uint8_t>& value) {
245         status_t legacyStatus =
246             mLegacyPlugin->setPropertyByteArray(String8(propertyName.c_str()),
247                     toVector(value));
248         return toStatus(legacyStatus);
249     }
250 
setCipherAlgorithm(const hidl_vec<uint8_t> & sessionId,const hidl_string & algorithm)251     Return<Status> DrmPlugin::setCipherAlgorithm(
252             const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) {
253         status_t legacyStatus =
254             mLegacyPlugin->setCipherAlgorithm(toVector(sessionId),
255                 String8(algorithm.c_str()));
256         return toStatus(legacyStatus);
257     }
258 
setMacAlgorithm(const hidl_vec<uint8_t> & sessionId,const hidl_string & algorithm)259     Return<Status> DrmPlugin::setMacAlgorithm(
260             const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) {
261         status_t legacyStatus =
262             mLegacyPlugin->setMacAlgorithm(toVector(sessionId),
263                 String8(algorithm.c_str()));
264         return toStatus(legacyStatus);
265     }
266 
encrypt(const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & keyId,const hidl_vec<uint8_t> & input,const hidl_vec<uint8_t> & iv,encrypt_cb _hidl_cb)267     Return<void> DrmPlugin::encrypt(const hidl_vec<uint8_t>& sessionId,
268             const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
269             const hidl_vec<uint8_t>& iv, encrypt_cb _hidl_cb) {
270 
271         Vector<uint8_t> legacyOutput;
272         status_t status = mLegacyPlugin->encrypt(toVector(sessionId),
273                 toVector(keyId), toVector(input), toVector(iv), legacyOutput);
274         _hidl_cb(toStatus(status), toHidlVec(legacyOutput));
275         return Void();
276     }
277 
decrypt(const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & keyId,const hidl_vec<uint8_t> & input,const hidl_vec<uint8_t> & iv,decrypt_cb _hidl_cb)278     Return<void> DrmPlugin::decrypt(const hidl_vec<uint8_t>& sessionId,
279             const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
280             const hidl_vec<uint8_t>& iv, decrypt_cb _hidl_cb) {
281 
282         Vector<uint8_t> legacyOutput;
283         status_t status = mLegacyPlugin->decrypt(toVector(sessionId),
284                 toVector(keyId), toVector(input), toVector(iv), legacyOutput);
285         _hidl_cb(toStatus(status), toHidlVec(legacyOutput));
286         return Void();
287     }
288 
sign(const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & keyId,const hidl_vec<uint8_t> & message,sign_cb _hidl_cb)289     Return<void> DrmPlugin::sign(const hidl_vec<uint8_t>& sessionId,
290             const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
291             sign_cb _hidl_cb) {
292         Vector<uint8_t> legacySignature;
293         status_t status = mLegacyPlugin->sign(toVector(sessionId),
294                 toVector(keyId), toVector(message), legacySignature);
295         _hidl_cb(toStatus(status), toHidlVec(legacySignature));
296         return Void();
297     }
298 
verify(const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & keyId,const hidl_vec<uint8_t> & message,const hidl_vec<uint8_t> & signature,verify_cb _hidl_cb)299     Return<void> DrmPlugin::verify(const hidl_vec<uint8_t>& sessionId,
300             const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
301             const hidl_vec<uint8_t>& signature, verify_cb _hidl_cb) {
302 
303         bool match;
304         status_t status = mLegacyPlugin->verify(toVector(sessionId),
305                 toVector(keyId), toVector(message), toVector(signature),
306                 match);
307         _hidl_cb(toStatus(status), match);
308         return Void();
309     }
310 
signRSA(const hidl_vec<uint8_t> & sessionId,const hidl_string & algorithm,const hidl_vec<uint8_t> & message,const hidl_vec<uint8_t> & wrappedKey,signRSA_cb _hidl_cb)311     Return<void> DrmPlugin::signRSA(const hidl_vec<uint8_t>& sessionId,
312             const hidl_string& algorithm, const hidl_vec<uint8_t>& message,
313             const hidl_vec<uint8_t>& wrappedKey, signRSA_cb _hidl_cb) {
314 
315         Vector<uint8_t> legacySignature;
316         status_t status = mLegacyPlugin->signRSA(toVector(sessionId),
317                 String8(algorithm.c_str()), toVector(message), toVector(wrappedKey),
318                 legacySignature);
319         _hidl_cb(toStatus(status), toHidlVec(legacySignature));
320         return Void();
321     }
322 
setListener(const sp<IDrmPluginListener> & listener)323     Return<void> DrmPlugin::setListener(const sp<IDrmPluginListener>& listener) {
324         mListener = listener;
325         mLegacyPlugin->setListener(listener == NULL ? NULL : this);
326         return Void();
327     }
328 
sendEvent(EventType eventType,const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & data)329     Return<void> DrmPlugin::sendEvent(EventType eventType,
330             const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
331         if (mListener != nullptr) {
332             mListener->sendEvent(eventType, sessionId, data);
333         }
334         return Void();
335     }
336 
sendExpirationUpdate(const hidl_vec<uint8_t> & sessionId,int64_t expiryTimeInMS)337     Return<void> DrmPlugin::sendExpirationUpdate(
338             const hidl_vec<uint8_t>& sessionId, int64_t expiryTimeInMS) {
339         if (mListener != nullptr) {
340             mListener->sendExpirationUpdate(sessionId, expiryTimeInMS);
341         }
342         return Void();
343     }
344 
sendKeysChange(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus> & keyStatusList,bool hasNewUsableKey)345     Return<void> DrmPlugin::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
346             const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
347         if (mListener != nullptr) {
348             mListener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
349         }
350         return Void();
351     }
352 
353 
354     // Methods from android::DrmPluginListener
355 
sendEvent(android::DrmPlugin::EventType legacyEventType,int,Vector<uint8_t> const * sessionId,Vector<uint8_t> const * data)356     void DrmPlugin::sendEvent(android::DrmPlugin::EventType legacyEventType,
357             int /*unused*/, Vector<uint8_t> const *sessionId,
358             Vector<uint8_t> const *data) {
359 
360         EventType eventType;
361         bool sendEvent = true;
362         switch(legacyEventType) {
363         case android::DrmPlugin::kDrmPluginEventProvisionRequired:
364             eventType = EventType::PROVISION_REQUIRED;
365             break;
366         case android::DrmPlugin::kDrmPluginEventKeyNeeded:
367             eventType = EventType::KEY_NEEDED;
368             break;
369         case android::DrmPlugin::kDrmPluginEventKeyExpired:
370             eventType = EventType::KEY_EXPIRED;
371             break;
372         case android::DrmPlugin::kDrmPluginEventVendorDefined:
373             eventType = EventType::VENDOR_DEFINED;
374             break;
375         case android::DrmPlugin::kDrmPluginEventSessionReclaimed:
376             eventType = EventType::SESSION_RECLAIMED;
377             break;
378         default:
379             sendEvent = false;
380             break;
381         }
382         if (sendEvent) {
383             Vector<uint8_t> emptyVector;
384             mListener->sendEvent(eventType,
385                     toHidlVec(sessionId == NULL ? emptyVector: *sessionId),
386                     toHidlVec(data == NULL ? emptyVector: *data));
387         }
388     }
389 
sendExpirationUpdate(Vector<uint8_t> const * sessionId,int64_t expiryTimeInMS)390     void DrmPlugin::sendExpirationUpdate(Vector<uint8_t> const *sessionId,
391             int64_t expiryTimeInMS) {
392         mListener->sendExpirationUpdate(toHidlVec(*sessionId), expiryTimeInMS);
393     }
394 
sendKeysChange(Vector<uint8_t> const * sessionId,Vector<android::DrmPlugin::KeyStatus> const * legacyKeyStatusList,bool hasNewUsableKey)395     void DrmPlugin::sendKeysChange(Vector<uint8_t> const *sessionId,
396             Vector<android::DrmPlugin::KeyStatus> const *legacyKeyStatusList,
397             bool hasNewUsableKey) {
398 
399         Vector<KeyStatus> keyStatusVec;
400         for (size_t i = 0; i < legacyKeyStatusList->size(); i++) {
401             const android::DrmPlugin::KeyStatus &legacyKeyStatus =
402                 legacyKeyStatusList->itemAt(i);
403 
404             KeyStatus keyStatus;
405 
406             switch(legacyKeyStatus.mType) {
407             case android::DrmPlugin::kKeyStatusType_Usable:
408                 keyStatus.type = KeyStatusType::USABLE;
409                 break;
410             case android::DrmPlugin::kKeyStatusType_Expired:
411                 keyStatus.type = KeyStatusType::EXPIRED;
412                 break;
413             case android::DrmPlugin::kKeyStatusType_OutputNotAllowed:
414                 keyStatus.type = KeyStatusType::OUTPUTNOTALLOWED;
415                 break;
416             case android::DrmPlugin::kKeyStatusType_StatusPending:
417                 keyStatus.type = KeyStatusType::STATUSPENDING;
418                 break;
419             case android::DrmPlugin::kKeyStatusType_InternalError:
420             default:
421                 keyStatus.type = KeyStatusType::INTERNALERROR;
422                 break;
423             }
424 
425             keyStatus.keyId = toHidlVec(legacyKeyStatus.mKeyId);
426             keyStatusVec.push_back(keyStatus);
427         }
428         mListener->sendKeysChange(toHidlVec(*sessionId),
429                 toHidlVec(keyStatusVec), hasNewUsableKey);
430     }
431 
432 }  // namespace implementation
433 }  // namespace V1_0
434 }  // namespace drm
435 }  // namespace hardware
436 }  // namespace android
437