E2EE: PBKDF API implementation
[platform/core/test/security-tests.git] / src / e2ee-adaptation-layer / e2ee-adaptation-layer.cpp
index d5b39ec..73d068e 100644 (file)
@@ -19,6 +19,8 @@
 #include <cstring>
 #include <memory>
 
+#include <openssl/evp.h>
+
 #include <ckmc/ckmc-manager.h>
 
 namespace {
@@ -26,6 +28,7 @@ namespace {
 const char* const LABEL = "label";
 const char* const CONTEXT = "context";
 const char* const SECRET_ALIAS = "temporary_shared_e2ee_secret";
+constexpr size_t ITERATIONS = 1000;
 
 typedef std::unique_ptr<struct __ckmc_param_list, decltype(&ckmc_param_list_free)> ParamsPtr;
 
@@ -153,14 +156,36 @@ int ckmew_key_agreement(const char *private_key_alias,
     return ckmc_key_derive(kbkdf_params.get(), SECRET_ALIAS, nullptr, new_key_alias, unexportable);
 }
 
-int ckmew_key_derive_pbkdf2(const char * /*password*/,
-                            const unsigned char * /*salt*/,
-                            size_t /*salt_len*/,
-                            size_t /*new_key_len*/,
-                            const char * /*new_key_alias*/)
+int ckmew_key_derive_pbkdf2(const char *password,
+                            const unsigned char *salt,
+                            size_t salt_len,
+                            size_t new_key_len,
+                            const char *new_key_alias)
 {
-    // TODO
-    return CKMC_ERROR_NONE;
+    if (password == nullptr || salt == nullptr || new_key_alias == nullptr || new_key_len == 0)
+        return CKMC_ERROR_INVALID_PARAMETER;
+
+    unsigned char derived[new_key_len];
+
+    if (1 != PKCS5_PBKDF2_HMAC_SHA1(password,
+                                    strlen(password),
+                                    salt,
+                                    salt_len,
+                                    ITERATIONS,
+                                    new_key_len,
+                                    derived))
+        return CKMC_ERROR_SERVER_ERROR;
+
+    ckmc_key_s* key = nullptr;
+    int ret = ckmc_key_new(derived, new_key_len, CKMC_KEY_AES, nullptr, &key);
+    if (ret != CKMC_ERROR_NONE)
+        return ret;
+
+    ckmc_policy_s unexportable { nullptr, false };
+    ret = ckmc_save_key(new_key_alias, *key, unexportable);
+    ckmc_key_free(key);
+
+    return ret;
 }
 
 int ckmew_get_ocf_cert_chain(char ** /*cert_chain*/, size_t * /*cert_chain_len*/)