• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }