2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FSec_DeviceKeyGenerator.cpp
20 * @brief This file contains the implementation of DeviceKeyGenerator class.
23 #include <unique_ptr.h>
24 #include <FBaseResult.h>
25 #include <FBaseErrors.h>
26 #include <FBaseUtilStringUtil.h>
27 #include <FSecCryptoSha1Hash.h>
28 #include <FSecCryptoSha1Hmac.h>
29 #include <FSecSecretKey.h>
30 #include <FBaseSysLog.h>
31 #include <FBase_StringConverter.h>
32 #include <FSec_DeviceKeyGenerator.h>
34 using namespace Tizen::Base;
35 using namespace Tizen::Base::Utility;
36 using namespace Tizen::Security::Crypto;
39 namespace Tizen { namespace Security
42 static const int _HASH_LEN = 20;
44 _DeviceKeyGenerator::_DeviceKeyGenerator(void)
49 _DeviceKeyGenerator::~_DeviceKeyGenerator(void)
55 _DeviceKeyGenerator::GenerateDeviceKeyN(int keySize)
59 ByteBuffer deviceInfoBuffer;
60 std::unique_ptr <ByteBuffer> pHashValue(null);
61 std::unique_ptr <ISecretKey> pKey(null);
62 ByteBuffer* pTempValue = null;
63 ByteBuffer* pTempInfoBuffer = null;
66 char* pDeviceInfo = null;
68 SysLog(NID_SEC, "GenerateDeviceKeyN called.");
70 SysTryReturn(NID_SEC, keySize > 0, null, E_INVALID_ARG,
71 "[E_INVALID_ARG] The device key size MUST be a valid integer greater than 0.");
72 deviceInfo.Append(L"1234567890abcdefghijklmnopqrstuvwxyz");
73 if (keySize % _HASH_LEN == 0)
75 count = keySize / _HASH_LEN;
79 count = keySize / _HASH_LEN + 1;
82 pHashValue.reset(new (std::nothrow) ByteBuffer());
83 SysTryReturn(NID_SEC, pHashValue != null, null, r = E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
84 r = pHashValue->Construct(count * _HASH_LEN);
85 SysTryReturn(NID_SEC, r == E_SUCCESS, null, r = E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
87 pDeviceInfo = _StringConverter::CopyToCharArrayN(deviceInfo);
88 deviceInfoBuffer.Construct(deviceInfo.GetLength());
89 deviceInfoBuffer.SetArray(reinterpret_cast <byte*>(pDeviceInfo), 0, deviceInfo.GetLength());
90 deviceInfoBuffer.Flip();
93 for (int i = 0; i < count; i++)
97 pTempValue = hash.GetHashN(deviceInfoBuffer);
101 pTempValue = hash.GetHashN(*pTempInfoBuffer);
103 SysTryCatch(NID_SEC, pTempValue != null, , GetLastResult(), "[%s] Failed to generate hash code.",
104 GetErrorMessage(GetLastResult()));
106 if (pTempInfoBuffer != null)
107 delete pTempInfoBuffer;
108 pTempInfoBuffer = new (std::nothrow) ByteBuffer();
109 r = pTempInfoBuffer->Construct(*pTempValue);
111 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] A system error has occurred.", GetErrorMessage(r));
112 r = pHashValue->CopyFrom(*pTempInfoBuffer);
113 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] A system error has occurred.", GetErrorMessage(r));
117 pHashValue->SetLimit(keySize);
118 pKey.reset(new (std::nothrow) SecretKey());
119 SysTryCatch(NID_SEC, pKey != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
120 r = pKey->SetKey(*(pHashValue.get()));
121 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] Failed to generate device unique key.", GetErrorMessage(r));
125 delete pTempInfoBuffer;
127 return pKey.release();
131 _DeviceKeyGenerator::GenerateDeviceKeyN(String& appId, int keySize)
133 result r = E_SUCCESS;
135 ByteBuffer deviceInfoBuffer;
136 std::unique_ptr <ByteBuffer> pHashValue(null);
137 std::unique_ptr <ByteBuffer> pHmacKey(null);
138 std::unique_ptr <ISecretKey> pSecretKey(null);
139 std::unique_ptr <ISecretKey> pKey(null);
140 ByteBuffer* pTempValue = null;
141 ByteBuffer* pTempInfoBuffer = null;
144 char* pDeviceInfo = null;
146 SysLog(NID_SEC, "GenerateDeviceKeyN called.");
148 SysTryReturn(NID_SEC, keySize > 0 && appId.GetLength() > 0, null, E_INVALID_ARG,
149 "[E_INVALID_ARG] The device key size MUST be a valid integer greater than 0.");
154 deviceInfo.Append(L"1234567890abcdefghijklmnopqrstuvwxyz");
155 if (keySize % _HASH_LEN == 0)
157 count = keySize / _HASH_LEN;
161 count = keySize / _HASH_LEN + 1;
164 pHashValue.reset(new (std::nothrow) ByteBuffer());
165 SysTryReturn(NID_SEC, pHashValue != null, null, r = E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
166 r = pHashValue->Construct(count * _HASH_LEN);
167 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] A system error has occurred.", GetErrorMessage(r));
169 pDeviceInfo = _StringConverter::CopyToCharArrayN(deviceInfo);
170 deviceInfoBuffer.Construct(deviceInfo.GetLength());
171 deviceInfoBuffer.SetArray(reinterpret_cast <byte*>(pDeviceInfo), 0, deviceInfo.GetLength());
172 deviceInfoBuffer.Flip();
173 delete[] pDeviceInfo;
175 pHmacKey.reset(StringUtil::StringToUtf8N(appId));
177 pSecretKey.reset(new (std::nothrow) SecretKey());
178 r = pSecretKey->SetKey(*(pHmacKey.get()));
179 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] A system error has occurred.", GetErrorMessage(r));
180 hmac.SetKey(*(pSecretKey.get()));
182 for (int i = 0; i < count; i++)
186 pTempValue = hmac.GetHmacN(deviceInfoBuffer);
190 pTempValue = hmac.GetHmacN(*pTempInfoBuffer);
192 SysTryCatch(NID_SEC, pTempValue != null, , GetLastResult(), "[%s] Failed to generate hash code.",
193 GetErrorMessage(GetLastResult()));
195 if (pTempInfoBuffer != null)
196 delete pTempInfoBuffer;
197 pTempInfoBuffer = new (std::nothrow) ByteBuffer();
198 r = pTempInfoBuffer->Construct(*pTempValue);
200 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] A system error has occurred.", GetErrorMessage(r));
201 r = pHashValue->CopyFrom(*pTempInfoBuffer);
202 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] A system error has occurred.", GetErrorMessage(r));
206 pHashValue->SetLimit(keySize);
207 pKey.reset(new (std::nothrow) SecretKey());
208 SysTryCatch(NID_SEC, pKey != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
209 r = pKey->SetKey(*(pHashValue.get()));
210 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] Failed to generate device unique key.", GetErrorMessage(r));
214 delete pTempInfoBuffer;
216 return pKey.release();