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 "key_manager.h"
17
18 #include "alg_defs.h"
19 #include "alg_loader.h"
20 #include "common_defs.h"
21 #include "device_auth_defines.h"
22 #include "hc_dev_info.h"
23 #include "hc_log.h"
24 #include "hc_types.h"
25 #include "json_utils.h"
26 #include "pseudonym_manager.h"
27 #include "uint8buff_utils.h"
28 #include "hisysevent_common.h"
29
30 #define PAKE_X25519_KEY_PAIR_LEN 32
31 #define MK_LEN 32
32 #define MK_DERIVE_INFO "dev_auth_mk_derivation"
33 #define PAKE_KEY_ALIAS_LEN 64
34 #define MK_ALIAS_PREFIX "MK_"
35 #define PSEUDONYM_PSK_ALIAS_PREFIX "PSEUDONYM_"
36
ConvertHashToAlias(const Uint8Buff * keyAliasHash,Uint8Buff * outKeyAlias)37 static int32_t ConvertHashToAlias(const Uint8Buff *keyAliasHash, Uint8Buff *outKeyAlias)
38 {
39 uint32_t keyAliasHexLen = keyAliasHash->length * BYTE_TO_HEX_OPER_LENGTH + 1;
40 char *keyAliasHex = (char *)HcMalloc(keyAliasHexLen, 0);
41 if (keyAliasHex == NULL) {
42 LOGE("Failed to alloc key alias hex memory!");
43 return HC_ERR_ALLOC_MEMORY;
44 }
45 int32_t res = ByteToHexString(keyAliasHash->val, keyAliasHash->length, keyAliasHex, keyAliasHexLen);
46 if (res != HC_SUCCESS) {
47 LOGE("Failed to convert key alias hash to hex!");
48 HcFree(keyAliasHex);
49 return res;
50 }
51 if (memcpy_s(outKeyAlias->val, outKeyAlias->length, keyAliasHex, HcStrlen(keyAliasHex)) != EOK) {
52 LOGE("Failed to copy key alias hex!");
53 HcFree(keyAliasHex);
54 return HC_ERR_MEMORY_COPY;
55 }
56 HcFree(keyAliasHex);
57 return HC_SUCCESS;
58 }
59
ConvertHashToAliasWithPrefix(const char * prefix,const Uint8Buff * keyAliasHash,Uint8Buff * keyAlias)60 static int32_t ConvertHashToAliasWithPrefix(const char *prefix, const Uint8Buff *keyAliasHash, Uint8Buff *keyAlias)
61 {
62 uint32_t keyAliasHexLen = keyAliasHash->length * BYTE_TO_HEX_OPER_LENGTH + 1;
63 char *keyAliasHex = (char *)HcMalloc(keyAliasHexLen, 0);
64 if (keyAliasHex == NULL) {
65 LOGE("Failed to alloc key alias hex memory!");
66 return HC_ERR_ALLOC_MEMORY;
67 }
68 int32_t res = ByteToHexString(keyAliasHash->val, keyAliasHash->length, keyAliasHex, keyAliasHexLen);
69 if (res != HC_SUCCESS) {
70 LOGE("Failed to convert key alias hash to hex!");
71 HcFree(keyAliasHex);
72 return res;
73 }
74 uint32_t prefixLen = HcStrlen(prefix);
75 if (memcpy_s(keyAlias->val, keyAlias->length, prefix, prefixLen) != EOK) {
76 LOGE("Failed to copy key alias prefix!");
77 HcFree(keyAliasHex);
78 return HC_ERR_MEMORY_COPY;
79 }
80 // The remaining key alias len is less than keyAliasHexLen len after substract prefixLen,
81 // so copy the remaining len other than keyAliasHexLen in order that the key alias len is 64.
82 if (memcpy_s(keyAlias->val + prefixLen, keyAlias->length - prefixLen, keyAliasHex,
83 keyAlias->length - prefixLen) != EOK) {
84 LOGE("Failed to copy key alias hex!");
85 HcFree(keyAliasHex);
86 return HC_ERR_MEMORY_COPY;
87 }
88 HcFree(keyAliasHex);
89 return HC_SUCCESS;
90 }
91
GenerateDevKeyAlias(Uint8Buff * outKeyAlias)92 static int32_t GenerateDevKeyAlias(Uint8Buff *outKeyAlias)
93 {
94 char selfUdid[INPUT_UDID_LEN] = { 0 };
95 int32_t res = HcGetUdid((uint8_t *)selfUdid, INPUT_UDID_LEN);
96 if (res != HC_SUCCESS) {
97 LOGE("Failed to get local udid!");
98 return res;
99 }
100 uint8_t hashValue[SHA256_LEN] = { 0 };
101 Uint8Buff keyAliasHash = { hashValue, SHA256_LEN };
102 Uint8Buff msgBuff = { (uint8_t *)selfUdid, HcStrlen(selfUdid) };
103 res = GetLoaderInstance()->sha256(&msgBuff, &keyAliasHash);
104 if (res != HC_SUCCESS) {
105 LOGE("Failed to generate key alias hash!");
106 return res;
107 }
108 res = ConvertHashToAlias(&keyAliasHash, outKeyAlias);
109 if (res != HC_SUCCESS) {
110 LOGE("Failed to convert hash to alias!");
111 }
112 return res;
113 }
114
GenerateMkAlias(const char * peerDeviceId,Uint8Buff * keyAlias)115 static int32_t GenerateMkAlias(const char *peerDeviceId, Uint8Buff *keyAlias)
116 {
117 Uint8Buff peerDevIdBuff = { (uint8_t *)peerDeviceId, HcStrlen(peerDeviceId) };
118 uint8_t hashValue[SHA256_LEN] = { 0 };
119 Uint8Buff keyAliasHash = { hashValue, SHA256_LEN };
120 int32_t res = GetLoaderInstance()->sha256(&peerDevIdBuff, &keyAliasHash);
121 if (res != HC_SUCCESS) {
122 LOGE("Failed to generate key alias hash!");
123 return res;
124 }
125 res = ConvertHashToAliasWithPrefix(MK_ALIAS_PREFIX, &keyAliasHash, keyAlias);
126 if (res != HC_SUCCESS) {
127 LOGE("Failed to convert hash to alias!");
128 }
129 return res;
130 }
131
GeneratePseudonymPskAlias(const char * peerDeviceId,Uint8Buff * keyAlias)132 static int32_t GeneratePseudonymPskAlias(const char *peerDeviceId, Uint8Buff *keyAlias)
133 {
134 uint8_t hashValue[SHA256_LEN] = { 0 };
135 Uint8Buff keyAliasHash = { hashValue, SHA256_LEN };
136 Uint8Buff peerDevIdBuff = { (uint8_t *)peerDeviceId, HcStrlen(peerDeviceId) };
137 int32_t res = GetLoaderInstance()->sha256(&peerDevIdBuff, &keyAliasHash);
138 if (res != HC_SUCCESS) {
139 LOGE("Failed to generate key alias hash!");
140 return res;
141 }
142
143 res = ConvertHashToAliasWithPrefix(PSEUDONYM_PSK_ALIAS_PREFIX, &keyAliasHash, keyAlias);
144 if (res != HC_SUCCESS) {
145 LOGE("Failed to convert hash to alias!");
146 }
147 return res;
148 }
149
KeyDerivation(int32_t osAccountId,const Uint8Buff * baseAlias,const Uint8Buff * salt,bool isAlias,Uint8Buff * returnKey)150 static int32_t KeyDerivation(int32_t osAccountId, const Uint8Buff *baseAlias, const Uint8Buff *salt, bool isAlias,
151 Uint8Buff *returnKey)
152 {
153 Uint8Buff keyInfo = { (uint8_t *)MK_DERIVE_INFO, HcStrlen(MK_DERIVE_INFO) };
154 KeyParams keyAliasParams = { { baseAlias->val, baseAlias->length, isAlias }, false, osAccountId };
155 int32_t res = GetLoaderInstance()->computeHkdf(&keyAliasParams, salt, &keyInfo, returnKey);
156 if (res != HC_SUCCESS) {
157 LOGE("Failed to compute hkdf!");
158 }
159 return res;
160 }
161
GenerateDeviceKeyPair(int32_t osAccountId)162 int32_t GenerateDeviceKeyPair(int32_t osAccountId)
163 {
164 uint8_t keyAlias[PAKE_KEY_ALIAS_LEN] = { 0 };
165 Uint8Buff keyAliasBuff = { keyAlias, PAKE_KEY_ALIAS_LEN };
166 int32_t res = GenerateDevKeyAlias(&keyAliasBuff);
167 if (res != HC_SUCCESS) {
168 LOGE("Failed to generate device key alias!");
169 return res;
170 }
171 if (GetLoaderInstance()->checkKeyExist(&keyAliasBuff, false, osAccountId) == HC_SUCCESS) {
172 LOGI("Device Key pair already exists!");
173 return HC_SUCCESS;
174 }
175
176 char selfUdid[INPUT_UDID_LEN] = { 0 };
177 res = HcGetUdid((uint8_t *)selfUdid, INPUT_UDID_LEN);
178 if (res != HC_SUCCESS) {
179 LOGE("Failed to get local udid!");
180 return res;
181 }
182 Uint8Buff authIdBuff = { (uint8_t *)selfUdid, HcStrlen(selfUdid) };
183 ExtraInfo exInfo = { authIdBuff, -1, -1 };
184 KeyParams keyParams = { { keyAliasBuff.val, keyAliasBuff.length, true }, false, osAccountId };
185 res = GetLoaderInstance()->generateKeyPairWithStorage(&keyParams, PAKE_X25519_KEY_PAIR_LEN, X25519,
186 KEY_PURPOSE_SIGN_VERIFY, &exInfo);
187 if (res != HC_SUCCESS) {
188 LOGE("Failed to generate device key pair!");
189 return res;
190 }
191 LOGI("Generate device key pair successfully!");
192 return HC_SUCCESS;
193 }
194
GenerateMk(int32_t osAccountId,const char * peerDeviceId,const Uint8Buff * peerPubKey)195 int32_t GenerateMk(int32_t osAccountId, const char *peerDeviceId, const Uint8Buff *peerPubKey)
196 {
197 if (peerDeviceId == NULL || peerPubKey == NULL) {
198 LOGE("Invalid input params!");
199 return HC_ERR_INVALID_PARAMS;
200 }
201 uint8_t mkAlias[PAKE_KEY_ALIAS_LEN] = { 0 };
202 Uint8Buff mkAliasBuff = { mkAlias, PAKE_KEY_ALIAS_LEN };
203 int32_t res = GenerateMkAlias(peerDeviceId, &mkAliasBuff);
204 if (res != HC_SUCCESS) {
205 LOGE("Failed to generate mk alias!");
206 return res;
207 }
208 uint8_t devKeyAlias[PAKE_KEY_ALIAS_LEN] = { 0 };
209 Uint8Buff devKeyAliasBuff = { devKeyAlias, PAKE_KEY_ALIAS_LEN };
210 res = GenerateDevKeyAlias(&devKeyAliasBuff);
211 if (res != HC_SUCCESS) {
212 LOGE("Failed to generate device key alias!");
213 return res;
214 }
215 KeyParams selfKeyParams = { { devKeyAliasBuff.val, devKeyAliasBuff.length, true }, false, osAccountId };
216 KeyBuff peerKeyBuff = { peerPubKey->val, peerPubKey->length, false };
217 res = GetLoaderInstance()->agreeSharedSecretWithStorage(&selfKeyParams, &peerKeyBuff, X25519,
218 MK_LEN, &mkAliasBuff);
219 if (res != HC_SUCCESS) {
220 LOGE("Failed to agree sharedSecret!");
221 ReportRadarEvent(res);
222 return res;
223 }
224 LOGI("Generate mk successfully!");
225 return HC_SUCCESS;
226 }
227
DeleteMk(int32_t osAccountId,const char * peerDeviceId)228 int32_t DeleteMk(int32_t osAccountId, const char *peerDeviceId)
229 {
230 if (peerDeviceId == NULL) {
231 LOGE("Invalid input param!");
232 return HC_ERR_INVALID_PARAMS;
233 }
234 uint8_t mkAlias[PAKE_KEY_ALIAS_LEN] = { 0 };
235 Uint8Buff mkAliasBuff = { mkAlias, PAKE_KEY_ALIAS_LEN };
236 int32_t res = GenerateMkAlias(peerDeviceId, &mkAliasBuff);
237 if (res != HC_SUCCESS) {
238 LOGE("Failed to generate mk alias!");
239 return res;
240 }
241 if (GetLoaderInstance()->checkKeyExist(&mkAliasBuff, false, osAccountId) != HC_SUCCESS) {
242 LOGI("mk does not exist, no need to delete!");
243 return HC_SUCCESS;
244 }
245 res = GetLoaderInstance()->deleteKey(&mkAliasBuff, false, osAccountId);
246 if (res != HC_SUCCESS) {
247 LOGE("Failed to delete mk!");
248 return res;
249 }
250 LOGI("Delete mk successfully!");
251 return HC_SUCCESS;
252 }
253
GeneratePseudonymPsk(int32_t osAccountId,const char * peerDeviceId,const Uint8Buff * salt)254 int32_t GeneratePseudonymPsk(int32_t osAccountId, const char *peerDeviceId, const Uint8Buff *salt)
255 {
256 if (peerDeviceId == NULL || salt == NULL) {
257 LOGE("Invalid input params!");
258 return HC_ERR_INVALID_PARAMS;
259 }
260 uint8_t pseudonymPskAlias[PAKE_KEY_ALIAS_LEN] = { 0 };
261 Uint8Buff pskAliasBuff = { pseudonymPskAlias, PAKE_KEY_ALIAS_LEN };
262 int32_t res = GeneratePseudonymPskAlias(peerDeviceId, &pskAliasBuff);
263 if (res != HC_SUCCESS) {
264 LOGE("Failed to generate pseudonym psk alias!");
265 return res;
266 }
267 uint8_t mkAlias[PAKE_KEY_ALIAS_LEN] = { 0 };
268 Uint8Buff mkAliasBuff = { mkAlias, PAKE_KEY_ALIAS_LEN };
269 res = GenerateMkAlias(peerDeviceId, &mkAliasBuff);
270 if (res != HC_SUCCESS) {
271 LOGE("Failed to generate mk alias!");
272 return res;
273 }
274 Uint8Buff pskBuff = { NULL, 0 };
275 if (InitUint8Buff(&pskBuff, MK_LEN) != HC_SUCCESS) {
276 LOGE("Failed to init pseudonym psk!");
277 return HC_ERR_ALLOC_MEMORY;
278 }
279 res = KeyDerivation(osAccountId, &mkAliasBuff, salt, true, &pskBuff);
280 if (res != HC_SUCCESS) {
281 LOGE("Failed to derive pseudonym psk!");
282 FreeUint8Buff(&pskBuff);
283 return res;
284 }
285 KeyParams keyParams = { { pskAliasBuff.val, pskAliasBuff.length, true }, false, osAccountId };
286 res = GetLoaderInstance()->importSymmetricKey(&keyParams, &pskBuff, KEY_PURPOSE_MAC, NULL);
287 ClearFreeUint8Buff(&pskBuff);
288 if (res != HC_SUCCESS) {
289 LOGE("Failed to import pseudonym psk!");
290 return res;
291 }
292 LOGI("Generate and save pseudonym psk successfully!");
293 return HC_SUCCESS;
294 }
295
DeletePseudonymPsk(int32_t osAccountId,const char * peerDeviceId)296 int32_t DeletePseudonymPsk(int32_t osAccountId, const char *peerDeviceId)
297 {
298 if (peerDeviceId == NULL) {
299 LOGE("Invalid input param!");
300 return HC_ERR_INVALID_PARAMS;
301 }
302 uint8_t pseudonymPskAlias[PAKE_KEY_ALIAS_LEN] = { 0 };
303 Uint8Buff pskAliasBuff = { pseudonymPskAlias, PAKE_KEY_ALIAS_LEN };
304 int32_t res = GeneratePseudonymPskAlias(peerDeviceId, &pskAliasBuff);
305 if (res != HC_SUCCESS) {
306 LOGE("Failed to generate psk alias!");
307 return res;
308 }
309 if (GetLoaderInstance()->checkKeyExist(&pskAliasBuff, false, osAccountId) != HC_SUCCESS) {
310 LOGI("Pseudonym psk does not exist, no need to delete!");
311 return HC_SUCCESS;
312 }
313 res = GetLoaderInstance()->deleteKey(&pskAliasBuff, false, osAccountId);
314 if (res != HC_SUCCESS) {
315 LOGE("Failed to delete pseudonym psk!");
316 return res;
317 }
318 LOGI("Delete pseudonym psk successfully!");
319 return HC_SUCCESS;
320 }
321
GenerateAndSavePseudonymId(int32_t osAccountId,const char * peerDeviceId,const PseudonymKeyInfo * info,const Uint8Buff * saltBuff,Uint8Buff * returnHmac)322 int32_t GenerateAndSavePseudonymId(int32_t osAccountId, const char *peerDeviceId, const PseudonymKeyInfo *info,
323 const Uint8Buff *saltBuff, Uint8Buff *returnHmac)
324 {
325 if (peerDeviceId == NULL || info == NULL || saltBuff == NULL || returnHmac == NULL) {
326 LOGE("Invalid input params!");
327 return HC_ERR_INVALID_PARAMS;
328 }
329 uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
330 Uint8Buff pskAliasBuff = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
331 int32_t res = GeneratePseudonymPskAlias(peerDeviceId, &pskAliasBuff);
332 if (res != HC_SUCCESS) {
333 LOGE("Failed to generate pseudonym psk alias!");
334 return res;
335 }
336 uint8_t pseudonymIdVal[MK_LEN] = { 0 };
337 Uint8Buff pseudonymIdBuff = { pseudonymIdVal, MK_LEN };
338 KeyParams keyParams = { { pskAliasBuff.val, pskAliasBuff.length, true }, false, osAccountId };
339 res = GetLoaderInstance()->computeHmac(&keyParams, saltBuff, &pseudonymIdBuff);
340 if (res != HC_SUCCESS) {
341 LOGE("Failed to compute hmac!");
342 return res;
343 }
344 if (DeepCopyUint8Buff(&pseudonymIdBuff, returnHmac) != HC_SUCCESS) {
345 LOGE("Failed to copy hmac!");
346 return HC_ERR_ALLOC_MEMORY;
347 }
348 uint32_t pdidLen = pseudonymIdBuff.length * BYTE_TO_HEX_OPER_LENGTH + 1;
349 char *pdid = (char *)HcMalloc(pdidLen, 0);
350 if (pdid == NULL) {
351 LOGE("Failed to alloc memory for pdid!");
352 ClearFreeUint8Buff(returnHmac);
353 return HC_ERR_ALLOC_MEMORY;
354 }
355 res = ByteToHexString(pseudonymIdBuff.val, pseudonymIdBuff.length, pdid, pdidLen);
356 if (res != HC_SUCCESS) {
357 LOGE("Failed to convert pdid from byte to hex string!");
358 ClearFreeUint8Buff(returnHmac);
359 HcFree(pdid);
360 return res;
361 }
362 res = GetPseudonymInstance()->savePseudonymId(osAccountId, pdid, info->peerInfo, peerDeviceId, info->pdidIndex);
363 HcFree(pdid);
364 if (res != HC_SUCCESS) {
365 LOGE("Failed to save pdid!");
366 ClearFreeUint8Buff(returnHmac);
367 return res;
368 }
369 LOGI("Generate and save pdid successfully!");
370 return HC_SUCCESS;
371 }
372
GetDevicePubKey(int32_t osAccountId,Uint8Buff * devicePk)373 int32_t GetDevicePubKey(int32_t osAccountId, Uint8Buff *devicePk)
374 {
375 if (devicePk == NULL) {
376 LOGE("Invalid input param!");
377 return HC_ERR_INVALID_PARAMS;
378 }
379 uint8_t keyAlias[PAKE_KEY_ALIAS_LEN] = { 0 };
380 Uint8Buff keyAliasBuff = { keyAlias, PAKE_KEY_ALIAS_LEN };
381 int32_t res = GenerateDevKeyAlias(&keyAliasBuff);
382 if (res != HC_SUCCESS) {
383 LOGE("Failed to generate device key alias!");
384 return res;
385 }
386 KeyParams keyParams = { { keyAliasBuff.val, keyAliasBuff.length, true }, false, osAccountId };
387 res = GetLoaderInstance()->exportPublicKey(&keyParams, devicePk);
388 if (res != HC_SUCCESS) {
389 LOGE("Failed to export device pk!");
390 }
391 return res;
392 }