1 /*
2 * Copyright (c) 2022 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 "huks_wrapped_test_common.h"
17
18 #include <gtest/gtest.h>
19
20 #include "huks_three_stage_test_common.h"
21
22 using namespace testing::ext;
23 namespace Unittest::ImportWrapped
24 {
25 static struct OH_Huks_Param g_aesKekEncryptParams[] = {
26 {.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_AES},
27 {.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_ENCRYPT},
28 {.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_AES_KEY_SIZE_256},
29 {.tag = OH_HUKS_TAG_PADDING, .uint32Param = OH_HUKS_PADDING_NONE},
30 {.tag = OH_HUKS_TAG_BLOCK_MODE, .uint32Param = OH_HUKS_MODE_GCM},
31 {.tag = OH_HUKS_TAG_DIGEST, .uint32Param = OH_HUKS_DIGEST_NONE},
32 {.tag = OH_HUKS_TAG_ASSOCIATED_DATA,
33 .blob = {.size = Unittest::ImportWrapped::AAD_SIZE, .data = (uint8_t *)Unittest::ImportWrapped::AAD}},
34 {.tag = OH_HUKS_TAG_NONCE,
35 .blob = {.size = Unittest::ImportWrapped::NONCE_SIZE, .data = (uint8_t *)Unittest::ImportWrapped::NONCE}},
36 {.tag = OH_HUKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = OH_HUKS_AUTH_STORAGE_LEVEL_DE}};
37
38 static struct OH_Huks_Param g_importAgreeKeyParams[] = {
39 {.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_AES},
40 {.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_ENCRYPT},
41 {.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_AES_KEY_SIZE_256},
42 {.tag = OH_HUKS_TAG_PADDING, .uint32Param = OH_HUKS_PADDING_NONE},
43 {.tag = OH_HUKS_TAG_BLOCK_MODE, .uint32Param = OH_HUKS_MODE_GCM},
44 {.tag = OH_HUKS_TAG_DIGEST, .uint32Param = OH_HUKS_DIGEST_NONE},
45 {.tag = OH_HUKS_TAG_IV,
46 .blob = {.size = Unittest::ImportWrapped::IV_SIZE, .data = (uint8_t *)Unittest::ImportWrapped::IV}},
47 {.tag = OH_HUKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = OH_HUKS_AUTH_STORAGE_LEVEL_DE}};
48
BuildWrappedKeyData(struct OH_Huks_Blob ** blobArray,uint32_t size,struct OH_Huks_Blob * outData)49 static OH_Huks_Result BuildWrappedKeyData(struct OH_Huks_Blob **blobArray, uint32_t size, struct OH_Huks_Blob *outData)
50 {
51 uint32_t totalLength = size * sizeof(uint32_t);
52 struct OH_Huks_Result ret;
53 ret.errorCode = OH_HUKS_SUCCESS;
54
55 /* counter size */
56 for (uint32_t i = 0; i < size; ++i) {
57 totalLength += blobArray[i]->size;
58 }
59
60 struct OH_Huks_Blob outBlob = {0, nullptr};
61 outBlob.size = totalLength;
62 (void)MallocAndCheckBlobData(&outBlob, outBlob.size);
63
64 uint32_t offset = 0;
65
66 /* copy data */
67 for (uint32_t i = 0; i < size; ++i) {
68 if (memcpy_s(outBlob.data + offset, totalLength - offset, reinterpret_cast<uint8_t *>(&blobArray[i]->size),
69 sizeof(blobArray[i]->size)) != EOK) {
70 ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
71 return ret;
72 }
73 offset += sizeof(blobArray[i]->size);
74
75 if (memcpy_s(outBlob.data + offset, totalLength - offset, blobArray[i]->data, blobArray[i]->size) != EOK) {
76 ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
77 return ret;
78 }
79 offset += blobArray[i]->size;
80 }
81
82 outData->size = outBlob.size;
83 outData->data = outBlob.data;
84 return ret;
85 }
86
CheckParamsValid(const struct HksImportWrappedKeyTestParams * params)87 static OH_Huks_Result CheckParamsValid(const struct HksImportWrappedKeyTestParams *params)
88 {
89 struct OH_Huks_Result ret;
90 ret.errorCode = OH_HUKS_SUCCESS;
91 if (params == nullptr) {
92 ret.errorCode = OH_HUKS_ERR_CODE_ILLEGAL_ARGUMENT;
93 return ret;
94 }
95
96 if (params->wrappingKeyAlias == nullptr || params->genWrappingKeyParamSet == nullptr ||
97 params->agreeKeyAlgName == nullptr || params->callerKeyAlias == nullptr ||
98 params->genCallerKeyParamSet == nullptr || params->callerKekAlias == nullptr || params->callerKek == nullptr ||
99 params->importCallerKekParamSet == nullptr || params->callerAgreeKeyAlias == nullptr ||
100 params->agreeParamSet == nullptr || params->importWrappedKeyParamSet == nullptr ||
101 params->importedKeyAlias == nullptr || params->importedPlainKey == nullptr) {
102 ret.errorCode = OH_HUKS_ERR_CODE_ILLEGAL_ARGUMENT;
103 return ret;
104 }
105 return ret;
106 }
107
GenerateAndExportHuksPublicKey(const struct HksImportWrappedKeyTestParams * params,struct OH_Huks_Blob * huksPublicKey)108 static void GenerateAndExportHuksPublicKey(const struct HksImportWrappedKeyTestParams *params,
109 struct OH_Huks_Blob *huksPublicKey)
110 {
111 OH_Huks_Result ret = OH_Huks_GenerateKeyItem(params->wrappingKeyAlias, params->genWrappingKeyParamSet, nullptr);
112 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "Generate huks key failed.";
113 huksPublicKey->size = params->publicKeySize;
114
115 EXPECT_EQ(MallocAndCheckBlobData(huksPublicKey, huksPublicKey->size).errorCode, (int32_t)OH_HUKS_SUCCESS)
116 << "Malloc pub key failed.";
117 ret = OH_Huks_ExportPublicKeyItem(params->wrappingKeyAlias, params->genWrappingKeyParamSet, huksPublicKey);
118 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "Export huks public key failed.";
119 }
120
GenerateAndExportCallerPublicKey(const struct HksImportWrappedKeyTestParams * params,struct OH_Huks_Blob * callerSelfPublicKey)121 static void GenerateAndExportCallerPublicKey(const struct HksImportWrappedKeyTestParams *params,
122 struct OH_Huks_Blob *callerSelfPublicKey)
123 {
124 OH_Huks_Result ret = OH_Huks_GenerateKeyItem(params->callerKeyAlias, params->genCallerKeyParamSet, nullptr);
125 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "Generate caller key failed.";
126
127 callerSelfPublicKey->size = params->publicKeySize;
128 EXPECT_EQ(MallocAndCheckBlobData(callerSelfPublicKey, callerSelfPublicKey->size).errorCode,
129 (int32_t)OH_HUKS_SUCCESS)
130 << "malloc fail";
131 ret = OH_Huks_ExportPublicKeyItem(params->callerKeyAlias, params->genWrappingKeyParamSet, callerSelfPublicKey);
132 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "Export caller public key failed.";
133 }
134
ImportKekAndAgreeSharedSecret(const struct HksImportWrappedKeyTestParams * params,const struct OH_Huks_Blob * huksPublicKey,struct OH_Huks_Blob * outSharedKey)135 static void ImportKekAndAgreeSharedSecret(const struct HksImportWrappedKeyTestParams *params,
136 const struct OH_Huks_Blob *huksPublicKey, struct OH_Huks_Blob *outSharedKey)
137 {
138 OH_Huks_Result ret =
139 OH_Huks_ImportKeyItem(params->callerKekAlias, params->importCallerKekParamSet, params->callerKek);
140 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "ImportCallerSelfKek failed.";
141 EXPECT_EQ(MallocAndCheckBlobData(outSharedKey, outSharedKey->size).errorCode, (int32_t)OH_HUKS_SUCCESS)
142 << "Malloc sharedKey failed.";
143
144 ret = HuksAgreeKey(params->agreeParamSet, params->callerKeyAlias, huksPublicKey, outSharedKey);
145 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS)
146 << "HuksAgreeKey with huks public key and caller private key failed.";
147
148 struct OH_Huks_ParamSet *importAgreeKeyParams = nullptr;
149 ret = InitParamSet(&importAgreeKeyParams, g_importAgreeKeyParams,
150 sizeof(g_importAgreeKeyParams) / sizeof(OH_Huks_Param));
151 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "InitParamSet(importAgreeKey) failed.";
152
153 ret = OH_Huks_ImportKeyItem(params->callerAgreeKeyAlias, importAgreeKeyParams, outSharedKey);
154 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "import agree shared key failed.";
155 OH_Huks_FreeParamSet(&importAgreeKeyParams);
156 }
157
EncryptImportedPlainKeyAndKek(const struct HksImportWrappedKeyTestParams * params,struct OH_Huks_Blob * plainCipherText,struct OH_Huks_Blob * kekCipherText)158 static void EncryptImportedPlainKeyAndKek(const struct HksImportWrappedKeyTestParams *params,
159 struct OH_Huks_Blob *plainCipherText, struct OH_Huks_Blob *kekCipherText)
160 {
161 struct OH_Huks_ParamSet *encryptParamSet = nullptr;
162 OH_Huks_Result ret =
163 InitParamSet(&encryptParamSet, g_aesKekEncryptParams, sizeof(g_aesKekEncryptParams) / sizeof(OH_Huks_Param));
164 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "InitParamSet(aesKekEnc) failed.";
165 ret = HuksEncrypt(params->callerKekAlias, encryptParamSet, params->importedPlainKey, plainCipherText);
166 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "HuksEncrypt plain key to be imported failed.";
167
168 ret = HuksEncrypt(params->callerAgreeKeyAlias, encryptParamSet, params->callerKek, kekCipherText);
169 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "Kek encrypt failed.";
170 OH_Huks_FreeParamSet(&encryptParamSet);
171 }
172
ImportWrappedKey(const struct HksImportWrappedKeyTestParams * params,struct OH_Huks_Blob * plainCipher,struct OH_Huks_Blob * kekCipherText,struct OH_Huks_Blob * peerPublicKey,struct OH_Huks_Blob * wrappedKeyData)173 static void ImportWrappedKey(const struct HksImportWrappedKeyTestParams *params, struct OH_Huks_Blob *plainCipher,
174 struct OH_Huks_Blob *kekCipherText, struct OH_Huks_Blob *peerPublicKey,
175 struct OH_Huks_Blob *wrappedKeyData)
176 {
177 struct OH_Huks_Blob commonAad = {.size = Unittest::ImportWrapped::AAD_SIZE,
178 .data = reinterpret_cast<uint8_t *>(Unittest::ImportWrapped::AAD)};
179 struct OH_Huks_Blob commonNonce = {.size = Unittest::ImportWrapped::NONCE_SIZE,
180 .data = reinterpret_cast<uint8_t *>(Unittest::ImportWrapped::NONCE)};
181 struct OH_Huks_Blob keyMaterialLen = {.size = sizeof(uint32_t), .data = (uint8_t *)¶ms->keyMaterialLen};
182
183 /* copy AEAD tag from cipher text and decrease its size */
184 const uint32_t tagSize = Unittest::ImportWrapped::AEAD_TAG_SIZE;
185 uint8_t kekTagBuf[tagSize] = {0};
186 struct OH_Huks_Blob kekTag = {.size = tagSize, .data = kekTagBuf};
187 if (memcpy_s(kekTag.data, tagSize, plainCipher->data + (plainCipher->size - tagSize), tagSize) != EOK) {
188 EXPECT_EQ(OH_HUKS_ERR_CODE_ILLEGAL_ARGUMENT, EOK) << "memcpy kek tag failed.";
189 }
190 plainCipher->size -= tagSize;
191
192 /* copy AEAD tag from kek cipher text and decrease its size */
193 uint8_t agreeKeyTagBuf[tagSize] = {0};
194 struct OH_Huks_Blob agreeKeyTag = {.size = tagSize, .data = agreeKeyTagBuf};
195 if (memcpy_s(agreeKeyTagBuf, tagSize, kekCipherText->data + (kekCipherText->size - tagSize), tagSize) != EOK) {
196 EXPECT_EQ(OH_HUKS_ERR_CODE_ILLEGAL_ARGUMENT, EOK) << "memcpy agreekey tag failed.";
197 }
198 kekCipherText->size -= tagSize;
199
200 struct OH_Huks_Blob *blobArray[] = {peerPublicKey, &commonAad, &commonNonce, &agreeKeyTag, kekCipherText,
201 &commonAad, &commonNonce, &kekTag, &keyMaterialLen, plainCipher};
202 OH_Huks_Result ret = BuildWrappedKeyData(blobArray, OH_HUKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS, wrappedKeyData);
203 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "BuildWrappedKeyData failed.";
204
205 struct OH_Huks_Param *purpose = nullptr;
206 ret = OH_Huks_GetParam(params->importWrappedKeyParamSet, OH_HUKS_TAG_PURPOSE, &purpose);
207 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "Get wrapped purpose param failed.";
208
209 ret = OH_Huks_ImportWrappedKeyItem(params->importedKeyAlias, params->wrappingKeyAlias,
210 params->importWrappedKeyParamSet, wrappedKeyData);
211
212 if (purpose->uint32Param == (uint32_t)OH_HUKS_KEY_PURPOSE_UNWRAP) {
213 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_ERR_CODE_INVALID_CRYPTO_ALG_ARGUMENT)
214 << "Import unwrap purpose wrapped key shouldn't be success.";
215 } else {
216 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "OH_Huks_ImportWrappedKeyItem failed.";
217 }
218 }
219
HksImportWrappedKeyTestCommonCase(const struct HksImportWrappedKeyTestParams * params)220 void HksImportWrappedKeyTestCommonCase(const struct HksImportWrappedKeyTestParams *params)
221 {
222 OH_Huks_Result ret = CheckParamsValid(params);
223 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "CheckParamsValid failed.";
224 if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
225 return;
226 }
227
228 struct OH_Huks_Blob huksPublicKey = {0, nullptr};
229 struct OH_Huks_Blob callerSelfPublicKey = {0, nullptr};
230 struct OH_Huks_Blob outSharedKey = {.size = OH_HUKS_KEY_BYTES(OH_HUKS_AES_KEY_SIZE_256), .data = nullptr};
231 struct OH_Huks_Blob wrappedKeyData = {0, nullptr};
232 uint8_t plainKeyCipherBuffer[OH_HUKS_MAX_KEY_SIZE] = {0};
233 struct OH_Huks_Blob plainCipherText = {OH_HUKS_MAX_KEY_SIZE, plainKeyCipherBuffer};
234 uint8_t kekCipherTextBuffer[OH_HUKS_MAX_KEY_SIZE] = {0};
235 struct OH_Huks_Blob kekCipherText = {OH_HUKS_MAX_KEY_SIZE, kekCipherTextBuffer};
236
237 GenerateAndExportHuksPublicKey(params, &huksPublicKey);
238 GenerateAndExportCallerPublicKey(params, &callerSelfPublicKey);
239 ImportKekAndAgreeSharedSecret(params, &huksPublicKey, &outSharedKey);
240 EncryptImportedPlainKeyAndKek(params, &plainCipherText, &kekCipherText);
241 ImportWrappedKey(params, &plainCipherText, &kekCipherText, &callerSelfPublicKey, &wrappedKeyData);
242
243 HUKS_FREE_BLOB(huksPublicKey);
244 HUKS_FREE_BLOB(callerSelfPublicKey);
245 HUKS_FREE_BLOB(outSharedKey);
246 HUKS_FREE_BLOB(wrappedKeyData);
247 }
248
HksClearKeysForWrappedKeyTest(const struct HksImportWrappedKeyTestParams * params)249 void HksClearKeysForWrappedKeyTest(const struct HksImportWrappedKeyTestParams *params)
250 {
251 OH_Huks_Result ret = CheckParamsValid(params);
252 EXPECT_EQ(ret.errorCode, (int32_t)OH_HUKS_SUCCESS) << "CheckParamsValid failed.";
253 if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
254 return;
255 }
256 (void)OH_Huks_DeleteKeyItem(params->wrappingKeyAlias, params->genWrappingKeyParamSet);
257 (void)OH_Huks_DeleteKeyItem(params->callerKeyAlias, params->genCallerKeyParamSet);
258 (void)OH_Huks_DeleteKeyItem(params->callerKekAlias, params->importCallerKekParamSet);
259 (void)OH_Huks_DeleteKeyItem(params->callerAgreeKeyAlias, params->agreeParamSet);
260 (void)OH_Huks_DeleteKeyItem(params->importedKeyAlias, params->importWrappedKeyParamSet);
261 }
262 } // namespace Unittest::ImportWrapped
263