1 /*
2  * Copyright (c) 2023-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 #include "hks_chipset_platform_key.h"
16 
17 #include "hks_chipset_platform_decrypt.h"
18 #include "hks_crypto_hal.h"
19 #include "hks_log.h"
20 #include "hks_mem.h"
21 #include "hks_template.h"
22 
23 #include "securec.h"
24 
25 static const uint8_t PLATFORM_KEY_PLATFORM_PRI_KEY[PLATFORM_KEY_PLATFORM_PRI_KEY_SIZE] = {
26     0xF1, 0xDB, 0x27, 0xE9, 0xD8, 0x3A, 0xB6, 0x3F, 0xD6, 0x65, 0x1B, 0x2E, 0xC6, 0x2F, 0x67, 0x60,
27     0xE7, 0x90, 0x67, 0x47, 0x8A, 0xA3, 0x03, 0x06, 0x1F, 0x5F, 0xC9, 0x32, 0x4B, 0xA4, 0x9A, 0x50,
28 };
29 
30 static const uint8_t PLATFORM_KEY_PLATFORM_PUB_KEY[PLATFORM_KEY_PLATFORM_PUB_KEY_SIZE] = {
31     0x28, 0x22, 0xFE, 0xDC, 0xCF, 0x23, 0x14, 0x19, 0x16, 0xA6, 0xBE, 0x98, 0x1D, 0x7A, 0x11, 0x19,
32     0x25, 0xAA, 0xBC, 0xCF, 0x01, 0x97, 0x93, 0x33, 0xB5, 0x86, 0x6C, 0xB7, 0xE6, 0x09, 0x9A, 0x93,
33     0xB9, 0x46, 0xD5, 0xBB, 0x6B, 0x8E, 0x03, 0x53, 0xC0, 0xA6, 0x2D, 0x99, 0x3D, 0x5A, 0x10, 0xCF,
34     0x8D, 0x8A, 0xEC, 0x9C, 0x39, 0xFE, 0xD5, 0x84, 0x37, 0xE7, 0x44, 0x0C, 0xF4, 0xFC, 0xAD, 0xB2,
35 };
36 
37 enum {
38     FULL_PLATFORM_PUBLIC_KEY_SIZE = sizeof(struct KeyMaterialEcc) + PLATFORM_KEY_PLATFORM_PUB_KEY_SIZE,
39     FULL_PLATFORM_PRIVATE_KEY_SIZE = FULL_PLATFORM_PUBLIC_KEY_SIZE + PLATFORM_KEY_PLATFORM_PRI_KEY_SIZE,
40 };
41 
42 // Notice: you MUST call HKS_FREE_BLOB after using fullHksPubKey
MallocAndFillFullHksPublicKey(const struct HksBlob * rawPubKey,struct HksBlob * fullHksPubKey)43 static int32_t MallocAndFillFullHksPublicKey(const struct HksBlob *rawPubKey, struct HksBlob *fullHksPubKey)
44 {
45     struct KeyMaterialEcc publicKeyMaterial = {
46         .keyAlg = HKS_ALG_ECC,
47         .keySize = PLATFORM_KEY_PLATFORM_PRI_KEY_SIZE * HKS_BITS_PER_BYTE,
48         .xSize = PLATFORM_KEY_PLATFORM_PRI_KEY_SIZE,
49         .ySize = PLATFORM_KEY_PLATFORM_PRI_KEY_SIZE,
50         .zSize = 0,
51     };
52 
53     fullHksPubKey->data = (uint8_t *)HksMalloc(FULL_PLATFORM_PUBLIC_KEY_SIZE);
54     HKS_IF_NULL_LOGE_RETURN(fullHksPubKey->data, HKS_ERROR_MALLOC_FAIL, "malloc full hks public key failed")
55     fullHksPubKey->size = FULL_PLATFORM_PUBLIC_KEY_SIZE;
56     int32_t ret;
57     do {
58         ret = memcpy_s(fullHksPubKey->data, fullHksPubKey->size,
59             &publicKeyMaterial, sizeof(publicKeyMaterial));
60         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "copy public key material failed")
61         ret = memcpy_s(fullHksPubKey->data + sizeof(publicKeyMaterial),
62             fullHksPubKey->size - sizeof(publicKeyMaterial),
63             rawPubKey->data, rawPubKey->size);
64         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "copy raw public key failed")
65         return HKS_SUCCESS;
66     } while (false);
67     (void)memset_s(fullHksPubKey->data, FULL_PLATFORM_PUBLIC_KEY_SIZE, 0, FULL_PLATFORM_PUBLIC_KEY_SIZE);
68     HKS_FREE_BLOB(*fullHksPubKey);
69     return HKS_ERROR_INTERNAL_ERROR;
70 }
71 
72 /**
73  * malloc a new blob and fill with full platform private key
74  * Notice: you MUST free the blob data after using
75  */
MallocFullPlatformPrivateKey(struct HksBlob * privateKey)76 static int32_t MallocFullPlatformPrivateKey(struct HksBlob *privateKey)
77 {
78     struct KeyMaterialEcc privateKeyMaterial = {
79         .keyAlg = HKS_ALG_ECC,
80         .keySize = PLATFORM_KEY_PLATFORM_PRI_KEY_SIZE * HKS_BITS_PER_BYTE,
81         .xSize = PLATFORM_KEY_PLATFORM_PRI_KEY_SIZE,
82         .ySize = PLATFORM_KEY_PLATFORM_PRI_KEY_SIZE,
83         .zSize = PLATFORM_KEY_PLATFORM_PRI_KEY_SIZE,
84     };
85     privateKey->data = (uint8_t *)HksMalloc(FULL_PLATFORM_PRIVATE_KEY_SIZE);
86     HKS_IF_NULL_LOGE_RETURN(privateKey->data, HKS_ERROR_MALLOC_FAIL, "malloc private key failed")
87     privateKey->size = FULL_PLATFORM_PRIVATE_KEY_SIZE;
88     do {
89         int32_t ret = memcpy_s(privateKey->data, privateKey->size, &privateKeyMaterial, sizeof(privateKeyMaterial));
90         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "copy private key material failed")
91         ret = memcpy_s(privateKey->data + sizeof(privateKeyMaterial), privateKey->size - sizeof(privateKeyMaterial),
92             PLATFORM_KEY_PLATFORM_PUB_KEY, PLATFORM_KEY_PLATFORM_PUB_KEY_SIZE);
93         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "copy public key failed")
94         ret = memcpy_s(privateKey->data + sizeof(privateKeyMaterial) + PLATFORM_KEY_PLATFORM_PUB_KEY_SIZE,
95             privateKey->size - sizeof(privateKeyMaterial) - PLATFORM_KEY_PLATFORM_PUB_KEY_SIZE,
96             PLATFORM_KEY_PLATFORM_PRI_KEY, PLATFORM_KEY_PLATFORM_PRI_KEY_SIZE);
97         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "copy private key failed")
98         return HKS_SUCCESS;
99     } while (false);
100     (void)(memset_s(privateKey->data, FULL_PLATFORM_PRIVATE_KEY_SIZE, 0, FULL_PLATFORM_PRIVATE_KEY_SIZE));
101     HKS_FREE_BLOB(*privateKey);
102     return HKS_ERROR_INTERNAL_ERROR;
103 }
104 
HksChipsetPlatformDeriveKeyAndEcdh(const struct HksBlob * peerPk,const struct HksBlob * salt,struct HksBlob * sharedKey)105 int32_t HksChipsetPlatformDeriveKeyAndEcdh(const struct HksBlob *peerPk, const struct HksBlob *salt,
106     struct HksBlob *sharedKey)
107 {
108     // salt is ignored in the hardcoded key implementation,
109     // and it SHOULD be used in true hardware based implementations.
110     (void)(salt);
111     struct HksKeySpec ecdhSpec = {
112         .algType = HKS_ALG_ECDH,
113         .keyLen = HKS_ECC_KEY_SIZE_256,
114         .algParam = NULL,
115     };
116     struct HksBlob platformPrivateKey = { .size = 0, .data = NULL };
117     struct HksBlob peerHksPubKey = { .size = 0, .data = NULL };
118     int32_t ret = MallocFullPlatformPrivateKey(&platformPrivateKey);
119     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "malloc full platform private key failed")
120     do {
121         ret = MallocAndFillFullHksPublicKey(peerPk, &peerHksPubKey);
122         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "malloc or fill full hks pub key failed");
123 
124         HKS_LOG_I("DoGenEcdhSharedKey hal start");
125         ret = HksCryptoHalAgreeKey(&platformPrivateKey, &peerHksPubKey, &ecdhSpec, sharedKey);
126         HKS_LOG_I("DoGenEcdhSharedKey hal end");
127     } while (false);
128     (void)(memset_s(peerHksPubKey.data, peerHksPubKey.size, 0, peerHksPubKey.size));
129     (void)(memset_s(platformPrivateKey.data, platformPrivateKey.size, 0, platformPrivateKey.size));
130     HKS_FREE_BLOB(peerHksPubKey);
131     HKS_FREE_BLOB(platformPrivateKey);
132     return ret;
133 }
134 
HksChipsetPlatformDerivePubKey(const struct HksBlob * salt,struct HksBlob * pubKey)135 int32_t HksChipsetPlatformDerivePubKey(const struct HksBlob *salt, struct HksBlob *pubKey)
136 {
137     // salt is ignored in the hardcoded key implementation,
138     // and it SHOULD be used in true hardware based implementations.
139     (void)(salt);
140     if (CheckBlob(pubKey) != HKS_SUCCESS || pubKey->size != PLATFORM_KEY_PLATFORM_PUB_KEY_SIZE) {
141         HKS_LOG_E("invalid out param pub key");
142         return HKS_ERROR_INVALID_ARGUMENT;
143     }
144     (void)memcpy_s(pubKey->data, PLATFORM_KEY_PLATFORM_PUB_KEY_SIZE,
145         PLATFORM_KEY_PLATFORM_PUB_KEY, PLATFORM_KEY_PLATFORM_PUB_KEY_SIZE);
146     return HKS_SUCCESS;
147 }
148