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 *)¶ms->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