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;
34 typedef std::unique_ptr<ckmc_raw_buffer_s, decltype(&ckmc_buffer_free)> BufferPtr;
36 std::tuple<ParamsPtr, int> makeParams()
38 ckmc_param_list_h params = nullptr;
39 int ret = ckmc_param_list_new(¶ms);
40 return std::make_tuple(ParamsPtr(params, ckmc_param_list_free), ret);
43 std::tuple<BufferPtr, int> makeBuffer(const unsigned char* data, size_t size)
45 ckmc_raw_buffer_s* buffer = nullptr;
46 int ret = ckmc_buffer_new(const_cast<unsigned char*>(data), size, &buffer);
47 return std::make_tuple(BufferPtr(buffer, ckmc_buffer_free), ret);
53 AliasRemover(const char *alias) : alias(alias) {}
55 ckmc_remove_alias(alias);
62 } // anonymous namespace
64 int ckmew_key_agreement(const char *private_key_alias,
65 const unsigned char *raw_public_key,
66 size_t raw_public_key_len,
67 const char *new_key_alias)
69 if (private_key_alias == nullptr || raw_public_key == nullptr || raw_public_key_len == 0 ||
70 new_key_alias == nullptr)
71 return CKMC_ERROR_INVALID_PARAMETER;
73 ckmc_policy_s unexportable { nullptr, false };
75 auto [ecdh_params, ret] = makeParams();
76 if (ret != CKMC_ERROR_NONE)
79 ret = ckmc_param_list_set_integer(ecdh_params.get(), CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_ECDH);
80 if (ret != CKMC_ERROR_NONE)
83 auto [peers_public, ret2] = makeBuffer(raw_public_key, raw_public_key_len);
84 if (ret2 != CKMC_ERROR_NONE)
87 ret = ckmc_param_list_set_buffer(ecdh_params.get(), CKMC_PARAM_ECDH_PUBKEY, peers_public.get());
88 if (ret != CKMC_ERROR_NONE)
91 // derive shared secret
92 ret = ckmc_key_derive(ecdh_params.get(),
97 if (ret != CKMC_ERROR_NONE)
101 AliasRemover remover(SECRET_ALIAS);
104 auto [kbkdf_params, ret3] = makeParams();
105 if (ret3 != CKMC_ERROR_NONE)
108 ret = ckmc_param_list_set_integer(kbkdf_params.get(), CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_KBKDF);
109 if (ret != CKMC_ERROR_NONE)
112 ret = ckmc_param_list_set_integer(kbkdf_params.get(),
114 CKMC_KDF_PRF_HMAC_SHA256);
115 if (ret != CKMC_ERROR_NONE)
118 ret = ckmc_param_list_set_integer(kbkdf_params.get(),
119 CKMC_PARAM_KBKDF_MODE,
120 CKMC_KBKDF_MODE_COUNTER);
121 if (ret != CKMC_ERROR_NONE)
124 ret = ckmc_param_list_set_integer(kbkdf_params.get(),
125 CKMC_PARAM_KBKDF_COUNTER_LOCATION,
126 CKMC_KBKDF_COUNTER_BEFORE_FIXED);
127 if (ret != CKMC_ERROR_NONE)
130 auto [label_buf, ret4] = makeBuffer(reinterpret_cast<const unsigned char*>(LABEL),
132 if (ret4 != CKMC_ERROR_NONE)
135 ret = ckmc_param_list_set_buffer(kbkdf_params.get(), CKMC_PARAM_KBKDF_LABEL, label_buf.get());
136 if (ret != CKMC_ERROR_NONE)
139 auto [context_buf, ret5] = makeBuffer(reinterpret_cast<const unsigned char*>(CONTEXT),
141 if (ret5 != CKMC_ERROR_NONE)
144 ret = ckmc_param_list_set_buffer(kbkdf_params.get(),
145 CKMC_PARAM_KBKDF_CONTEXT,
147 if (ret != CKMC_ERROR_NONE)
150 ret = ckmc_param_list_set_integer(kbkdf_params.get(), CKMC_PARAM_KDF_LEN, 32);
151 if (ret != CKMC_ERROR_NONE)
154 // derive symmetric key
155 return ckmc_key_derive(kbkdf_params.get(), SECRET_ALIAS, nullptr, new_key_alias, unexportable);
158 int ckmew_key_derive_pbkdf2(const char *password,
159 const unsigned char *salt,
162 const char *new_key_alias)
164 if (password == nullptr || salt == nullptr || new_key_alias == nullptr || new_key_len == 0)
165 return CKMC_ERROR_INVALID_PARAMETER;
167 unsigned char derived[new_key_len];
169 if (1 != PKCS5_PBKDF2_HMAC_SHA1(password,
176 return CKMC_ERROR_SERVER_ERROR;
178 ckmc_key_s* key = nullptr;
179 int ret = ckmc_key_new(derived, new_key_len, CKMC_KEY_AES, nullptr, &key);
180 if (ret != CKMC_ERROR_NONE)
183 ckmc_policy_s unexportable { nullptr, false };
184 ret = ckmc_save_key(new_key_alias, *key, unexportable);