1 /*
2 * SHA-256 implementation with hardware ESP support added.
3 *
4 * SPDX-FileCopyrightText: The Mbed TLS Contributors
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
9 */
10 /*
11 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
12 *
13 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
14 */
15
16 #include <mbedtls/build_info.h>
17
18 #if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA256_ALT)
19
20 #include "mbedtls/sha256.h"
21
22 #include <string.h>
23 #include <assert.h>
24
25 #if defined(MBEDTLS_SELF_TEST)
26 #if defined(MBEDTLS_PLATFORM_C)
27 #include "mbedtls/platform.h"
28 #else
29 #include <stdio.h>
30 #define mbedtls_printf printf
31 #endif /* MBEDTLS_PLATFORM_C */
32 #endif /* MBEDTLS_SELF_TEST */
33
34 #include "sha/sha_block.h"
35
36 /* Implementation that should never be optimized out by the compiler */
mbedtls_zeroize(void * v,size_t n)37 static void mbedtls_zeroize( void *v, size_t n )
38 {
39 volatile unsigned char *p = v;
40 while ( n-- ) {
41 *p++ = 0;
42 }
43 }
44
45 /*
46 * 32-bit integer manipulation macros (big endian)
47 */
48 #ifndef GET_UINT32_BE
49 #define GET_UINT32_BE(n,b,i) \
50 do { \
51 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
52 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
53 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
54 | ( (uint32_t) (b)[(i) + 3] ); \
55 } while( 0 )
56 #endif
57
58 #ifndef PUT_UINT32_BE
59 #define PUT_UINT32_BE(n,b,i) \
60 do { \
61 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
62 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
63 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
64 (b)[(i) + 3] = (unsigned char) ( (n) ); \
65 } while( 0 )
66 #endif
67
mbedtls_sha256_init(mbedtls_sha256_context * ctx)68 void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
69 {
70 assert(ctx != NULL);
71
72 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
73 }
74
mbedtls_sha256_free(mbedtls_sha256_context * ctx)75 void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
76 {
77 if ( ctx == NULL ) {
78 return;
79 }
80
81 mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
82 }
83
mbedtls_sha256_clone(mbedtls_sha256_context * dst,const mbedtls_sha256_context * src)84 void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
85 const mbedtls_sha256_context *src )
86 {
87 *dst = *src;
88 }
89
90 /*
91 * SHA-256 context setup
92 */
mbedtls_sha256_starts(mbedtls_sha256_context * ctx,int is224)93 int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
94 {
95 memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
96
97 if ( is224 ) {
98 ctx->mode = SHA2_224;
99 } else {
100 ctx->mode = SHA2_256;
101 }
102
103 return 0;
104 }
105
esp_internal_sha_update_state(mbedtls_sha256_context * ctx)106 static void esp_internal_sha_update_state(mbedtls_sha256_context *ctx)
107 {
108 if (ctx->sha_state == ESP_SHA256_STATE_INIT) {
109 ctx->first_block = true;
110 ctx->sha_state = ESP_SHA256_STATE_IN_PROCESS;
111 } else if (ctx->sha_state == ESP_SHA256_STATE_IN_PROCESS) {
112 ctx->first_block = false;
113 esp_sha_write_digest_state(ctx->mode, ctx->state);
114 }
115 }
116
esp_internal_sha256_block_process(mbedtls_sha256_context * ctx,const uint8_t * data)117 static void esp_internal_sha256_block_process(mbedtls_sha256_context *ctx, const uint8_t *data)
118 {
119 esp_sha_block(ctx->mode, data, ctx->first_block);
120
121 if (ctx->first_block) {
122 ctx->first_block = false;
123 }
124 }
125
mbedtls_internal_sha256_process(mbedtls_sha256_context * ctx,const unsigned char data[64])126 int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
127 {
128 esp_sha_acquire_hardware();
129 esp_internal_sha_update_state(ctx);
130 esp_sha_block(ctx->mode, data, ctx->first_block);
131 esp_sha_read_digest_state(ctx->mode, ctx->state);
132 esp_sha_release_hardware();
133 return 0;
134 }
135
136 /*
137 * SHA-256 process buffer
138 */
mbedtls_sha256_update(mbedtls_sha256_context * ctx,const unsigned char * input,size_t ilen)139 int mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
140 size_t ilen )
141 {
142 size_t fill;
143 uint32_t left, local_len = 0;
144
145 if ( ilen == 0 ) {
146 return 0;
147 }
148
149 left = ctx->total[0] & 0x3F;
150 fill = 64 - left;
151
152 ctx->total[0] += (uint32_t) ilen;
153 ctx->total[0] &= 0xFFFFFFFF;
154
155 if ( ctx->total[0] < (uint32_t) ilen ) {
156 ctx->total[1]++;
157 }
158
159 /* Check if any data pending from previous call to this API */
160 if ( left && ilen >= fill ) {
161 memcpy( (void *) (ctx->buffer + left), input, fill );
162
163 input += fill;
164 ilen -= fill;
165 left = 0;
166 local_len = 64;
167 }
168
169 if ( (ilen >= 64) || local_len) {
170
171 esp_sha_acquire_hardware();
172
173 esp_internal_sha_update_state(ctx);
174
175 /* First process buffered block, if any */
176 if ( local_len ) {
177 esp_internal_sha256_block_process(ctx, ctx->buffer);
178 }
179
180 while ( ilen >= 64 ) {
181 esp_internal_sha256_block_process(ctx, input);
182
183 input += 64;
184 ilen -= 64;
185 }
186 esp_sha_read_digest_state(ctx->mode, ctx->state);
187
188 esp_sha_release_hardware();
189
190 }
191
192 if ( ilen > 0 ) {
193 memcpy( (void *) (ctx->buffer + left), input, ilen);
194 }
195
196 return 0;
197 }
198
199 static const unsigned char sha256_padding[64] = {
200 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
204 };
205
206 /*
207 * SHA-256 final digest
208 */
mbedtls_sha256_finish(mbedtls_sha256_context * ctx,unsigned char * output)209 int mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char *output )
210 {
211 int ret = -1;
212 uint32_t last, padn;
213 uint32_t high, low;
214 unsigned char msglen[8];
215
216 high = ( ctx->total[0] >> 29 )
217 | ( ctx->total[1] << 3 );
218 low = ( ctx->total[0] << 3 );
219
220 PUT_UINT32_BE( high, msglen, 0 );
221 PUT_UINT32_BE( low, msglen, 4 );
222
223 last = ctx->total[0] & 0x3F;
224 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
225
226 if ( ( ret = mbedtls_sha256_update( ctx, sha256_padding, padn ) ) != 0 ) {
227 return ret;
228 }
229
230 if ( ( ret = mbedtls_sha256_update( ctx, msglen, 8 ) ) != 0 ) {
231 return ret;
232 }
233
234 memcpy(output, ctx->state, 32);
235
236 return ret;
237 }
238
239 #endif /* MBEDTLS_SHA256_C && MBEDTLS_SHA256_ALT */
240