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 r = deviceInfoBuffer.SetArray(reinterpret_cast <byte*>(pDeviceInfo), 0, deviceInfo.GetLength());
90 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] A system error has occurred.", GetErrorMessage(r));
91 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[] pDeviceInfo;
126 delete pTempInfoBuffer;
128 return pKey.release();
132 _DeviceKeyGenerator::GenerateDeviceKeyN(String& appId, int keySize)
134 result r = E_SUCCESS;
136 ByteBuffer deviceInfoBuffer;
137 std::unique_ptr <ByteBuffer> pHashValue(null);
138 std::unique_ptr <ByteBuffer> pHmacKey(null);
139 std::unique_ptr <ISecretKey> pSecretKey(null);
140 std::unique_ptr <ISecretKey> pKey(null);
141 ByteBuffer* pTempValue = null;
142 ByteBuffer* pTempInfoBuffer = null;
145 char* pDeviceInfo = null;
147 SysLog(NID_SEC, "GenerateDeviceKeyN called.");
149 SysTryReturn(NID_SEC, keySize > 0 && appId.GetLength() > 0, null, E_INVALID_ARG,
150 "[E_INVALID_ARG] The device key size MUST be a valid integer greater than 0.");
155 deviceInfo.Append(L"1234567890abcdefghijklmnopqrstuvwxyz");
156 if (keySize % _HASH_LEN == 0)
158 count = keySize / _HASH_LEN;
162 count = keySize / _HASH_LEN + 1;
165 pHashValue.reset(new (std::nothrow) ByteBuffer());
166 SysTryReturn(NID_SEC, pHashValue != null, null, r = E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
167 r = pHashValue->Construct(count * _HASH_LEN);
168 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] A system error has occurred.", GetErrorMessage(r));
170 pDeviceInfo = _StringConverter::CopyToCharArrayN(deviceInfo);
171 deviceInfoBuffer.Construct(deviceInfo.GetLength());
172 r = deviceInfoBuffer.SetArray(reinterpret_cast <byte*>(pDeviceInfo), 0, deviceInfo.GetLength());
173 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] A system error has occurred.", GetErrorMessage(r));
174 deviceInfoBuffer.Flip();
176 pHmacKey.reset(StringUtil::StringToUtf8N(appId));
178 pSecretKey.reset(new (std::nothrow) SecretKey());
179 r = pSecretKey->SetKey(*(pHmacKey.get()));
180 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] A system error has occurred.", GetErrorMessage(r));
181 hmac.SetKey(*(pSecretKey.get()));
183 for (int i = 0; i < count; i++)
187 pTempValue = hmac.GetHmacN(deviceInfoBuffer);
191 pTempValue = hmac.GetHmacN(*pTempInfoBuffer);
193 SysTryCatch(NID_SEC, pTempValue != null, , GetLastResult(), "[%s] Failed to generate hash code.",
194 GetErrorMessage(GetLastResult()));
196 if (pTempInfoBuffer != null)
197 delete pTempInfoBuffer;
198 pTempInfoBuffer = new (std::nothrow) ByteBuffer();
199 r = pTempInfoBuffer->Construct(*pTempValue);
201 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] A system error has occurred.", GetErrorMessage(r));
202 r = pHashValue->CopyFrom(*pTempInfoBuffer);
203 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] A system error has occurred.", GetErrorMessage(r));
207 pHashValue->SetLimit(keySize);
208 pKey.reset(new (std::nothrow) SecretKey());
209 SysTryCatch(NID_SEC, pKey != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
210 r = pKey->SetKey(*(pHashValue.get()));
211 SysTryCatch(NID_SEC, r == E_SUCCESS, , r, "[%s] Failed to generate device unique key.", GetErrorMessage(r));
215 delete[] pDeviceInfo;
216 delete pTempInfoBuffer;
218 return pKey.release();