+/*
+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd. All rights reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file internals.cpp
+ * @author isaac2.lee (isaac2.lee@samsung.com)
+ * @version 1.0
+ */
+
+#include <functional>
+#include <unistd.h>
+#include <generic-backend/exception.h>
+#include <generic-backend/algo-validation.h>
+#include <generic-backend/crypto-params.h>
+#include <dpl/log/log.h>
+#include <ckm/ckm-type.h>
+
+#include <se-backend/internals.h>
+#include <key-manager-se-backend.h>
+#include <key-provider.h>
+
+#ifndef UNUSED_PARAMETER
+#define UNUSED_PARAMETER(x) (void)(x)
+#endif
+
+namespace CKM {
+namespace Crypto {
+namespace SE {
+namespace Internals {
+
+RawBuffer toRawBuffer(unsigned char* buf, uint32_t buf_len)
+{
+ RawBuffer output;
+ output.assign(buf, buf + buf_len);
+ return output;
+}
+
+kmsb_hash_algo_e getHashType(const CryptoAlgorithm &alg)
+{
+ HashAlgorithm hash = unpack<HashAlgorithm>(alg, ParamName::SV_HASH_ALGO);
+ switch (hash)
+ {
+ case HashAlgorithm::SHA1:
+ return KMSB_HASH_SHA1;
+ case HashAlgorithm::SHA256:
+ return KMSB_HASH_SHA256;
+ case HashAlgorithm::SHA384:
+ return KMSB_HASH_SHA384;
+ case HashAlgorithm::SHA512:
+ return KMSB_HASH_SHA512;
+ default:
+ break;
+ }
+ return KMSB_HASH_SHA256;
+}
+
+kmsb_ec_type_e getEcType(const ElipticCurve ecType)
+{
+ if (ecType == ElipticCurve::prime192v1)
+ return KMSB_EC_PRIME192V1;
+ else if (ecType == ElipticCurve::prime256v1)
+ return KMSB_EC_PRIME256V1;
+ else if (ecType == ElipticCurve::secp384r1)
+ return KMSB_EC_SECP384R1;
+ return KMSB_EC_PRIME256V1;
+}
+
+int kmsb_failure_retry(std::function<int()> func)
+{
+ int result = KMSB_ERROR_NONE;
+ for (size_t attempt = 0; attempt < 3; ++attempt) {
+ result = func();
+ if (result == KMSB_ERROR_NONE || result == KMSB_ERROR_NO_KEY)
+ break;
+ LogError("occured err inside SE(errcode:" << result << ")");
+ usleep(100000);
+ }
+ return result;
+}
+
+void generateSKey(const CryptoAlgorithm &alg,
+ const uint32_t key_idx)
+{
+ UNUSED_PARAMETER(alg);
+ UNUSED_PARAMETER(key_idx);
+
+ ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported");
+}
+
+void generateAKey(const CryptoAlgorithm &alg,
+ const uint32_t key_idx)
+{
+ UNUSED_PARAMETER(alg);
+ UNUSED_PARAMETER(key_idx);
+
+ ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported");
+}
+
+/// @brief encrypt key data using SE api for DB metadata
+/// @param key: target data for encryption
+/// @param key_len: target data length
+/// @param iv: iv data
+/// @param iv_len: iv data length
+/// @return Rawbuffer encrypted output
+RawBuffer encryptWithDbpKey(const unsigned char* key, const uint32_t key_len,
+ const unsigned char* iv, const uint32_t iv_len)
+{
+
+ unsigned char* output_data;
+ uint32_t output_len;
+
+ int ret = kmsb_failure_retry(std::bind(kmsb_encrypt_with_dbp_key,
+ SE_BACKEND_DBP_SCHEME_VERSION,
+ key, key_len,
+ iv, iv_len,
+ &output_data, &output_len));
+ if (ret == KMSB_ERROR_NO_KEY) {
+ ret = kmsb_failure_retry(std::bind(kmsb_generate_dbp_key,
+ false));
+ if (ret != KMSB_ERROR_NONE) {
+ LogError("Generate Key: SE Internal error: " << ret);
+ ThrowErr(Exc::Crypto::InternalError, "Generate Key: SE Internal error");
+ }
+ ret = kmsb_failure_retry(std::bind(kmsb_encrypt_with_dbp_key,
+ SE_BACKEND_DBP_SCHEME_VERSION,
+ key, key_len,
+ iv, iv_len,
+ &output_data, &output_len));
+ }
+ if (ret != KMSB_ERROR_NONE) {
+ LogError("Encrypt Key: SE Internal error: " << ret);
+ ThrowErr(Exc::Crypto::InternalError, "Encrypt key: SE Internal error");
+ }
+ return toRawBuffer(output_data, output_len);
+}
+
+RawBuffer halAES(const uint32_t key_idx,
+ const CryptoAlgorithm &alg,
+ RawBuffer &data,
+ const bool isEncrypt)
+{
+ UNUSED_PARAMETER(key_idx);
+ UNUSED_PARAMETER(alg);
+ UNUSED_PARAMETER(data);
+ UNUSED_PARAMETER(isEncrypt);
+
+ ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported AES yet");
+}
+
+RawBuffer symmetricEncrypt(const uint32_t key_idx,
+ const CryptoAlgorithm &alg,
+ RawBuffer &data)
+{
+ return halAES(key_idx, alg, data, true);
+}
+
+RawBuffer symmetricDecrypt(const uint32_t key_idx,
+ const CryptoAlgorithm &alg,
+ RawBuffer &data)
+{
+ return halAES(key_idx, alg, data, false);
+}
+
+RawBuffer asymmetricEncrypt(const uint32_t key_idx,
+ const CryptoAlgorithm &alg,
+ RawBuffer &data)
+{
+ UNUSED_PARAMETER(key_idx);
+ UNUSED_PARAMETER(alg);
+ UNUSED_PARAMETER(data);
+
+ ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported RSA");
+}
+
+RawBuffer asymmetricDecrypt(const uint32_t key_idx,
+ const CryptoAlgorithm &alg,
+ RawBuffer &data)
+{
+ UNUSED_PARAMETER(key_idx);
+ UNUSED_PARAMETER(alg);
+ UNUSED_PARAMETER(data);
+
+ ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported RSA");
+}
+
+RawBuffer sign(const uint32_t key_idx,
+ const CryptoAlgorithm &alg,
+ RawBuffer &message)
+{
+ UNUSED_PARAMETER(key_idx);
+ UNUSED_PARAMETER(alg);
+ UNUSED_PARAMETER(message);
+
+ ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported signing yet");
+}
+
+int verify(const uint32_t key_idx,
+ const CryptoAlgorithm &alg,
+ RawBuffer &hash,
+ RawBuffer &signature)
+{
+ UNUSED_PARAMETER(key_idx);
+ UNUSED_PARAMETER(alg);
+ UNUSED_PARAMETER(hash);
+ UNUSED_PARAMETER(signature);
+
+ ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported verifying yet");
+}
+
+} // namespace Internals
+} // namespace SE
+} // namespace Crypto
+} // namespace CKM