• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hs_hashstream.h"
17 
18 #include <iomanip>
19 #include <sstream>
20 
21 #include "filemgmt_libhilog.h"
22 
23 namespace OHOS {
24 namespace FileManagement {
25 namespace ModuleFileIO {
26 using namespace std;
27 
GetHashAlgorithm(const string & alg)28 static HASH_ALGORITHM_TYPE GetHashAlgorithm(const string &alg)
29 {
30     return (algorithmMaps.find(alg) != algorithmMaps.end()) ? algorithmMaps.at(alg) : HASH_ALGORITHM_TYPE_UNSUPPORTED;
31 }
32 
HashFinal(const unique_ptr<unsigned char[]> & hashBuf,size_t hashLen)33 static string HashFinal(const unique_ptr<unsigned char[]> &hashBuf, size_t hashLen)
34 {
35     stringstream ss;
36     for (size_t i = 0; i < hashLen; ++i) {
37         const int hexPerByte = 2;
38         ss << std::uppercase << std::setfill('0') << std::setw(hexPerByte) << std::hex
39            << static_cast<uint32_t>(hashBuf[i]);
40     }
41 
42     return ss.str();
43 }
44 
GetHsEntity()45 tuple<bool, HsHashStreamEntity *> HsHashStream::GetHsEntity()
46 {
47     if (!entity) {
48         return { false, nullptr };
49     }
50 
51     return { true, entity.get() };
52 }
53 
Update(ArrayBuffer & buffer)54 FsResult<void> HsHashStream::Update(ArrayBuffer &buffer)
55 {
56     auto [succ, hsEntity] = GetHsEntity();
57     if (!succ) {
58         HILOGE("Failed to get entity of HashStream");
59         return FsResult<void>::Error(EIO);
60     }
61 
62     switch (hsEntity->algType) {
63         case HASH_ALGORITHM_TYPE_MD5:
64             MD5_Update(&hsEntity->md5Ctx, buffer.buf, buffer.length);
65             break;
66         case HASH_ALGORITHM_TYPE_SHA1:
67             SHA1_Update(&hsEntity->shaCtx, buffer.buf, buffer.length);
68             break;
69         case HASH_ALGORITHM_TYPE_SHA256:
70             SHA256_Update(&hsEntity->sha256Ctx, buffer.buf, buffer.length);
71             break;
72         default:
73             break;
74     }
75 
76     return FsResult<void>::Success();
77 }
78 
Digest()79 FsResult<string> HsHashStream::Digest()
80 {
81     auto [succ, hsEntity] = GetHsEntity();
82     if (!succ) {
83         HILOGE("Failed to get entity of HashStream");
84         return FsResult<string>::Error(EIO);
85     }
86 
87     string digestStr;
88     switch (hsEntity->algType) {
89         case HASH_ALGORITHM_TYPE_MD5: {
90             auto res = make_unique<unsigned char[]>(MD5_DIGEST_LENGTH);
91             MD5_Final(res.get(), &hsEntity->md5Ctx);
92             digestStr = HashFinal(res, MD5_DIGEST_LENGTH);
93             break;
94         }
95         case HASH_ALGORITHM_TYPE_SHA1: {
96             auto res = make_unique<unsigned char[]>(SHA_DIGEST_LENGTH);
97             SHA1_Final(res.get(), &hsEntity->shaCtx);
98             digestStr = HashFinal(res, SHA_DIGEST_LENGTH);
99             break;
100         }
101         case HASH_ALGORITHM_TYPE_SHA256: {
102             auto res = make_unique<unsigned char[]>(SHA256_DIGEST_LENGTH);
103             SHA256_Final(res.get(), &hsEntity->sha256Ctx);
104             digestStr = HashFinal(res, SHA256_DIGEST_LENGTH);
105             break;
106         }
107         default:
108             break;
109     }
110     return FsResult<string>::Success(digestStr);
111 }
112 
Constructor(string alg)113 FsResult<HsHashStream *> HsHashStream::Constructor(string alg)
114 {
115     HASH_ALGORITHM_TYPE algType = GetHashAlgorithm(alg);
116     if (algType == HASH_ALGORITHM_TYPE_UNSUPPORTED) {
117         HILOGE("algType is not found.");
118         return FsResult<HsHashStream *>::Error(EINVAL);
119     }
120 
121     HsHashStreamEntity *rawPtr = new (std::nothrow) HsHashStreamEntity();
122     if (rawPtr == nullptr) {
123         HILOGE("Failed to request heap memory.");
124         return FsResult<HsHashStream *>::Error(ENOMEM);
125     }
126     std::unique_ptr<HsHashStreamEntity> hsEntity(rawPtr);
127     hsEntity->algType = algType;
128 
129     switch (algType) {
130         case HASH_ALGORITHM_TYPE_MD5: {
131             MD5_CTX ctx;
132             MD5_Init(&ctx);
133             hsEntity->md5Ctx = ctx;
134             break;
135         }
136         case HASH_ALGORITHM_TYPE_SHA1: {
137             SHA_CTX ctx;
138             SHA1_Init(&ctx);
139             hsEntity->shaCtx = ctx;
140             break;
141         }
142         case HASH_ALGORITHM_TYPE_SHA256: {
143             SHA256_CTX ctx;
144             SHA256_Init(&ctx);
145             hsEntity->sha256Ctx = ctx;
146             break;
147         }
148         default:
149             break;
150     }
151 
152     HsHashStream *hsStreamPtr = new HsHashStream(move(hsEntity));
153     if (hsStreamPtr == nullptr) {
154         HILOGE("Failed to create HsHashStream object on heap.");
155         return FsResult<HsHashStream *>::Error(ENOMEM);
156     }
157 
158     return FsResult<HsHashStream *>::Success(move(hsStreamPtr));
159 }
160 
161 } // namespace ModuleFileIO
162 } // namespace FileManagement
163 } // namespace OHOS