2 // Open Service Platform
3 // Copyright (c) 2013 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 FSecPkcs_Pkcs05PbKdf2ParametersImpl.cpp
20 * @brief This is the implementation file for _Pkcs05PbKdf2ParametersImpl class.
22 * This header file contains the implementation of _Pkcs05PbKdf2ParametersImpl class.
27 #include <openssl/evp.h>
28 #include <openssl/crypto.h>
29 #include <openssl/x509.h>
30 #include <openssl/hmac.h>
31 #include <openssl/asn1t.h>
32 #include <openssl/asn1.h>
33 #include <openssl/objects.h>
34 #include <openssl/obj_mac.h>
35 #include <unique_ptr.h>
36 #include <FBaseSysLog.h>
37 #include <FBaseByteBuffer.h>
38 #include <FBaseResult.h>
39 #include <FBaseInteger.h>
40 #include <FSecPkcsIAlgorithmParameters.h>
41 #include <FSecPkcsAlgorithmIdentifier.h>
42 #include <FSecPkcsTypes.h>
43 #include <FSecPkcsPkcs05PbKdf2Parameters.h>
44 #include "FSecPkcs_PkcsUtility.h"
45 #include "FSecPkcs_Pkcs05PbKdf2ParametersImpl.h"
47 using namespace Tizen::Base;
49 namespace Tizen { namespace Security { namespace Pkcs
52 _Pkcs05PbKdf2ParametersImpl::_Pkcs05PbKdf2ParametersImpl(void)
53 : __derivedKeyLength(0)
60 _Pkcs05PbKdf2ParametersImpl::~_Pkcs05PbKdf2ParametersImpl(void)
66 _Pkcs05PbKdf2ParametersImpl::Construct(const Tizen::Base::ByteBuffer& encodedData)
70 Tizen::Base::ByteBuffer saltBuffer;
71 Tizen::Base::String prfOid = null;
73 int derivedKeyLength = 0;
77 PBKDF2PARAM* pKdf = null;
79 SysAssertf(__saltBuffer.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class. ");
81 const byte* pBuffer = encodedData.GetPointer();
82 SysTryReturnResult(NID_SEC_CRYPTO, pBuffer != null, E_INVALID_ARG, "The specified input parameter is invalid.");
84 bufferLen = encodedData.GetRemaining();
85 SysTryReturnResult(NID_SEC_CRYPTO, bufferLen > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
87 pKdf = d2i_PBKDF2PARAM(null, reinterpret_cast< const unsigned char** >(&pBuffer), bufferLen);
88 SysTryCatch(NID_SEC_CRYPTO, pKdf != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
90 SysTryCatch(NID_SEC_CRYPTO, pKdf->salt->type == V_ASN1_OCTET_STRING, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
92 pSalt = pKdf->salt->value.octet_string->data;
93 SysTryCatch(NID_SEC_CRYPTO, pSalt != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
95 saltLength = pKdf->salt->value.octet_string->length;
96 SysTryCatch(NID_SEC_CRYPTO, saltLength > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
98 r = saltBuffer.Construct(saltLength);
99 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
101 r = saltBuffer.SetArray(pSalt, 0, saltLength);
102 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
106 r = __saltBuffer.Construct(saltBuffer);
107 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
109 iter = ASN1_INTEGER_get(pKdf->iter);
110 SysTryCatch(NID_SEC_CRYPTO, iter > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
112 __iterationCount = iter;
114 derivedKeyLength = ASN1_INTEGER_get(pKdf->keylength);
116 __derivedKeyLength = derivedKeyLength;
120 prfNid = OBJ_obj2nid(pKdf->prf->algorithm);
121 prfOid = _PkcsUtility::ConvertToOid(prfNid);
124 SysTryCatch(NID_SEC_CRYPTO, r != E_UNSUPPORTED_ALGORITHM, r = E_UNSUPPORTED_ALGORITHM, E_UNSUPPORTED_ALGORITHM, "[E_UNSUPPORTED_ALGORITHM] The input algorithm is not supported.");
126 r = __oidPrf.Construct(prfOid, null);
127 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
132 r = __oidPrf.Construct(OID_HMAC_SHA1, null);
133 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
138 PBKDF2PARAM_free(pKdf);
143 _Pkcs05PbKdf2ParametersImpl::Construct(const Tizen::Base::ByteBuffer& saltBuffer, int iterationCount, int derivedKeyLength)
145 result r = E_SUCCESS;
147 SysAssertf(__saltBuffer.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class. ");
149 SysTryReturnResult(NID_SEC_CRYPTO, saltBuffer.GetRemaining() > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
150 SysTryReturnResult(NID_SEC_CRYPTO, iterationCount > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
151 SysTryReturnResult(NID_SEC_CRYPTO, derivedKeyLength >= 0, E_INVALID_ARG, "The specified input parameter is invalid.");
153 r = __saltBuffer.Construct(saltBuffer);
154 SysTryReturnResult(NID_SEC_CRYPTO, !IsFailed(r), E_OUT_OF_MEMORY, "The memory is insufficient.");
156 __iterationCount = iterationCount;
158 __derivedKeyLength = derivedKeyLength; // derivedKeyLength is an optional parameter so no need to check its length
160 r = __oidPrf.Construct(OID_HMAC_SHA1, null);
161 SysTryReturnResult(NID_SEC_CRYPTO, !IsFailed(r), E_OUT_OF_MEMORY, "The memory is insufficient.")
168 _Pkcs05PbKdf2ParametersImpl::Construct(const Tizen::Base::ByteBuffer& saltBuffer, int iterationCount, const AlgorithmIdentifier& prf, int derivedKeyLength)
170 result r = E_SUCCESS;
172 SysAssertf(__saltBuffer.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class. ");
174 SysTryReturnResult(NID_SEC_CRYPTO, saltBuffer.GetRemaining() > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
175 SysTryReturnResult(NID_SEC_CRYPTO, derivedKeyLength >= 0, E_INVALID_ARG, "The specified input parameter is invalid.");
177 r = __saltBuffer.Construct(saltBuffer);
178 SysTryReturnResult(NID_SEC_CRYPTO, !IsFailed(r), E_OUT_OF_MEMORY, "The memory is insufficient.");
180 SysTryReturnResult(NID_SEC_CRYPTO, iterationCount > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
181 __iterationCount = iterationCount;
184 __derivedKeyLength = derivedKeyLength; // derivedKeyLength is an optional parameter
186 r = __oidPrf.Construct(prf.GetAlgorithmObjectId(), null); // prf is a default parameter.
187 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to construct the algorithm identifier", GetErrorMessage(r));
193 _Pkcs05PbKdf2ParametersImpl::GetEncodedDataN(void) const
196 result r = E_SUCCESS;
197 PBKDF2PARAM* pKdf = null;
198 ASN1_OCTET_STRING* pSalt = null;
199 std::unique_ptr< ByteBuffer > pEncKdfParam;
204 byte* pSaltData = null;
208 SysAssertf(__saltBuffer.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
210 saltLength = __saltBuffer.GetRemaining();
211 SysTryReturn(NID_SEC_CRYPTO, saltLength > 0, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
213 pKdf = PBKDF2PARAM_new();
214 SysTryReturn(NID_SEC_CRYPTO, pKdf != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
216 pSalt = M_ASN1_OCTET_STRING_new();
217 SysTryReturn(NID_SEC_CRYPTO, pSalt != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
220 pKdf->salt->value.octet_string = pSalt;
221 pKdf->salt->type = V_ASN1_OCTET_STRING;
223 pSalt->data = static_cast< unsigned char* >(OPENSSL_malloc(saltLength));
224 SysTryCatch(NID_SEC_CRYPTO, pSalt->data != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
226 pSalt->length = saltLength;
228 pSaltData = const_cast< byte* >(__saltBuffer.GetPointer());
229 SysTryCatch(NID_SEC_CRYPTO, pSaltData != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
231 memcpy(pSalt->data, pSaltData, saltLength);
233 ASN1_INTEGER_set(pKdf->iter, __iterationCount);
235 if (__derivedKeyLength != 0) //optional parameter
237 pKdf->keylength = M_ASN1_INTEGER_new();
238 SysTryCatch(NID_SEC_CRYPTO, pKdf->keylength != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
240 ASN1_INTEGER_set(pKdf->keylength, __derivedKeyLength);
243 prfNid = _PkcsUtility::ConvertToNid(__oidPrf.GetAlgorithmObjectId());
245 if (prfNid != NID_hmacWithSHA1) // default : not required
247 pKdf->prf = X509_ALGOR_new();
248 SysTryCatch(NID_SEC_CRYPTO, (pKdf->prf != null), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
250 ret = X509_ALGOR_set0(pKdf->prf, OBJ_nid2obj(prfNid), V_ASN1_NULL, NULL);
251 SysTryCatch(NID_SEC_CRYPTO, ret > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
254 value = i2d_PBKDF2PARAM(pKdf, &pTemp);
255 SysTryCatch(NID_SEC_CRYPTO, value > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
256 SysTryCatch(NID_SEC_CRYPTO, pTemp != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
258 pEncKdfParam = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
259 SysTryCatch(NID_SEC_CRYPTO, pEncKdfParam, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
261 r = pEncKdfParam->Construct(value);
262 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
264 r = pEncKdfParam->SetArray(pTemp, 0, value);
265 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
267 pEncKdfParam->Flip();
273 pEncKdfParam.reset(null);
275 PBKDF2PARAM_free(pKdf);
278 return pEncKdfParam.release();
283 _Pkcs05PbKdf2ParametersImpl::GetSaltValue(void) const
287 SysAssertf(__saltBuffer.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
293 _Pkcs05PbKdf2ParametersImpl::GetIterationCount(void) const
297 SysAssertf(__saltBuffer.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
299 return __iterationCount;
302 _Pkcs05PbKdf2ParametersImpl::GetDerivedKeyLength(void) const
306 SysAssertf(__saltBuffer.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
308 return __derivedKeyLength;
311 const AlgorithmIdentifier&
312 _Pkcs05PbKdf2ParametersImpl::GetPrf(void) const
316 SysAssertf(__saltBuffer.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
321 PkcsAlgorithmParameterType
322 _Pkcs05PbKdf2ParametersImpl::GetType(void) const
325 return PKCS_ALGO_PARAM_TYPE_PKCS05_KDF02;
330 _Pkcs05PbKdf2ParametersImpl::Equals(const Object& obj) const
333 const _Pkcs05PbKdf2ParametersImpl* pOther = dynamic_cast< const _Pkcs05PbKdf2ParametersImpl* >(&obj);
335 SysAssertf(__saltBuffer.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
337 SysTryReturn(NID_SEC_CRYPTO, pOther != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
344 SysTryReturn(NID_SEC_CRYPTO, pOther->GetSaltValue().GetRemaining() > 0, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
346 SysTryReturn(NID_SEC_CRYPTO, pOther->GetPrf().GetAlgorithmObjectId().GetLength() > 0, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
348 value = (__saltBuffer == pOther->GetSaltValue()) && (__oidPrf.GetAlgorithmObjectId() == pOther->GetPrf().GetAlgorithmObjectId()) && (__derivedKeyLength == pOther->GetDerivedKeyLength())
349 && (__iterationCount == pOther->GetIterationCount());
356 _Pkcs05PbKdf2ParametersImpl::GetHashCode(void) const
358 SysAssertf(__saltBuffer.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
360 if (__derivedKeyLength > 0)
362 return (__saltBuffer.GetHashCode() + __oidPrf.GetAlgorithmObjectId().GetHashCode() + Integer::GetHashCode(__derivedKeyLength) + Integer::GetHashCode(__iterationCount));
366 return (__saltBuffer.GetHashCode() + __oidPrf.GetAlgorithmObjectId().GetHashCode() + Integer::GetHashCode(__iterationCount));
370 _Pkcs05PbKdf2ParametersImpl*
371 _Pkcs05PbKdf2ParametersImpl::GetInstance(Pkcs05PbKdf2Parameters& pkcs05PbKdf2Parameters)
373 return pkcs05PbKdf2Parameters.__pPkcs05PbKdf2ParametersImpl;
376 const _Pkcs05PbKdf2ParametersImpl*
377 _Pkcs05PbKdf2ParametersImpl::GetInstance(const Pkcs05PbKdf2Parameters& pkcs05PbKdf2Parameters)
379 return pkcs05PbKdf2Parameters.__pPkcs05PbKdf2ParametersImpl;
382 } } } // end of namespace Pkcs