1 /*
2 * Copyright (c) 2023 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 <chrono>
21 #include <sys/mman.h>
22 #include <unistd.h>
23 #include "openssl/aes.h"
24 #include "openssl/evp.h"
25 #include "openssl/rand.h"
26 #include "session.h"
27 #include "ashmem.h"
28 #include "securec.h"
29
30 #define HDF_LOG_TAG media_decrypt_module_service
31
32 namespace OHOS {
33 namespace HDI {
34 namespace Drm {
35 namespace V1_0 {
36 static const size_t BLOCK_SIZE = AES_BLOCK_SIZE;
37 static const size_t BLOCK_BIT_SIZE = BLOCK_SIZE * 8;
38
MediaDecryptModuleService(sptr<Session> & session)39 MediaDecryptModuleService::MediaDecryptModuleService(sptr<Session> &session)
40 {
41 HDF_LOGI("%{public}s: start", __func__);
42 session_ = session;
43 HDF_LOGI("%{public}s: end", __func__);
44 }
45
DecryptMediaData(bool secure,const CryptoInfo & cryptoInfo,const DrmBuffer & srcBuffer,const DrmBuffer & destBuffer)46 int32_t MediaDecryptModuleService::DecryptMediaData(bool secure, const CryptoInfo &cryptoInfo,
47 const DrmBuffer &srcBuffer, const DrmBuffer &destBuffer)
48 {
49 HDF_LOGI("%{public}s: start", __func__);
50 auto start = std::chrono::high_resolution_clock::now();
51 ++decryptNumber;
52 int32_t ret = HDF_FAILURE;
53 if (session_ == nullptr || secure == true) {
54 ++errorDecryptNumber;
55 (void)::close(srcBuffer.fd);
56 (void)::close(destBuffer.fd);
57 return HDF_FAILURE;
58 }
59 std::vector<uint8_t> key;
60 ret = session_->getKeyValueByKeyId(cryptoInfo.keyId, key);
61 if (ret != HDF_SUCCESS) {
62 HDF_LOGI("%{public}s: could not find key", __func__);
63 }
64
65 uint8_t *srcData = nullptr;
66 uint8_t *destData = nullptr;
67 size_t data_size = 0;
68 for (auto &subSample : cryptoInfo.subSamples) {
69 if (subSample.clearHeaderLen > 0) {
70 data_size += subSample.clearHeaderLen;
71 }
72
73 if (subSample.payLoadLen > 0) {
74 data_size += subSample.payLoadLen;
75 }
76 }
77
78 srcData = (uint8_t *)mmap(nullptr, data_size, PROT_READ | PROT_WRITE, MAP_SHARED, srcBuffer.fd, 0);
79 if (srcData == nullptr) {
80 HDF_LOGE("%{public}s: invalid src_shared_mem", __func__);
81 ++errorDecryptNumber;
82 (void)::close(srcBuffer.fd);
83 (void)::close(destBuffer.fd);
84 return HDF_FAILURE;
85 }
86
87 destData = (uint8_t *)mmap(nullptr, data_size, PROT_READ | PROT_WRITE, MAP_SHARED, destBuffer.fd, 0);
88 if (destData == nullptr) {
89 HDF_LOGE("%{public}s: invalid dest_shared_mem", __func__);
90 (void)munmap(srcData, data_size);
91 ++errorDecryptNumber;
92 (void)::close(srcBuffer.fd);
93 (void)::close(destBuffer.fd);
94 return HDF_FAILURE;
95 }
96
97 switch (cryptoInfo.type) {
98 case ALGTYPE_UNENCRYPTED:
99 ret = CopyBuffer(srcData, destData, cryptoInfo.subSamples);
100 break;
101 case ALGTYPE_AES_WV:
102 ret = DecryptByAesCbc(key, cryptoInfo.iv, srcData, destData, cryptoInfo.subSamples);
103 break;
104 case ALGTYPE_AES_CBC:
105 ret = DecryptByAesCbc(key, cryptoInfo.iv, srcData, destData, cryptoInfo.subSamples);
106 break;
107 case ALGTYPE_AES_CTR:
108 case ALGTYPE_SM4_CBC:
109 ret = DecryptBySM4Cbc(key, cryptoInfo.iv, srcData, destData, cryptoInfo.subSamples);
110 break;
111 default:
112 (void)munmap(srcData, data_size);
113 (void)munmap(destData, data_size);
114 (void)::close(srcBuffer.fd);
115 (void)::close(destBuffer.fd);
116 HDF_LOGE("CryptoAlgorithmType is not supported");
117 ++errorDecryptNumber;
118 return HDF_ERR_INVALID_PARAM;
119 }
120 (void)munmap(srcData, data_size);
121 (void)munmap(destData, data_size);
122 (void)::close(srcBuffer.fd);
123 (void)::close(destBuffer.fd);
124 if (ret != HDF_SUCCESS) {
125 ++errorDecryptNumber;
126 return ret;
127 }
128 auto end = std::chrono::high_resolution_clock::now();
129 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
130 HDF_LOGD("decryption time is %{public}lld", duration.count());
131 decryptTimes.push_back(duration.count());
132 HDF_LOGI("%{public}s: end", __func__);
133 return HDF_SUCCESS;
134 }
135
DecryptBySM4Cbc(const std::vector<uint8_t> & key,const std::vector<uint8_t> & iv,uint8_t * srcData,uint8_t * destData,const std::vector<SubSample> & subSamples)136 int32_t MediaDecryptModuleService::DecryptBySM4Cbc(const std::vector<uint8_t> &key, const std::vector<uint8_t> &iv,
137 uint8_t *srcData, uint8_t *destData, const std::vector<SubSample> &subSamples)
138 {
139 HDF_LOGI("%{public}s: start", __func__);
140 EVP_CIPHER_CTX *ctx;
141 size_t offset = 0;
142 int len;
143 int32_t ret = HDF_FAILURE;
144 if (key.size() != BLOCK_SIZE || iv.size() != BLOCK_SIZE) {
145 HDF_LOGE("key or iv length error");
146 return HDF_ERR_INVALID_PARAM;
147 }
148 HDF_LOGI("%{public}s: before EVP_DecryptInit_ex", __func__);
149 ctx = EVP_CIPHER_CTX_new();
150 EVP_DecryptInit_ex(ctx, EVP_sm4_cbc(), nullptr, key.data(), iv.data());
151 EVP_CIPHER_CTX_set_padding(ctx, 0);
152 HDF_LOGI("%{public}s: after EVP_DecryptInit_ex", __func__);
153
154 for (auto &subSample : subSamples) {
155 if (subSample.clearHeaderLen > 0) {
156 HDF_LOGI("%{public}s: before clear header memcpy_s", __func__);
157 ret = memcpy_s(destData + offset, subSample.clearHeaderLen, srcData + offset, subSample.clearHeaderLen);
158 if (ret != 0) {
159 HDF_LOGI("%{public}s: memcpy_s faild!", __func__);
160 return ret;
161 }
162 HDF_LOGI("%{public}s: after clear header memcpy_s", __func__);
163 offset += subSample.clearHeaderLen;
164 }
165
166 if (subSample.payLoadLen > 0) {
167 HDF_LOGI("%{public}s: before EVP_DecryptUpdate", __func__);
168 // Decrypt data
169 EVP_DecryptUpdate(ctx, (unsigned char *)(destData + offset), &len,
170 (const unsigned char *)(srcData + offset), (int)(subSample.payLoadLen));
171 // End decryption process
172 EVP_DecryptFinal_ex(ctx, (unsigned char *)(destData + offset + len), &len);
173 HDF_LOGI("%{public}s: after EVP_DecryptFinal_ex", __func__);
174 offset += subSample.payLoadLen;
175 }
176 }
177 // release context
178 EVP_CIPHER_CTX_free(ctx);
179 HDF_LOGI("%{public}s: end", __func__);
180 return HDF_SUCCESS;
181 }
182
DecryptByAesCbc(const std::vector<uint8_t> & key,const std::vector<uint8_t> & iv,uint8_t * srcData,uint8_t * destData,const std::vector<SubSample> & subSamples)183 int32_t MediaDecryptModuleService::DecryptByAesCbc(const std::vector<uint8_t> &key, const std::vector<uint8_t> &iv,
184 uint8_t *srcData, uint8_t *destData, const std::vector<SubSample> &subSamples)
185 {
186 HDF_LOGI("%{public}s: start", __func__);
187 size_t offset = 0;
188 AES_KEY opensslKey;
189 int32_t ret = HDF_FAILURE;
190 if (key.size() != BLOCK_SIZE || iv.size() != BLOCK_SIZE) {
191 HDF_LOGE("key or iv length error");
192 return HDF_ERR_INVALID_PARAM;
193 }
194 HDF_LOGI("%{public}s: before AES_set_decrypt_key", __func__);
195 AES_set_decrypt_key((unsigned char *)key.data(), BLOCK_BIT_SIZE, &opensslKey);
196 HDF_LOGI("%{public}s: after AES_set_decrypt_key", __func__);
197
198 for (auto &subSample : subSamples) {
199 if (subSample.clearHeaderLen > 0) {
200 HDF_LOGI("%{public}s: before clear header memcpy_s", __func__);
201 ret = memcpy_s(destData + offset, subSample.clearHeaderLen, srcData + offset, subSample.clearHeaderLen);
202 if (ret != 0) {
203 HDF_LOGE("%{public}s: memcpy_s faild", __func__);
204 return ret;
205 }
206 HDF_LOGI("%{public}s: after clear header memcpy_s", __func__);
207 offset += subSample.clearHeaderLen;
208 }
209
210 if (subSample.payLoadLen > 0) {
211 HDF_LOGI("%{public}s: before AES_cbc_encrypt", __func__);
212 AES_cbc_encrypt((uint8_t *)srcData + offset, (uint8_t *)destData + offset, subSample.payLoadLen,
213 &opensslKey, (unsigned char *)iv.data(), AES_DECRYPT);
214 HDF_LOGI("%{public}s: after AES_cbc_encrypt", __func__);
215 offset += subSample.payLoadLen;
216 }
217 }
218 HDF_LOGI("%{public}s: end", __func__);
219 return HDF_SUCCESS;
220 }
221
CopyBuffer(uint8_t * srcBuffer,uint8_t * destBuffer,const std::vector<SubSample> & subSamples)222 int32_t MediaDecryptModuleService::CopyBuffer(uint8_t *srcBuffer, uint8_t *destBuffer,
223 const std::vector<SubSample> &subSamples)
224 {
225 HDF_LOGI("%{public}s: start", __func__);
226 size_t offset = 0;
227 int32_t ret = HDF_FAILURE;
228 for (auto &subSample : subSamples) {
229 if (subSample.clearHeaderLen > 0) {
230 ret = memcpy_s(destBuffer + offset, subSample.clearHeaderLen, srcBuffer + offset, subSample.clearHeaderLen);
231 if (ret != 0) {
232 HDF_LOGE("%{public}s: memcpy_s faild", __func__);
233 return ret;
234 }
235 offset += subSample.clearHeaderLen;
236 }
237
238 if (subSample.payLoadLen > 0) {
239 ret = memcpy_s(destBuffer + offset, subSample.clearHeaderLen, srcBuffer + offset, subSample.payLoadLen);
240 if (ret != 0) {
241 HDF_LOGE("%{public}s: memcpy_s faild", __func__);
242 return ret;
243 }
244 offset += subSample.payLoadLen;
245 }
246 }
247 HDF_LOGI("%{public}s: end", __func__);
248 return HDF_SUCCESS;
249 }
250
GetDecryptNumber()251 int32_t MediaDecryptModuleService::GetDecryptNumber()
252 {
253 HDF_LOGI("%{public}s: start", __func__);
254 HDF_LOGI("%{public}s: end", __func__);
255 return decryptNumber;
256 }
257
GetDecryptTimes(std::vector<double> & times)258 int32_t MediaDecryptModuleService::GetDecryptTimes(std::vector<double> ×)
259 {
260 HDF_LOGI("%{public}s: start", __func__);
261 times.assign(decryptTimes.begin(), decryptTimes.end());
262 HDF_LOGI("%{public}s: end", __func__);
263 return HDF_SUCCESS;
264 }
265
GetErrorDecryptNumber()266 int32_t MediaDecryptModuleService::GetErrorDecryptNumber()
267 {
268 HDF_LOGI("%{public}s: start", __func__);
269 HDF_LOGI("%{public}s: end", __func__);
270 return errorDecryptNumber;
271 }
272
Release()273 int32_t MediaDecryptModuleService::Release()
274 {
275 HDF_LOGI("%{public}s: start", __func__);
276 HDF_LOGI("%{public}s: end", __func__);
277 return HDF_SUCCESS;
278 }
279 } // V1_0
280 } // Drm
281 } // HDI
282 } // OHOS
283