From d6af2fe1baed9c782fc492936718ed6d0303bbee Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Tue, 2 Feb 2016 16:32:04 +0900 Subject: [PATCH] Integrate dukgenerator API to cryptsvc Change-Id: Idfefdf9444a69fa7b9f18a2b249809f7abc89ad3 Signed-off-by: Kyungwook Tak --- include/SecCryptoSvc.h | 29 ++++++++++++++++++++++--- srcs/SecCryptoSvc.c | 47 +++++++++++++++++++++++++++++++++++++++++ test/cs_test.cc | 57 +++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 118 insertions(+), 15 deletions(-) diff --git a/include/SecCryptoSvc.h b/include/SecCryptoSvc.h index 2b6808f..6a9f696 100644 --- a/include/SecCryptoSvc.h +++ b/include/SecCryptoSvc.h @@ -1,7 +1,5 @@ /* - * 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. @@ -95,6 +93,11 @@ typedef enum #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', @@ -119,6 +122,26 @@ char* Base64Encoding(const char *data, int size); 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 diff --git a/srcs/SecCryptoSvc.c b/srcs/SecCryptoSvc.c index 0624288..6a146c2 100644 --- a/srcs/SecCryptoSvc.c +++ b/srcs/SecCryptoSvc.c @@ -269,3 +269,50 @@ exit: 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; +} diff --git a/test/cs_test.cc b/test/cs_test.cc index 831802d..a0695fc 100644 --- a/test/cs_test.cc +++ b/test/cs_test.cc @@ -20,6 +20,9 @@ * @version * @brief */ + +#include +#include #include #include @@ -32,33 +35,63 @@ BOOST_AUTO_TEST_CASE(PLATFORM_UNIQUE_KEY) { 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(cek), - static_cast(KeyLen)); - BOOST_REQUIRE_MESSAGE(encoded_cek != nullptr, "Failed to base64 encoding."); + std::unique_ptr encoded_cek( + Base64Encoding(reinterpret_cast(cek), static_cast(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 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 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 pKey(key, free); + + std::unique_ptr encoded_key( + Base64Encoding(reinterpret_cast(key), static_cast(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() -- 2.7.4