Merge "[Security] Fixed memory leaks through valgrind tool" into tizen_2.1
[platform/framework/native/appfw.git] / src / security / pkcs / FSecPkcs_Pkcs05SchemesImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2013 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                FSecPkcs_Pkcs05SchemesImpl.cpp
20  * @brief               This is the implementation file for _Pkcs05SchemesImpl class.
21  *
22  * This header file contains the implementation of _Pkcs05SchemesImpl class.
23  *
24  */
25
26 #include <new>
27 #include <openssl/hmac.h>
28 #include <openssl/x509.h>
29 #include <openssl/evp.h>
30 #include <openssl/objects.h>
31 #include <openssl/obj_mac.h>
32 #include <unique_ptr.h>
33 #include <FBaseSysLog.h>
34 #include <FBaseByteBuffer.h>
35 #include <FBaseResult.h>
36 #include <FSecPkcsAlgorithmIdentifier.h>
37 #include <FSecPkcsPkcs05PbKdf2Parameters.h>
38 #include <FSecPkcsPkcs05PbEs2Parameters.h>
39 #include <FSecPkcsPkcs05PbMacParameters.h>
40 #include <FSecPkcsTypes.h>
41 #include <FSecPkcsPkcs05Schemes.h>
42 #include "FSecPkcs_PkcsUtility.h"
43 #include "FSecPkcs_Pkcs05SchemesImpl.h"
44
45 using namespace Tizen::Base;
46
47 namespace Tizen { namespace Security { namespace Pkcs
48 {
49
50 _Pkcs05SchemesImpl::_Pkcs05SchemesImpl(void)
51         : __pMacAlgo(EVP_sha1())
52         , __derivedKeyLength(0)
53 {
54
55 }
56
57 _Pkcs05SchemesImpl::~_Pkcs05SchemesImpl(void)
58 {
59         //do nothing
60 }
61
62 result
63 _Pkcs05SchemesImpl::Construct(const Tizen::Base::ByteBuffer& password, int derivedKeyLength)
64 {
65         result r = E_SUCCESS;
66
67         SysAssertf(__password.GetRemaining() <= 0, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
68
69         SysTryReturnResult(NID_SEC_CRYPTO, password.GetRemaining() > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
70         SysTryReturnResult(NID_SEC_CRYPTO, derivedKeyLength > 0, E_INVALID_ARG, "The specified input parameter is invalid.");
71
72         __derivedKeyLength = derivedKeyLength;
73
74         r = __password.Construct(password);
75         SysTryReturnResult(NID_SEC_CRYPTO, !IsFailed(r), E_OUT_OF_MEMORY, "The memory is insufficient.");
76
77         return r;
78 }
79
80
81 ByteBuffer*
82 _Pkcs05SchemesImpl::GenerateKeyKdf2N(const Pkcs05PbKdf2Parameters& params)
83 {
84
85         result r = E_SUCCESS;
86         std::unique_ptr< ByteBuffer > pOut;
87         std::unique_ptr< ByteBuffer > pSaltBuffer;
88         unsigned char out[1024] = {0, };
89         const char* pPassword = null;
90         int iterationCount = 0;
91         int saltLen = 0;
92         int derivedKeyLength = 0;
93         int passwordLen = 0;
94         int ret = 0;
95         _OidType oidValue = _OID_TYPE_UNKNOWN;
96
97         ClearLastResult();
98
99         SysAssertf(__password.GetPointer() != null, "Not yet constructed. Construct () should be called before use.");
100         SysAssertf(__password.GetRemaining() > 0, "Not yet constructed. Construct () should be called before use.");
101
102         pPassword = reinterpret_cast< const char* >(__password.GetPointer());
103         passwordLen = __password.GetRemaining();
104
105         SysTryReturn(NID_SEC_CRYPTO, params.GetPrf().GetAlgorithmObjectId().GetLength() > 0, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
106
107         saltLen = params.GetSaltValue().GetRemaining();
108         SysTryReturn(NID_SEC_CRYPTO, saltLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
109
110         iterationCount = params.GetIterationCount();
111         SysTryReturn(NID_SEC_CRYPTO, iterationCount > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
112
113         derivedKeyLength = params.GetDerivedKeyLength();
114
115         if (derivedKeyLength <= 0)
116         {
117                 derivedKeyLength = __derivedKeyLength;
118         }
119         oidValue = _PkcsUtility::ConvertOidToEnum(params.GetPrf().GetAlgorithmObjectId());
120
121         switch (oidValue)
122         {
123         case _OID_TYPE_HMAC_SHA1:
124                 __pMacAlgo = EVP_sha1();
125                 break;
126
127         case _OID_TYPE_HMAC_SHA2_224:
128                 __pMacAlgo = EVP_sha224();
129                 break;
130
131         case _OID_TYPE_HMAC_SHA2_256:
132                 __pMacAlgo = EVP_sha256();
133                 break;
134
135         case _OID_TYPE_HMAC_SHA2_384:
136                 __pMacAlgo = EVP_sha384();
137                 break;
138
139         case _OID_TYPE_HMAC_SHA2_512:
140                 __pMacAlgo = EVP_sha512();
141                 break;
142
143         default:
144                 r = E_UNSUPPORTED_ALGORITHM;
145                 SetLastResult(r);
146                 return null;
147         }
148
149         ret = PKCS5_PBKDF2_HMAC(pPassword, passwordLen, params.GetSaltValue().GetPointer(), saltLen, iterationCount, __pMacAlgo, derivedKeyLength, out);
150         SysTryReturn(NID_SEC_CRYPTO, ret == 1, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
151
152         pOut = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
153         SysTryReturn(NID_SEC_CRYPTO, pOut, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
154
155         r = pOut->Construct(derivedKeyLength);
156         SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
157
158         r = pOut->SetArray(out, 0, derivedKeyLength);
159         SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
160
161         pOut->Flip();
162
163         if (IsFailed(r))
164         {
165                 pOut.reset(null);
166         }
167         return pOut.release();
168
169 }
170
171 ByteBuffer*
172 _Pkcs05SchemesImpl::EncryptionScheme2N(const Pkcs05PbEs2Parameters& params, const Tizen::Base::ByteBuffer& message)
173 {
174
175         result r = E_SUCCESS;
176         std::unique_ptr< ByteBuffer > pDKey;
177         std::unique_ptr< Pkcs05PbKdf2Parameters > pKeyDerivationFuncParam;
178         std::unique_ptr< ByteBuffer > pOutBuffer;
179         Tizen::Base::String keyOid = null;
180         Tizen::Base::String tempOid = null;
181         int modeValue = 1;
182
183         ClearLastResult();
184
185         SysTryReturn(NID_SEC_CRYPTO, params.GetKeyDerivationAlgorithm().GetAlgorithmObjectId().GetLength() > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
186         SysTryReturn(NID_SEC_CRYPTO, params.GetEncryptionScheme().GetAlgorithmObjectId().GetLength() > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
187
188         tempOid = params.GetEncryptionScheme().GetAlgorithmObjectId();
189
190         pKeyDerivationFuncParam = std::unique_ptr< Pkcs05PbKdf2Parameters >(dynamic_cast< Pkcs05PbKdf2Parameters* >(params.GetKeyDerivationAlgorithm().GetParametersN()));
191         SysTryReturn(NID_SEC_CRYPTO, pKeyDerivationFuncParam, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
192
193         keyOid = params.GetKeyDerivationAlgorithm().GetAlgorithmObjectId();
194         SysTryReturn(NID_SEC_CRYPTO, keyOid == OID_PBKDF2, null, E_UNSUPPORTED_ALGORITHM, "[E_UNSUPPORTED_ALGORITHM] The input algorithm is not supported.");
195
196         pDKey = std::unique_ptr< ByteBuffer >(GenerateKeyKdf2N(*pKeyDerivationFuncParam));
197         r = GetLastResult();
198         SysTryReturn(NID_SEC_CRYPTO, pDKey != null, null, r, "[%s] Failed to generate key.", GetErrorMessage(r));
199
200         pOutBuffer = std::unique_ptr< ByteBuffer >(_PkcsUtility::EncryptDecryptN(params.GetEncryptionScheme(), *pDKey, message, modeValue));
201         r = GetLastResult();
202         SysTryReturn(NID_SEC_CRYPTO, pOutBuffer != null, null, r, "[%s] Failed to encrypt message.", GetErrorMessage(r));
203
204         if (IsFailed(r))
205         {
206                 pOutBuffer.reset(null);
207         }
208         return pOutBuffer.release();
209 }
210
211 ByteBuffer*
212 _Pkcs05SchemesImpl::DecryptionScheme2N(const Pkcs05PbEs2Parameters& params, const Tizen::Base::ByteBuffer& message)
213 {
214         result r = E_SUCCESS;
215         std::unique_ptr< ByteBuffer > pDKey;
216         std::unique_ptr< Pkcs05PbKdf2Parameters > pKeyDerivationFuncParam;
217         std::unique_ptr< ByteBuffer > pOutBuffer;
218         Tizen::Base::String keyOid = null;
219         Tizen::Base::String tempOid = null;
220         int modeValue = 0;
221
222         ClearLastResult();
223
224         SysTryReturn(NID_SEC_CRYPTO, params.GetKeyDerivationAlgorithm().GetAlgorithmObjectId().GetLength() > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
225         SysTryReturn(NID_SEC_CRYPTO, params.GetEncryptionScheme().GetAlgorithmObjectId().GetLength() > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
226
227         tempOid = params.GetEncryptionScheme().GetAlgorithmObjectId();
228
229         pKeyDerivationFuncParam = std::unique_ptr< Pkcs05PbKdf2Parameters >(dynamic_cast< Pkcs05PbKdf2Parameters* >(params.GetKeyDerivationAlgorithm().GetParametersN()));
230         SysTryReturn(NID_SEC_CRYPTO, pKeyDerivationFuncParam, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
231
232         keyOid = params.GetKeyDerivationAlgorithm().GetAlgorithmObjectId();
233         SysTryReturn(NID_SEC_CRYPTO, keyOid == OID_PBKDF2, null, E_UNSUPPORTED_ALGORITHM, "[E_UNSUPPORTED_ALGORITHM] The input algorithm is not supported.");
234
235         pDKey = std::unique_ptr< ByteBuffer >(GenerateKeyKdf2N(*pKeyDerivationFuncParam));
236         r = GetLastResult();
237         SysTryReturn(NID_SEC_CRYPTO, pDKey != null, null, r, "[%s] Failed to generate key.", GetErrorMessage(r));
238
239         pOutBuffer = std::unique_ptr< ByteBuffer >(_PkcsUtility::EncryptDecryptN(params.GetEncryptionScheme(), *pDKey, message, modeValue));
240         r = GetLastResult();
241         SysTryReturn(NID_SEC_CRYPTO, pOutBuffer != null, null, r, "[%s] Failed to encrypt message.", GetErrorMessage(r));
242
243         if (IsFailed(r))
244         {
245                 pOutBuffer.reset(null);
246         }
247
248         return pOutBuffer.release();
249 }
250
251 ByteBuffer*
252 _Pkcs05SchemesImpl::GetPbHMacN(const Pkcs05PbMacParameters& params, const Tizen::Base::ByteBuffer& message)
253 {
254
255         result r = E_SUCCESS;
256         std::unique_ptr< ByteBuffer > pDKey;
257         std::unique_ptr< Pkcs05PbKdf2Parameters > pKeyDerivationFuncParam;
258         std::unique_ptr< byte > pMd;
259         std::unique_ptr< ByteBuffer > pOutput;
260         Tizen::Base::String keyOid = null;
261         Tizen::Base::String messageAuthScheme = null;
262         unsigned int mdLen = 0;
263         int dataLen = 0;
264         int keyLen = 0;
265         byte* pData = null;
266         byte* pKey = null;
267         _OidType oidValue = _OID_TYPE_UNKNOWN;
268
269         ClearLastResult();
270
271         SysTryReturn(NID_SEC_CRYPTO, params.GetKeyDerivationAlgorithm().GetAlgorithmObjectId().GetLength() > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
272         SysTryReturn(NID_SEC_CRYPTO, params.GetMacAlgorithm().GetAlgorithmObjectId().GetLength() > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
273
274         keyOid = params.GetKeyDerivationAlgorithm().GetAlgorithmObjectId();
275         SysTryReturn(NID_SEC_CRYPTO, keyOid == OID_PBKDF2, null, E_UNSUPPORTED_ALGORITHM, "[E_UNSUPPORTED_ALGORITHM] The input algorithm is not supported.");
276
277         pData = const_cast< byte* >(message.GetPointer());
278         SysTryReturn(NID_SEC_CRYPTO, pData != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
279
280         dataLen = message.GetRemaining();
281         SysTryReturn(NID_SEC_CRYPTO, dataLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
282
283         pKeyDerivationFuncParam = std::unique_ptr< Pkcs05PbKdf2Parameters >(dynamic_cast< Pkcs05PbKdf2Parameters* >(params.GetKeyDerivationAlgorithm().GetParametersN()));
284         SysTryReturn(NID_SEC_CRYPTO, pKeyDerivationFuncParam, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
285
286         pDKey = std::unique_ptr< ByteBuffer >(GenerateKeyKdf2N(*pKeyDerivationFuncParam));
287         SysTryReturn(NID_SEC_CRYPTO, pDKey, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
288
289         messageAuthScheme = params.GetMacAlgorithm().GetAlgorithmObjectId();
290
291         oidValue = _PkcsUtility::ConvertOidToEnum(messageAuthScheme);
292         switch (oidValue)
293         {
294         case _OID_TYPE_HMAC_SHA1:
295                 __pMacAlgo = EVP_sha1();
296                 break;
297
298         case _OID_TYPE_HMAC_SHA2_224:
299                 __pMacAlgo = EVP_sha224();
300                 break;
301
302         case _OID_TYPE_HMAC_SHA2_256:
303                 __pMacAlgo = EVP_sha256();
304                 break;
305
306         case _OID_TYPE_HMAC_SHA2_384:
307                 __pMacAlgo = EVP_sha384();
308                 break;
309
310         case _OID_TYPE_HMAC_SHA2_512:
311                 __pMacAlgo = EVP_sha512();
312                 break;
313
314         default:
315                 r = E_UNSUPPORTED_ALGORITHM;
316                 SetLastResult(r);
317                 return null;
318         }
319
320         mdLen = EVP_MD_size(__pMacAlgo);
321         SysTryReturn(NID_SEC_CRYPTO, mdLen > 0, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
322
323         pMd = std::unique_ptr< byte >(new (std::nothrow) byte[mdLen]);
324         SysTryReturn(NID_SEC_CRYPTO, pMd, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
325
326         memset(pMd.get(), 0, mdLen);
327
328         pKey = const_cast< byte* >(pDKey->GetPointer());
329         SysTryReturn(NID_SEC_CRYPTO, pKey != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
330
331         keyLen = pDKey->GetRemaining();
332         SysTryReturn(NID_SEC_CRYPTO, keyLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
333
334
335         //gets HMAC of the input data for SEC_MAC_SHA224
336         HMAC(__pMacAlgo, pKey, keyLen, pData, dataLen, pMd.get(), &mdLen);
337         SysTryReturn(NID_SEC_CRYPTO, mdLen != 0, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
338
339         //stores the HMAC output in bytebuffer
340         pOutput = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
341         SysTryReturn(NID_SEC_CRYPTO, pOutput, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
342
343         r = pOutput->Construct(mdLen);
344         SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_OUT_OF_MEMORY, "[E_OUT_MEMORY] The memory is insufficient.");
345
346         r = pOutput->SetArray(pMd.get(), 0, mdLen);
347         SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
348
349         pOutput->Flip();
350
351         if (IsFailed(r))
352         {
353                 pOutput.reset(null);
354         }
355         return pOutput.release();
356
357 }
358
359 result
360 _Pkcs05SchemesImpl::VerifyPbMac(const Pkcs05PbMacParameters& params, const Tizen::Base::ByteBuffer& message, const Tizen::Base::ByteBuffer& mac)
361 {
362         result r = E_SUCCESS;
363         std::unique_ptr< ByteBuffer > pDKey;
364         std::unique_ptr< Pkcs05PbKdf2Parameters > pKeyDerivationFuncParam;
365         std::unique_ptr< byte > pMd;
366         std::unique_ptr< ByteBuffer > pOutput;
367         Tizen::Base::String keyOid = null;
368         Tizen::Base::String messageAuthScheme = null;
369         unsigned int mdLen = 0;
370         int dataLen = 0;
371         int keyLen = 0;
372         byte* pData = null;
373         byte* pKey = null;
374         _OidType oidValue = _OID_TYPE_UNKNOWN;
375
376         ClearLastResult();
377
378         SysTryReturn(NID_SEC_CRYPTO, params.GetKeyDerivationAlgorithm().GetAlgorithmObjectId().GetLength() > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
379         SysTryReturn(NID_SEC_CRYPTO, params.GetMacAlgorithm().GetAlgorithmObjectId().GetLength() > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
380
381         keyOid = params.GetKeyDerivationAlgorithm().GetAlgorithmObjectId();
382         SysTryReturn(NID_SEC_CRYPTO, keyOid == OID_PBKDF2, null, E_UNSUPPORTED_ALGORITHM, "[E_UNSUPPORTED_ALGORITHM] The input algorithm is not supported.");
383
384         pData = const_cast< byte* >(message.GetPointer());
385         SysTryReturn(NID_SEC_CRYPTO, pData != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
386
387         dataLen = message.GetRemaining();
388         SysTryReturn(NID_SEC_CRYPTO, dataLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The specified input parameter is invalid.");
389
390         pKeyDerivationFuncParam = std::unique_ptr< Pkcs05PbKdf2Parameters >(dynamic_cast< Pkcs05PbKdf2Parameters* >(params.GetKeyDerivationAlgorithm().GetParametersN()));
391         SysTryReturn(NID_SEC_CRYPTO, pKeyDerivationFuncParam, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
392
393         pDKey = std::unique_ptr< ByteBuffer >(GenerateKeyKdf2N(*pKeyDerivationFuncParam));
394         SysTryReturn(NID_SEC_CRYPTO, pDKey, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
395
396         messageAuthScheme = params.GetMacAlgorithm().GetAlgorithmObjectId();
397
398         oidValue = _PkcsUtility::ConvertOidToEnum(messageAuthScheme);
399         switch (oidValue)
400         {
401         case _OID_TYPE_HMAC_SHA1:
402                 __pMacAlgo = EVP_sha1();
403                 break;
404
405         case _OID_TYPE_HMAC_SHA2_224:
406                 __pMacAlgo = EVP_sha224();
407                 break;
408
409         case _OID_TYPE_HMAC_SHA2_256:
410                 __pMacAlgo = EVP_sha256();
411                 break;
412
413         case _OID_TYPE_HMAC_SHA2_384:
414                 __pMacAlgo = EVP_sha384();
415                 break;
416
417         case _OID_TYPE_HMAC_SHA2_512:
418                 __pMacAlgo = EVP_sha512();
419                 break;
420
421         default:
422                 r = E_UNSUPPORTED_ALGORITHM;
423                 SetLastResult(r);
424                 return null;
425         }
426
427         mdLen = EVP_MD_size(__pMacAlgo);
428         SysTryReturn(NID_SEC_CRYPTO, mdLen > 0, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
429
430         pMd = std::unique_ptr< byte >(new (std::nothrow) byte[mdLen]);
431         SysTryReturn(NID_SEC_CRYPTO, pMd, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
432
433         memset(pMd.get(), 0, mdLen);
434
435         pKey = const_cast< byte* >(pDKey->GetPointer());
436         SysTryReturn(NID_SEC_CRYPTO, pKey != null, null, E_KEY_NOT_FOUND, "[E_INVALID_ARG] The specified input parameter is invalid.");
437
438         keyLen = pDKey->GetRemaining();
439         SysTryReturn(NID_SEC_CRYPTO, keyLen > 0, null, E_KEY_NOT_FOUND, "[E_INVALID_ARG] The specified input parameter is invalid.");
440
441
442         //gets HMAC of the input data for SEC_MAC_SHA224
443         HMAC(__pMacAlgo, pKey, keyLen, pData, dataLen, pMd.get(), &mdLen);
444         SysTryReturn(NID_SEC_CRYPTO, mdLen != 0, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
445
446         //stores the HMAC output in bytebuffer
447         pOutput = std::unique_ptr< ByteBuffer >(new (std::nothrow) ByteBuffer());
448         SysTryReturn(NID_SEC_CRYPTO, pOutput, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
449
450         r = pOutput->Construct(mdLen);
451         SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_OUT_OF_MEMORY, "[E_OUT_MEMORY] The memory is insufficient.");
452
453         r = pOutput->SetArray(pMd.get(), 0, mdLen);
454         SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
455
456         pOutput->Flip();
457
458         if (pOutput->GetRemaining() == mac.GetRemaining())
459         {
460                 SysTryReturn(NID_SEC_CRYPTO, mac == *pOutput, null, E_SYSTEM, "[E_SYSTEM] The method cannot proceed due to a severe system error.");
461         }
462
463         return r;
464
465 }
466
467 _Pkcs05SchemesImpl*
468 _Pkcs05SchemesImpl::GetInstance(Pkcs05Schemes& pkcs05Schemes)
469 {
470         return pkcs05Schemes.__pPkcs05SchemesImpl;
471 }
472
473 const _Pkcs05SchemesImpl*
474 _Pkcs05SchemesImpl::GetInstance(const Pkcs05Schemes& pkcs05Schemes)
475 {
476         return pkcs05Schemes.__pPkcs05SchemesImpl;
477 }
478
479
480 } } } // end of namespace Pkcs05