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 FSecPkcsPkcs05PbMacParameters.cpp
20 * @brief This is the implementation file for Pkcs05PbMacParameters class.
22 * This header file contains the implementation of Pkcs05PbMacParameters class.
27 #include <openssl/evp.h>
28 #include <openssl/crypto.h>
29 #include <openssl/x509.h>
30 #include <openssl/hmac.h>
31 #include <openssl/objects.h>
32 #include <openssl/obj_mac.h>
33 #include <unique_ptr.h>
34 #include <FBaseSysLog.h>
35 #include <FBaseByteBuffer.h>
36 #include <FBaseResult.h>
37 #include <FSecPkcsIAlgorithmParameters.h>
38 #include <FSecPkcsPkcs05PbKdf2Parameters.h>
39 #include <FSecPkcsAlgorithmIdentifier.h>
40 #include <FSecPkcsTypes.h>
41 #include <FSecPkcsPkcs05PbMacParameters.h>
42 #include "FSecPkcs_PkcsUtility.h"
43 #include "FSecPkcs_Pkcs05PbMacParametersImpl.h"
45 using namespace Tizen::Base;
47 namespace Tizen { namespace Security { namespace Pkcs
51 _Pkcs05PbMacParametersImpl::_Pkcs05PbMacParametersImpl(void)
58 _Pkcs05PbMacParametersImpl::~_Pkcs05PbMacParametersImpl(void)
64 _Pkcs05PbMacParametersImpl::Construct(const Tizen::Base::ByteBuffer& encodedData)
67 const byte* pBuffer = null;
68 const unsigned char* pBuf = null;
72 PBE2PARAM* pMacObj = null;
73 std::unique_ptr< ByteBuffer > pKdfParam;
74 Tizen::Base::String macOid = null;
75 ASN1_TYPE* pParam = null;
76 std::unique_ptr< Pkcs05PbKdf2Parameters > pKdf2Parameters;
79 SysAssertf(__keyDerivationFunction.GetAlgorithmObjectId().GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class. ");
80 SysAssertf(__messageAuthScheme.GetAlgorithmObjectId().GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class. ");
82 pBuffer = encodedData.GetPointer();
83 SysTryReturnResult(NID_SEC_CRYPTO, pBuffer != null, E_INVALID_ARG, "The specified input parameter is invalid.");
85 bufferLen = encodedData.GetRemaining();
86 SysTryReturnResult(NID_SEC_CRYPTO, bufferLen > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
88 pMacObj = d2i_PBE2PARAM(null, reinterpret_cast< const unsigned char** >(&pBuffer), bufferLen);
89 SysTryReturnResult(NID_SEC_CRYPTO, pMacObj != null, E_INVALID_ARG, "The specified input parameter is invalid.");
91 SysTryCatch(NID_SEC_CRYPTO, OBJ_obj2nid(pMacObj->keyfunc->algorithm) == NID_id_pbkdf2, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
93 pParam = pMacObj->keyfunc->parameter;
94 SysTryReturn(NID_SEC_CRYPTO, !((!pParam) || (pParam->type != V_ASN1_SEQUENCE)), E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
96 pBuf = pParam->value.sequence->data;
97 SysTryCatch(NID_SEC_CRYPTO, pBuf != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
99 paramLen = pParam->value.sequence->length;
100 SysTryCatch(NID_SEC_CRYPTO, paramLen > 0, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
102 pKdfParam = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
103 SysTryCatch(NID_SEC_CRYPTO, pKdfParam, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
105 r = pKdfParam->Construct(paramLen);
106 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
108 r = pKdfParam->SetArray(pBuf, 0, paramLen);
109 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
113 pKdf2Parameters = std::unique_ptr< Pkcs05PbKdf2Parameters >(new (std::nothrow) Pkcs05PbKdf2Parameters());
114 SysTryCatch(NID_SEC_CRYPTO, pKdf2Parameters, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
116 r = pKdf2Parameters->Construct(*pKdfParam);
117 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
119 __keyDerivationFunction.Construct(OID_PBKDF2, pKdf2Parameters.get());
120 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
122 nidMacAlgo = OBJ_obj2nid(pMacObj->encryption->algorithm);
123 macOid = _PkcsUtility::ConvertToOid(nidMacAlgo);
126 SysTryCatch(NID_SEC_CRYPTO, r != E_UNSUPPORTED_ALGORITHM, r = E_UNSUPPORTED_ALGORITHM, E_UNSUPPORTED_ALGORITHM, "[E_UNSUPPORTED_ALGORITHM] The input algorithm is not supported.");
128 __messageAuthScheme.Construct(macOid, null);
129 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
133 PBE2PARAM_free(pMacObj);
138 _Pkcs05PbMacParametersImpl::Construct(const AlgorithmIdentifier& keyDerivationFunction, const AlgorithmIdentifier& messageAuthScheme)
140 result r = E_SUCCESS;
142 SysAssertf(__keyDerivationFunction.GetAlgorithmObjectId().GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class. ");
143 SysAssertf(__messageAuthScheme.GetAlgorithmObjectId().GetLength() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class. ");
145 std::unique_ptr< IAlgorithmParameters > pParam(keyDerivationFunction.GetParametersN());
147 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to get the parameters.", GetErrorMessage(r));
149 r = __keyDerivationFunction.Construct(keyDerivationFunction.GetAlgorithmObjectId(), pParam.get());
150 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to construct the algorithm identifier.", GetErrorMessage(r));
152 std::unique_ptr< IAlgorithmParameters > pAuthParam(messageAuthScheme.GetParametersN());
154 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to get the parameters.", GetErrorMessage(r));
156 r = __messageAuthScheme.Construct(messageAuthScheme.GetAlgorithmObjectId(), pAuthParam.get());
157 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), r, r, "[%s] Failed to construct the algorithm identifier.", GetErrorMessage(r));
164 _Pkcs05PbMacParametersImpl::GetEncodedDataN(void) const
167 result r = E_SUCCESS;
168 PBE2PARAM* pMacObj = null;
174 Tizen::Base::String keyOid = null;
175 Tizen::Base::String macAlgo = null;
176 Tizen::Base::String prfOid = null;
177 std::unique_ptr< Pkcs05PbKdf2Parameters > pKeyParams;
178 std::unique_ptr< ByteBuffer > pSalt;
179 std::unique_ptr< ByteBuffer > pEncMacParam;
181 SysAssertf(__keyDerivationFunction.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
182 SysAssertf(__messageAuthScheme.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
184 keyOid = __keyDerivationFunction.GetAlgorithmObjectId();
186 macAlgo = __messageAuthScheme.GetAlgorithmObjectId();
188 pKeyParams = std::unique_ptr< Pkcs05PbKdf2Parameters >(dynamic_cast< Pkcs05PbKdf2Parameters* >(__keyDerivationFunction.GetParametersN()));
189 SysTryReturn(NID_SEC_CRYPTO, pKeyParams, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
191 pSalt = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
192 SysTryCatch(NID_SEC_CRYPTO, pSalt != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
194 SysTryCatch(NID_SEC_CRYPTO, pKeyParams->GetSaltValue().GetRemaining() > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
196 r = pSalt->Construct(pKeyParams->GetSaltValue());
197 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
199 pMacObj = PBE2PARAM_new();
200 SysTryReturn(NID_SEC_CRYPTO, pMacObj != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
202 prfOid = (pKeyParams->GetPrf()).GetAlgorithmObjectId();
203 prfNid = _PkcsUtility::ConvertToNid(prfOid);
205 pMacObj->keyfunc = _PkcsUtility::GenerateKdfParametersN(pKeyParams->GetIterationCount(), const_cast< unsigned char* >(pSalt->GetPointer()), pSalt->GetRemaining(), prfNid, pKeyParams->GetDerivedKeyLength());
206 SysTryCatch(NID_SEC_CRYPTO, pMacObj->keyfunc != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
208 algoNid = _PkcsUtility::ConvertToNid(macAlgo);
210 pMacObj->encryption = X509_ALGOR_new();
211 SysTryCatch(NID_SEC_CRYPTO, (pMacObj->encryption != null), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
213 ret = X509_ALGOR_set0(pMacObj->encryption, OBJ_nid2obj(algoNid), V_ASN1_NULL, NULL);
214 SysTryCatch(NID_SEC_CRYPTO, ret > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
216 // encode the PBE2PARAM structure
218 value = i2d_PBE2PARAM(pMacObj, &pTemp);
219 SysTryCatch(NID_SEC_CRYPTO, value > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
221 pEncMacParam = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
222 SysTryCatch(NID_SEC_CRYPTO, pEncMacParam, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
224 r = pEncMacParam->Construct(value);
225 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
227 r = pEncMacParam->SetArray(pTemp, 0, value);
228 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
230 pEncMacParam->Flip();
236 pEncMacParam.reset(null);
238 PBE2PARAM_free(pMacObj);
241 return pEncMacParam.release();
247 const AlgorithmIdentifier&
248 _Pkcs05PbMacParametersImpl::GetKeyDerivationAlgorithm(void) const
251 return __keyDerivationFunction;
254 const AlgorithmIdentifier&
255 _Pkcs05PbMacParametersImpl::GetMacAlgorithm(void) const
258 return __messageAuthScheme;
261 PkcsAlgorithmParameterType
262 _Pkcs05PbMacParametersImpl::GetType(void) const
265 return PKCS_ALGO_PARAM_TYPE_PKCS05_MAC;
269 _Pkcs05PbMacParametersImpl::Equals(const Object& obj) const
273 const _Pkcs05PbMacParametersImpl* pOther = dynamic_cast< const _Pkcs05PbMacParametersImpl* >(&obj);
275 SysTryReturn(NID_SEC_CRYPTO, pOther != null, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
282 SysTryReturn(NID_SEC_CRYPTO, pOther->GetKeyDerivationAlgorithm().GetAlgorithmObjectId().GetLength() > 0, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
283 SysTryReturn(NID_SEC_CRYPTO, pOther->GetMacAlgorithm().GetAlgorithmObjectId().GetLength() > 0, false, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
285 value = (__keyDerivationFunction.Equals(pOther->GetKeyDerivationAlgorithm())) && (__messageAuthScheme.Equals(pOther->GetMacAlgorithm()));
292 _Pkcs05PbMacParametersImpl::GetHashCode(void) const
294 SysAssertf(__keyDerivationFunction.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
295 SysAssertf(__messageAuthScheme.GetAlgorithmObjectId().GetLength() > 0, "Not yet constructed. Construct () should be called before use.");
298 return __keyDerivationFunction.GetHashCode() + __messageAuthScheme.GetHashCode();
301 _Pkcs05PbMacParametersImpl*
302 _Pkcs05PbMacParametersImpl::GetInstance(Pkcs05PbMacParameters& pkcs05PbMacParameters)
304 return pkcs05PbMacParameters.__pPkcs05PbMacParametersImpl;
307 const _Pkcs05PbMacParametersImpl*
308 _Pkcs05PbMacParametersImpl::GetInstance(const Pkcs05PbMacParameters& pkcs05PbMacParameters)
310 return pkcs05PbMacParameters.__pPkcs05PbMacParametersImpl;
313 } } } // end of namespace Pkcs