• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *)&params->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