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