xref: /aosp_15_r20/frameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "NuPlayerDrm"
19*ec779b8eSAndroid Build Coastguard Worker 
20*ec779b8eSAndroid Build Coastguard Worker #include "NuPlayerDrm.h"
21*ec779b8eSAndroid Build Coastguard Worker 
22*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/DrmUtils.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
24*ec779b8eSAndroid Build Coastguard Worker 
25*ec779b8eSAndroid Build Coastguard Worker namespace android {
26*ec779b8eSAndroid Build Coastguard Worker 
27*ec779b8eSAndroid Build Coastguard Worker // static helpers - internal
28*ec779b8eSAndroid Build Coastguard Worker 
CreateDrm(status_t * pstatus)29*ec779b8eSAndroid Build Coastguard Worker sp<IDrm> NuPlayerDrm::CreateDrm(status_t *pstatus)
30*ec779b8eSAndroid Build Coastguard Worker {
31*ec779b8eSAndroid Build Coastguard Worker     return DrmUtils::MakeDrm(IDRM_NUPLAYER, pstatus);
32*ec779b8eSAndroid Build Coastguard Worker }
33*ec779b8eSAndroid Build Coastguard Worker 
createCrypto(status_t * pstatus)34*ec779b8eSAndroid Build Coastguard Worker sp<ICrypto> NuPlayerDrm::createCrypto(status_t *pstatus)
35*ec779b8eSAndroid Build Coastguard Worker {
36*ec779b8eSAndroid Build Coastguard Worker 
37*ec779b8eSAndroid Build Coastguard Worker     return DrmUtils::MakeCrypto(pstatus);
38*ec779b8eSAndroid Build Coastguard Worker }
39*ec779b8eSAndroid Build Coastguard Worker 
parsePSSH(const void * pssh,size_t psshsize)40*ec779b8eSAndroid Build Coastguard Worker Vector<DrmUUID> NuPlayerDrm::parsePSSH(const void *pssh, size_t psshsize)
41*ec779b8eSAndroid Build Coastguard Worker {
42*ec779b8eSAndroid Build Coastguard Worker     Vector<DrmUUID> drmSchemes, empty;
43*ec779b8eSAndroid Build Coastguard Worker     const int DATALEN_SIZE = 4;
44*ec779b8eSAndroid Build Coastguard Worker 
45*ec779b8eSAndroid Build Coastguard Worker     // the format of the buffer is 1 or more of:
46*ec779b8eSAndroid Build Coastguard Worker     //    {
47*ec779b8eSAndroid Build Coastguard Worker     //        16 byte uuid
48*ec779b8eSAndroid Build Coastguard Worker     //        4 byte data length N
49*ec779b8eSAndroid Build Coastguard Worker     //        N bytes of data
50*ec779b8eSAndroid Build Coastguard Worker     //    }
51*ec779b8eSAndroid Build Coastguard Worker     // Determine the number of entries in the source data.
52*ec779b8eSAndroid Build Coastguard Worker     // Since we got the data from stagefright, we trust it is valid and properly formatted.
53*ec779b8eSAndroid Build Coastguard Worker 
54*ec779b8eSAndroid Build Coastguard Worker     const uint8_t *data = (const uint8_t*)pssh;
55*ec779b8eSAndroid Build Coastguard Worker     size_t len = psshsize;
56*ec779b8eSAndroid Build Coastguard Worker     size_t numentries = 0;
57*ec779b8eSAndroid Build Coastguard Worker     while (len > 0) {
58*ec779b8eSAndroid Build Coastguard Worker         if (len < DrmUUID::UUID_SIZE) {
59*ec779b8eSAndroid Build Coastguard Worker             ALOGE("ParsePSSH: invalid PSSH data");
60*ec779b8eSAndroid Build Coastguard Worker             return empty;
61*ec779b8eSAndroid Build Coastguard Worker         }
62*ec779b8eSAndroid Build Coastguard Worker 
63*ec779b8eSAndroid Build Coastguard Worker         const uint8_t *uuidPtr = data;
64*ec779b8eSAndroid Build Coastguard Worker 
65*ec779b8eSAndroid Build Coastguard Worker         // skip uuid
66*ec779b8eSAndroid Build Coastguard Worker         data += DrmUUID::UUID_SIZE;
67*ec779b8eSAndroid Build Coastguard Worker         len -= DrmUUID::UUID_SIZE;
68*ec779b8eSAndroid Build Coastguard Worker 
69*ec779b8eSAndroid Build Coastguard Worker         // get data length
70*ec779b8eSAndroid Build Coastguard Worker         if (len < DATALEN_SIZE) {
71*ec779b8eSAndroid Build Coastguard Worker             ALOGE("ParsePSSH: invalid PSSH data");
72*ec779b8eSAndroid Build Coastguard Worker             return empty;
73*ec779b8eSAndroid Build Coastguard Worker         }
74*ec779b8eSAndroid Build Coastguard Worker 
75*ec779b8eSAndroid Build Coastguard Worker         uint32_t datalen = *((uint32_t*)data);
76*ec779b8eSAndroid Build Coastguard Worker         data += DATALEN_SIZE;
77*ec779b8eSAndroid Build Coastguard Worker         len -= DATALEN_SIZE;
78*ec779b8eSAndroid Build Coastguard Worker 
79*ec779b8eSAndroid Build Coastguard Worker         if (len < datalen) {
80*ec779b8eSAndroid Build Coastguard Worker             ALOGE("ParsePSSH: invalid PSSH data");
81*ec779b8eSAndroid Build Coastguard Worker             return empty;
82*ec779b8eSAndroid Build Coastguard Worker         }
83*ec779b8eSAndroid Build Coastguard Worker 
84*ec779b8eSAndroid Build Coastguard Worker         // skip the data
85*ec779b8eSAndroid Build Coastguard Worker         data += datalen;
86*ec779b8eSAndroid Build Coastguard Worker         len -= datalen;
87*ec779b8eSAndroid Build Coastguard Worker 
88*ec779b8eSAndroid Build Coastguard Worker         DrmUUID _uuid(uuidPtr);
89*ec779b8eSAndroid Build Coastguard Worker         drmSchemes.add(_uuid);
90*ec779b8eSAndroid Build Coastguard Worker 
91*ec779b8eSAndroid Build Coastguard Worker         ALOGV("ParsePSSH[%zu]: %s: %s", numentries,
92*ec779b8eSAndroid Build Coastguard Worker                 _uuid.toHexString().c_str(),
93*ec779b8eSAndroid Build Coastguard Worker                 DrmUUID::arrayToHex(data, datalen).c_str()
94*ec779b8eSAndroid Build Coastguard Worker              );
95*ec779b8eSAndroid Build Coastguard Worker 
96*ec779b8eSAndroid Build Coastguard Worker         numentries++;
97*ec779b8eSAndroid Build Coastguard Worker     }
98*ec779b8eSAndroid Build Coastguard Worker 
99*ec779b8eSAndroid Build Coastguard Worker     return drmSchemes;
100*ec779b8eSAndroid Build Coastguard Worker }
101*ec779b8eSAndroid Build Coastguard Worker 
getSupportedDrmSchemes(const void * pssh,size_t psshsize)102*ec779b8eSAndroid Build Coastguard Worker Vector<DrmUUID> NuPlayerDrm::getSupportedDrmSchemes(const void *pssh, size_t psshsize)
103*ec779b8eSAndroid Build Coastguard Worker {
104*ec779b8eSAndroid Build Coastguard Worker     Vector<DrmUUID> psshDRMs = parsePSSH(pssh, psshsize);
105*ec779b8eSAndroid Build Coastguard Worker 
106*ec779b8eSAndroid Build Coastguard Worker     Vector<DrmUUID> supportedDRMs;
107*ec779b8eSAndroid Build Coastguard Worker      // temporary DRM object for crypto Scheme enquiry (without creating a plugin)
108*ec779b8eSAndroid Build Coastguard Worker     status_t status = OK;
109*ec779b8eSAndroid Build Coastguard Worker     sp<IDrm> drm = CreateDrm(&status);
110*ec779b8eSAndroid Build Coastguard Worker     if (drm != NULL) {
111*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < psshDRMs.size(); i++) {
112*ec779b8eSAndroid Build Coastguard Worker             DrmUUID uuid = psshDRMs[i];
113*ec779b8eSAndroid Build Coastguard Worker             bool isSupported = false;
114*ec779b8eSAndroid Build Coastguard Worker             status = drm->isCryptoSchemeSupported(uuid.ptr(), String8(),
115*ec779b8eSAndroid Build Coastguard Worker                     DrmPlugin::kSecurityLevelUnknown, &isSupported);
116*ec779b8eSAndroid Build Coastguard Worker             if (status == OK && isSupported) {
117*ec779b8eSAndroid Build Coastguard Worker                 supportedDRMs.add(uuid);
118*ec779b8eSAndroid Build Coastguard Worker             }
119*ec779b8eSAndroid Build Coastguard Worker         }
120*ec779b8eSAndroid Build Coastguard Worker 
121*ec779b8eSAndroid Build Coastguard Worker         drm.clear();
122*ec779b8eSAndroid Build Coastguard Worker     } else {
123*ec779b8eSAndroid Build Coastguard Worker         ALOGE("getSupportedDrmSchemes: Can't create Drm obj: %d", status);
124*ec779b8eSAndroid Build Coastguard Worker     }
125*ec779b8eSAndroid Build Coastguard Worker 
126*ec779b8eSAndroid Build Coastguard Worker     ALOGV("getSupportedDrmSchemes: psshDRMs: %zu supportedDRMs: %zu",
127*ec779b8eSAndroid Build Coastguard Worker             psshDRMs.size(), supportedDRMs.size());
128*ec779b8eSAndroid Build Coastguard Worker 
129*ec779b8eSAndroid Build Coastguard Worker     return supportedDRMs;
130*ec779b8eSAndroid Build Coastguard Worker }
131*ec779b8eSAndroid Build Coastguard Worker 
132*ec779b8eSAndroid Build Coastguard Worker // static helpers - public
133*ec779b8eSAndroid Build Coastguard Worker 
createCryptoAndPlugin(const uint8_t uuid[16],const Vector<uint8_t> & drmSessionId,status_t & status)134*ec779b8eSAndroid Build Coastguard Worker sp<ICrypto> NuPlayerDrm::createCryptoAndPlugin(const uint8_t uuid[16],
135*ec779b8eSAndroid Build Coastguard Worker         const Vector<uint8_t> &drmSessionId, status_t &status)
136*ec779b8eSAndroid Build Coastguard Worker {
137*ec779b8eSAndroid Build Coastguard Worker     // Extra check
138*ec779b8eSAndroid Build Coastguard Worker     if (drmSessionId.isEmpty()) {
139*ec779b8eSAndroid Build Coastguard Worker         status = INVALID_OPERATION;
140*ec779b8eSAndroid Build Coastguard Worker         ALOGE("createCryptoAndPlugin: Failed. Empty drmSessionId. status: %d", status);
141*ec779b8eSAndroid Build Coastguard Worker         return NULL;
142*ec779b8eSAndroid Build Coastguard Worker     }
143*ec779b8eSAndroid Build Coastguard Worker 
144*ec779b8eSAndroid Build Coastguard Worker     status = OK;
145*ec779b8eSAndroid Build Coastguard Worker     sp<ICrypto> crypto = createCrypto(&status);
146*ec779b8eSAndroid Build Coastguard Worker     if (crypto == NULL) {
147*ec779b8eSAndroid Build Coastguard Worker         ALOGE("createCryptoAndPlugin: createCrypto failed. status: %d", status);
148*ec779b8eSAndroid Build Coastguard Worker         return NULL;
149*ec779b8eSAndroid Build Coastguard Worker     }
150*ec779b8eSAndroid Build Coastguard Worker     ALOGV("createCryptoAndPlugin: createCrypto succeeded");
151*ec779b8eSAndroid Build Coastguard Worker 
152*ec779b8eSAndroid Build Coastguard Worker     status = crypto->createPlugin(uuid, drmSessionId.array(), drmSessionId.size());
153*ec779b8eSAndroid Build Coastguard Worker     if (status != OK) {
154*ec779b8eSAndroid Build Coastguard Worker         ALOGE("createCryptoAndPlugin: createCryptoPlugin failed. status: %d", status);
155*ec779b8eSAndroid Build Coastguard Worker         // crypto will clean itself when leaving the current scope
156*ec779b8eSAndroid Build Coastguard Worker         return NULL;
157*ec779b8eSAndroid Build Coastguard Worker     }
158*ec779b8eSAndroid Build Coastguard Worker 
159*ec779b8eSAndroid Build Coastguard Worker     return crypto;
160*ec779b8eSAndroid Build Coastguard Worker }
161*ec779b8eSAndroid Build Coastguard Worker 
162*ec779b8eSAndroid Build Coastguard Worker // Parcel has only private copy constructor so passing it in rather than returning
retrieveDrmInfo(const void * pssh,size_t psshsize,Parcel * parcel)163*ec779b8eSAndroid Build Coastguard Worker void NuPlayerDrm::retrieveDrmInfo(const void *pssh, size_t psshsize, Parcel *parcel)
164*ec779b8eSAndroid Build Coastguard Worker {
165*ec779b8eSAndroid Build Coastguard Worker     // 1) PSSH bytes
166*ec779b8eSAndroid Build Coastguard Worker     parcel->writeUint32(psshsize);
167*ec779b8eSAndroid Build Coastguard Worker     parcel->writeByteArray(psshsize, (const uint8_t*)pssh);
168*ec779b8eSAndroid Build Coastguard Worker 
169*ec779b8eSAndroid Build Coastguard Worker     ALOGV("retrieveDrmInfo: MEDIA_DRM_INFO  PSSH: size: %zu %s", psshsize,
170*ec779b8eSAndroid Build Coastguard Worker             DrmUUID::arrayToHex((uint8_t*)pssh, psshsize).c_str());
171*ec779b8eSAndroid Build Coastguard Worker 
172*ec779b8eSAndroid Build Coastguard Worker     // 2) supportedDRMs
173*ec779b8eSAndroid Build Coastguard Worker     Vector<DrmUUID> supportedDRMs = getSupportedDrmSchemes(pssh, psshsize);
174*ec779b8eSAndroid Build Coastguard Worker     parcel->writeUint32(supportedDRMs.size());
175*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < supportedDRMs.size(); i++) {
176*ec779b8eSAndroid Build Coastguard Worker         DrmUUID uuid = supportedDRMs[i];
177*ec779b8eSAndroid Build Coastguard Worker         parcel->writeByteArray(DrmUUID::UUID_SIZE, uuid.ptr());
178*ec779b8eSAndroid Build Coastguard Worker 
179*ec779b8eSAndroid Build Coastguard Worker         ALOGV("retrieveDrmInfo: MEDIA_DRM_INFO  supportedScheme[%zu] %s", i,
180*ec779b8eSAndroid Build Coastguard Worker                 uuid.toHexString().c_str());
181*ec779b8eSAndroid Build Coastguard Worker     }
182*ec779b8eSAndroid Build Coastguard Worker }
183*ec779b8eSAndroid Build Coastguard Worker 
184*ec779b8eSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////////////
185*ec779b8eSAndroid Build Coastguard Worker /// Helpers for NuPlayerDecoder
186*ec779b8eSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////////////
187*ec779b8eSAndroid Build Coastguard Worker 
makeCryptoInfo(int numSubSamples,uint8_t key[kBlockSize],uint8_t iv[kBlockSize],CryptoPlugin::Mode mode,uint32_t * clearbytes,uint32_t * encryptedbytes)188*ec779b8eSAndroid Build Coastguard Worker NuPlayerDrm::CryptoInfo *NuPlayerDrm::makeCryptoInfo(
189*ec779b8eSAndroid Build Coastguard Worker         int numSubSamples,
190*ec779b8eSAndroid Build Coastguard Worker         uint8_t key[kBlockSize],
191*ec779b8eSAndroid Build Coastguard Worker         uint8_t iv[kBlockSize],
192*ec779b8eSAndroid Build Coastguard Worker         CryptoPlugin::Mode mode,
193*ec779b8eSAndroid Build Coastguard Worker         uint32_t *clearbytes,
194*ec779b8eSAndroid Build Coastguard Worker         uint32_t *encryptedbytes)
195*ec779b8eSAndroid Build Coastguard Worker {
196*ec779b8eSAndroid Build Coastguard Worker     // size needed to store all the crypto data
197*ec779b8eSAndroid Build Coastguard Worker     size_t cryptosize;
198*ec779b8eSAndroid Build Coastguard Worker     // sizeof(CryptoInfo) + sizeof(CryptoPlugin::SubSample) * numSubSamples;
199*ec779b8eSAndroid Build Coastguard Worker     if (__builtin_mul_overflow(sizeof(CryptoPlugin::SubSample), numSubSamples, &cryptosize) ||
200*ec779b8eSAndroid Build Coastguard Worker             __builtin_add_overflow(cryptosize, sizeof(CryptoInfo), &cryptosize)) {
201*ec779b8eSAndroid Build Coastguard Worker         ALOGE("crypto size overflow");
202*ec779b8eSAndroid Build Coastguard Worker         return NULL;
203*ec779b8eSAndroid Build Coastguard Worker     }
204*ec779b8eSAndroid Build Coastguard Worker 
205*ec779b8eSAndroid Build Coastguard Worker     CryptoInfo *ret = (CryptoInfo*) malloc(cryptosize);
206*ec779b8eSAndroid Build Coastguard Worker     if (ret == NULL) {
207*ec779b8eSAndroid Build Coastguard Worker         ALOGE("couldn't allocate %zu bytes", cryptosize);
208*ec779b8eSAndroid Build Coastguard Worker         return NULL;
209*ec779b8eSAndroid Build Coastguard Worker     }
210*ec779b8eSAndroid Build Coastguard Worker     ret->numSubSamples = numSubSamples;
211*ec779b8eSAndroid Build Coastguard Worker     memcpy(ret->key, key, kBlockSize);
212*ec779b8eSAndroid Build Coastguard Worker     memcpy(ret->iv, iv, kBlockSize);
213*ec779b8eSAndroid Build Coastguard Worker     ret->mode = mode;
214*ec779b8eSAndroid Build Coastguard Worker     ret->pattern.mEncryptBlocks = 0;
215*ec779b8eSAndroid Build Coastguard Worker     ret->pattern.mSkipBlocks = 0;
216*ec779b8eSAndroid Build Coastguard Worker     ret->subSamples = (CryptoPlugin::SubSample*)(ret + 1);
217*ec779b8eSAndroid Build Coastguard Worker     CryptoPlugin::SubSample *subSamples = ret->subSamples;
218*ec779b8eSAndroid Build Coastguard Worker 
219*ec779b8eSAndroid Build Coastguard Worker     for (int i = 0; i < numSubSamples; i++) {
220*ec779b8eSAndroid Build Coastguard Worker         subSamples[i].mNumBytesOfClearData = (clearbytes == NULL) ? 0 : clearbytes[i];
221*ec779b8eSAndroid Build Coastguard Worker         subSamples[i].mNumBytesOfEncryptedData = (encryptedbytes == NULL) ?
222*ec779b8eSAndroid Build Coastguard Worker                                                   0 :
223*ec779b8eSAndroid Build Coastguard Worker                                                   encryptedbytes[i];
224*ec779b8eSAndroid Build Coastguard Worker     }
225*ec779b8eSAndroid Build Coastguard Worker 
226*ec779b8eSAndroid Build Coastguard Worker     return ret;
227*ec779b8eSAndroid Build Coastguard Worker }
228*ec779b8eSAndroid Build Coastguard Worker 
getSampleCryptoInfo(MetaDataBase & meta)229*ec779b8eSAndroid Build Coastguard Worker NuPlayerDrm::CryptoInfo *NuPlayerDrm::getSampleCryptoInfo(MetaDataBase &meta)
230*ec779b8eSAndroid Build Coastguard Worker {
231*ec779b8eSAndroid Build Coastguard Worker     uint32_t type;
232*ec779b8eSAndroid Build Coastguard Worker     const void *crypteddata;
233*ec779b8eSAndroid Build Coastguard Worker     size_t cryptedsize;
234*ec779b8eSAndroid Build Coastguard Worker 
235*ec779b8eSAndroid Build Coastguard Worker     if (!meta.findData(kKeyEncryptedSizes, &type, &crypteddata, &cryptedsize)) {
236*ec779b8eSAndroid Build Coastguard Worker         return NULL;
237*ec779b8eSAndroid Build Coastguard Worker     }
238*ec779b8eSAndroid Build Coastguard Worker     size_t numSubSamples = cryptedsize / sizeof(uint32_t);
239*ec779b8eSAndroid Build Coastguard Worker 
240*ec779b8eSAndroid Build Coastguard Worker     if (numSubSamples <= 0) {
241*ec779b8eSAndroid Build Coastguard Worker         ALOGE("getSampleCryptoInfo INVALID numSubSamples: %zu", numSubSamples);
242*ec779b8eSAndroid Build Coastguard Worker         return NULL;
243*ec779b8eSAndroid Build Coastguard Worker     }
244*ec779b8eSAndroid Build Coastguard Worker 
245*ec779b8eSAndroid Build Coastguard Worker     const void *cleardata;
246*ec779b8eSAndroid Build Coastguard Worker     size_t clearsize;
247*ec779b8eSAndroid Build Coastguard Worker     if (meta.findData(kKeyPlainSizes, &type, &cleardata, &clearsize)) {
248*ec779b8eSAndroid Build Coastguard Worker         if (clearsize != cryptedsize) {
249*ec779b8eSAndroid Build Coastguard Worker             // The two must be of the same length.
250*ec779b8eSAndroid Build Coastguard Worker             ALOGE("getSampleCryptoInfo mismatch cryptedsize: %zu != clearsize: %zu",
251*ec779b8eSAndroid Build Coastguard Worker                     cryptedsize, clearsize);
252*ec779b8eSAndroid Build Coastguard Worker             return NULL;
253*ec779b8eSAndroid Build Coastguard Worker         }
254*ec779b8eSAndroid Build Coastguard Worker     }
255*ec779b8eSAndroid Build Coastguard Worker 
256*ec779b8eSAndroid Build Coastguard Worker     const void *key;
257*ec779b8eSAndroid Build Coastguard Worker     size_t keysize;
258*ec779b8eSAndroid Build Coastguard Worker     if (meta.findData(kKeyCryptoKey, &type, &key, &keysize)) {
259*ec779b8eSAndroid Build Coastguard Worker         if (keysize != kBlockSize) {
260*ec779b8eSAndroid Build Coastguard Worker             ALOGE("getSampleCryptoInfo Keys must be %d bytes in length: %zu",
261*ec779b8eSAndroid Build Coastguard Worker                     kBlockSize, keysize);
262*ec779b8eSAndroid Build Coastguard Worker             // Keys must be 16 bytes in length.
263*ec779b8eSAndroid Build Coastguard Worker             return NULL;
264*ec779b8eSAndroid Build Coastguard Worker         }
265*ec779b8eSAndroid Build Coastguard Worker     }
266*ec779b8eSAndroid Build Coastguard Worker 
267*ec779b8eSAndroid Build Coastguard Worker     const void *iv;
268*ec779b8eSAndroid Build Coastguard Worker     size_t ivsize;
269*ec779b8eSAndroid Build Coastguard Worker     if (meta.findData(kKeyCryptoIV, &type, &iv, &ivsize)) {
270*ec779b8eSAndroid Build Coastguard Worker         if (ivsize != kBlockSize) {
271*ec779b8eSAndroid Build Coastguard Worker             ALOGE("getSampleCryptoInfo IV must be %d bytes in length: %zu",
272*ec779b8eSAndroid Build Coastguard Worker                     kBlockSize, ivsize);
273*ec779b8eSAndroid Build Coastguard Worker             // IVs must be 16 bytes in length.
274*ec779b8eSAndroid Build Coastguard Worker             return NULL;
275*ec779b8eSAndroid Build Coastguard Worker         }
276*ec779b8eSAndroid Build Coastguard Worker     }
277*ec779b8eSAndroid Build Coastguard Worker 
278*ec779b8eSAndroid Build Coastguard Worker     int32_t mode;
279*ec779b8eSAndroid Build Coastguard Worker     if (!meta.findInt32(kKeyCryptoMode, &mode)) {
280*ec779b8eSAndroid Build Coastguard Worker         mode = CryptoPlugin::kMode_AES_CTR;
281*ec779b8eSAndroid Build Coastguard Worker     }
282*ec779b8eSAndroid Build Coastguard Worker 
283*ec779b8eSAndroid Build Coastguard Worker     return makeCryptoInfo(numSubSamples,
284*ec779b8eSAndroid Build Coastguard Worker             (uint8_t*) key,
285*ec779b8eSAndroid Build Coastguard Worker             (uint8_t*) iv,
286*ec779b8eSAndroid Build Coastguard Worker             (CryptoPlugin::Mode)mode,
287*ec779b8eSAndroid Build Coastguard Worker             (uint32_t*) cleardata,
288*ec779b8eSAndroid Build Coastguard Worker             (uint32_t*) crypteddata);
289*ec779b8eSAndroid Build Coastguard Worker }
290*ec779b8eSAndroid Build Coastguard Worker 
291*ec779b8eSAndroid Build Coastguard Worker }   // namespace android
292*ec779b8eSAndroid Build Coastguard Worker 
293