Revert DCM E2EE API tests
[platform/core/test/security-tests.git] / src / e2ee-adaptation-layer / e2ee-adaptation-layer.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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
15  */
16
17 #include "e2ee-adaptation-layer.h"
18
19 #include <cstring>
20 #include <memory>
21
22 #include <openssl/evp.h>
23
24 #include <ckmc/ckmc-manager.h>
25
26 namespace {
27
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;
32
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;
35
36 std::tuple<ParamsPtr, int> makeParams()
37 {
38     ckmc_param_list_h params = nullptr;
39     int ret = ckmc_param_list_new(&params);
40     return std::make_tuple(ParamsPtr(params, ckmc_param_list_free), ret);
41 }
42
43 std::tuple<BufferPtr, int> makeBuffer(const unsigned char* data, size_t size)
44 {
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);
48 }
49
50 class AliasRemover
51 {
52 public:
53     AliasRemover(const char *alias) : alias(alias) {}
54     ~AliasRemover() {
55         ckmc_remove_alias(alias);
56     }
57
58 private:
59     const char* alias;
60 };
61
62 } // anonymous namespace
63
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)
68 {
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;
72
73     ckmc_policy_s unexportable { nullptr, false };
74
75     auto [ecdh_params, ret] = makeParams();
76     if (ret != CKMC_ERROR_NONE)
77         return ret;
78
79     ret = ckmc_param_list_set_integer(ecdh_params.get(), CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_ECDH);
80     if (ret != CKMC_ERROR_NONE)
81         return ret;
82
83     auto [peers_public, ret2] = makeBuffer(raw_public_key, raw_public_key_len);
84     if (ret2 != CKMC_ERROR_NONE)
85         return ret2;
86
87     ret = ckmc_param_list_set_buffer(ecdh_params.get(), CKMC_PARAM_ECDH_PUBKEY, peers_public.get());
88     if (ret != CKMC_ERROR_NONE)
89         return ret;
90
91     // derive shared secret
92     ret = ckmc_key_derive(ecdh_params.get(),
93                           private_key_alias,
94                           nullptr,
95                           SECRET_ALIAS,
96                           unexportable);
97     if (ret != CKMC_ERROR_NONE)
98         return ret;
99
100     // delete secret
101     AliasRemover remover(SECRET_ALIAS);
102
103     // set KBKDF params
104     auto [kbkdf_params, ret3] = makeParams();
105     if (ret3 != CKMC_ERROR_NONE)
106         return ret3;
107
108     ret = ckmc_param_list_set_integer(kbkdf_params.get(), CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_KBKDF);
109     if (ret != CKMC_ERROR_NONE)
110         return ret;
111
112     ret = ckmc_param_list_set_integer(kbkdf_params.get(),
113                                       CKMC_PARAM_KDF_PRF,
114                                       CKMC_KDF_PRF_HMAC_SHA256);
115     if (ret != CKMC_ERROR_NONE)
116         return ret;
117
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)
122         return ret;
123
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)
128         return ret;
129
130     auto [label_buf, ret4] = makeBuffer(reinterpret_cast<const unsigned char*>(LABEL),
131                                         strlen(LABEL));
132     if (ret4 != CKMC_ERROR_NONE)
133         return ret4;
134
135     ret = ckmc_param_list_set_buffer(kbkdf_params.get(), CKMC_PARAM_KBKDF_LABEL, label_buf.get());
136     if (ret != CKMC_ERROR_NONE)
137         return ret;
138
139     auto [context_buf, ret5] = makeBuffer(reinterpret_cast<const unsigned char*>(CONTEXT),
140                                           strlen(CONTEXT));
141     if (ret5 != CKMC_ERROR_NONE)
142         return ret5;
143
144     ret = ckmc_param_list_set_buffer(kbkdf_params.get(),
145                                      CKMC_PARAM_KBKDF_CONTEXT,
146                                      context_buf.get());
147     if (ret != CKMC_ERROR_NONE)
148         return ret;
149
150     ret = ckmc_param_list_set_integer(kbkdf_params.get(), CKMC_PARAM_KDF_LEN, 32);
151     if (ret != CKMC_ERROR_NONE)
152         return ret;
153
154     // derive symmetric key
155     return ckmc_key_derive(kbkdf_params.get(), SECRET_ALIAS, nullptr, new_key_alias, unexportable);
156 }
157
158 int ckmew_key_derive_pbkdf2(const char *password,
159                             const unsigned char *salt,
160                             size_t salt_len,
161                             size_t new_key_len,
162                             const char *new_key_alias)
163 {
164     if (password == nullptr || salt == nullptr || new_key_alias == nullptr || new_key_len == 0)
165         return CKMC_ERROR_INVALID_PARAMETER;
166
167     unsigned char derived[new_key_len];
168
169     if (1 != PKCS5_PBKDF2_HMAC_SHA1(password,
170                                     strlen(password),
171                                     salt,
172                                     salt_len,
173                                     ITERATIONS,
174                                     new_key_len,
175                                     derived))
176         return CKMC_ERROR_SERVER_ERROR;
177
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)
181         return ret;
182
183     ckmc_policy_s unexportable { nullptr, false };
184     ret = ckmc_save_key(new_key_alias, *key, unexportable);
185     ckmc_key_free(key);
186
187     return ret;
188 }