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