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 
17 #include <string>
18 #include <refbase.h>
19 #include <securec.h>
20 #include "drm_log.h"
21 #include "http.h"
22 #include "native_drm_common.h"
23 #include "native_drm_base.h"
24 #include "native_drm_object.h"
25 #include "native_mediakeysession.h"
26 #include "mediakeydecryptndk_fuzzer.h"
27 #include "media_decrypt_module_service_proxy.h"
28 
29 #define OFFRESPONSE                                                                                                 \
30     {                                                                                                               \
31         0x31, 0x64, 0x6E, 0x5A, 0x32, 0x4E, 0x57, 0x74, 0x76, 0x4D, 0x47, 0x34, 0x34, 0x4E, 0x6A, 0x42, 0x30, 0x4D, \
32             0x32, 0x77, 0x33, 0x4E, 0x67, 0x3D, 0x3D, 0x3A, 0x59, 0x7A, 0x56, 0x78, 0x63, 0x48, 0x64, 0x70, 0x61,   \
33             0x6D, 0x30, 0x34, 0x59, 0x57, 0x45, 0x34, 0x5A, 0x48, 0x6B, 0x79, 0x4D, 0x67, 0x3D, 0x3D                \
34     }
35 #define REQUESTINFODATA                                                                                             \
36     {                                                                                                               \
37         0x00, 0x00, 0x00, 0x8B, 0x70, 0x73, 0x73, 0x68, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x5E, 0x6D, 0x35, 0x9B, 0x9A, \
38             0x41, 0xE8, 0xB8, 0x43, 0xDD, 0x3C, 0x6E, 0x72, 0xC4, 0x2C, 0x00, 0x00, 0x00, 0x6B, 0x7B, 0x22, 0x76,   \
39             0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x22, 0x3A, 0x22, 0x56, 0x31, 0x2E, 0x30, 0x22, 0x2C, 0x22, 0x63,   \
40             0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x49, 0x44, 0x22, 0x3A, 0x22, 0x64, 0x48, 0x4D, 0x74, 0x4D, 0x6A,   \
41             0x59, 0x30, 0x4C, 0x54, 0x45, 0x77, 0x4F, 0x44, 0x41, 0x74, 0x59, 0x57, 0x56, 0x7A, 0x22, 0x2C, 0x22,   \
42             0x6B, 0x69, 0x64, 0x73, 0x22, 0x3A, 0x5B, 0x22, 0x47, 0x2B, 0x45, 0x6B, 0x2F, 0x2B, 0x58, 0x6D, 0x55,   \
43             0x6B, 0x70, 0x42, 0x48, 0x51, 0x67, 0x58, 0x59, 0x57, 0x51, 0x51, 0x49, 0x67, 0x3D, 0x3D, 0x22, 0x5D,   \
44             0x2C, 0x22, 0x65, 0x6E, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x22, 0x3A, 0x22, 0x63, 0x62, 0x63, 0x31,   \
45             0x22, 0x7D                                                                                              \
46     }
47 #define PROVISION_URL "https://drmkit.hwcloudtest.cn:8080/provision/v1/wiseplay"
48 #define LICENSE_URL "http://license.dev.trustdta.com:8080/drmproxy/v3/getLicense"
49 #define HTTPOUTTIME 10
50 using namespace std;
51 using namespace OHOS;
52 using namespace DrmStandard;
53 const int32_t MEMMAXSIZE = 128;
54 const int32_t OFFRESPONSELEN = 50;
55 const int32_t DATAMAXSIZE = 12288;
56 namespace OHOS {
57 namespace DrmStandard {
TestsessionEventCallBack(DRM_EventType eventType,unsigned char * info,int32_t infoLen,char * extra)58 Drm_ErrCode TestsessionEventCallBack(DRM_EventType eventType, unsigned char *info, int32_t infoLen, char *extra)
59 {
60     DRM_INFO_LOG("TestsessionEventCallBack ok");
61     return DRM_ERR_OK;
62 }
63 
TestSessoinEventCallBack(DRM_EventType eventType,unsigned char * info,int32_t infoLen,char * extra)64 Drm_ErrCode TestSessoinEventCallBack(DRM_EventType eventType, unsigned char *info, int32_t infoLen, char *extra)
65 {
66     DRM_INFO_LOG("TestSessoinEventCallBack ok");
67     return DRM_ERR_OK;
68 }
69 
TestSessoinKeyChangeCallBack(DRM_KeysInfo * keysInfo,bool hasNewGoodKeys)70 Drm_ErrCode TestSessoinKeyChangeCallBack(DRM_KeysInfo *keysInfo, bool hasNewGoodKeys)
71 {
72     DRM_INFO_LOG("TestSessoinKeyChangeCallBack ok");
73     return DRM_ERR_OK;
74 }
75 
MediadecryptNdkFuzzer()76 MediadecryptNdkFuzzer::MediadecryptNdkFuzzer() {}
77 
~MediadecryptNdkFuzzer()78 MediadecryptNdkFuzzer::~MediadecryptNdkFuzzer() {}
79 
GetUuid()80 void MediadecryptNdkFuzzer::GetUuid()
81 {
82     if (OH_MediaKeySystem_IsSupported("com.clearplay.drm")) {
83         uuid = "com.clearplay.drm";
84     } else if (OH_MediaKeySystem_IsSupported("com.wiseplay.drm")) {
85         uuid = "com.wiseplay.drm";
86     }
87 }
88 
IsWisePlay()89 void MediadecryptNdkFuzzer::IsWisePlay()
90 {
91     if (OH_MediaKeySystem_IsSupported("com.wiseplay.drm")) {
92         wisePlay = true;
93     }
94 }
95 
GenerateDeviceCertificate()96 void MediadecryptNdkFuzzer::GenerateDeviceCertificate()
97 {
98     DRM_INFO_LOG("MediadecryptNdkFuzzer::GenerateDeviceCertificate start");
99     unsigned char request[12288] = { 0 }; // 12288:request len
100     int32_t requestLen = 12288;           // 12288:request len
101     char defaultUrl[2048] = { 0 };       // 2048:url len
102     int32_t defaultUrlLen = 2048;        // 2048:url len
103     OH_MediaKeySystem_GenerateKeySystemRequest(mediaKeySystem, request, &requestLen, defaultUrl, defaultUrlLen);
104     uint8_t Response[12288] = OFFRESPONSE;
105     int32_t ResponseLen = sizeof(Response);
106     if (wisePlay == true) {
107         HttpPost(PROVISION_URL, request, requestLen, Response, &ResponseLen, HTTPOUTTIME);
108     }
109     OH_MediaKeySystem_ProcessKeySystemResponse(mediaKeySystem, Response, ResponseLen);
110     DRM_INFO_LOG("MediadecryptNdkFuzzer::GenerateDeviceCertificate end");
111 }
112 
GenerateLicense()113 void MediadecryptNdkFuzzer::GenerateLicense()
114 {
115     DRM_INFO_LOG("MediaKeysessionNdkFuzzer::GenerateLicense start");
116     DRM_MediaKeyRequest mediaKeyRequest;
117     DRM_MediaKeyRequestInfo info;
118     unsigned char testData[139] = REQUESTINFODATA;
119     memset_s(&info, sizeof(DRM_MediaKeyRequestInfo), 0, sizeof(DRM_MediaKeyRequestInfo));
120     info.initDataLen = sizeof(testData);
121     info.type = MEDIA_KEY_TYPE_ONLINE;
122     memcpy_s(info.mimeType, sizeof("video/mp4"), "video/mp4", sizeof("video/mp4"));
123     memcpy_s(info.initData, sizeof(testData), testData, sizeof(testData));
124     int ret = memcpy_s(info.optionName[0], sizeof("optionalDataName"), "optionalDataName", sizeof("optionalDataName"));
125     if (ret != 0) {
126         DRM_INFO_LOG("memcpy_s faild!");
127     }
128     ret = memcpy_s(info.optionData[0], sizeof("optionalDataValue"), "optionalDataValue", sizeof("optionalDataValue"));
129     if (ret != 0) {
130         DRM_INFO_LOG("memcpy_s faild!");
131     }
132     info.optionsCount = 1;
133     OH_MediaKeySession_GenerateMediaKeyRequest(mediaKeySession, &info, &mediaKeyRequest);
134     DRM_INFO_LOG("MediaKeysessionNdkFuzzer::GenerateLicense end");
135     unsigned char keySessionResponse[12288] = OFFRESPONSE;
136     int32_t keySessionResponseLen = sizeof(keySessionResponse);
137     if (wisePlay) {
138         HttpPost(LICENSE_URL, mediaKeyRequest.data, (uint32_t)mediaKeyRequest.dataLen, keySessionResponse,
139             &keySessionResponseLen, HTTPOUTTIME);
140     } else {
141         keySessionResponseLen = OFFRESPONSELEN;
142     }
143     uint8_t mediaKeyId[64] = { 0 }; // 64:OFFLINE_MEDIA_KEY_ID_LEN
144     int32_t mediaKeyIdLen = 64;     // 64:OFFLINE_MEDIA_KEY_ID_LEN
145     OH_MediaKeySession_ProcessMediaKeyResponse(mediaKeySession, keySessionResponse, keySessionResponseLen,
146         mediaKeyId, &mediaKeyIdLen);
147 }
148 
149 
Init()150 void MediadecryptNdkFuzzer::Init()
151 {
152     DRM_INFO_LOG("MediadecryptNdkFuzzer::Init start");
153     GetUuid();
154     IsWisePlay();
155     DRM_INFO_LOG("uuid = %{public}s", uuid.c_str());
156     DRM_INFO_LOG("wisePlay = %{public}d", wisePlay);
157     OH_MediaKeySystem_Create((const char *)uuid.c_str(), &mediaKeySystem);
158     DRM_INFO_LOG("MediadecryptNdkFuzzer::Init end");
159 }
160 
Deinitialize()161 void MediadecryptNdkFuzzer::Deinitialize()
162 {
163     DRM_INFO_LOG("MediadecryptNdkFuzzer::Deinitialize start");
164     if (mediaKeySystem != nullptr) {
165         OH_MediaKeySystem_Destroy(mediaKeySystem);
166         mediaKeySystem = nullptr;
167     }
168     DRM_INFO_LOG("MediadecryptNdkFuzzer::Deinitialize end");
169 }
170 
FuzzTestMediaKeyDecryptNdk(uint8_t * rawData,size_t size)171 bool MediadecryptNdkFuzzer::FuzzTestMediaKeyDecryptNdk(uint8_t *rawData, size_t size)
172 {
173     if (rawData == nullptr || size < sizeof(int32_t)) {
174         return false;
175     }
176     Init();
177     GenerateDeviceCertificate();
178     OH_MediaKeySystem_CreateMediaKeySession(mediaKeySystem, &ContentProtectionLevel, &mediaKeySession);
179     GenerateLicense();
180     if (mediaKeySession) {
181         MediaKeySessionObject *sessionObject = reinterpret_cast<MediaKeySessionObject *>(mediaKeySession);
182         sptr<IMediaKeySessionService> SessionServiceProxy =
183             sessionObject->sessionImpl_->GetMediaKeySessionServiceProxy();
184         sptr<IMediaDecryptModuleService> decryptModule;
185         SessionServiceProxy->GetMediaDecryptModule(decryptModule);
186         IMediaDecryptModuleService::DrmBuffer srcBuffer;
187         IMediaDecryptModuleService::DrmBuffer dstBuffer;
188         bool secureDecodrtState = false;
189         IMediaDecryptModuleService::CryptInfo cryptInfo;
190         decryptModule->Release();
191         sptr<MediaKeySessionImplCallback> callback = sessionObject->sessionImpl_->GetApplicationCallback();
192         callback->~MediaKeySessionImplCallback();
193     }
194     if (mediaKeySession != nullptr) {
195         OH_MediaKeySession_Destroy(mediaKeySession);
196         mediaKeySession = nullptr;
197     }
198     Deinitialize();
199     DRM_INFO_LOG("MediadecryptNdkFuzzer::FuzzTestMediaKeysessionConfigurationNdk end");
200     return true;
201 }
202 } // namespace DrmStandard
203 
FuzzMediaKeysessionNdk(uint8_t * data,size_t size)204 bool FuzzMediaKeysessionNdk(uint8_t *data, size_t size)
205 {
206     if (data == nullptr) {
207         return true;
208     }
209     MediadecryptNdkFuzzer testMediasession;
210     testMediasession.FuzzTestMediaKeyDecryptNdk(data, size);
211     return true;
212 }
213 } // namesapce OHOS
214 
215 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(uint8_t * data,size_t size)216 extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size)
217 {
218     /* Run your code on data */
219     uint8_t rawData[DATAMAXSIZE] = { 0 };
220     int32_t ret = memcpy_s(rawData, DATAMAXSIZE - 1, data, size);
221     if (ret != 0) {
222         return -1;
223     }
224     OHOS::FuzzMediaKeysessionNdk(rawData, size);
225     return 0;
226 }
227