• 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 <gtest/gtest.h>
17 
18 #include "hks_mem.h"
19 #include "hks_test_log.h"
20 #include "hks_type.h"
21 #include "hks_param.h"
22 #include "hks_three_stage_test_common.h"
23 
24 #include "hks_import_wrapped_test_common.h"
25 
26 using namespace testing::ext;
27 namespace Unittest::ImportWrappedKey {
28     static struct HksParam g_aesKekEncryptParams[] = {
29         {.tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES},
30         {.tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT},
31         {.tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256},
32         {.tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE},
33         {.tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM},
34         {.tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_NONE},
35         {.tag = HKS_TAG_ASSOCIATED_DATA, .blob = {.size = Unittest::ImportWrappedKey::AAD_SIZE,
36                                                   .data = (uint8_t *) Unittest::ImportWrappedKey::AAD}
37         },
38         { .tag = HKS_TAG_NONCE, .blob = {.size = Unittest::ImportWrappedKey::NONCE_SIZE,
39                                          .data = (uint8_t *) Unittest::ImportWrappedKey::NONCE}
40         }
41     };
42 
43     static struct HksParam g_importAgreeKeyParams[] = {
44         {.tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES},
45         {.tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT},
46         {.tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256},
47         {.tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE},
48         {.tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM},
49         {.tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_NONE},
50         {.tag = HKS_TAG_IV, .blob = {.size = Unittest::ImportWrappedKey::IV_SIZE,
51                                      .data = (uint8_t *) Unittest::ImportWrappedKey::IV }
52         }
53     };
54 
BuildWrappedKeyData(struct HksBlob ** blobArray,uint32_t size,struct HksBlob * outData)55     static int32_t BuildWrappedKeyData(struct HksBlob **blobArray, uint32_t size, struct HksBlob *outData)
56     {
57         uint32_t totalLength = size * sizeof(uint32_t);
58 
59         /* counter size */
60         for (uint32_t i = 0; i < size; ++i) {
61             totalLength += blobArray[i]->size;
62         }
63 
64         struct HksBlob outBlob = { 0, nullptr };
65         outBlob.size = totalLength;
66         (void)MallocAndCheckBlobData(&outBlob, outBlob.size);
67 
68         uint32_t offset = 0;
69 
70         /* copy data */
71         for (uint32_t i = 0; i < size; ++i) {
72             if (memcpy_s(outBlob.data + offset, totalLength - offset, reinterpret_cast<uint8_t *>(&blobArray[i]->size),
73                 sizeof(blobArray[i]->size)) != EOK) {
74                 return HKS_ERROR_BUFFER_TOO_SMALL;
75             }
76             offset += sizeof(blobArray[i]->size);
77 
78             if (memcpy_s(outBlob.data + offset, totalLength - offset, blobArray[i]->data,
79                 blobArray[i]->size) != EOK) {
80                 return HKS_ERROR_BUFFER_TOO_SMALL;
81             }
82             offset += blobArray[i]->size;
83         }
84 
85         outData->size = outBlob.size;
86         outData->data = outBlob.data;
87         return HKS_SUCCESS;
88     }
89 
CheckParamsValid(const struct HksImportWrappedKeyTestParams * params)90     static int32_t CheckParamsValid(const struct HksImportWrappedKeyTestParams *params)
91     {
92         if (params == nullptr) {
93             return HKS_ERROR_INVALID_ARGUMENT;
94         }
95 
96         if (params->wrappingKeyAlias == nullptr || params->genWrappingKeyParamSet == nullptr ||
97             params->agreeKeyAlgName == nullptr || params->callerKeyAlias == nullptr ||
98             params->genCallerKeyParamSet == nullptr || params->callerKekAlias == nullptr ||
99             params->callerKek == nullptr || params->importCallerKekParamSet == nullptr ||
100             params->callerAgreeKeyAlias == nullptr || params->agreeParamSet == nullptr ||
101             params->importWrappedKeyParamSet == nullptr || params->importedKeyAlias == nullptr ||
102             params->importedPlainKey == nullptr) {
103             return HKS_ERROR_INVALID_ARGUMENT;
104         }
105         return HKS_SUCCESS;
106     }
107 
GenerateAndExportHuksPublicKey(const struct HksImportWrappedKeyTestParams * params,struct HksBlob * huksPublicKey)108     static void GenerateAndExportHuksPublicKey(const struct HksImportWrappedKeyTestParams *params,
109         struct HksBlob *huksPublicKey)
110     {
111         HKS_TEST_LOG_I("-------------1. Test_GenerateHuks[%s]Key1\n",
112             reinterpret_cast<char *>(params->agreeKeyAlgName->data));
113         int32_t ret = HksGenerateKey(params->wrappingKeyAlias, params->genWrappingKeyParamSet, nullptr);
114         EXPECT_EQ(ret, HKS_SUCCESS) << "Generate huks key failed.";
115 
116         HKS_TEST_LOG_I("-------------2. Test_ExportHuks[%s]Key1\n",
117             reinterpret_cast<char *>(params->agreeKeyAlgName->data));
118         huksPublicKey->size = params->publicKeySize;
119 
120         EXPECT_EQ(MallocAndCheckBlobData(huksPublicKey, huksPublicKey->size),
121             HKS_SUCCESS) << "Malloc pub key failed.";
122         ret = HksExportPublicKey(params->wrappingKeyAlias, nullptr, huksPublicKey);
123         EXPECT_EQ(ret, HKS_SUCCESS) << "Export huks public key failed.";
124     }
125 
GenerateAndExportCallerPublicKey(const struct HksImportWrappedKeyTestParams * params,struct HksBlob * callerSelfPublicKey)126     static void GenerateAndExportCallerPublicKey(const struct HksImportWrappedKeyTestParams *params,
127         struct HksBlob *callerSelfPublicKey)
128     {
129         HKS_TEST_LOG_I("-------------3. Test_GenerateCallerSelf[%s]Key!\n",
130             reinterpret_cast<char *>(params->agreeKeyAlgName->data));
131         int32_t ret = HksGenerateKey(params->callerKeyAlias, params->genCallerKeyParamSet, nullptr);
132         EXPECT_EQ(ret, HKS_SUCCESS) << "Generate caller key failed.";
133 
134         callerSelfPublicKey->size = params->publicKeySize;
135         EXPECT_EQ(MallocAndCheckBlobData(callerSelfPublicKey,
136             callerSelfPublicKey->size), HKS_SUCCESS) << "malloc fail";
137         ret = HksExportPublicKey(params->callerKeyAlias, params->genWrappingKeyParamSet, callerSelfPublicKey);
138         EXPECT_EQ(ret, HKS_SUCCESS) << "Export caller public key failed.";
139     }
140 
ImportKekAndAgreeSharedSecret(const struct HksImportWrappedKeyTestParams * params,const struct HksBlob * huksPublicKey,struct HksBlob * outSharedKey)141     static void ImportKekAndAgreeSharedSecret(const struct HksImportWrappedKeyTestParams *params,
142         const struct HksBlob *huksPublicKey, struct HksBlob *outSharedKey)
143     {
144         HKS_TEST_LOG_I("-------------4. Test_ImportCallerSelfKek!\n");
145         int32_t ret = HksImportKey(params->callerKekAlias, params->importCallerKekParamSet, params->callerKek);
146         EXPECT_EQ(ret, HKS_SUCCESS) << "ImportCallerSelfKek failed.";
147 
148         HKS_TEST_LOG_I("-------------5. Test_CallerAgree[%s]Key and Import To Huks!\n",
149                        reinterpret_cast<char *>(params->agreeKeyAlgName->data));
150         EXPECT_EQ(MallocAndCheckBlobData(outSharedKey, outSharedKey->size), HKS_SUCCESS) << "Malloc sharedKey failed.";
151 
152         ret = HksAgreeKey(params->agreeParamSet, params->callerKeyAlias, huksPublicKey, outSharedKey);
153         EXPECT_EQ(ret, HKS_SUCCESS) << "HksAgreeKey with huks public key and caller private key failed.";
154 
155         struct HksParamSet *importAgreeKeyParams = nullptr;
156         ret = InitParamSet(&importAgreeKeyParams, g_importAgreeKeyParams,
157                            sizeof(g_importAgreeKeyParams) / sizeof(HksParam));
158         EXPECT_EQ(ret, HKS_SUCCESS) << "InitParamSet(importAgreeKey) failed.";
159 
160         ret = HksImportKey(params->callerAgreeKeyAlias, importAgreeKeyParams, outSharedKey);
161         EXPECT_EQ(ret, HKS_SUCCESS) << "import agree shared key failed.";
162         HksFreeParamSet(&importAgreeKeyParams);
163     }
164 
EncryptImportedPlainKeyAndKek(const struct HksImportWrappedKeyTestParams * params,struct HksBlob * plainCipherText,struct HksBlob * kekCipherText)165     static void EncryptImportedPlainKeyAndKek(const struct HksImportWrappedKeyTestParams *params,
166         struct HksBlob *plainCipherText, struct HksBlob *kekCipherText)
167     {
168         HKS_TEST_LOG_I("-------------6. Test_CallerEncryptPlainKeyUseKek!\n");
169         struct HksParamSet *encryptParamSet = nullptr;
170         int32_t ret = InitParamSet(&encryptParamSet, g_aesKekEncryptParams,
171                                    sizeof(g_aesKekEncryptParams) / sizeof(HksParam));
172         EXPECT_EQ(ret, HKS_SUCCESS) << "InitParamSet(aesKekEnc) failed.";
173         ret = HksEncrypt(params->callerKekAlias, encryptParamSet, params->importedPlainKey, plainCipherText);
174         EXPECT_EQ(ret, HKS_SUCCESS) << "HksEncrypt plain key to be imported failed.";
175 
176         HKS_TEST_LOG_I("-------------7. Test_CallerEncryptKekUseAgreeKey!\n");
177         ret = HksEncrypt(params->callerAgreeKeyAlias, encryptParamSet, params->callerKek, kekCipherText);
178         EXPECT_EQ(ret, HKS_SUCCESS) << "Kek encrypt failed.";
179         HksFreeParamSet(&encryptParamSet);
180     }
181 
ImportWrappedKey(const struct HksImportWrappedKeyTestParams * params,struct HksBlob * plainCipher,struct HksBlob * kekCipherText,struct HksBlob * peerPublicKey,struct HksBlob * wrappedKeyData)182     static void ImportWrappedKey(const struct HksImportWrappedKeyTestParams *params, struct HksBlob *plainCipher,
183         struct HksBlob *kekCipherText, struct HksBlob *peerPublicKey, struct HksBlob *wrappedKeyData)
184     {
185         HKS_TEST_LOG_I("-------------8. Test_ImportWrappedKey!\n");
186         struct HksBlob commonAad = {.size = Unittest::ImportWrappedKey::AAD_SIZE,
187                                     .data = reinterpret_cast<uint8_t *>(Unittest::ImportWrappedKey::AAD)};
188         struct HksBlob commonNonce = {.size = Unittest::ImportWrappedKey::NONCE_SIZE,
189                                       .data = reinterpret_cast<uint8_t *>(Unittest::ImportWrappedKey::NONCE)};
190         struct HksBlob keyMaterialLen = {.size = sizeof(uint32_t), .data = (uint8_t *)&params->keyMaterialLen };
191 
192         /* copy AEAD tag from cipher text and decrease its size */
193         const uint32_t tagSize = Unittest::ImportWrappedKey::AEAD_TAG_SIZE;
194         uint8_t kekTagBuf[tagSize] = {0};
195         struct HksBlob kekTag = { .size = tagSize, .data = kekTagBuf };
196         if (memcpy_s(kekTag.data, tagSize, plainCipher->data + (plainCipher->size - tagSize), tagSize) != EOK) {
197             EXPECT_EQ(HKS_ERROR_BUFFER_TOO_SMALL, EOK) << "memcpy kek tag failed.";
198         }
199         plainCipher->size -= tagSize;
200 
201         /* copy AEAD tag from kek cipher text and decrease its size */
202         uint8_t agreeKeyTagBuf[tagSize] = {0};
203         struct HksBlob agreeKeyTag = { .size = tagSize, .data = agreeKeyTagBuf };
204         if (memcpy_s(agreeKeyTagBuf, tagSize, kekCipherText->data + (kekCipherText->size - tagSize), tagSize) != EOK) {
205             EXPECT_EQ(HKS_ERROR_BUFFER_TOO_SMALL, EOK) << "memcpy agreekey tag failed.";
206         }
207         kekCipherText->size -= tagSize;
208 
209         struct HksBlob *blobArray[] = { peerPublicKey, &commonAad, &commonNonce, &agreeKeyTag, kekCipherText,
210                                         &commonAad, &commonNonce, &kekTag, &keyMaterialLen, plainCipher };
211         int32_t ret = BuildWrappedKeyData(blobArray, HKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS, wrappedKeyData);
212         EXPECT_EQ(ret, HKS_SUCCESS) << "BuildWrappedKeyData failed.";
213 
214         struct HksParam *purpose = nullptr;
215         ret = HksGetParam(params->importWrappedKeyParamSet, HKS_TAG_PURPOSE, &purpose);
216         EXPECT_EQ(ret, HKS_SUCCESS) << "Get wrapped purpose param failed.";
217 
218         ret = HksImportWrappedKey(params->importedKeyAlias, params->wrappingKeyAlias,
219                                   params->importWrappedKeyParamSet, wrappedKeyData);
220 
221         if (purpose->uint32Param == (uint32_t)HKS_KEY_PURPOSE_UNWRAP) {
222             EXPECT_EQ(ret, HKS_ERROR_INVALID_PURPOSE) << "Import unwrap purpose wrapped key shouldn't be success.";
223         } else {
224             EXPECT_EQ(ret, HKS_SUCCESS) << "HksImportWrappedKey failed.";
225         }
226     }
227 
HksImportWrappedKeyTestCommonCase(const struct HksImportWrappedKeyTestParams * params)228     void HksImportWrappedKeyTestCommonCase(const struct HksImportWrappedKeyTestParams *params)
229     {
230         int32_t ret = CheckParamsValid(params);
231         EXPECT_EQ(ret, HKS_SUCCESS) << "CheckParamsValid failed.";
232         if (ret != HKS_SUCCESS) {
233             return;
234         }
235 
236         struct HksBlob huksPublicKey = { 0, nullptr };
237         struct HksBlob callerSelfPublicKey = { 0, nullptr };
238         struct HksBlob outSharedKey = { .size = HKS_KEY_BYTES(HKS_AES_KEY_SIZE_256), .data = nullptr };
239         struct HksBlob wrappedKeyData = { 0, nullptr };
240         uint8_t plainKeyCipherBuffer[MAX_KEY_SIZE] = {0};
241         struct HksBlob plainCipherText = { MAX_KEY_SIZE, plainKeyCipherBuffer };
242         uint8_t kekCipherTextBuffer[MAX_KEY_SIZE] = {0};
243         struct HksBlob kekCipherText = { MAX_KEY_SIZE, kekCipherTextBuffer };
244 
245         GenerateAndExportHuksPublicKey(params, &huksPublicKey);
246         GenerateAndExportCallerPublicKey(params, &callerSelfPublicKey);
247         ImportKekAndAgreeSharedSecret(params, &huksPublicKey, &outSharedKey);
248         EncryptImportedPlainKeyAndKek(params, &plainCipherText, &kekCipherText);
249         ImportWrappedKey(params, &plainCipherText, &kekCipherText, &callerSelfPublicKey, &wrappedKeyData);
250 
251         HKS_FREE_BLOB(huksPublicKey);
252         HKS_FREE_BLOB(callerSelfPublicKey);
253         HKS_FREE_BLOB(outSharedKey);
254         HKS_FREE_BLOB(wrappedKeyData);
255     }
256 
HksClearKeysForWrappedKeyTest(const struct HksImportWrappedKeyTestParams * params)257     void HksClearKeysForWrappedKeyTest(const struct HksImportWrappedKeyTestParams *params)
258     {
259         int32_t ret = CheckParamsValid(params);
260         EXPECT_EQ(ret, HKS_SUCCESS) << "CheckParamsValid failed.";
261         if (ret != HKS_SUCCESS) {
262             return;
263         }
264         (void)HksDeleteKey(params->wrappingKeyAlias, nullptr);
265         (void)HksDeleteKey(params->callerKeyAlias, nullptr);
266         (void)HksDeleteKey(params->callerKekAlias, nullptr);
267         (void)HksDeleteKey(params->callerAgreeKeyAlias, nullptr);
268         (void)HksDeleteKey(params->importedKeyAlias, nullptr);
269     }
270 }
271