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