• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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