• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "v1_0/media_decrypt_module_service.h"
17 #include <hdf_base.h>
18 #include <hdf_log.h>
19 #include <memory>
20 #include <sys/mman.h>
21 #include <unistd.h>
22 #include "openssl/aes.h"
23 #include "openssl/evp.h"
24 #include "openssl/rand.h"
25 #include "session.h"
26 #include "ashmem.h"
27 #include "securec.h"
28 
29 #define HDF_LOG_TAG media_decrypt_module_service
30 
31 namespace OHOS {
32 namespace HDI {
33 namespace Drm {
34 namespace V1_0 {
35 static const size_t BLOCK_SIZE = AES_BLOCK_SIZE;
36 static const size_t BLOCK_BIT_SIZE = BLOCK_SIZE * 8;
37 
MediaDecryptModuleService(sptr<Session> & session)38 MediaDecryptModuleService::MediaDecryptModuleService(sptr<Session> &session)
39 {
40     HDF_LOGI("%{public}s: start", __func__);
41     session_ = session;
42     HDF_LOGI("%{public}s: end", __func__);
43 }
44 
DecryptMediaData(bool secure,const CryptoInfo & cryptoInfo,const DrmBuffer & srcBuffer,const DrmBuffer & destBuffer)45 int32_t MediaDecryptModuleService::DecryptMediaData(bool secure, const CryptoInfo &cryptoInfo,
46     const DrmBuffer &srcBuffer, const DrmBuffer &destBuffer)
47 {
48     HDF_LOGI("%{public}s: start", __func__);
49     ++decryptNumber;
50     int32_t ret = HDF_FAILURE;
51     if (session_ == nullptr) {
52         ++errorDecryptNumber;
53         (void)::close(srcBuffer.fd);
54         (void)::close(destBuffer.fd);
55         return HDF_FAILURE;
56     }
57     std::vector<uint8_t> key;
58     ret = session_->getKeyValueByKeyId(cryptoInfo.keyId, key);
59     if (ret != HDF_SUCCESS) {
60         HDF_LOGI("%{public}s: could not find key", __func__);
61     }
62 
63     uint8_t *srcData = nullptr;
64     uint8_t *destData = nullptr;
65     size_t data_size = 0;
66     for (auto &subSample : cryptoInfo.subSamples) {
67         if (subSample.clearHeaderLen > 0) {
68             data_size += subSample.clearHeaderLen;
69         }
70 
71         if (subSample.payLoadLen > 0) {
72             data_size += subSample.payLoadLen;
73         }
74     }
75 
76     srcData = (uint8_t *)mmap(nullptr, data_size, PROT_READ | PROT_WRITE, MAP_SHARED, srcBuffer.fd, 0);
77     if (srcData == nullptr) {
78         HDF_LOGE("%{public}s: invalid src_shared_mem", __func__);
79         ++errorDecryptNumber;
80         (void)::close(srcBuffer.fd);
81         (void)::close(destBuffer.fd);
82         return HDF_FAILURE;
83     }
84 
85     destData = (uint8_t *)mmap(nullptr, data_size, PROT_READ | PROT_WRITE, MAP_SHARED, destBuffer.fd, 0);
86     if (destData == nullptr) {
87         HDF_LOGE("%{public}s: invalid dest_shared_mem", __func__);
88         (void)munmap(srcData, data_size);
89         ++errorDecryptNumber;
90         (void)::close(srcBuffer.fd);
91         (void)::close(destBuffer.fd);
92         return HDF_FAILURE;
93     }
94 
95     switch (cryptoInfo.type) {
96         case ALGTYPE_UNENCRYPTED:
97             ret = CopyBuffer(srcData, destData, cryptoInfo.subSamples);
98             break;
99         case ALGTYPE_AES_WV:
100             ret = DecryptByAesCbc(key, cryptoInfo.iv, srcData, destData, cryptoInfo.subSamples);
101             break;
102         case ALGTYPE_AES_CBC:
103             ret = DecryptByAesCbc(key, cryptoInfo.iv, srcData, destData, cryptoInfo.subSamples);
104             break;
105         case ALGTYPE_AES_CTR:
106         case ALGTYPE_SM4_CBC:
107             ret = DecryptBySM4Cbc(key, cryptoInfo.iv, srcData, destData, cryptoInfo.subSamples);
108             break;
109         default:
110             (void)munmap(srcData, data_size);
111             (void)munmap(destData, data_size);
112             (void)::close(srcBuffer.fd);
113             (void)::close(destBuffer.fd);
114             HDF_LOGE("CryptoAlgorithmType is not supported");
115             ++errorDecryptNumber;
116             return HDF_ERR_INVALID_PARAM;
117     }
118     (void)munmap(srcData, data_size);
119     (void)munmap(destData, data_size);
120     (void)::close(srcBuffer.fd);
121     (void)::close(destBuffer.fd);
122     if (ret != HDF_SUCCESS) {
123         ++errorDecryptNumber;
124         return ret;
125     }
126     HDF_LOGI("%{public}s: end", __func__);
127     return HDF_SUCCESS;
128 }
129 
DecryptBySM4Cbc(const std::vector<uint8_t> & key,const std::vector<uint8_t> & iv,uint8_t * srcData,uint8_t * destData,const std::vector<SubSample> & subSamples)130 int32_t MediaDecryptModuleService::DecryptBySM4Cbc(const std::vector<uint8_t> &key, const std::vector<uint8_t> &iv,
131     uint8_t *srcData, uint8_t *destData, const std::vector<SubSample> &subSamples)
132 {
133     HDF_LOGI("%{public}s: start", __func__);
134     EVP_CIPHER_CTX *ctx;
135     size_t offset = 0;
136     int len;
137     int32_t ret = HDF_FAILURE;
138     if (key.size() != BLOCK_SIZE || iv.size() != BLOCK_SIZE) {
139         HDF_LOGE("key or iv length error");
140         return HDF_ERR_INVALID_PARAM;
141     }
142     HDF_LOGI("%{public}s: before EVP_DecryptInit_ex", __func__);
143     ctx = EVP_CIPHER_CTX_new();
144     EVP_DecryptInit_ex(ctx, EVP_sm4_cbc(), nullptr, key.data(), iv.data());
145     EVP_CIPHER_CTX_set_padding(ctx, 0);
146     HDF_LOGI("%{public}s: after EVP_DecryptInit_ex", __func__);
147 
148     for (auto &subSample : subSamples) {
149         if (subSample.clearHeaderLen > 0) {
150             HDF_LOGI("%{public}s: before clear header memcpy_s", __func__);
151             ret = memcpy_s(destData + offset, subSample.clearHeaderLen, srcData + offset, subSample.clearHeaderLen);
152             if (ret != 0) {
153                 HDF_LOGI("%{public}s: memcpy_s faild!", __func__);
154                 return ret;
155             }
156             HDF_LOGI("%{public}s: after clear header memcpy_s", __func__);
157             offset += subSample.clearHeaderLen;
158         }
159 
160         if (subSample.payLoadLen > 0) {
161             HDF_LOGI("%{public}s: before EVP_DecryptUpdate", __func__);
162             // Decrypt data
163             EVP_DecryptUpdate(ctx, (unsigned char *)(destData + offset), &len,
164                 (const unsigned char *)(srcData + offset), (int)(subSample.payLoadLen));
165             // End decryption process
166             EVP_DecryptFinal_ex(ctx, (unsigned char *)(destData + offset + len), &len);
167             HDF_LOGI("%{public}s: after EVP_DecryptFinal_ex", __func__);
168             offset += subSample.payLoadLen;
169         }
170     }
171     // release context
172     EVP_CIPHER_CTX_free(ctx);
173     HDF_LOGI("%{public}s: end", __func__);
174     return HDF_SUCCESS;
175 }
176 
DecryptByAesCbc(const std::vector<uint8_t> & key,const std::vector<uint8_t> & iv,uint8_t * srcData,uint8_t * destData,const std::vector<SubSample> & subSamples)177 int32_t MediaDecryptModuleService::DecryptByAesCbc(const std::vector<uint8_t> &key, const std::vector<uint8_t> &iv,
178     uint8_t *srcData, uint8_t *destData, const std::vector<SubSample> &subSamples)
179 {
180     HDF_LOGI("%{public}s: start", __func__);
181     size_t offset = 0;
182     AES_KEY opensslKey;
183     int32_t ret = HDF_FAILURE;
184     if (key.size() != BLOCK_SIZE || iv.size() != BLOCK_SIZE) {
185         HDF_LOGE("key or iv length error");
186         return HDF_ERR_INVALID_PARAM;
187     }
188     HDF_LOGI("%{public}s: before AES_set_decrypt_key", __func__);
189     AES_set_decrypt_key((unsigned char *)key.data(), BLOCK_BIT_SIZE, &opensslKey);
190     HDF_LOGI("%{public}s: after AES_set_decrypt_key", __func__);
191 
192     for (auto &subSample : subSamples) {
193         if (subSample.clearHeaderLen > 0) {
194             HDF_LOGI("%{public}s: before clear header memcpy_s", __func__);
195             ret = memcpy_s(destData + offset, subSample.clearHeaderLen, srcData + offset, subSample.clearHeaderLen);
196             if (ret != 0) {
197                 HDF_LOGE("%{public}s: memcpy_s faild", __func__);
198                 return ret;
199             }
200             HDF_LOGI("%{public}s: after clear header memcpy_s", __func__);
201             offset += subSample.clearHeaderLen;
202         }
203 
204         if (subSample.payLoadLen > 0) {
205             HDF_LOGI("%{public}s: before AES_cbc_encrypt", __func__);
206             AES_cbc_encrypt((uint8_t *)srcData + offset, (uint8_t *)destData + offset, subSample.payLoadLen,
207                 &opensslKey, (unsigned char *)iv.data(), AES_DECRYPT);
208             HDF_LOGI("%{public}s: after AES_cbc_encrypt", __func__);
209             offset += subSample.payLoadLen;
210         }
211     }
212     HDF_LOGI("%{public}s: end", __func__);
213     return HDF_SUCCESS;
214 }
215 
CopyBuffer(uint8_t * srcBuffer,uint8_t * destBuffer,const std::vector<SubSample> & subSamples)216 int32_t MediaDecryptModuleService::CopyBuffer(uint8_t *srcBuffer, uint8_t *destBuffer,
217     const std::vector<SubSample> &subSamples)
218 {
219     HDF_LOGI("%{public}s: start", __func__);
220     size_t offset = 0;
221     int32_t ret = HDF_FAILURE;
222     for (auto &subSample : subSamples) {
223         if (subSample.clearHeaderLen > 0) {
224             ret = memcpy_s(destBuffer + offset, subSample.clearHeaderLen, srcBuffer + offset, subSample.clearHeaderLen);
225             if (ret != 0) {
226                 HDF_LOGE("%{public}s: memcpy_s faild", __func__);
227                 return ret;
228             }
229             offset += subSample.clearHeaderLen;
230         }
231 
232         if (subSample.payLoadLen > 0) {
233             ret = memcpy_s(destBuffer + offset, subSample.clearHeaderLen, srcBuffer + offset, subSample.payLoadLen);
234             if (ret != 0) {
235                 HDF_LOGE("%{public}s: memcpy_s faild", __func__);
236                 return ret;
237             }
238             offset += subSample.payLoadLen;
239         }
240     }
241     HDF_LOGI("%{public}s: end", __func__);
242     return HDF_SUCCESS;
243 }
244 
GetDecryptNumber()245 int32_t MediaDecryptModuleService::GetDecryptNumber()
246 {
247     HDF_LOGI("%{public}s: start", __func__);
248     HDF_LOGI("%{public}s: end", __func__);
249     return decryptNumber;
250 }
251 
GetErrorDecryptNumber()252 int32_t MediaDecryptModuleService::GetErrorDecryptNumber()
253 {
254     HDF_LOGI("%{public}s: start", __func__);
255     HDF_LOGI("%{public}s: end", __func__);
256     return errorDecryptNumber;
257 }
258 
Release()259 int32_t MediaDecryptModuleService::Release()
260 {
261     HDF_LOGI("%{public}s: start", __func__);
262     HDF_LOGI("%{public}s: end", __func__);
263     return HDF_SUCCESS;
264 }
265 } // V1_0
266 } // Drm
267 } // HDI
268 } // OHOS
269