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