blob: 74f32369bb72319e00ce60b1e47a4c1dcc594c4a [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
Dave Rodgman7ff79652023-11-03 12:04:52 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker5121ce52009-01-03 21:22:43 +00006 */
7/*
8 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
9 *
10 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
11 */
12
Gilles Peskinedb09ef62020-06-03 01:43:33 +020013#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000014
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020015#if defined(MBEDTLS_SHA256_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000016
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000017#include "mbedtls/sha256.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050018#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000019#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000020
Rich Evans00ab4702015-02-06 13:43:58 +000021#include <string.h>
22
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000023#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010024
Hanno Becker2f6de422018-12-20 10:22:32 +000025#define SHA256_VALIDATE_RET(cond) \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010026 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA)
27#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE(cond)
Hanno Becker2f6de422018-12-20 10:22:32 +000028
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020029#if !defined(MBEDTLS_SHA256_ALT)
30
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010031void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020032{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010033 SHA256_VALIDATE(ctx != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000034
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010035 memset(ctx, 0, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020036}
37
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010038void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020039{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010040 if (ctx == NULL) {
Paul Bakker5b4af392014-06-26 12:09:34 +020041 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010042 }
Paul Bakker5b4af392014-06-26 12:09:34 +020043
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010044 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020045}
46
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010047void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
48 const mbedtls_sha256_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020049{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010050 SHA256_VALIDATE(dst != NULL);
51 SHA256_VALIDATE(src != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000052
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020053 *dst = *src;
54}
55
Paul Bakker5121ce52009-01-03 21:22:43 +000056/*
57 * SHA-256 context setup
58 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010059int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +000060{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010061 SHA256_VALIDATE_RET(ctx != NULL);
62 SHA256_VALIDATE_RET(is224 == 0 || is224 == 1);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +000063
Paul Bakker5121ce52009-01-03 21:22:43 +000064 ctx->total[0] = 0;
65 ctx->total[1] = 0;
66
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010067 if (is224 == 0) {
Paul Bakker5121ce52009-01-03 21:22:43 +000068 /* SHA-256 */
69 ctx->state[0] = 0x6A09E667;
70 ctx->state[1] = 0xBB67AE85;
71 ctx->state[2] = 0x3C6EF372;
72 ctx->state[3] = 0xA54FF53A;
73 ctx->state[4] = 0x510E527F;
74 ctx->state[5] = 0x9B05688C;
75 ctx->state[6] = 0x1F83D9AB;
76 ctx->state[7] = 0x5BE0CD19;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010077 } else {
Paul Bakker5121ce52009-01-03 21:22:43 +000078 /* SHA-224 */
79 ctx->state[0] = 0xC1059ED8;
80 ctx->state[1] = 0x367CD507;
81 ctx->state[2] = 0x3070DD17;
82 ctx->state[3] = 0xF70E5939;
83 ctx->state[4] = 0xFFC00B31;
84 ctx->state[5] = 0x68581511;
85 ctx->state[6] = 0x64F98FA7;
86 ctx->state[7] = 0xBEFA4FA4;
87 }
88
89 ctx->is224 = is224;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +010090
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010091 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +000092}
93
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +020094#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010095void mbedtls_sha256_starts(mbedtls_sha256_context *ctx,
96 int is224)
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +020097{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010098 mbedtls_sha256_starts_ret(ctx, is224);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +020099}
100#endif
101
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200102#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200103static const uint32_t K[] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000104{
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200105 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
106 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
107 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
108 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
109 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
110 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
111 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
112 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
113 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
114 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
115 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
116 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
117 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
118 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
119 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
120 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
121};
Paul Bakker5121ce52009-01-03 21:22:43 +0000122
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100123#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
124#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000125
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100126#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
127#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
Paul Bakker5121ce52009-01-03 21:22:43 +0000128
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100129#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
130#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
Paul Bakker5121ce52009-01-03 21:22:43 +0000131
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100132#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
133#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000134
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200135#define R(t) \
136 ( \
137 local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \
138 S0(local.W[(t) - 15]) + local.W[(t) - 16] \
Hanno Becker1eeca412018-10-15 12:01:35 +0100139 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000140
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100141#define P(a, b, c, d, e, f, g, h, x, K) \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200142 do \
143 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100144 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
145 local.temp2 = S2(a) + F0((a), (b), (c)); \
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200146 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100147 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000148
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100149int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
150 const unsigned char data[64])
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200151{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100152 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200153 uint32_t temp1, temp2, W[64];
154 uint32_t A[8];
155 } local;
156
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200157 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000158
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100159 SHA256_VALIDATE_RET(ctx != NULL);
160 SHA256_VALIDATE_RET((const unsigned char *) data != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000161
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100162 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200163 local.A[i] = ctx->state[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100164 }
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200165
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200166#if defined(MBEDTLS_SHA256_SMALLER)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100167 for (i = 0; i < 64; i++) {
168 if (i < 16) {
169 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
170 } else {
171 R(i);
172 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200173
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100174 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
175 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200176
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200177 local.temp1 = local.A[7]; local.A[7] = local.A[6];
178 local.A[6] = local.A[5]; local.A[5] = local.A[4];
179 local.A[4] = local.A[3]; local.A[3] = local.A[2];
180 local.A[2] = local.A[1]; local.A[1] = local.A[0];
181 local.A[0] = local.temp1;
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200182 }
183#else /* MBEDTLS_SHA256_SMALLER */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100184 for (i = 0; i < 16; i++) {
185 local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200186 }
187
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100188 for (i = 0; i < 16; i += 8) {
189 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
190 local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]);
191 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
192 local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]);
193 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
194 local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]);
195 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
196 local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]);
197 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
198 local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]);
199 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
200 local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]);
201 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
202 local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]);
203 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
204 local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]);
205 }
206
207 for (i = 16; i < 64; i += 8) {
208 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
209 local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]);
210 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
211 local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]);
212 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
213 local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]);
214 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
215 local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]);
216 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
217 local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]);
218 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
219 local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]);
220 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
221 local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]);
222 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
223 local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]);
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200224 }
Manuel Pégourié-Gonnardeb0d8702015-05-28 12:54:04 +0200225#endif /* MBEDTLS_SHA256_SMALLER */
Manuel Pégourié-Gonnarda7a3a5f2015-05-28 12:14:49 +0200226
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100227 for (i = 0; i < 8; i++) {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200228 ctx->state[i] += local.A[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100229 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100230
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200231 /* Zeroise buffers and variables to clear sensitive data from memory. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100232 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100233
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100234 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000235}
Jaeden Amero041039f2018-02-19 15:28:08 +0000236
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200237#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100238void mbedtls_sha256_process(mbedtls_sha256_context *ctx,
239 const unsigned char data[64])
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200240{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100241 mbedtls_internal_sha256_process(ctx, data);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200242}
243#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200244#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000245
246/*
247 * SHA-256 process buffer
248 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100249int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx,
250 const unsigned char *input,
251 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000252{
Janos Follath24eed8d2019-11-22 13:21:35 +0000253 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000254 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000255 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000256
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100257 SHA256_VALIDATE_RET(ctx != NULL);
258 SHA256_VALIDATE_RET(ilen == 0 || input != NULL);
Hanno Becker596e0142018-12-18 15:00:38 +0000259
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100260 if (ilen == 0) {
261 return 0;
262 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000263
264 left = ctx->total[0] & 0x3F;
265 fill = 64 - left;
266
Paul Bakker5c2364c2012-10-01 14:41:15 +0000267 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000268 ctx->total[0] &= 0xFFFFFFFF;
269
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100270 if (ctx->total[0] < (uint32_t) ilen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000271 ctx->total[1]++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100272 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000273
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100274 if (left && ilen >= fill) {
275 memcpy((void *) (ctx->buffer + left), input, fill);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100276
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100277 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
278 return ret;
279 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100280
Paul Bakker5121ce52009-01-03 21:22:43 +0000281 input += fill;
282 ilen -= fill;
283 left = 0;
284 }
285
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100286 while (ilen >= 64) {
287 if ((ret = mbedtls_internal_sha256_process(ctx, input)) != 0) {
288 return ret;
289 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100290
Paul Bakker5121ce52009-01-03 21:22:43 +0000291 input += 64;
292 ilen -= 64;
293 }
294
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100295 if (ilen > 0) {
296 memcpy((void *) (ctx->buffer + left), input, ilen);
297 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100298
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100299 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000300}
301
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200302#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100303void mbedtls_sha256_update(mbedtls_sha256_context *ctx,
304 const unsigned char *input,
305 size_t ilen)
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200306{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100307 mbedtls_sha256_update_ret(ctx, input, ilen);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200308}
309#endif
310
Paul Bakker5121ce52009-01-03 21:22:43 +0000311/*
312 * SHA-256 final digest
313 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100314int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx,
315 unsigned char output[32])
Paul Bakker5121ce52009-01-03 21:22:43 +0000316{
Janos Follath24eed8d2019-11-22 13:21:35 +0000317 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200318 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000319 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000320
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100321 SHA256_VALIDATE_RET(ctx != NULL);
322 SHA256_VALIDATE_RET((unsigned char *) output != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000323
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200324 /*
325 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
326 */
327 used = ctx->total[0] & 0x3F;
328
329 ctx->buffer[used++] = 0x80;
330
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100331 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200332 /* Enough room for padding + length in current block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100333 memset(ctx->buffer + used, 0, 56 - used);
334 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200335 /* We'll need an extra block */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100336 memset(ctx->buffer + used, 0, 64 - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200337
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100338 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
339 return ret;
340 }
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200341
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100342 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200343 }
344
345 /*
346 * Add message length
347 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100348 high = (ctx->total[0] >> 29)
349 | (ctx->total[1] << 3);
350 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100352 MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56);
353 MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000354
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100355 if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) {
356 return ret;
357 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100358
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200359 /*
360 * Output final state
361 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100362 MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0);
363 MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4);
364 MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8);
365 MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12);
366 MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16);
367 MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20);
368 MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000369
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100370 if (ctx->is224 == 0) {
371 MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28);
372 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100373
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100374 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000375}
376
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200377#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100378void mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
379 unsigned char output[32])
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200380{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100381 mbedtls_sha256_finish_ret(ctx, output);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200382}
383#endif
384
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385#endif /* !MBEDTLS_SHA256_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200386
Paul Bakker5121ce52009-01-03 21:22:43 +0000387/*
388 * output = SHA-256( input buffer )
389 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100390int mbedtls_sha256_ret(const unsigned char *input,
391 size_t ilen,
392 unsigned char output[32],
393 int is224)
Paul Bakker5121ce52009-01-03 21:22:43 +0000394{
Janos Follath24eed8d2019-11-22 13:21:35 +0000395 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200396 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100398 SHA256_VALIDATE_RET(is224 == 0 || is224 == 1);
399 SHA256_VALIDATE_RET(ilen == 0 || input != NULL);
400 SHA256_VALIDATE_RET((unsigned char *) output != NULL);
Andres Amaya Garcia79e593f2018-12-09 20:41:20 +0000401
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100402 mbedtls_sha256_init(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100403
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100404 if ((ret = mbedtls_sha256_starts_ret(&ctx, is224)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100405 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100406 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100407
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100408 if ((ret = mbedtls_sha256_update_ret(&ctx, input, ilen)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100409 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100410 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100411
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100412 if ((ret = mbedtls_sha256_finish_ret(&ctx, output)) != 0) {
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100413 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100414 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100415
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100416exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100417 mbedtls_sha256_free(&ctx);
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100418
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100419 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000420}
421
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200422#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100423void mbedtls_sha256(const unsigned char *input,
424 size_t ilen,
425 unsigned char output[32],
426 int is224)
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200427{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100428 mbedtls_sha256_ret(input, ilen, output, is224);
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200429}
430#endif
431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000433/*
434 * FIPS-180-2 test vectors
435 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000436static const unsigned char sha256_test_buf[3][57] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000437{
438 { "abc" },
439 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
440 { "" }
441};
442
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100443static const size_t sha256_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000444{
445 3, 56, 1000
446};
447
Paul Bakker9e36f042013-06-30 14:34:05 +0200448static const unsigned char sha256_test_sum[6][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000449{
450 /*
451 * SHA-224 test vectors
452 */
453 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
454 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
455 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
456 0xE3, 0x6C, 0x9D, 0xA7 },
457 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
458 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
459 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
460 0x52, 0x52, 0x25, 0x25 },
461 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
462 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
463 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
464 0x4E, 0xE7, 0xAD, 0x67 },
465
466 /*
467 * SHA-256 test vectors
468 */
469 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
470 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
471 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
472 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
473 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
474 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
475 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
476 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
477 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
478 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
479 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
480 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
481};
482
483/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000484 * Checkup routine
485 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100486int mbedtls_sha256_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000487{
Paul Bakker5b4af392014-06-26 12:09:34 +0200488 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500489 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200490 unsigned char sha256sum[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491 mbedtls_sha256_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000492
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100493 buf = mbedtls_calloc(1024, sizeof(unsigned char));
494 if (NULL == buf) {
495 if (verbose != 0) {
496 mbedtls_printf("Buffer allocation failed\n");
497 }
Russ Butlerbb83b422016-10-12 17:36:50 -0500498
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100499 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500500 }
501
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100502 mbedtls_sha256_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200503
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100504 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000505 j = i % 3;
506 k = i < 3;
507
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100508 if (verbose != 0) {
509 mbedtls_printf(" SHA-%d test #%d: ", 256 - k * 32, j + 1);
510 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000511
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100512 if ((ret = mbedtls_sha256_starts_ret(&ctx, k)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100513 goto fail;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100514 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000515
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100516 if (j == 2) {
517 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000518
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100519 for (j = 0; j < 1000; j++) {
520 ret = mbedtls_sha256_update_ret(&ctx, buf, buflen);
521 if (ret != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100522 goto fail;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100523 }
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100524 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100525
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100526 } else {
527 ret = mbedtls_sha256_update_ret(&ctx, sha256_test_buf[j],
528 sha256_test_buflen[j]);
529 if (ret != 0) {
530 goto fail;
531 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100532 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000533
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100534 if ((ret = mbedtls_sha256_finish_ret(&ctx, sha256sum)) != 0) {
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100535 goto fail;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100536 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100537
Paul Bakker5121ce52009-01-03 21:22:43 +0000538
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100539 if (memcmp(sha256sum, sha256_test_sum[i], 32 - k * 4) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100540 ret = 1;
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100541 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100542 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000543
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100544 if (verbose != 0) {
545 mbedtls_printf("passed\n");
546 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000547 }
548
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100549 if (verbose != 0) {
550 mbedtls_printf("\n");
551 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000552
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100553 goto exit;
554
555fail:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100556 if (verbose != 0) {
557 mbedtls_printf("failed\n");
558 }
Andres Amaya Garcia72a7f532017-05-02 11:38:47 +0100559
Paul Bakker5b4af392014-06-26 12:09:34 +0200560exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100561 mbedtls_sha256_free(&ctx);
562 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200563
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100564 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000565}
566
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000568
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569#endif /* MBEDTLS_SHA256_C */