1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #ifdef HITLS_CRYPTO_SHA1
18
19 #include <stdlib.h>
20 #include "securec.h"
21 #include "crypt_errno.h"
22 #include "crypt_utils.h"
23 #include "bsl_err_internal.h"
24 #include "sha1_core.h"
25 #include "bsl_sal.h"
26 #include "crypt_sha1.h"
27 #include "crypt_types.h"
28
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif /* __cpluscplus */
33
34 /* SHA-1 context structure */
35 struct CryptSha1Ctx {
36 uint8_t m[CRYPT_SHA1_BLOCKSIZE]; /* store the remaining data which less than one block */
37 uint32_t h[CRYPT_SHA1_DIGESTSIZE / sizeof(uint32_t)]; /* store the intermediate data of the hash value */
38 uint32_t hNum, lNum; /* input data counter, maximum value 2 ^ 64 bits */
39 int32_t errorCode; /* Error code */
40 uint32_t count; /* Number of remaining data bytes less than one block, corresponding to the length of the m */
41 };
42
CRYPT_SHA1_NewCtx(void)43 CRYPT_SHA1_Ctx *CRYPT_SHA1_NewCtx(void)
44 {
45 return BSL_SAL_Calloc(1, sizeof(CRYPT_SHA1_Ctx));
46 }
47
CRYPT_SHA1_FreeCtx(CRYPT_SHA1_Ctx * ctx)48 void CRYPT_SHA1_FreeCtx(CRYPT_SHA1_Ctx *ctx)
49 {
50 CRYPT_SHA1_Ctx *mdCtx = ctx;
51 if (mdCtx == NULL) {
52 return;
53 }
54 BSL_SAL_ClearFree(ctx, sizeof(CRYPT_SHA1_Ctx));
55 }
56
57 /* e767 is because H is defined in SHA1 and MD5.
58 But the both the macros are different. So masked
59 this error */
CRYPT_SHA1_Init(CRYPT_SHA1_Ctx * ctx,BSL_Param * param)60 int32_t CRYPT_SHA1_Init(CRYPT_SHA1_Ctx *ctx, BSL_Param *param)
61 {
62 if (ctx == NULL) {
63 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
64 return CRYPT_NULL_INPUT;
65 }
66 (void) param;
67 (void)memset_s(ctx, sizeof(CRYPT_SHA1_Ctx), 0, sizeof(CRYPT_SHA1_Ctx));
68
69 /**
70 * RFC3174 6.1 Initialize the H constants of the input ctx
71 * These constants are provided by the standard
72 */
73 ctx->h[0] = 0x67452301;
74 ctx->h[1] = 0xefcdab89;
75 ctx->h[2] = 0x98badcfe;
76 ctx->h[3] = 0x10325476;
77 ctx->h[4] = 0xc3d2e1f0;
78 return CRYPT_SUCCESS;
79 }
80
CRYPT_SHA1_Deinit(CRYPT_SHA1_Ctx * ctx)81 void CRYPT_SHA1_Deinit(CRYPT_SHA1_Ctx *ctx)
82 {
83 if (ctx == NULL) {
84 return;
85 }
86 BSL_SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SHA1_Ctx));
87 }
88
CRYPT_SHA1_CopyCtx(CRYPT_SHA1_Ctx * dst,const CRYPT_SHA1_Ctx * src)89 int32_t CRYPT_SHA1_CopyCtx(CRYPT_SHA1_Ctx *dst, const CRYPT_SHA1_Ctx *src)
90 {
91 if (dst == NULL || src == NULL) {
92 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
93 return CRYPT_NULL_INPUT;
94 }
95
96 (void)memcpy_s(dst, sizeof(CRYPT_SHA1_Ctx), src, sizeof(CRYPT_SHA1_Ctx));
97 return CRYPT_SUCCESS;
98 }
99
CRYPT_SHA1_DupCtx(const CRYPT_SHA1_Ctx * src)100 CRYPT_SHA1_Ctx *CRYPT_SHA1_DupCtx(const CRYPT_SHA1_Ctx *src)
101 {
102 if (src == NULL) {
103 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
104 return NULL;
105 }
106 CRYPT_SHA1_Ctx *newCtx = CRYPT_SHA1_NewCtx();
107 if (newCtx == NULL) {
108 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
109 return NULL;
110 }
111 (void)memcpy_s(newCtx, sizeof(CRYPT_SHA1_Ctx), src, sizeof(CRYPT_SHA1_Ctx));
112 return newCtx;
113 }
114
SHA1_CheckIsCorrupted(CRYPT_SHA1_Ctx * ctx,uint32_t textLen)115 static int32_t SHA1_CheckIsCorrupted(CRYPT_SHA1_Ctx *ctx, uint32_t textLen)
116 {
117 uint32_t low = (ctx->lNum + (textLen << 3)) & 0xffffffffUL;
118 if (low < ctx->lNum) { /* overflow */
119 if (++ctx->hNum == 0) {
120 ctx->errorCode = CRYPT_SHA1_INPUT_OVERFLOW;
121 BSL_ERR_PUSH_ERROR(CRYPT_SHA1_INPUT_OVERFLOW);
122 return CRYPT_SHA1_INPUT_OVERFLOW;
123 }
124 }
125 uint32_t high = ctx->hNum + (uint32_t)(textLen >> (32 - 3));
126 if (high < ctx->hNum) { /* overflow */
127 ctx->errorCode = CRYPT_SHA1_INPUT_OVERFLOW;
128 BSL_ERR_PUSH_ERROR(CRYPT_SHA1_INPUT_OVERFLOW);
129 return CRYPT_SHA1_INPUT_OVERFLOW;
130 }
131 ctx->hNum = high;
132 ctx->lNum = low;
133
134 return CRYPT_SUCCESS;
135 }
136
SHA1_UpdateParamIsValid(CRYPT_SHA1_Ctx * ctx,const uint8_t * data,uint32_t nbytes)137 static int32_t SHA1_UpdateParamIsValid(CRYPT_SHA1_Ctx *ctx, const uint8_t *data, uint32_t nbytes)
138 {
139 if ((ctx == NULL) || (data == NULL && nbytes != 0)) {
140 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
141 return CRYPT_NULL_INPUT;
142 }
143
144 if (ctx->errorCode != CRYPT_SUCCESS) {
145 BSL_ERR_PUSH_ERROR(ctx->errorCode);
146 return ctx->errorCode;
147 }
148
149 if (SHA1_CheckIsCorrupted(ctx, nbytes) != CRYPT_SUCCESS) {
150 BSL_ERR_PUSH_ERROR(CRYPT_SHA1_INPUT_OVERFLOW);
151 return CRYPT_SHA1_INPUT_OVERFLOW;
152 }
153
154 return CRYPT_SUCCESS;
155 }
156
CRYPT_SHA1_Update(CRYPT_SHA1_Ctx * ctx,const uint8_t * in,uint32_t len)157 int32_t CRYPT_SHA1_Update(CRYPT_SHA1_Ctx *ctx, const uint8_t *in, uint32_t len)
158 {
159 int32_t ret = SHA1_UpdateParamIsValid(ctx, in, len);
160 if (ret != CRYPT_SUCCESS) {
161 return ret;
162 }
163 const uint8_t *data = in;
164 uint32_t dataLen = len;
165 uint32_t start = ctx->count;
166 uint32_t left = CRYPT_SHA1_BLOCKSIZE - start;
167
168 /* Check whether the user input data and cached data can form a block. */
169 if (dataLen < left) {
170 (void)memcpy_s(&ctx->m[start], left, data, dataLen);
171 ctx->count += dataLen;
172 return CRYPT_SUCCESS;
173 }
174
175 /* Preferentially process the buf data and form a block with the user input data. */
176 if (start != 0) {
177 (void)memcpy_s(&ctx->m[start], left, data, left);
178 (void)SHA1_Step(ctx->m, CRYPT_SHA1_BLOCKSIZE, ctx->h);
179 dataLen -= left;
180 data += left;
181 ctx->count = 0;
182 }
183
184 /* Cyclically process the input data */
185 data = SHA1_Step(data, dataLen, ctx->h);
186 dataLen = len - (data - in);
187
188 /* The remaining data is less than one block and stored in the buf. */
189 if (dataLen != 0) {
190 (void)memcpy_s(ctx->m, CRYPT_SHA1_BLOCKSIZE, data, dataLen);
191 ctx->count = dataLen;
192 }
193 return CRYPT_SUCCESS;
194 }
195
SHA1_FinalParamIsValid(const CRYPT_SHA1_Ctx * ctx,const uint8_t * out,const uint32_t * outLen)196 static int32_t SHA1_FinalParamIsValid(const CRYPT_SHA1_Ctx *ctx, const uint8_t *out, const uint32_t *outLen)
197 {
198 if ((ctx == NULL) || (out == NULL) || (outLen == NULL)) {
199 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
200 return CRYPT_NULL_INPUT;
201 }
202
203 if (*outLen < CRYPT_SHA1_DIGESTSIZE) {
204 BSL_ERR_PUSH_ERROR(CRYPT_SHA1_OUT_BUFF_LEN_NOT_ENOUGH);
205 return CRYPT_SHA1_OUT_BUFF_LEN_NOT_ENOUGH;
206 }
207
208 if (ctx->errorCode != CRYPT_SUCCESS) {
209 BSL_ERR_PUSH_ERROR(ctx->errorCode);
210 return ctx->errorCode;
211 }
212
213 return CRYPT_SUCCESS;
214 }
215
CRYPT_SHA1_Final(CRYPT_SHA1_Ctx * ctx,uint8_t * out,uint32_t * len)216 int32_t CRYPT_SHA1_Final(CRYPT_SHA1_Ctx *ctx, uint8_t *out, uint32_t *len)
217 {
218 int32_t ret = SHA1_FinalParamIsValid(ctx, out, len);
219 if (ret != CRYPT_SUCCESS) {
220 return ret;
221 }
222 uint32_t padLen;
223 uint32_t padPos;
224 /* Add "1" to the end of the user data */
225 ctx->m[ctx->count] = 0x80;
226 ctx->count++;
227
228 /* If here is one complete data block, one complete data block is processed first. */
229 if (ctx->count == CRYPT_SHA1_BLOCKSIZE) {
230 (void)SHA1_Step(ctx->m, CRYPT_SHA1_BLOCKSIZE, ctx->h);
231 ctx->count = 0;
232 }
233
234 /* Calculate the padding position. */
235 padPos = ctx->count;
236 padLen = CRYPT_SHA1_BLOCKSIZE - padPos;
237
238 if (padLen < 8) { /* 64 bits (8 bytes) of 512 bits are reserved to pad "0" */
239 (void)memset_s(&ctx->m[padPos], padLen, 0, padLen);
240 padPos = 0;
241 padLen = CRYPT_SHA1_BLOCKSIZE;
242 (void)SHA1_Step(ctx->m, CRYPT_SHA1_BLOCKSIZE, ctx->h);
243 }
244 /* offset 8 bytes, reserved for storing the data length */
245 (void)memset_s(&ctx->m[padPos], (padLen - 8), 0, (padLen - 8));
246 PUT_UINT32_BE(ctx->hNum, ctx->m, 56); /* The 56th byte starts to store the upper 32-bit data. */
247 PUT_UINT32_BE(ctx->lNum, ctx->m, 60); /* The 60th byte starts to store the lower 32-bit data. */
248 (void)SHA1_Step(ctx->m, CRYPT_SHA1_BLOCKSIZE, ctx->h);
249
250 PUT_UINT32_BE(ctx->h[0], out, 0);
251 PUT_UINT32_BE(ctx->h[1], out, 4);
252 PUT_UINT32_BE(ctx->h[2], out, 8);
253 PUT_UINT32_BE(ctx->h[3], out, 12);
254 PUT_UINT32_BE(ctx->h[4], out, 16);
255 *len = CRYPT_SHA1_DIGESTSIZE;
256 return CRYPT_SUCCESS;
257 }
258
259 #ifdef __cplusplus
260 }
261 #endif
262
263 #endif // HITLS_CRYPTO_SHA1
264