E2EE: Key agreement API implementation
[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 <ckmc/ckmc-manager.h>
23
24 namespace {
25
26 const char* const LABEL = "label";
27 const char* const CONTEXT = "context";
28 const char* const SECRET_ALIAS = "temporary_shared_e2ee_secret";
29
30 typedef std::unique_ptr<struct __ckmc_param_list, decltype(&ckmc_param_list_free)> ParamsPtr;
31
32 std::tuple<ParamsPtr, int> makeParams()
33 {
34     ckmc_param_list_h params = nullptr;
35     int ret = ckmc_param_list_new(&params);
36     return std::make_tuple(ParamsPtr(params, ckmc_param_list_free), ret);
37 }
38
39 typedef std::unique_ptr<ckmc_raw_buffer_s, decltype(&ckmc_buffer_free)> BufferPtr;
40
41 std::tuple<BufferPtr, int> makeBuffer(const unsigned char* data, size_t size)
42 {
43     ckmc_raw_buffer_s* buffer = nullptr;
44     int ret = ckmc_buffer_new(const_cast<unsigned char*>(data), size, &buffer);
45     return std::make_tuple(BufferPtr(buffer, ckmc_buffer_free), ret);
46 }
47
48 class AliasRemover
49 {
50 public:
51     AliasRemover(const char *alias) : alias(alias) {}
52     ~AliasRemover() {
53         ckmc_remove_alias(alias);
54     }
55
56 private:
57     const char* alias;
58 };
59
60 } // anonymous namespace
61
62 int ckmew_key_agreement(const char *private_key_alias,
63                         const unsigned char *raw_public_key,
64                         size_t raw_public_key_len,
65                         const char *new_key_alias)
66 {
67     if (private_key_alias == nullptr || raw_public_key == nullptr || raw_public_key_len == 0 ||
68         new_key_alias == nullptr)
69         return CKMC_ERROR_INVALID_PARAMETER;
70
71     ckmc_policy_s unexportable { nullptr, false };
72
73     auto [ecdh_params, ret] = makeParams();
74     if (ret != CKMC_ERROR_NONE)
75         return ret;
76
77     ret = ckmc_param_list_set_integer(ecdh_params.get(), CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_ECDH);
78     if (ret != CKMC_ERROR_NONE)
79         return ret;
80
81     auto [peers_public, ret2] = makeBuffer(raw_public_key, raw_public_key_len);
82     if (ret2 != CKMC_ERROR_NONE)
83         return ret2;
84
85     ret = ckmc_param_list_set_buffer(ecdh_params.get(), CKMC_PARAM_ECDH_PUBKEY, peers_public.get());
86     if (ret != CKMC_ERROR_NONE)
87         return ret;
88
89     // derive shared secret
90     ret = ckmc_key_derive(ecdh_params.get(),
91                           private_key_alias,
92                           nullptr,
93                           SECRET_ALIAS,
94                           unexportable);
95     if (ret != CKMC_ERROR_NONE)
96         return ret;
97
98     // delete secret
99     AliasRemover remover(SECRET_ALIAS);
100
101     // set KBKDF params
102     auto [kbkdf_params, ret3] = makeParams();
103     if (ret3 != CKMC_ERROR_NONE)
104         return ret3;
105
106     ret = ckmc_param_list_set_integer(kbkdf_params.get(), CKMC_PARAM_ALGO_TYPE, CKMC_ALGO_KBKDF);
107     if (ret != CKMC_ERROR_NONE)
108         return ret;
109
110     ret = ckmc_param_list_set_integer(kbkdf_params.get(),
111                                       CKMC_PARAM_KDF_PRF,
112                                       CKMC_KDF_PRF_HMAC_SHA256);
113     if (ret != CKMC_ERROR_NONE)
114         return ret;
115
116     ret = ckmc_param_list_set_integer(kbkdf_params.get(),
117                                       CKMC_PARAM_KBKDF_MODE,
118                                       CKMC_KBKDF_MODE_COUNTER);
119     if (ret != CKMC_ERROR_NONE)
120         return ret;
121
122     ret = ckmc_param_list_set_integer(kbkdf_params.get(),
123                                       CKMC_PARAM_KBKDF_COUNTER_LOCATION,
124                                       CKMC_KBKDF_COUNTER_BEFORE_FIXED);
125     if (ret != CKMC_ERROR_NONE)
126         return ret;
127
128     auto [label_buf, ret4] = makeBuffer(reinterpret_cast<const unsigned char*>(LABEL),
129                                         strlen(LABEL));
130     if (ret4 != CKMC_ERROR_NONE)
131         return ret4;
132
133     ret = ckmc_param_list_set_buffer(kbkdf_params.get(), CKMC_PARAM_KBKDF_LABEL, label_buf.get());
134     if (ret != CKMC_ERROR_NONE)
135         return ret;
136
137     auto [context_buf, ret5] = makeBuffer(reinterpret_cast<const unsigned char*>(CONTEXT),
138                                           strlen(CONTEXT));
139     if (ret5 != CKMC_ERROR_NONE)
140         return ret5;
141
142     ret = ckmc_param_list_set_buffer(kbkdf_params.get(),
143                                      CKMC_PARAM_KBKDF_CONTEXT,
144                                      context_buf.get());
145     if (ret != CKMC_ERROR_NONE)
146         return ret;
147
148     ret = ckmc_param_list_set_integer(kbkdf_params.get(), CKMC_PARAM_KDF_LEN, 32);
149     if (ret != CKMC_ERROR_NONE)
150         return ret;
151
152     // derive symmetric key
153     return ckmc_key_derive(kbkdf_params.get(), SECRET_ALIAS, nullptr, new_key_alias, unexportable);
154 }
155
156 int ckmew_key_derive_pbkdf2(const char * /*password*/,
157                             const unsigned char * /*salt*/,
158                             size_t /*salt_len*/,
159                             size_t /*new_key_len*/,
160                             const char * /*new_key_alias*/)
161 {
162     // TODO
163     return CKMC_ERROR_NONE;
164 }
165
166 int ckmew_get_ocf_cert_chain(char ** /*cert_chain*/, size_t * /*cert_chain_len*/)
167 {
168     // TODO
169     return 0;
170 }
171
172 int ckmew_sign_with_ocf(const char * /*public_key_alias*/,
173                         ckmc_raw_buffer_s** /*message_buf*/,
174                         ckmc_raw_buffer_s** /*signature_buf*/)
175 {
176     // TODO
177     return 0;
178 }