/*
- * libcryptsvc - device unique key
- *
- * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#define HASH_LEN 20
//#define SEC_KEYMGR_FEK_SIZE 16
+#define CS_ERROR_NONE 0
+#define CS_ERROR_BAD_ALLOC -1
+#define CS_ERROR_INTERNAL -2
+#define CS_ERROR_INVALID_PARAM -3
+
/*------ Base64 Encoding Table ------*/
static const char Base64EncodingTable[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
char* GetDuid(int size);
+/*
+ * Password based derivation routines with platform key
+ *
+ * @remarks Returned @a key should be freed by caller after use.
+ *
+ * @param[in] pass password used in the key derivation. Shouldn't be NULL
+ * @param[in] passlen length of @a password to use
+ * @param[in] keylen length of key to make which should be bigger than 0
+ * @param[out] key derived key with @a pass and platform key. Shouldn't be NULL
+ *
+ * @return CS_ERROR_NONE on success, otherwise negative error codes
+ * #retval CS_ERROR_NONE Success
+ * #retval CS_ERROR_BAD_ALLOC Memory allocation failed to new key
+ * #retval CS_ERROR_INTERNAL Internal error which should not be happened
+ * #retval CS_ERROR_INVALID_PARAM Invalid parameter. @a pass and @a key shouldn't be NULL
+ * and keylen should be bigger than 0
+ */
+int cs_derive_key_with_pass(const char *pass, int passlen, int keylen,
+ unsigned char **key);
+
#ifdef __cplusplus
}
#endif
return pKeyVersion;
}
+CS_API
+int cs_derive_key_with_pass(const char *pass, int passlen, int keylen, unsigned char **key)
+{
+ const int PBKDF_ITERATE_NUM = 1;
+ unsigned char *platform_key = NULL;
+ unsigned char *derived_key = NULL;
+ int retval = CS_ERROR_NONE;
+
+ if (pass == NULL || key == NULL || keylen <= 0)
+ return CS_ERROR_INVALID_PARAM;
+
+ platform_key = (unsigned char *)malloc(sizeof(unsigned char) * keylen);
+ if (platform_key == NULL)
+ return CS_ERROR_BAD_ALLOC;
+
+ if (!SecFrameGeneratePlatformUniqueKey(keylen, platform_key)) {
+ retval = CS_ERROR_INTERNAL;
+ goto exit;
+ }
+
+ derived_key = (unsigned char *)malloc(sizeof(unsigned char) * keylen);
+ if (derived_key == NULL) {
+ retval = CS_ERROR_BAD_ALLOC;
+ goto exit;
+ }
+
+ retval = PKCS5_PBKDF2_HMAC(pass, passlen,
+ platform_key, keylen,
+ PBKDF_ITERATE_NUM, EVP_sha1(),
+ keylen, derived_key);
+ if (retval != 1) {
+ retval = CS_ERROR_INTERNAL;
+ goto exit;
+ }
+
+ free(platform_key);
+
+ *key = derived_key;
+
+ return CS_ERROR_NONE;
+
+exit:
+ free(platform_key);
+ free(derived_key);
+
+ return retval;
+}
* @version
* @brief
*/
+
+#include <stdlib.h>
+#include <memory>
#include <iostream>
#include <boost/test/unit_test.hpp>
{
constexpr unsigned int KeyLen = 16;
unsigned char cek[KeyLen] = {0};
- char *encoded_cek = nullptr;
BOOST_REQUIRE_MESSAGE(SecFrameGeneratePlatformUniqueKey(KeyLen, cek),
"Failed to SecFrameGeneratePlatformUniqueKey.");
- encoded_cek = Base64Encoding(
- reinterpret_cast<char *>(cek),
- static_cast<int>(KeyLen));
- BOOST_REQUIRE_MESSAGE(encoded_cek != nullptr, "Failed to base64 encoding.");
+ std::unique_ptr<char, void(*)(void *)> encoded_cek(
+ Base64Encoding(reinterpret_cast<char *>(cek), static_cast<int>(KeyLen)),
+ free);
+ BOOST_REQUIRE_MESSAGE(!!encoded_cek, "Failed to base64 encoding.");
std::cout << "base64 encoded platform unique key(with len 16): "
- << encoded_cek << std::endl;
+ << encoded_cek.get() << std::endl;
}
BOOST_AUTO_TEST_CASE(GETDUID_16)
{
- char *duid = GetDuid(16);
- BOOST_REQUIRE_MESSAGE(duid != nullptr, "returned duid shouldn't be null");
- std::cout << "duid: " << duid << std::endl;
+ std::unique_ptr<char, void(*)(void *)> duid(GetDuid(16), free);
+ BOOST_REQUIRE_MESSAGE(!!duid, "returned duid shouldn't be null");
+ std::cout << "duid: " << duid.get() << std::endl;
}
BOOST_AUTO_TEST_CASE(GETDUID_20)
{
- char *duid = GetDuid(20);
- BOOST_REQUIRE_MESSAGE(duid != nullptr, "returned duid shouldn't be null");
- std::cout << "duid: " << duid << std::endl;
+ std::unique_ptr<char, void(*)(void *)> duid(GetDuid(20), free);
+ BOOST_REQUIRE_MESSAGE(!!duid, "returned duid shouldn't be null");
+ std::cout << "duid: " << duid.get() << std::endl;
}
+static void derive_key_with_pass(const char *pass, int passlen)
+{
+ int retval = CS_ERROR_NONE;
+
+ constexpr unsigned int KeyLen = 20;
+ unsigned char *key = nullptr;
+ BOOST_REQUIRE_MESSAGE(
+ (retval = cs_derive_key_with_pass(pass, passlen, KeyLen, &key)) == CS_ERROR_NONE,
+ "Failed to cs_derive_key_with_pass with retval: " << retval);
+
+ std::unique_ptr<unsigned char, void(*)(void *)> pKey(key, free);
+
+ std::unique_ptr<char, void(*)(void *)> encoded_key(
+ Base64Encoding(reinterpret_cast<char *>(key), static_cast<int>(KeyLen)),
+ free);
+ BOOST_REQUIRE_MESSAGE(!!encoded_key, "Failed to base64 encoding.");
+
+ std::cout << "base64 encoded key derived from pass(len " << KeyLen
+ << "): " << encoded_key.get() << std::endl;
+}
+
+BOOST_AUTO_TEST_CASE(DERIVE_KEY_WITH_PASS)
+{
+ const char *test_pass = "test-password";
+ derive_key_with_pass(test_pass, 5);
+ derive_key_with_pass(test_pass, 10);
+ derive_key_with_pass(test_pass, strlen(test_pass));
+
+ const char empty_pass[30] = {0, };
+ derive_key_with_pass(empty_pass, strlen(empty_pass));
+}
BOOST_AUTO_TEST_SUITE_END()