1 /*
2 * Copyright (c) 2021 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 #include "pkg_algo_digest.h"
16 #include "openssl/sha.h"
17 #include "pkg_algorithm.h"
18 #include "pkg_utils.h"
19 #include "zlib.h"
20
21 namespace hpackage {
GetDigestLen(int8_t digestMethod)22 size_t DigestAlgorithm::GetDigestLen(int8_t digestMethod)
23 {
24 static size_t digestLens[PKG_DIGEST_TYPE_MAX] = {0, DIGEST_CRC_LEN, DIGEST_SHA256_LEN, DIGEST_SHA256_LEN};
25 if (digestMethod < PKG_DIGEST_TYPE_MAX) {
26 return digestLens[digestMethod];
27 }
28 return 0;
29 }
30
GetSignatureLen(int8_t digestMethod)31 size_t DigestAlgorithm::GetSignatureLen(int8_t digestMethod)
32 {
33 static size_t signatureLens[PKG_DIGEST_TYPE_MAX] = {0, 0, SIGN_SHA256_LEN, SIGN_SHA384_LEN};
34 if (digestMethod < PKG_DIGEST_TYPE_MAX) {
35 return signatureLens[digestMethod];
36 }
37 return SIGN_SHA256_LEN;
38 }
39
GetDigestMethod(std::string version)40 uint8_t DigestAlgorithm::GetDigestMethod(std::string version)
41 {
42 if (version == "3") {
43 return PKG_DIGEST_TYPE_SHA384;
44 } else {
45 return PKG_DIGEST_TYPE_SHA256;
46 }
47 }
48
Init()49 int32_t Crc32Algorithm::Init()
50 {
51 crc32_ = 0;
52 return PKG_SUCCESS;
53 }
54
Update(const PkgBuffer & buffer,size_t size)55 int32_t Crc32Algorithm::Update(const PkgBuffer &buffer, size_t size)
56 {
57 PKG_CHECK(buffer.buffer != nullptr, return PKG_INVALID_PARAM, "Param null!");
58 crc32_ = crc32(crc32_, buffer.buffer, size);
59 return PKG_SUCCESS;
60 }
61
Final(PkgBuffer & result)62 int32_t Crc32Algorithm::Final(PkgBuffer &result)
63 {
64 PKG_CHECK(result.buffer != nullptr, return PKG_INVALID_PARAM, "Param null!");
65 PKG_CHECK(result.length == sizeof(uint32_t), return PKG_INVALID_PARAM, "Invalid size %zu", result.length);
66 WriteLE32(result.buffer, crc32_);
67 return PKG_SUCCESS;
68 }
69
Calculate(PkgBuffer & result,const PkgBuffer & buffer,size_t size)70 int32_t Crc32Algorithm::Calculate(PkgBuffer &result, const PkgBuffer &buffer, size_t size)
71 {
72 PKG_CHECK(result.buffer != nullptr && buffer.buffer != nullptr, return PKG_INVALID_PARAM, "Param null!");
73 PKG_CHECK(result.length == sizeof(uint32_t), return PKG_INVALID_PARAM, "Invalid size %zu", result.length);
74 auto crc = reinterpret_cast<uint32_t *>(result.buffer);
75 // Generate CRC32 of file.
76 *crc = crc32(*crc, buffer.buffer, size);
77 return PKG_SUCCESS;
78 }
79
Init()80 int32_t Sha256Algorithm::Init()
81 {
82 SHA256_Init(&sha256Ctx_);
83 return PKG_SUCCESS;
84 }
85
Update(const PkgBuffer & buffer,size_t size)86 int32_t Sha256Algorithm::Update(const PkgBuffer &buffer, size_t size)
87 {
88 PKG_CHECK(buffer.buffer != nullptr, return PKG_INVALID_PARAM, "Param null!");
89 SHA256_Update(&sha256Ctx_, buffer.buffer, size);
90 return PKG_SUCCESS;
91 }
92
Final(PkgBuffer & result)93 int32_t Sha256Algorithm::Final(PkgBuffer &result)
94 {
95 PKG_CHECK(result.buffer != nullptr && result.length == DIGEST_SHA256_LEN,
96 return PKG_INVALID_PARAM, "Param context null!");
97 SHA256_Final(result.buffer, &sha256Ctx_);
98 return PKG_SUCCESS;
99 }
100
Calculate(PkgBuffer & result,const PkgBuffer & buffer,size_t size)101 int32_t Sha256Algorithm::Calculate(PkgBuffer &result, const PkgBuffer &buffer, size_t size)
102 {
103 PKG_CHECK(result.buffer != nullptr && result.length == DIGEST_SHA256_LEN,
104 return PKG_INVALID_PARAM, "Param context null!");
105 PKG_CHECK(buffer.buffer != nullptr, return PKG_INVALID_PARAM, "Param null!");
106 SHA256_Init(&sha256Ctx_);
107 SHA256_Update(&sha256Ctx_, buffer.buffer, size);
108 SHA256_Final(result.buffer, &sha256Ctx_);
109 return PKG_SUCCESS;
110 }
111
Init()112 int32_t Sha384Algorithm::Init()
113 {
114 SHA512_Init(&shaCtx_);
115 return PKG_SUCCESS;
116 }
117
Update(const PkgBuffer & buffer,size_t size)118 int32_t Sha384Algorithm::Update(const PkgBuffer &buffer, size_t size)
119 {
120 PKG_CHECK(buffer.buffer != nullptr, return PKG_INVALID_PARAM, "Param null!");
121 SHA384_Update(&shaCtx_, buffer.buffer, size);
122 return PKG_SUCCESS;
123 }
124
Final(PkgBuffer & result)125 int32_t Sha384Algorithm::Final(PkgBuffer &result)
126 {
127 PKG_CHECK(result.buffer != nullptr && result.length == 64, // 64 length
128 return PKG_INVALID_PARAM, "Param context null!");
129 SHA384_Final(result.buffer, &shaCtx_);
130 return PKG_SUCCESS;
131 }
132
Calculate(PkgBuffer & result,const PkgBuffer & buffer,size_t size)133 int32_t Sha384Algorithm::Calculate(PkgBuffer &result, const PkgBuffer &buffer, size_t size)
134 {
135 PKG_CHECK(result.buffer != nullptr && result.length == 64, // 64 length
136 return PKG_INVALID_PARAM, "Param context null!");
137 PKG_CHECK(buffer.buffer != nullptr, return PKG_INVALID_PARAM, "Param null!");
138 SHA512_Init(&shaCtx_);
139 SHA384_Update(&shaCtx_, buffer.buffer, size);
140 SHA384_Final(result.buffer, &shaCtx_);
141 return PKG_SUCCESS;
142 }
143
GetDigestAlgorithm(uint8_t type)144 DigestAlgorithm::DigestAlgorithmPtr PkgAlgorithmFactory::GetDigestAlgorithm(uint8_t type)
145 {
146 switch (type) {
147 case PKG_DIGEST_TYPE_CRC:
148 return std::make_shared<Crc32Algorithm>();
149 case PKG_DIGEST_TYPE_SHA256:
150 case PKG_DIGEST_TYPE_SHA384:
151 return std::make_shared<Sha256Algorithm>();
152 default:
153 return std::make_shared<DigestAlgorithm>();
154 break;
155 }
156 return nullptr;
157 }
158 } // namespace hpackage
159