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 /**
17 * An implementation of sha1 that has 70% less in rom but lower performance.
18 */
19 #include "hitls_build.h"
20 #if defined(HITLS_CRYPTO_SHA1) && defined(HITLS_CRYPTO_SHA1_SMALL_MEM)
21
22 #include <stdlib.h>
23 #include "securec.h"
24 #include "crypt_errno.h"
25 #include "crypt_utils.h"
26 #include "bsl_err_internal.h"
27 #include "crypt_sha1.h"
28
29 #ifdef __cplusplus
30 extern "C" {
31 #endif /* __cpluscplus */
32
33 /* e767 is because H is defined in SHA1 and MD5.
34 But the both the macros are different. So masked
35 this error */
36
37 #define K0 0x5A827999
38 #define K1 0x6ED9EBA1
39 #define K2 0x8F1BBCDC
40 #define K3 0xCA62C1D6
41
42 typedef struct {
43 uint32_t a;
44 uint32_t b;
45 uint32_t c;
46 uint32_t d;
47 uint32_t e;
48 uint32_t w[16];
49 } SHA1_CTX;
50
51 #define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
52 #define F1(b, c, d) (((b) ^ (c)) ^ (d))
53 #define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
54 #define F3(b, c, d) (((b) ^ (c)) ^ (d))
55
56 #define ROUND00_15(s, a, b, c, d, e, Kt) \
57 do { \
58 temp = ROTL32(a, 5) + F##Kt(b, c, d) + (e) + (ctx.w)[s] + K##Kt; \
59 e = d; \
60 d = c; \
61 c = ROTL32(b, 30); \
62 b = a; \
63 a = temp; \
64 } while (0)
65
66 #define ROUND16_79(s, a, b, c, d, e, Kt) \
67 do { \
68 (ctx.w)[(s) & 0xF] = ROTL32( \
69 (ctx.w)[((s) + 13) & 0xF] ^ (ctx.w)[((s) + 8) & 0xF] ^ (ctx.w)[((s) + 2) & 0xF] ^ (ctx.w)[(s) & 0xF], 1); \
70 ROUND00_15((s) & 0xF, a, b, c, d, e, Kt); \
71 } while (0)
72
SHA1_Step(const uint8_t * input,uint32_t len,uint32_t * h)73 const uint8_t *SHA1_Step(const uint8_t *input, uint32_t len, uint32_t *h)
74 {
75 SHA1_CTX ctx = {0};
76 uint32_t temp;
77 const uint8_t *data = input;
78 uint32_t dataLen = len;
79
80 while (dataLen >= CRYPT_SHA1_BLOCKSIZE) {
81 for (int i = 0; i < 16; ++i) {
82 ctx.w[i] = GET_UINT32_BE(data, i * 4);
83 }
84
85 ctx.a = h[0];
86 ctx.b = h[1];
87 ctx.c = h[2];
88 ctx.d = h[3];
89 ctx.e = h[4];
90
91 // Round 0-15
92 for (uint32_t s = 0; s < 16; ++s) {
93 ROUND00_15(s, ctx.a, ctx.b, ctx.c, ctx.d, ctx.e, 0);
94 }
95
96 // Round 16-79
97 for (uint32_t s = 16; s < 20; ++s) {
98 ROUND16_79(s, ctx.a, ctx.b, ctx.c, ctx.d, ctx.e, 0);
99 }
100 for (uint32_t s = 20; s < 40; ++s) {
101 ROUND16_79(s, ctx.a, ctx.b, ctx.c, ctx.d, ctx.e, 1);
102 }
103 for (uint32_t s = 40; s < 60; ++s) {
104 ROUND16_79(s, ctx.a, ctx.b, ctx.c, ctx.d, ctx.e, 2);
105 }
106 for (uint32_t s = 60; s < 80; ++s) {
107 ROUND16_79(s, ctx.a, ctx.b, ctx.c, ctx.d, ctx.e, 3);
108 }
109
110 h[0] += ctx.a;
111 h[1] += ctx.b;
112 h[2] += ctx.c;
113 h[3] += ctx.d;
114 h[4] += ctx.e;
115
116 data += CRYPT_SHA1_BLOCKSIZE;
117 dataLen -= CRYPT_SHA1_BLOCKSIZE;
118 }
119
120 return data;
121 }
122
123 #ifdef __cplusplus
124 }
125 #endif
126
127 #endif // HITLS_CRYPTO_SHA1 && HITLS_CRYPTO_SHA1_SMALL_MEM
128