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 FSecCryptoSha2Hash.cpp
19 * @brief This file contains the implementation of Sha2Hash class.
21 #include <unique_ptr.h>
22 #include <openssl/sha.h>
23 #include <openssl/evp.h>
24 #include <FBaseResult.h>
25 #include <FBaseErrors.h>
26 #include <FSecCryptoSha2Hash.h>
27 #include <FBaseSysLog.h>
29 using namespace Tizen::Base;
31 namespace Tizen { namespace Security { namespace Crypto
33 static const int _SHA2_DIGEST_LENGTH = 64;
35 Sha2Hash::Sha2Hash(void)
36 : __pAlgorithm(EVP_sha256())
38 , __pSha2HashImpl(null)
42 Sha2Hash::~Sha2Hash(void)
48 Sha2Hash::SetAlgorithm(const Tizen::Base::String& algorithm)
52 if (algorithm.CompareTo(L"SHA2/224") == 0)
54 __pAlgorithm = EVP_sha224();
56 else if (algorithm.CompareTo(L"SHA2/256") == 0)
58 __pAlgorithm = EVP_sha256();
60 else if (algorithm.CompareTo(L"SHA2/384") == 0)
62 __pAlgorithm = EVP_sha384();
64 else if (algorithm.CompareTo(L"SHA2/512") == 0)
66 __pAlgorithm = EVP_sha512();
70 r = E_UNSUPPORTED_ALGORITHM;
77 Sha2Hash::GetHashN(const ByteBuffer& input) const
81 unsigned int outLen = 0;
83 byte hashOut[_SHA2_DIGEST_LENGTH] = {'\0'};
87 SysTryReturn(NID_SEC_CRYPTO, __pAlgorithm != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The algorithm value should be valid.");
89 pData = const_cast< byte* >(input.GetPointer());
90 SysTryReturn(NID_SEC_CRYPTO, pData != null, null, E_INVALID_ARG, "[E_INVALID_ARG] The input data value should be valid.");
92 dataLen = input.GetRemaining();
93 SysTryReturn(NID_SEC_CRYPTO, dataLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The input data length should be positive.");
95 outLen = EVP_MD_size(__pAlgorithm);
97 EVP_Digest(pData, dataLen, hashOut, &outLen, __pAlgorithm, null);
98 SysTryReturn(NID_SEC_CRYPTO, outLen > 0, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
100 //stores the hash in bytebuffer
101 std::unique_ptr<ByteBuffer> pOutput(new (std::nothrow) ByteBuffer());
102 SysTryReturn(NID_SEC_CRYPTO, pOutput != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
104 r = pOutput->Construct(outLen);
105 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
107 r = pOutput->SetArray(hashOut, 0, outLen);
108 SysTryReturn(NID_SEC_CRYPTO, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
112 return pOutput.release();
116 Sha2Hash::Initialize(void)
118 result r = E_SUCCESS;
121 SysAssertf(__pEvpMdCtx == null, "Already constructed. Calling Initialize() twice or more on a same instance is not allowed for this class.");
123 __pEvpMdCtx = new (std::nothrow) EVP_MD_CTX();
124 SysTryReturn(NID_SEC_CRYPTO, __pEvpMdCtx != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
126 ret = EVP_DigestInit(__pEvpMdCtx, __pAlgorithm);
127 SysTryCatch(NID_SEC_CRYPTO, ret == 1, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
140 Sha2Hash::Update(const Tizen::Base::ByteBuffer& input)
142 result r = E_SUCCESS;
147 SysAssertf(__pEvpMdCtx != null, "Not yet constructed. Initialize() should be called before use.");
149 pData = const_cast< byte* >(input.GetPointer());
150 SysTryReturn(NID_SEC_CRYPTO, pData != null, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The input data value should be valid.");
152 dataLen = input.GetRemaining();
153 SysTryReturn(NID_SEC_CRYPTO, dataLen > 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The input data length should be positive.");
155 //SHA2_update is called
156 ret = EVP_DigestUpdate(__pEvpMdCtx, pData, dataLen);
157 SysTryReturn(NID_SEC_CRYPTO, ret == 1, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
162 Tizen::Base::ByteBuffer*
163 Sha2Hash::FinalizeN(void)
165 result r = E_SUCCESS;
168 std::unique_ptr<ByteBuffer> pOutput(null);
169 std::unique_ptr<byte[]> pTempBuf(null);
173 SysAssertf(__pEvpMdCtx != null && __pAlgorithm != null, "Not yet constructed. Initialize() and SetAlgorithm() should be called before use.");
175 outLen = EVP_MD_size(__pAlgorithm);
176 SysTryCatch(NID_SEC_CRYPTO, outLen > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
178 pTempBuf = std::unique_ptr<byte[]>(new (std::nothrow) byte[outLen]);
179 SysTryCatch(NID_SEC_CRYPTO, pTempBuf != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
181 ret = EVP_DigestFinal(__pEvpMdCtx, pTempBuf.get(), null);
182 SysTryCatch(NID_SEC_CRYPTO, ret == 1, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
184 //hash is stored in bytebuffer
185 pOutput = std::unique_ptr<ByteBuffer>(new (std::nothrow) ByteBuffer());
186 SysTryCatch(NID_SEC_CRYPTO, pOutput != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
188 r = pOutput->Construct(outLen);
189 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory");
191 r = pOutput->SetArray(pTempBuf.get(), 0, outLen);
192 SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
198 EVP_MD_CTX_cleanup(__pEvpMdCtx);
208 return pOutput.release();
211 } } } //Tizen::Security::Crypto