2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 * @file FSecCryptoMd5Hash.cpp
19 * @brief This file contains the implementation of Md5Hash class.
22 #include <unique_ptr.h>
23 #include <openssl/md5.h>
24 #include <openssl/evp.h>
25 #include <FBaseResult.h>
26 #include <FBaseErrors.h>
27 #include <FSecCryptoMd5Hash.h>
28 #include <FBaseSysLog.h>
30 using namespace Tizen::Base;
33 namespace Tizen { namespace Security { namespace Crypto
36 Md5Hash::Md5Hash(void)
38 , __pMd5HashImpl(null)
42 Md5Hash::~Md5Hash(void)
48 Md5Hash::SetAlgorithm(const Tizen::Base::String& algorithm)
50 // Unsupported in Md5Hash
51 return E_UNSUPPORTED_ALGORITHM;
55 Md5Hash::GetHashN(const ByteBuffer& input) const
59 unsigned int outLen = 0;
61 byte hashOut[MD5_DIGEST_LENGTH] = {'\0'};
65 pData = const_cast< byte* >(input.GetPointer());
66 SysTryReturn(NID_SEC_CRYPTO, pData != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The input data value should be valid.");
68 dataLen = input.GetRemaining();
69 SysTryReturn(NID_SEC_CRYPTO, dataLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The input data length should be positive.");
71 //this function returns the MD5 hash hashOut
72 EVP_Digest(pData, dataLen, hashOut, &outLen, EVP_md5(), null);
73 SysTryReturn(NID_SEC_CRYPTO, outLen > 0, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
75 //stores the hash in bytebuffer
76 std::unique_ptr<ByteBuffer> pOutput(new (std::nothrow) ByteBuffer());
77 SysTryReturn(NID_SEC_CRYPTO, pOutput != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
79 r = pOutput->Construct(outLen);
80 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
82 r = pOutput->SetArray(hashOut, 0, outLen);
83 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
87 return pOutput.release();
91 Md5Hash::Initialize(void)
96 SysAssertf(__pEvpMdCtx == null, "Already constructed. Calling Initialize() twice or more on a same instance is not allowed for this class.");
99 __pEvpMdCtx = new (std::nothrow) EVP_MD_CTX();
100 SysTryReturn(NID_SEC_CRYPTO, __pEvpMdCtx != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
102 ret = EVP_DigestInit(__pEvpMdCtx, EVP_md5());
103 SysTryCatch(NID_SEC_CRYPTO, ret == 1, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
116 Md5Hash::Update(const ByteBuffer& input)
118 result r = E_SUCCESS;
123 SysAssertf(__pEvpMdCtx != null, "Not yet constructed. Initialize() should be called before use.");
125 pData = const_cast< byte* >(input.GetPointer());
126 SysTryReturn(NID_SEC_CRYPTO, pData != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The input data value should be valid.");
128 dataLen = input.GetRemaining();
129 SysTryReturn(NID_SEC_CRYPTO, dataLen > 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The input data length should be positive.");
131 //MD5_update is called
132 ret = EVP_DigestUpdate(__pEvpMdCtx, pData, dataLen);
133 SysTryReturn(NID_SEC_CRYPTO, ret == 1, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
139 Md5Hash::FinalizeN(void)
141 result r = E_SUCCESS;
143 int outLen = MD5_DIGEST_LENGTH;
144 std::unique_ptr<ByteBuffer> pOutput(null);
148 SysAssertf(__pEvpMdCtx != null, "Not yet constructed. Initialize() should be called before use.");
150 std::unique_ptr<byte[]> pTempBuf(new (std::nothrow) byte[outLen]);
151 SysTryCatch(NID_SEC_CRYPTO, pTempBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
153 //MD5_final is called and is stored in pTempBuf
154 ret = EVP_DigestFinal(__pEvpMdCtx, pTempBuf.get(), null);
155 SysTryCatch(NID_SEC_CRYPTO, ret == 1, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
157 //hash is stored in bytebuffer
158 pOutput = std::unique_ptr<ByteBuffer>(new (std::nothrow) ByteBuffer());
159 SysTryCatch(NID_SEC_CRYPTO, pOutput != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
161 r = pOutput->Construct(outLen);
162 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory");
164 r = pOutput->SetArray(pTempBuf.get(), 0, outLen);
165 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
171 EVP_MD_CTX_cleanup(__pEvpMdCtx);
181 return pOutput.release();
184 } } } //Tizen::Security::Crypto