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