1a339c2d4Sopenharmony_ci/* 2a339c2d4Sopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 3a339c2d4Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4a339c2d4Sopenharmony_ci * you may not use this file except in compliance with the License. 5a339c2d4Sopenharmony_ci * You may obtain a copy of the License at 6a339c2d4Sopenharmony_ci * 7a339c2d4Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8a339c2d4Sopenharmony_ci * 9a339c2d4Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10a339c2d4Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11a339c2d4Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12a339c2d4Sopenharmony_ci * See the License for the specific language governing permissions and 13a339c2d4Sopenharmony_ci * limitations under the License. 14a339c2d4Sopenharmony_ci */ 15a339c2d4Sopenharmony_ci 16a339c2d4Sopenharmony_ci#include "scrypt.h" 17a339c2d4Sopenharmony_ci#include <openssl/ossl_typ.h> 18a339c2d4Sopenharmony_ci#include <openssl/kdf.h> 19a339c2d4Sopenharmony_ci#include "securec.h" 20a339c2d4Sopenharmony_ci#include <unordered_map> 21a339c2d4Sopenharmony_ci#include "iam_logger.h" 22a339c2d4Sopenharmony_ci 23a339c2d4Sopenharmony_ci#define LOG_TAG "PIN_AUTH_SDK" 24a339c2d4Sopenharmony_ci 25a339c2d4Sopenharmony_cinamespace OHOS { 26a339c2d4Sopenharmony_cinamespace UserIam { 27a339c2d4Sopenharmony_cinamespace PinAuth { 28a339c2d4Sopenharmony_cinamespace { 29a339c2d4Sopenharmony_ciconstexpr uint32_t OUT_LENGTH = 64; 30a339c2d4Sopenharmony_ciconstexpr uint32_t SCRYPT_N_V0 = 32768; 31a339c2d4Sopenharmony_ciconstexpr uint32_t SCRYPT_N_V1 = 2048; 32a339c2d4Sopenharmony_ciconstexpr uint32_t SCRYPT_R = 8; 33a339c2d4Sopenharmony_ciconstexpr uint32_t SCRYPT_P = 1; 34a339c2d4Sopenharmony_ciconstexpr uint32_t SCRYPT_P_V3 = 2; 35a339c2d4Sopenharmony_ci 36a339c2d4Sopenharmony_cistruct ScryptParameters { 37a339c2d4Sopenharmony_ci int32_t scryptN; 38a339c2d4Sopenharmony_ci int32_t scryptR; 39a339c2d4Sopenharmony_ci int32_t scryptP; 40a339c2d4Sopenharmony_ci}; 41a339c2d4Sopenharmony_ci 42a339c2d4Sopenharmony_cistd::unordered_map<uint32_t, ScryptParameters> g_version2Param_ = { 43a339c2d4Sopenharmony_ci { PIN_ALGO_VERSION_V0, { SCRYPT_N_V0, SCRYPT_R, SCRYPT_P } }, 44a339c2d4Sopenharmony_ci { PIN_ALGO_VERSION_V1, { SCRYPT_N_V1, SCRYPT_R, SCRYPT_P } }, 45a339c2d4Sopenharmony_ci { PIN_ALGO_VERSION_V2, { SCRYPT_N_V1, SCRYPT_R, SCRYPT_P } }, 46a339c2d4Sopenharmony_ci { PIN_ALGO_VERSION_V3, { SCRYPT_N_V1, SCRYPT_R, SCRYPT_P_V3 } } 47a339c2d4Sopenharmony_ci}; 48a339c2d4Sopenharmony_ci} 49a339c2d4Sopenharmony_ci 50a339c2d4Sopenharmony_cibool Scrypt::DoScrypt(const std::vector<uint8_t> &data, uint32_t algoVersion, EVP_PKEY_CTX *pctx) 51a339c2d4Sopenharmony_ci{ 52a339c2d4Sopenharmony_ci auto index = g_version2Param_.find(algoVersion); 53a339c2d4Sopenharmony_ci if (index == g_version2Param_.end()) { 54a339c2d4Sopenharmony_ci IAM_LOGE("version is not in g_version2Param_"); 55a339c2d4Sopenharmony_ci return false; 56a339c2d4Sopenharmony_ci } 57a339c2d4Sopenharmony_ci ScryptParameters scryptParameters = index->second; 58a339c2d4Sopenharmony_ci if (EVP_PKEY_CTX_set1_pbe_pass(pctx, reinterpret_cast<const char *>(data.data()), data.size()) <= 0) { 59a339c2d4Sopenharmony_ci IAM_LOGE("EVP_PKEY_CTX_set1_pbe_pass fail"); 60a339c2d4Sopenharmony_ci return false; 61a339c2d4Sopenharmony_ci } 62a339c2d4Sopenharmony_ci if (EVP_PKEY_CTX_set1_scrypt_salt(pctx, algoParameter_.data(), algoParameter_.size()) <= 0) { 63a339c2d4Sopenharmony_ci IAM_LOGE("EVP_PKEY_CTX_set1_scrypt_salt fail"); 64a339c2d4Sopenharmony_ci return false; 65a339c2d4Sopenharmony_ci } 66a339c2d4Sopenharmony_ci if (EVP_PKEY_CTX_set_scrypt_N(pctx, scryptParameters.scryptN) <= 0) { 67a339c2d4Sopenharmony_ci IAM_LOGE("EVP_PKEY_CTX_set_scrypt_N fail"); 68a339c2d4Sopenharmony_ci return false; 69a339c2d4Sopenharmony_ci } 70a339c2d4Sopenharmony_ci if (EVP_PKEY_CTX_set_scrypt_r(pctx, scryptParameters.scryptR) <= 0) { 71a339c2d4Sopenharmony_ci IAM_LOGE("EVP_PKEY_CTX_set_scrypt_r fail"); 72a339c2d4Sopenharmony_ci return false; 73a339c2d4Sopenharmony_ci } 74a339c2d4Sopenharmony_ci if (EVP_PKEY_CTX_set_scrypt_p(pctx, scryptParameters.scryptP) <= 0) { 75a339c2d4Sopenharmony_ci IAM_LOGE("EVP_PKEY_CTX_set_scrypt_p fail"); 76a339c2d4Sopenharmony_ci return false; 77a339c2d4Sopenharmony_ci } 78a339c2d4Sopenharmony_ci 79a339c2d4Sopenharmony_ci return true; 80a339c2d4Sopenharmony_ci} 81a339c2d4Sopenharmony_ci 82a339c2d4Sopenharmony_cistd::vector<uint8_t> Scrypt::GetScrypt(const std::vector<uint8_t> &data, uint32_t algoVersion) 83a339c2d4Sopenharmony_ci{ 84a339c2d4Sopenharmony_ci IAM_LOGI("start"); 85a339c2d4Sopenharmony_ci std::vector<uint8_t> out; 86a339c2d4Sopenharmony_ci EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SCRYPT, NULL); 87a339c2d4Sopenharmony_ci if (EVP_PKEY_derive_init(pctx) <= 0) { 88a339c2d4Sopenharmony_ci IAM_LOGE("EVP_PKEY_derive_init fail"); 89a339c2d4Sopenharmony_ci return out; 90a339c2d4Sopenharmony_ci } 91a339c2d4Sopenharmony_ci 92a339c2d4Sopenharmony_ci if (!DoScrypt(data, algoVersion, pctx)) { 93a339c2d4Sopenharmony_ci IAM_LOGE("DoScrypt fail"); 94a339c2d4Sopenharmony_ci EVP_PKEY_CTX_free(pctx); 95a339c2d4Sopenharmony_ci return out; 96a339c2d4Sopenharmony_ci } 97a339c2d4Sopenharmony_ci out.resize(OUT_LENGTH); 98a339c2d4Sopenharmony_ci size_t outlen = out.size(); 99a339c2d4Sopenharmony_ci if (EVP_PKEY_derive(pctx, out.data(), &outlen) <= 0) { 100a339c2d4Sopenharmony_ci IAM_LOGE("EVP_PKEY_derive fail"); 101a339c2d4Sopenharmony_ci EVP_PKEY_CTX_free(pctx); 102a339c2d4Sopenharmony_ci (void)memset_s(out.data(), out.size(), 0, out.size()); 103a339c2d4Sopenharmony_ci out.clear(); 104a339c2d4Sopenharmony_ci return out; 105a339c2d4Sopenharmony_ci } 106a339c2d4Sopenharmony_ci 107a339c2d4Sopenharmony_ci EVP_PKEY_CTX_free(pctx); 108a339c2d4Sopenharmony_ci return out; 109a339c2d4Sopenharmony_ci} 110a339c2d4Sopenharmony_ci} // namespace PinAuth 111a339c2d4Sopenharmony_ci} // namespace UserIam 112a339c2d4Sopenharmony_ci} // namespace OHOS