blob: f7090396d26278682eb0b0a4e39a8345d98e2314 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Gilles Peskinedb09ef62020-06-03 01:43:33 +020025#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000026
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000028
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050030#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000031#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Rich Evans00ab4702015-02-06 13:43:58 +000033#include <string.h>
34
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000035#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010036
Hanno Becker2f6de422018-12-20 10:22:32 +000037#define SHA256_VALIDATE_RET(cond) \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010038 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA)
39#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE(cond)
Hanno Becker2f6de422018-12-20 10:22:32 +000040
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020041#if !defined(MBEDTLS_SHA256_ALT)
42
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010043void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020044{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010045 SHA256_VALIDATE(ctx != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000046
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010047 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020048}
49
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010050void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020051{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010052 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +020053 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010054 }
Paul Bakker5b4af392014-06-26 12:09:34 +020055
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010056 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020057}
58
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010059void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
60 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020061{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010062 SHA256_VALIDATE(dst != NULL);
63 SHA256_VALIDATE(src != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000064
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020065 *dst = *src;
66}
67
Paul Bakker5121ce52009-01-03 21:22:43 +000068/*
69 * SHA-256 context setup
70 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010071int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +000072{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010073 SHA256_VALIDATE_RET(ctx != NULL);
74 SHA256_VALIDATE_RET(is224 == 0 || is224 == 1);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000075
Paul Bakker5121ce52009-01-03 21:22:43 +000076 ctx->total[0] = 0;
77 ctx->total[1] = 0;
78
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010079 if (is224 == 0) {
Paul Bakker5121ce52009-01-03 21:22:43 +000080 /* SHA-256 */
81 ctx->state[0] = 0x6A09E667;
82 ctx->state[1] = 0xBB67AE85;
83 ctx->state[2] = 0x3C6EF372;
84 ctx->state[3] = 0xA54FF53A;
85 ctx->state[4] = 0x510E527F;
86 ctx->state[5] = 0x9B05688C;
87 ctx->state[6] = 0x1F83D9AB;
88 ctx->state[7] = 0x5BE0CD19;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010089 } else {
Paul Bakker5121ce52009-01-03 21:22:43 +000090 /* SHA-224 */
91 ctx->state[0] = 0xC1059ED8;
92 ctx->state[1] = 0x367CD507;
93 ctx->state[2] = 0x3070DD17;
94 ctx->state[3] = 0xF70E5939;
95 ctx->state[4] = 0xFFC00B31;
96 ctx->state[5] = 0x68581511;
97 ctx->state[6] = 0x64F98FA7;
98 ctx->state[7] = 0xBEFA4FA4;
99 }
100
101 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100102
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100103 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000104}
105
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200106#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100107void mbedtls_sha256_starts(mbedtls_sha256_context *ctx,
108 int is224)
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200109{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100110 mbedtls_sha256_starts_ret(ctx, is224);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200111}
112#endif
113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200115static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000116{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200117 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
118 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
119 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
120 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
121 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
122 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
123 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
124 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
125 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
126 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
127 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
128 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
129 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
130 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
131 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
132 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
133};
Paul Bakker5121ce52009-01-03 21:22:43 +0000134
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100135#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
136#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000137
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100138#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
139#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000140
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100141#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
142#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000143
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100144#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
145#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000146
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200147#define R(t) \
148 ( \
149 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
150 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100151 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000152
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100153#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200154 do \
155 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100156 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
157 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200158 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100159 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000160
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100161int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
162 const unsigned char data[64])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200163{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100164 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200165 uint32_t temp1, temp2, W[64];
166 uint32_t A[8];
167 } local;
168
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200169 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000170
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100171 SHA256_VALIDATE_RET(ctx != NULL);
172 SHA256_VALIDATE_RET((const unsigned char *) data != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000173
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100174 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200175 local.A[i] = ctx->state[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100176 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200177
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200178#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100179 for (i = 0; i < 64; i++) {
180 if (i < 16) {
181 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
182 } else {
183 R(i);
184 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200185
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100186 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
187 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200188
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200189 local.temp1 = local.A[7]; local.A[7] = local.A[6];
190 local.A[6] = local.A[5]; local.A[5] = local.A[4];
191 local.A[4] = local.A[3]; local.A[3] = local.A[2];
192 local.A[2] = local.A[1]; local.A[1] = local.A[0];
193 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200194 }
195#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100196 for (i = 0; i < 16; i++) {
197 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200198 }
199
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100200 for (i = 0; i < 16; i += 8) {
201 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
202 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
203 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
204 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
205 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
206 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
207 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
208 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
209 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
210 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
211 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
212 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
213 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
214 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
215 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
216 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
217 }
218
219 for (i = 16; i < 64; i += 8) {
220 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
221 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
222 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
223 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
224 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
225 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
226 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
227 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
228 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
229 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
230 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
231 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
232 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
233 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
234 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
235 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200236 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200237#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200238
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100239 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200240 ctx->state[i] += local.A[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100241 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100242
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200243 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100244 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100245
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100246 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000247}
Jaeden Amero041039f2018-02-19 15:28:08 +0000248
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200249#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100250void mbedtls_sha256_process(mbedtls_sha256_context *ctx,
251 const unsigned char data[64])
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200252{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100253 mbedtls_internal_sha256_process(ctx, data);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200254}
255#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200256#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000257
258/*
259 * SHA-256 process buffer
260 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100261int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx,
262 const unsigned char *input,
263 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000264{
Janos Follath24eed8d2019-11-22 13:21:35 +0000265 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000266 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000267 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000268
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100269 SHA256_VALIDATE_RET(ctx != NULL);
270 SHA256_VALIDATE_RET(ilen == 0 || input != NULL);
Hanno Becker596e0142018-12-18 15:00:38 +0000271
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100272 if (ilen == 0) {
273 return 0;
274 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000275
276 left = ctx->total[0] & 0x3F;
277 fill = 64 - left;
278
Paul Bakker5c2364c2012-10-01 14:41:15 +0000279 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000280 ctx->total[0] &= 0xFFFFFFFF;
281
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100282 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 ctx->total[1]++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100284 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000285
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100286 if (left && ilen >= fill) {
287 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100288
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100289 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
290 return ret;
291 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100292
Paul Bakker5121ce52009-01-03 21:22:43 +0000293 input += fill;
294 ilen -= fill;
295 left = 0;
296 }
297
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100298 while (ilen >= 64) {
299 if ((ret = mbedtls_internal_sha256_process(ctx, input)) != 0) {
300 return ret;
301 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100302
Paul Bakker5121ce52009-01-03 21:22:43 +0000303 input += 64;
304 ilen -= 64;
305 }
306
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100307 if (ilen > 0) {
308 memcpy((void *) (ctx->buffer + left), input, ilen);
309 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100310
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100311 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000312}
313
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200314#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100315void mbedtls_sha256_update(mbedtls_sha256_context *ctx,
316 const unsigned char *input,
317 size_t ilen)
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200318{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100319 mbedtls_sha256_update_ret(ctx, input, ilen);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200320}
321#endif
322
Paul Bakker5121ce52009-01-03 21:22:43 +0000323/*
324 * SHA-256 final digest
325 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100326int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx,
327 unsigned char output[32])
Paul Bakker5121ce52009-01-03 21:22:43 +0000328{
Janos Follath24eed8d2019-11-22 13:21:35 +0000329 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200330 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000331 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000332
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100333 SHA256_VALIDATE_RET(ctx != NULL);
334 SHA256_VALIDATE_RET((unsigned char *) output != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000335
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200336 /*
337 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
338 */
339 used = ctx->total[0] & 0x3F;
340
341 ctx->buffer[used++] = 0x80;
342
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100343 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200344 /* Enough room for padding + length in current block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100345 memset(ctx->buffer + used, 0, 56 - used);
346 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200347 /* We'll need an extra block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100348 memset(ctx->buffer + used, 0, 64 - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200349
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100350 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
351 return ret;
352 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200353
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100354 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200355 }
356
357 /*
358 * Add message length
359 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100360 high = (ctx->total[0] >> 29)
361 | (ctx->total[1] << 3);
362 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000363
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100364 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
365 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000366
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100367 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
368 return ret;
369 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100370
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200371 /*
372 * Output final state
373 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100374 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
375 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
376 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
377 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
378 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
379 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
380 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100382 if (ctx->is224 == 0) {
383 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
384 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100385
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100386 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000387}
388
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200389#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100390void mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
391 unsigned char output[32])
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200392{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100393 mbedtls_sha256_finish_ret(ctx, output);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200394}
395#endif
396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200398
Paul Bakker5121ce52009-01-03 21:22:43 +0000399/*
400 * output = SHA-256( input buffer )
401 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100402int mbedtls_sha256_ret(const unsigned char *input,
403 size_t ilen,
404 unsigned char output[32],
405 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000406{
Janos Follath24eed8d2019-11-22 13:21:35 +0000407 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100410 SHA256_VALIDATE_RET(is224 == 0 || is224 == 1);
411 SHA256_VALIDATE_RET(ilen == 0 || input != NULL);
412 SHA256_VALIDATE_RET((unsigned char *) output != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000413
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100414 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100415
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100416 if ((ret = mbedtls_sha256_starts_ret(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100417 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100418 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100419
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100420 if ((ret = mbedtls_sha256_update_ret(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100421 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100422 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100423
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100424 if ((ret = mbedtls_sha256_finish_ret(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100425 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100426 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100427
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100428exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100429 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100430
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100431 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000432}
433
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200434#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100435void mbedtls_sha256(const unsigned char *input,
436 size_t ilen,
437 unsigned char output[32],
438 int is224)
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200439{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100440 mbedtls_sha256_ret(input, ilen, output, is224);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200441}
442#endif
443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000445/*
446 * FIPS-180-2 test vectors
447 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000448static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000449{
450 { "abc" },
451 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
452 { "" }
453};
454
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100455static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000456{
457 3, 56, 1000
458};
459
Paul Bakker9e36f042013-06-30 14:34:05 +0200460static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000461{
462 /*
463 * SHA-224 test vectors
464 */
465 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
466 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
467 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
468 0xE3, 0x6C, 0x9D, 0xA7 },
469 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
470 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
471 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
472 0x52, 0x52, 0x25, 0x25 },
473 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
474 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
475 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
476 0x4E, 0xE7, 0xAD, 0x67 },
477
478 /*
479 * SHA-256 test vectors
480 */
481 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
482 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
483 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
484 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
485 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
486 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
487 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
488 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
489 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
490 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
491 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
492 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
493};
494
495/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000496 * Checkup routine
497 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100498int mbedtls_sha256_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000499{
Paul Bakker5b4af392014-06-26 12:09:34 +0200500 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500501 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200502 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000504
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100505 buf = mbedtls_calloc(1024, sizeof(unsigned char));
506 if (NULL == buf) {
507 if (verbose != 0) {
508 mbedtls_printf("Buffer allocation failed\n");
509 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500510
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100511 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500512 }
513
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100514 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200515
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100516 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000517 j = i % 3;
518 k = i < 3;
519
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100520 if (verbose != 0) {
521 mbedtls_printf(" SHA-%d test #%d: ", 256 - k * 32, j + 1);
522 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000523
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100524 if ((ret = mbedtls_sha256_starts_ret(&ctx, k)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100525 goto fail;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100526 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000527
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100528 if (j == 2) {
529 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000530
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100531 for (j = 0; j < 1000; j++) {
532 ret = mbedtls_sha256_update_ret(&ctx, buf, buflen);
533 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100534 goto fail;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100535 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100536 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100537
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100538 } else {
539 ret = mbedtls_sha256_update_ret(&ctx, sha256_test_buf[j],
540 sha256_test_buflen[j]);
541 if (ret != 0) {
542 goto fail;
543 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100544 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000545
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100546 if ((ret = mbedtls_sha256_finish_ret(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100547 goto fail;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100548 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100549
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100551 if (memcmp(sha256sum, sha256_test_sum[i], 32 - k * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100552 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100553 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100554 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100556 if (verbose != 0) {
557 mbedtls_printf("passed\n");
558 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000559 }
560
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100561 if (verbose != 0) {
562 mbedtls_printf("\n");
563 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000564
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100565 goto exit;
566
567fail:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100568 if (verbose != 0) {
569 mbedtls_printf("failed\n");
570 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100571
Paul Bakker5b4af392014-06-26 12:09:34 +0200572exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100573 mbedtls_sha256_free(&ctx);
574 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200575
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100576 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000577}
578
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581#endif /* MBEDTLS_SHA256_C */