ff218cc52d69d600640a7023a42770fd73e9cd3c
[platform/framework/native/appfw.git] / src / security / FSec_DeviceKeyGenerator.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 /**
19  * @file        FSec_DeviceKeyGenerator.cpp
20  * @brief       This file contains the implementation of DeviceKeyGenerator class.
21  */
22
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>
33
34 using namespace Tizen::Base;
35 using namespace Tizen::Base::Utility;
36 using namespace Tizen::Security::Crypto;
37
38
39 namespace Tizen { namespace Security
40 {
41
42 static const int _HASH_LEN = 20;
43
44 _DeviceKeyGenerator::_DeviceKeyGenerator(void)
45 {
46
47 }
48
49 _DeviceKeyGenerator::~_DeviceKeyGenerator(void)
50 {
51
52 }
53
54 ISecretKey*
55 _DeviceKeyGenerator::GenerateDeviceKeyN(int keySize)
56 {
57         result r = E_SUCCESS;
58         String deviceInfo;
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;
64         Sha1Hash hash;
65         int count = 0;
66         char* pDeviceInfo = null;
67
68         SysLog(NID_SEC, "GenerateDeviceKeyN called.");
69
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)
74         {
75                 count = keySize / _HASH_LEN;
76         }
77         else
78         {
79                 count = keySize / _HASH_LEN + 1;
80         }
81
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.");
86
87         pDeviceInfo = _StringConverter::CopyToCharArrayN(deviceInfo);
88         deviceInfoBuffer.Construct(deviceInfo.GetLength());
89         deviceInfoBuffer.SetArray(reinterpret_cast <byte*>(pDeviceInfo), 0, deviceInfo.GetLength());
90         deviceInfoBuffer.Flip();
91         delete[] pDeviceInfo;
92
93         for (int i = 0; i < count; i++)
94         {
95                 if (i == 0)
96                 {
97                         pTempValue = hash.GetHashN(deviceInfoBuffer);
98                 }
99                 else
100                 {
101                         pTempValue = hash.GetHashN(*pTempInfoBuffer);
102                 }
103                 SysTryCatch(NID_SEC, pTempValue != null, , GetLastResult(), "[%s] Failed to generate hash code.",
104                                    GetErrorMessage(GetLastResult()));
105
106                 if (pTempInfoBuffer != null)
107                         delete pTempInfoBuffer;
108                 pTempInfoBuffer = new (std::nothrow) ByteBuffer();
109                 r = pTempInfoBuffer->Construct(*pTempValue);
110                 delete 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));
114         }
115
116         pHashValue->Flip();
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));
122
123 CATCH:
124         SetLastResult(r);
125         delete pTempInfoBuffer;
126
127         return pKey.release();
128 }
129
130 ISecretKey*
131 _DeviceKeyGenerator::GenerateDeviceKeyN(String& appId, int keySize)
132 {
133         result r = E_SUCCESS;
134         String deviceInfo;
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;
142         Sha1Hmac hmac;
143         int count = 0;
144         char* pDeviceInfo = null;
145
146         SysLog(NID_SEC, "GenerateDeviceKeyN called.");
147
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.");
150
151 //ToDo
152 //Add slp API
153
154         deviceInfo.Append(L"1234567890abcdefghijklmnopqrstuvwxyz");
155         if (keySize % _HASH_LEN == 0)
156         {
157                 count = keySize / _HASH_LEN;
158         }
159         else
160         {
161                 count = keySize / _HASH_LEN + 1;
162         }
163
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));
168
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;
174
175         pHmacKey.reset(StringUtil::StringToUtf8N(appId));
176
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()));
181
182         for (int i = 0; i < count; i++)
183         {
184                 if (i == 0)
185                 {
186                         pTempValue = hmac.GetHmacN(deviceInfoBuffer);
187                 }
188                 else
189                 {
190                         pTempValue = hmac.GetHmacN(*pTempInfoBuffer);
191                 }
192                 SysTryCatch(NID_SEC, pTempValue != null, , GetLastResult(), "[%s] Failed to generate hash code.",
193                                    GetErrorMessage(GetLastResult()));
194
195                 if (pTempInfoBuffer != null)
196                         delete pTempInfoBuffer;
197                 pTempInfoBuffer = new (std::nothrow) ByteBuffer();
198                 r = pTempInfoBuffer->Construct(*pTempValue);
199                 delete 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));
203         }
204
205         pHashValue->Flip();
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));
211
212 CATCH:
213         SetLastResult(r);
214         delete pTempInfoBuffer;
215
216         return pKey.release();
217 }
218
219 } //Tizen::Security
220 } //Osp