2 * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
17 #include "e2ee-adaptation-layer.h"
22 #include <openssl/evp.h>
24 #include <ckmc/ckmc-manager.h>
28 const char* const LABEL = "label";
29 const char* const CONTEXT = "context";
30 const char* const SECRET_ALIAS = "temporary_shared_e2ee_secret";
31 constexpr size_t ITERATIONS = 1000;
33 typedef std::unique_ptr<struct __ckmc_param_list, decltype(&ckmc_param_list_free)> ParamsPtr;
35 std::tuple<ParamsPtr, int> makeParams()
37 ckmc_param_list_h params = nullptr;
38 int ret = ckmc_param_list_new(¶ms);
39 return std::make_tuple(ParamsPtr(params, ckmc_param_list_free), ret);
42 typedef std::unique_ptr<ckmc_raw_buffer_s, decltype(&ckmc_buffer_free)> BufferPtr;
44 std::tuple<BufferPtr, int> makeBuffer(const unsigned char* data, size_t size)
46 ckmc_raw_buffer_s* buffer = nullptr;
47 int ret = ckmc_buffer_new(const_cast<unsigned char*>(data), size, &buffer);
48 return std::make_tuple(BufferPtr(buffer, ckmc_buffer_free), ret);
54 AliasRemover(const char *alias) : alias(alias) {}
56 ckmc_remove_alias(alias);
63 } // anonymous namespace
65 int ckmew_key_agreement(const char *private_key_alias,
66 const unsigned char *raw_public_key,
67 size_t raw_public_key_len,
68 const char *new_key_alias)
70 if (private_key_alias == nullptr || raw_public_key == nullptr || raw_public_key_len == 0 ||
71 new_key_alias == nullptr)
72 return CKMC_ERROR_INVALID_PARAMETER;
74 ckmc_policy_s unexportable { nullptr, false };
76 auto [ecdh_params, ret] = makeParams();
77 if (ret != CKMC_ERROR_NONE)
80 ret = ckmc_param_list_set_integer(ecdh_params.get(), CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_ECDH);
81 if (ret != CKMC_ERROR_NONE)
84 auto [peers_public, ret2] = makeBuffer(raw_public_key, raw_public_key_len);
85 if (ret2 != CKMC_ERROR_NONE)
88 ret = ckmc_param_list_set_buffer(ecdh_params.get(), CKMC_PARAM_ECDH_PUBKEY, peers_public.get());
89 if (ret != CKMC_ERROR_NONE)
92 // derive shared secret
93 ret = ckmc_key_derive(ecdh_params.get(),
98 if (ret != CKMC_ERROR_NONE)
102 AliasRemover remover(SECRET_ALIAS);
105 auto [kbkdf_params, ret3] = makeParams();
106 if (ret3 != CKMC_ERROR_NONE)
109 ret = ckmc_param_list_set_integer(kbkdf_params.get(), CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_KBKDF);
110 if (ret != CKMC_ERROR_NONE)
113 ret = ckmc_param_list_set_integer(kbkdf_params.get(),
115 CKMC_KDF_PRF_HMAC_SHA256);
116 if (ret != CKMC_ERROR_NONE)
119 ret = ckmc_param_list_set_integer(kbkdf_params.get(),
120 CKMC_PARAM_KBKDF_MODE,
121 CKMC_KBKDF_MODE_COUNTER);
122 if (ret != CKMC_ERROR_NONE)
125 ret = ckmc_param_list_set_integer(kbkdf_params.get(),
126 CKMC_PARAM_KBKDF_COUNTER_LOCATION,
127 CKMC_KBKDF_COUNTER_BEFORE_FIXED);
128 if (ret != CKMC_ERROR_NONE)
131 auto [label_buf, ret4] = makeBuffer(reinterpret_cast<const unsigned char*>(LABEL),
133 if (ret4 != CKMC_ERROR_NONE)
136 ret = ckmc_param_list_set_buffer(kbkdf_params.get(), CKMC_PARAM_KBKDF_LABEL, label_buf.get());
137 if (ret != CKMC_ERROR_NONE)
140 auto [context_buf, ret5] = makeBuffer(reinterpret_cast<const unsigned char*>(CONTEXT),
142 if (ret5 != CKMC_ERROR_NONE)
145 ret = ckmc_param_list_set_buffer(kbkdf_params.get(),
146 CKMC_PARAM_KBKDF_CONTEXT,
148 if (ret != CKMC_ERROR_NONE)
151 ret = ckmc_param_list_set_integer(kbkdf_params.get(), CKMC_PARAM_KDF_LEN, 32);
152 if (ret != CKMC_ERROR_NONE)
155 // derive symmetric key
156 return ckmc_key_derive(kbkdf_params.get(), SECRET_ALIAS, nullptr, new_key_alias, unexportable);
159 int ckmew_key_derive_pbkdf2(const char *password,
160 const unsigned char *salt,
163 const char *new_key_alias)
165 if (password == nullptr || salt == nullptr || new_key_alias == nullptr || new_key_len == 0)
166 return CKMC_ERROR_INVALID_PARAMETER;
168 unsigned char derived[new_key_len];
170 if (1 != PKCS5_PBKDF2_HMAC_SHA1(password,
177 return CKMC_ERROR_SERVER_ERROR;
179 ckmc_key_s* key = nullptr;
180 int ret = ckmc_key_new(derived, new_key_len, CKMC_KEY_AES, nullptr, &key);
181 if (ret != CKMC_ERROR_NONE)
184 ckmc_policy_s unexportable { nullptr, false };
185 ret = ckmc_save_key(new_key_alias, *key, unexportable);
191 int ckmew_get_ocf_cert_chain(char ** /*cert_chain*/, size_t * /*cert_chain_len*/)
197 int ckmew_sign_with_ocf(const char * /*public_key_alias*/,
198 ckmc_raw_buffer_s** /*message_buf*/,
199 ckmc_raw_buffer_s** /*signature_buf*/)