blob: 86a371a69f9b089fc12717cbd490116c27391fd8 [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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020029# include "mbedtls/sha256.h"
30# include "mbedtls/platform_util.h"
31# include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020033# include <string.h>
Rich Evans00ab4702015-02-06 13:43:58 +000034
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020035# if defined(MBEDTLS_SELF_TEST)
36# if defined(MBEDTLS_PLATFORM_C)
37# include "mbedtls/platform.h"
38# else
39# include <stdio.h>
40# include <stdlib.h>
41# define mbedtls_printf printf
42# define mbedtls_calloc calloc
43# define mbedtls_free free
44# endif /* MBEDTLS_PLATFORM_C */
45# endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010046
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020047# define SHA256_VALIDATE_RET(cond) \
48 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA)
49# define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE(cond)
Hanno Becker2f6de422018-12-20 10:22:32 +000050
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020051# if !defined(MBEDTLS_SHA256_ALT)
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020052
Paul Bakker5121ce52009-01-03 21:22:43 +000053/*
54 * 32-bit integer manipulation macros (big endian)
55 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020056# ifndef GET_UINT32_BE
57# define GET_UINT32_BE(n, b, i) \
58 do { \
59 (n) = ((uint32_t)(b)[(i)] << 24) | \
60 ((uint32_t)(b)[(i) + 1] << 16) | \
61 ((uint32_t)(b)[(i) + 2] << 8) | \
62 ((uint32_t)(b)[(i) + 3]); \
63 } while (0)
64# endif
Paul Bakker5121ce52009-01-03 21:22:43 +000065
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020066# ifndef PUT_UINT32_BE
67# define PUT_UINT32_BE(n, b, i) \
68 do { \
69 (b)[(i)] = (unsigned char)((n) >> 24); \
70 (b)[(i) + 1] = (unsigned char)((n) >> 16); \
71 (b)[(i) + 2] = (unsigned char)((n) >> 8); \
72 (b)[(i) + 3] = (unsigned char)((n)); \
73 } while (0)
74# endif
Paul Bakker5121ce52009-01-03 21:22:43 +000075
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020076void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020077{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020078 SHA256_VALIDATE(ctx != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000079
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020080 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020081}
82
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020083void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020084{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020085 if (ctx == NULL)
Paul Bakker5b4af392014-06-26 12:09:34 +020086 return;
87
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020088 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020089}
90
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020091void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
92 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020093{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020094 SHA256_VALIDATE(dst != NULL);
95 SHA256_VALIDATE(src != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000096
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020097 *dst = *src;
98}
99
Paul Bakker5121ce52009-01-03 21:22:43 +0000100/*
101 * SHA-256 context setup
102 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200103int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000104{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200105 SHA256_VALIDATE_RET(ctx != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000106
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200107# if defined(MBEDTLS_SHA224_C)
108 SHA256_VALIDATE_RET(is224 == 0 || is224 == 1);
109# else
110 SHA256_VALIDATE_RET(is224 == 0);
111# endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200112
Paul Bakker5121ce52009-01-03 21:22:43 +0000113 ctx->total[0] = 0;
114 ctx->total[1] = 0;
115
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200116 if (is224 == 0) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000117 /* SHA-256 */
118 ctx->state[0] = 0x6A09E667;
119 ctx->state[1] = 0xBB67AE85;
120 ctx->state[2] = 0x3C6EF372;
121 ctx->state[3] = 0xA54FF53A;
122 ctx->state[4] = 0x510E527F;
123 ctx->state[5] = 0x9B05688C;
124 ctx->state[6] = 0x1F83D9AB;
125 ctx->state[7] = 0x5BE0CD19;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200126 } else {
127# if defined(MBEDTLS_SHA224_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000128 /* SHA-224 */
129 ctx->state[0] = 0xC1059ED8;
130 ctx->state[1] = 0x367CD507;
131 ctx->state[2] = 0x3070DD17;
132 ctx->state[3] = 0xF70E5939;
133 ctx->state[4] = 0xFFC00B31;
134 ctx->state[5] = 0x68581511;
135 ctx->state[6] = 0x64F98FA7;
136 ctx->state[7] = 0xBEFA4FA4;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200137# endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000138 }
139
140 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100141
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200142 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000143}
144
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200145# if !defined(MBEDTLS_SHA256_PROCESS_ALT)
146static const uint32_t K[] = {
147 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1,
148 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
149 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786,
150 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
151 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147,
152 0x06CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
153 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B,
154 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
155 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A,
156 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200157 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
158};
Paul Bakker5121ce52009-01-03 21:22:43 +0000159
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200160# define SHR(x, n) (((x)&0xFFFFFFFF) >> (n))
161# define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000162
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200163# define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
164# define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000165
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200166# define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
167# define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000168
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200169# define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
170# define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000171
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200172# define R(t) \
173 (local.W[t] = S1(local.W[(t)-2]) + local.W[(t)-7] + \
174 S0(local.W[(t)-15]) + local.W[(t)-16])
Paul Bakker5121ce52009-01-03 21:22:43 +0000175
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200176# define P(a, b, c, d, e, f, g, h, x, K) \
177 do { \
178 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
179 local.temp2 = S2(a) + F0((a), (b), (c)); \
180 (d) += local.temp1; \
181 (h) = local.temp1 + local.temp2; \
182 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000183
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200184int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
185 const unsigned char data[64])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200186{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200187 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200188 uint32_t temp1, temp2, W[64];
189 uint32_t A[8];
190 } local;
191
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200192 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000193
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200194 SHA256_VALIDATE_RET(ctx != NULL);
195 SHA256_VALIDATE_RET((const unsigned char *)data != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000196
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200197 for (i = 0; i < 8; i++)
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200198 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200199
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200200# if defined(MBEDTLS_SHA256_SMALLER)
201 for (i = 0; i < 64; i++) {
202 if (i < 16)
203 GET_UINT32_BE(local.W[i], data, 4 * i);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200204 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200205 R(i);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200206
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200207 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
208 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200209
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200210 local.temp1 = local.A[7];
211 local.A[7] = local.A[6];
212 local.A[6] = local.A[5];
213 local.A[5] = local.A[4];
214 local.A[4] = local.A[3];
215 local.A[3] = local.A[2];
216 local.A[2] = local.A[1];
217 local.A[1] = local.A[0];
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200218 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200219 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200220# else /* MBEDTLS_SHA256_SMALLER */
221 for (i = 0; i < 16; i++)
222 GET_UINT32_BE(local.W[i], data, 4 * i);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200223
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200224 for (i = 0; i < 16; i += 8) {
225 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
226 local.A[5], local.A[6], local.A[7], local.W[i + 0], K[i + 0]);
227 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
228 local.A[4], local.A[5], local.A[6], local.W[i + 1], K[i + 1]);
229 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
230 local.A[3], local.A[4], local.A[5], local.W[i + 2], K[i + 2]);
231 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
232 local.A[2], local.A[3], local.A[4], local.W[i + 3], K[i + 3]);
233 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
234 local.A[1], local.A[2], local.A[3], local.W[i + 4], K[i + 4]);
235 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
236 local.A[0], local.A[1], local.A[2], local.W[i + 5], K[i + 5]);
237 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
238 local.A[7], local.A[0], local.A[1], local.W[i + 6], K[i + 6]);
239 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
240 local.A[6], local.A[7], local.A[0], local.W[i + 7], K[i + 7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200241 }
242
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200243 for (i = 16; i < 64; i += 8) {
244 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
245 local.A[5], local.A[6], local.A[7], R(i + 0), K[i + 0]);
246 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
247 local.A[4], local.A[5], local.A[6], R(i + 1), K[i + 1]);
248 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
249 local.A[3], local.A[4], local.A[5], R(i + 2), K[i + 2]);
250 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
251 local.A[2], local.A[3], local.A[4], R(i + 3), K[i + 3]);
252 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
253 local.A[1], local.A[2], local.A[3], R(i + 4), K[i + 4]);
254 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
255 local.A[0], local.A[1], local.A[2], R(i + 5), K[i + 5]);
256 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
257 local.A[7], local.A[0], local.A[1], R(i + 6), K[i + 6]);
258 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
259 local.A[6], local.A[7], local.A[0], R(i + 7), K[i + 7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200260 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200261# endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200262
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200263 for (i = 0; i < 8; i++)
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200264 ctx->state[i] += local.A[i];
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100265
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200266 /* Zeroise buffers and variables to clear sensitive data from memory. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200267 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100268
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200269 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000270}
Jaeden Amero041039f2018-02-19 15:28:08 +0000271
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200272# endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000273
274/*
275 * SHA-256 process buffer
276 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200277int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
278 const unsigned char *input,
279 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000280{
Janos Follath24eed8d2019-11-22 13:21:35 +0000281 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000282 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000283 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000284
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200285 SHA256_VALIDATE_RET(ctx != NULL);
286 SHA256_VALIDATE_RET(ilen == 0 || input != NULL);
Hanno Becker596e0142018-12-18 15:00:38 +0000287
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200288 if (ilen == 0)
289 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000290
291 left = ctx->total[0] & 0x3F;
292 fill = 64 - left;
293
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200294 ctx->total[0] += (uint32_t)ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000295 ctx->total[0] &= 0xFFFFFFFF;
296
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200297 if (ctx->total[0] < (uint32_t)ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000298 ctx->total[1]++;
299
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200300 if (left && ilen >= fill) {
301 memcpy((void *)(ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100302
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200303 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0)
304 return ret;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100305
Paul Bakker5121ce52009-01-03 21:22:43 +0000306 input += fill;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200307 ilen -= fill;
Paul Bakker5121ce52009-01-03 21:22:43 +0000308 left = 0;
309 }
310
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200311 while (ilen >= 64) {
312 if ((ret = mbedtls_internal_sha256_process(ctx, input)) != 0)
313 return ret;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100314
Paul Bakker5121ce52009-01-03 21:22:43 +0000315 input += 64;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200316 ilen -= 64;
Paul Bakker5121ce52009-01-03 21:22:43 +0000317 }
318
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200319 if (ilen > 0)
320 memcpy((void *)(ctx->buffer + left), input, ilen);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100321
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200322 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000323}
324
Paul Bakker5121ce52009-01-03 21:22:43 +0000325/*
326 * SHA-256 final digest
327 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200328int mbedtls_sha256_finish(mbedtls_sha256_context *ctx, unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000329{
Janos Follath24eed8d2019-11-22 13:21:35 +0000330 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200331 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000332 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000333
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200334 SHA256_VALIDATE_RET(ctx != NULL);
335 SHA256_VALIDATE_RET((unsigned char *)output != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000336
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200337 /*
338 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
339 */
340 used = ctx->total[0] & 0x3F;
341
342 ctx->buffer[used++] = 0x80;
343
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200344 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200345 /* Enough room for padding + length in current block */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200346 memset(ctx->buffer + used, 0, 56 - used);
347 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200348 /* We'll need an extra block */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200349 memset(ctx->buffer + used, 0, 64 - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200350
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200351 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0)
352 return ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200353
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200354 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200355 }
356
357 /*
358 * Add message length
359 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200360 high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
361 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200363 PUT_UINT32_BE(high, ctx->buffer, 56);
364 PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000365
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200366 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0)
367 return ret;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100368
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200369 /*
370 * Output final state
371 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200372 PUT_UINT32_BE(ctx->state[0], output, 0);
373 PUT_UINT32_BE(ctx->state[1], output, 4);
374 PUT_UINT32_BE(ctx->state[2], output, 8);
375 PUT_UINT32_BE(ctx->state[3], output, 12);
376 PUT_UINT32_BE(ctx->state[4], output, 16);
377 PUT_UINT32_BE(ctx->state[5], output, 20);
378 PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000379
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200380# if defined(MBEDTLS_SHA224_C)
381 if (ctx->is224 == 0)
382# endif
383 PUT_UINT32_BE(ctx->state[7], output, 28);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100384
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200385 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000386}
387
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200388# endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200389
Paul Bakker5121ce52009-01-03 21:22:43 +0000390/*
391 * output = SHA-256( input buffer )
392 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200393int mbedtls_sha256(const unsigned char *input,
394 size_t ilen,
395 unsigned char *output,
396 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000397{
Janos Follath24eed8d2019-11-22 13:21:35 +0000398 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200399 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000400
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200401# if defined(MBEDTLS_SHA224_C)
402 SHA256_VALIDATE_RET(is224 == 0 || is224 == 1);
403# else
404 SHA256_VALIDATE_RET(is224 == 0);
405# endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200406
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200407 SHA256_VALIDATE_RET(ilen == 0 || input != NULL);
408 SHA256_VALIDATE_RET((unsigned char *)output != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000409
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200410 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100411
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200412 if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0)
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100413 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100414
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200415 if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0)
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100416 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100417
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200418 if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0)
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100419 goto exit;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100420
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100421exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200422 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100423
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200424 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000425}
426
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200427# if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000428/*
429 * FIPS-180-2 test vectors
430 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200431static const unsigned char sha256_test_buf[3][57] = {
Paul Bakker5121ce52009-01-03 21:22:43 +0000432 { "abc" },
433 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
434 { "" }
435};
436
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200437static const size_t sha256_test_buflen[3] = { 3, 56, 1000 };
Paul Bakker5121ce52009-01-03 21:22:43 +0000438
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200439static const unsigned char sha256_test_sum[6][32] = {
Paul Bakker5121ce52009-01-03 21:22:43 +0000440 /*
441 * SHA-224 test vectors
442 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200443 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, 0x86, 0x42,
444 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3, 0x2A, 0xAD, 0xBC, 0xE4,
445 0xBD, 0xA0, 0xB3, 0xF7, 0xE3, 0x6C, 0x9D, 0xA7 },
446 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, 0x5D, 0xBA,
447 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50, 0xB0, 0xC6, 0x45, 0x5C,
448 0xB4, 0xF5, 0x8B, 0x19, 0x52, 0x52, 0x25, 0x25 },
449 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8, 0xBB, 0xB4,
450 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B, 0xF0, 0x3F, 0x42, 0x58,
451 0x19, 0x48, 0xB2, 0xEE, 0x4E, 0xE7, 0xAD, 0x67 },
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
453 /*
454 * SHA-256 test vectors
455 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200456 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, 0x41, 0x41, 0x40,
457 0xDE, 0x5D, 0xAE, 0x22, 0x23, 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17,
458 0x7A, 0x9C, 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
459 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, 0xE5, 0xC0, 0x26,
460 0x93, 0x0C, 0x3E, 0x60, 0x39, 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF,
461 0x21, 0x67, 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
462 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, 0x81, 0xA1, 0xC7,
463 0xE2, 0x84, 0xD7, 0x3E, 0x67, 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97,
464 0x20, 0x0E, 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000465};
466
467/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000468 * Checkup routine
469 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200470int mbedtls_sha256_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000471{
Paul Bakker5b4af392014-06-26 12:09:34 +0200472 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500473 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200474 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000476
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200477 buf = mbedtls_calloc(1024, sizeof(unsigned char));
478 if (NULL == buf) {
479 if (verbose != 0)
480 mbedtls_printf("Buffer allocation failed\n");
Russ Butlerbb83b422016-10-12 17:36:50 -0500481
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200482 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500483 }
484
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200485 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200486
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200487 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000488 j = i % 3;
489 k = i < 3;
490
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200491 if (verbose != 0)
492 mbedtls_printf(" SHA-%d test #%d: ", 256 - k * 32, j + 1);
Paul Bakker5121ce52009-01-03 21:22:43 +0000493
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200494 if ((ret = mbedtls_sha256_starts(&ctx, k)) != 0)
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100495 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000496
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200497 if (j == 2) {
498 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000499
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200500 for (j = 0; j < 1000; j++) {
501 ret = mbedtls_sha256_update(&ctx, buf, buflen);
502 if (ret != 0)
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100503 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100504 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100505
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200506 } else {
507 ret = mbedtls_sha256_update(&ctx, sha256_test_buf[j],
508 sha256_test_buflen[j]);
509 if (ret != 0)
510 goto fail;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100511 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000512
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200513 if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0)
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100514 goto fail;
515
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200516 if (memcmp(sha256sum, sha256_test_sum[i], 32 - k * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100517 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100518 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100519 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000520
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200521 if (verbose != 0)
522 mbedtls_printf("passed\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000523 }
524
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200525 if (verbose != 0)
526 mbedtls_printf("\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000527
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100528 goto exit;
529
530fail:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200531 if (verbose != 0)
532 mbedtls_printf("failed\n");
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100533
Paul Bakker5b4af392014-06-26 12:09:34 +0200534exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200535 mbedtls_sha256_free(&ctx);
536 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200537
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200538 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000539}
540
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200541# endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000542
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200543#endif /* MBEDTLS_SHA256_C */