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