blob: 0e5e35d548e9b8c7c5983dc6eac82c135136ed63 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-1 compliant SHA-1 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-1 standard was published by NIST in 1993.
21 *
22 * http://www.itl.nist.gov/fipspubs/fip180-1.htm
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_SHA1_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000028
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020029# include "mbedtls/sha1.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# define mbedtls_printf printf
41# endif /* MBEDTLS_PLATFORM_C */
42# endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010043
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020044# define SHA1_VALIDATE_RET(cond) \
45 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA)
Hanno Beckerb3c70232018-12-20 10:18:05 +000046
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020047# define SHA1_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE(cond)
Hanno Beckerb3c70232018-12-20 10:18:05 +000048
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020049# if !defined(MBEDTLS_SHA1_ALT)
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020050
Paul Bakker5121ce52009-01-03 21:22:43 +000051/*
52 * 32-bit integer manipulation macros (big endian)
53 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020054# ifndef GET_UINT32_BE
55# define GET_UINT32_BE(n, b, i) \
56 { \
57 (n) = ((uint32_t)(b)[(i)] << 24) | \
58 ((uint32_t)(b)[(i) + 1] << 16) | \
59 ((uint32_t)(b)[(i) + 2] << 8) | \
60 ((uint32_t)(b)[(i) + 3]); \
61 }
62# endif
Paul Bakker5121ce52009-01-03 21:22:43 +000063
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020064# ifndef PUT_UINT32_BE
65# define PUT_UINT32_BE(n, b, i) \
66 { \
67 (b)[(i)] = (unsigned char)((n) >> 24); \
68 (b)[(i) + 1] = (unsigned char)((n) >> 16); \
69 (b)[(i) + 2] = (unsigned char)((n) >> 8); \
70 (b)[(i) + 3] = (unsigned char)((n)); \
71 }
72# endif
Paul Bakker5121ce52009-01-03 21:22:43 +000073
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020074void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020075{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020076 SHA1_VALIDATE(ctx != NULL);
Andres Amaya Garciaf7c43b32018-12-09 19:12:19 +000077
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020078 memset(ctx, 0, sizeof(mbedtls_sha1_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020079}
80
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020081void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +020082{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020083 if (ctx == NULL)
Paul Bakker5b4af392014-06-26 12:09:34 +020084 return;
85
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020086 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha1_context));
Paul Bakker5b4af392014-06-26 12:09:34 +020087}
88
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020089void mbedtls_sha1_clone(mbedtls_sha1_context *dst,
90 const mbedtls_sha1_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020091{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020092 SHA1_VALIDATE(dst != NULL);
93 SHA1_VALIDATE(src != NULL);
Andres Amaya Garciaf7c43b32018-12-09 19:12:19 +000094
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020095 *dst = *src;
96}
97
Paul Bakker5121ce52009-01-03 21:22:43 +000098/*
99 * SHA-1 context setup
100 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200101int mbedtls_sha1_starts(mbedtls_sha1_context *ctx)
Paul Bakker5121ce52009-01-03 21:22:43 +0000102{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200103 SHA1_VALIDATE_RET(ctx != NULL);
Andres Amaya Garciaf7c43b32018-12-09 19:12:19 +0000104
Paul Bakker5121ce52009-01-03 21:22:43 +0000105 ctx->total[0] = 0;
106 ctx->total[1] = 0;
107
108 ctx->state[0] = 0x67452301;
109 ctx->state[1] = 0xEFCDAB89;
110 ctx->state[2] = 0x98BADCFE;
111 ctx->state[3] = 0x10325476;
112 ctx->state[4] = 0xC3D2E1F0;
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100113
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200114 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000115}
116
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200117# if !defined(MBEDTLS_SHA1_PROCESS_ALT)
118int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx,
119 const unsigned char data[64])
Paul Bakker5121ce52009-01-03 21:22:43 +0000120{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200121 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200122 uint32_t temp, W[16], A, B, C, D, E;
123 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000124
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200125 SHA1_VALIDATE_RET(ctx != NULL);
126 SHA1_VALIDATE_RET((const unsigned char *)data != NULL);
Andres Amaya Garciaf7c43b32018-12-09 19:12:19 +0000127
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200128 GET_UINT32_BE(local.W[0], data, 0);
129 GET_UINT32_BE(local.W[1], data, 4);
130 GET_UINT32_BE(local.W[2], data, 8);
131 GET_UINT32_BE(local.W[3], data, 12);
132 GET_UINT32_BE(local.W[4], data, 16);
133 GET_UINT32_BE(local.W[5], data, 20);
134 GET_UINT32_BE(local.W[6], data, 24);
135 GET_UINT32_BE(local.W[7], data, 28);
136 GET_UINT32_BE(local.W[8], data, 32);
137 GET_UINT32_BE(local.W[9], data, 36);
138 GET_UINT32_BE(local.W[10], data, 40);
139 GET_UINT32_BE(local.W[11], data, 44);
140 GET_UINT32_BE(local.W[12], data, 48);
141 GET_UINT32_BE(local.W[13], data, 52);
142 GET_UINT32_BE(local.W[14], data, 56);
143 GET_UINT32_BE(local.W[15], data, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000144
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200145# define S(x, n) (((x) << (n)) | (((x)&0xFFFFFFFF) >> (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000146
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200147# define R(t) \
148 (local.temp = local.W[((t)-3) & 0x0F] ^ \
149 local.W[((t)-8) & 0x0F] ^ \
150 local.W[((t)-14) & 0x0F] ^ local.W[(t)&0x0F], \
151 (local.W[(t)&0x0F] = S(local.temp, 1)))
Paul Bakker5121ce52009-01-03 21:22:43 +0000152
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200153# define P(a, b, c, d, e, x) \
154 do { \
155 (e) += S((a), 5) + F((b), (c), (d)) + K + (x); \
156 (b) = S((b), 30); \
157 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000158
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200159 local.A = ctx->state[0];
160 local.B = ctx->state[1];
161 local.C = ctx->state[2];
162 local.D = ctx->state[3];
163 local.E = ctx->state[4];
Paul Bakker5121ce52009-01-03 21:22:43 +0000164
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200165# define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
166# define K 0x5A827999
Paul Bakker5121ce52009-01-03 21:22:43 +0000167
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200168 P(local.A, local.B, local.C, local.D, local.E, local.W[0]);
169 P(local.E, local.A, local.B, local.C, local.D, local.W[1]);
170 P(local.D, local.E, local.A, local.B, local.C, local.W[2]);
171 P(local.C, local.D, local.E, local.A, local.B, local.W[3]);
172 P(local.B, local.C, local.D, local.E, local.A, local.W[4]);
173 P(local.A, local.B, local.C, local.D, local.E, local.W[5]);
174 P(local.E, local.A, local.B, local.C, local.D, local.W[6]);
175 P(local.D, local.E, local.A, local.B, local.C, local.W[7]);
176 P(local.C, local.D, local.E, local.A, local.B, local.W[8]);
177 P(local.B, local.C, local.D, local.E, local.A, local.W[9]);
178 P(local.A, local.B, local.C, local.D, local.E, local.W[10]);
179 P(local.E, local.A, local.B, local.C, local.D, local.W[11]);
180 P(local.D, local.E, local.A, local.B, local.C, local.W[12]);
181 P(local.C, local.D, local.E, local.A, local.B, local.W[13]);
182 P(local.B, local.C, local.D, local.E, local.A, local.W[14]);
183 P(local.A, local.B, local.C, local.D, local.E, local.W[15]);
184 P(local.E, local.A, local.B, local.C, local.D, R(16));
185 P(local.D, local.E, local.A, local.B, local.C, R(17));
186 P(local.C, local.D, local.E, local.A, local.B, R(18));
187 P(local.B, local.C, local.D, local.E, local.A, R(19));
Paul Bakker5121ce52009-01-03 21:22:43 +0000188
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200189# undef K
190# undef F
Paul Bakker5121ce52009-01-03 21:22:43 +0000191
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200192# define F(x, y, z) ((x) ^ (y) ^ (z))
193# define K 0x6ED9EBA1
Paul Bakker5121ce52009-01-03 21:22:43 +0000194
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200195 P(local.A, local.B, local.C, local.D, local.E, R(20));
196 P(local.E, local.A, local.B, local.C, local.D, R(21));
197 P(local.D, local.E, local.A, local.B, local.C, R(22));
198 P(local.C, local.D, local.E, local.A, local.B, R(23));
199 P(local.B, local.C, local.D, local.E, local.A, R(24));
200 P(local.A, local.B, local.C, local.D, local.E, R(25));
201 P(local.E, local.A, local.B, local.C, local.D, R(26));
202 P(local.D, local.E, local.A, local.B, local.C, R(27));
203 P(local.C, local.D, local.E, local.A, local.B, R(28));
204 P(local.B, local.C, local.D, local.E, local.A, R(29));
205 P(local.A, local.B, local.C, local.D, local.E, R(30));
206 P(local.E, local.A, local.B, local.C, local.D, R(31));
207 P(local.D, local.E, local.A, local.B, local.C, R(32));
208 P(local.C, local.D, local.E, local.A, local.B, R(33));
209 P(local.B, local.C, local.D, local.E, local.A, R(34));
210 P(local.A, local.B, local.C, local.D, local.E, R(35));
211 P(local.E, local.A, local.B, local.C, local.D, R(36));
212 P(local.D, local.E, local.A, local.B, local.C, R(37));
213 P(local.C, local.D, local.E, local.A, local.B, R(38));
214 P(local.B, local.C, local.D, local.E, local.A, R(39));
Paul Bakker5121ce52009-01-03 21:22:43 +0000215
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200216# undef K
217# undef F
Paul Bakker5121ce52009-01-03 21:22:43 +0000218
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200219# define F(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
220# define K 0x8F1BBCDC
Paul Bakker5121ce52009-01-03 21:22:43 +0000221
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200222 P(local.A, local.B, local.C, local.D, local.E, R(40));
223 P(local.E, local.A, local.B, local.C, local.D, R(41));
224 P(local.D, local.E, local.A, local.B, local.C, R(42));
225 P(local.C, local.D, local.E, local.A, local.B, R(43));
226 P(local.B, local.C, local.D, local.E, local.A, R(44));
227 P(local.A, local.B, local.C, local.D, local.E, R(45));
228 P(local.E, local.A, local.B, local.C, local.D, R(46));
229 P(local.D, local.E, local.A, local.B, local.C, R(47));
230 P(local.C, local.D, local.E, local.A, local.B, R(48));
231 P(local.B, local.C, local.D, local.E, local.A, R(49));
232 P(local.A, local.B, local.C, local.D, local.E, R(50));
233 P(local.E, local.A, local.B, local.C, local.D, R(51));
234 P(local.D, local.E, local.A, local.B, local.C, R(52));
235 P(local.C, local.D, local.E, local.A, local.B, R(53));
236 P(local.B, local.C, local.D, local.E, local.A, R(54));
237 P(local.A, local.B, local.C, local.D, local.E, R(55));
238 P(local.E, local.A, local.B, local.C, local.D, R(56));
239 P(local.D, local.E, local.A, local.B, local.C, R(57));
240 P(local.C, local.D, local.E, local.A, local.B, R(58));
241 P(local.B, local.C, local.D, local.E, local.A, R(59));
Paul Bakker5121ce52009-01-03 21:22:43 +0000242
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200243# undef K
244# undef F
Paul Bakker5121ce52009-01-03 21:22:43 +0000245
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200246# define F(x, y, z) ((x) ^ (y) ^ (z))
247# define K 0xCA62C1D6
Paul Bakker5121ce52009-01-03 21:22:43 +0000248
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200249 P(local.A, local.B, local.C, local.D, local.E, R(60));
250 P(local.E, local.A, local.B, local.C, local.D, R(61));
251 P(local.D, local.E, local.A, local.B, local.C, R(62));
252 P(local.C, local.D, local.E, local.A, local.B, R(63));
253 P(local.B, local.C, local.D, local.E, local.A, R(64));
254 P(local.A, local.B, local.C, local.D, local.E, R(65));
255 P(local.E, local.A, local.B, local.C, local.D, R(66));
256 P(local.D, local.E, local.A, local.B, local.C, R(67));
257 P(local.C, local.D, local.E, local.A, local.B, R(68));
258 P(local.B, local.C, local.D, local.E, local.A, R(69));
259 P(local.A, local.B, local.C, local.D, local.E, R(70));
260 P(local.E, local.A, local.B, local.C, local.D, R(71));
261 P(local.D, local.E, local.A, local.B, local.C, R(72));
262 P(local.C, local.D, local.E, local.A, local.B, R(73));
263 P(local.B, local.C, local.D, local.E, local.A, R(74));
264 P(local.A, local.B, local.C, local.D, local.E, R(75));
265 P(local.E, local.A, local.B, local.C, local.D, R(76));
266 P(local.D, local.E, local.A, local.B, local.C, R(77));
267 P(local.C, local.D, local.E, local.A, local.B, R(78));
268 P(local.B, local.C, local.D, local.E, local.A, R(79));
Paul Bakker5121ce52009-01-03 21:22:43 +0000269
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200270# undef K
271# undef F
Paul Bakker5121ce52009-01-03 21:22:43 +0000272
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200273 ctx->state[0] += local.A;
274 ctx->state[1] += local.B;
275 ctx->state[2] += local.C;
276 ctx->state[3] += local.D;
277 ctx->state[4] += local.E;
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100278
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200279 /* Zeroise buffers and variables to clear sensitive data from memory. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200280 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100281
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200282 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000283}
Jaeden Amero041039f2018-02-19 15:28:08 +0000284
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200285# endif /* !MBEDTLS_SHA1_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000286
287/*
288 * SHA-1 process buffer
289 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200290int mbedtls_sha1_update(mbedtls_sha1_context *ctx,
291 const unsigned char *input,
292 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000293{
Janos Follath24eed8d2019-11-22 13:21:35 +0000294 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000295 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000296 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000297
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200298 SHA1_VALIDATE_RET(ctx != NULL);
299 SHA1_VALIDATE_RET(ilen == 0 || input != NULL);
Hanno Beckerb3906d82018-12-18 11:35:00 +0000300
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200301 if (ilen == 0)
302 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000303
304 left = ctx->total[0] & 0x3F;
305 fill = 64 - left;
306
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200307 ctx->total[0] += (uint32_t)ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000308 ctx->total[0] &= 0xFFFFFFFF;
309
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200310 if (ctx->total[0] < (uint32_t)ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000311 ctx->total[1]++;
312
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200313 if (left && ilen >= fill) {
314 memcpy((void *)(ctx->buffer + left), input, fill);
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100315
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200316 if ((ret = mbedtls_internal_sha1_process(ctx, ctx->buffer)) != 0)
317 return ret;
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100318
Paul Bakker5121ce52009-01-03 21:22:43 +0000319 input += fill;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200320 ilen -= fill;
Paul Bakker5121ce52009-01-03 21:22:43 +0000321 left = 0;
322 }
323
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200324 while (ilen >= 64) {
325 if ((ret = mbedtls_internal_sha1_process(ctx, input)) != 0)
326 return ret;
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100327
Paul Bakker5121ce52009-01-03 21:22:43 +0000328 input += 64;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200329 ilen -= 64;
Paul Bakker5121ce52009-01-03 21:22:43 +0000330 }
331
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200332 if (ilen > 0)
333 memcpy((void *)(ctx->buffer + left), input, ilen);
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100334
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200335 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000336}
337
Paul Bakker5121ce52009-01-03 21:22:43 +0000338/*
339 * SHA-1 final digest
340 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200341int mbedtls_sha1_finish(mbedtls_sha1_context *ctx, unsigned char output[20])
Paul Bakker5121ce52009-01-03 21:22:43 +0000342{
Janos Follath24eed8d2019-11-22 13:21:35 +0000343 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200344 uint32_t used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000345 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200347 SHA1_VALIDATE_RET(ctx != NULL);
348 SHA1_VALIDATE_RET((unsigned char *)output != NULL);
Andres Amaya Garciaf7c43b32018-12-09 19:12:19 +0000349
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200350 /*
351 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
352 */
353 used = ctx->total[0] & 0x3F;
354
355 ctx->buffer[used++] = 0x80;
356
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200357 if (used <= 56) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200358 /* Enough room for padding + length in current block */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200359 memset(ctx->buffer + used, 0, 56 - used);
360 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200361 /* We'll need an extra block */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200362 memset(ctx->buffer + used, 0, 64 - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200363
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200364 if ((ret = mbedtls_internal_sha1_process(ctx, ctx->buffer)) != 0)
365 return ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200366
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200367 memset(ctx->buffer, 0, 56);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200368 }
369
370 /*
371 * Add message length
372 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200373 high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
374 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000375
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200376 PUT_UINT32_BE(high, ctx->buffer, 56);
377 PUT_UINT32_BE(low, ctx->buffer, 60);
Paul Bakker5121ce52009-01-03 21:22:43 +0000378
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200379 if ((ret = mbedtls_internal_sha1_process(ctx, ctx->buffer)) != 0)
380 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200382 /*
383 * Output final state
384 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200385 PUT_UINT32_BE(ctx->state[0], output, 0);
386 PUT_UINT32_BE(ctx->state[1], output, 4);
387 PUT_UINT32_BE(ctx->state[2], output, 8);
388 PUT_UINT32_BE(ctx->state[3], output, 12);
389 PUT_UINT32_BE(ctx->state[4], output, 16);
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100390
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200391 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000392}
393
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200394# endif /* !MBEDTLS_SHA1_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200395
Paul Bakker5121ce52009-01-03 21:22:43 +0000396/*
397 * output = SHA-1( input buffer )
398 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200399int mbedtls_sha1(const unsigned char *input,
400 size_t ilen,
401 unsigned char output[20])
Paul Bakker5121ce52009-01-03 21:22:43 +0000402{
Janos Follath24eed8d2019-11-22 13:21:35 +0000403 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 mbedtls_sha1_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200406 SHA1_VALIDATE_RET(ilen == 0 || input != NULL);
407 SHA1_VALIDATE_RET((unsigned char *)output != NULL);
Andres Amaya Garciaf7c43b32018-12-09 19:12:19 +0000408
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200409 mbedtls_sha1_init(&ctx);
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100410
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200411 if ((ret = mbedtls_sha1_starts(&ctx)) != 0)
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100412 goto exit;
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100413
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200414 if ((ret = mbedtls_sha1_update(&ctx, input, ilen)) != 0)
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100415 goto exit;
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100416
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200417 if ((ret = mbedtls_sha1_finish(&ctx, output)) != 0)
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100418 goto exit;
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100419
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100420exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200421 mbedtls_sha1_free(&ctx);
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100422
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200423 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000424}
425
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200426# if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000427/*
428 * FIPS-180-1 test vectors
429 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200430static const unsigned char sha1_test_buf[3][57] = {
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 { "abc" },
432 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
433 { "" }
434};
435
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200436static const size_t sha1_test_buflen[3] = { 3, 56, 1000 };
Paul Bakker5121ce52009-01-03 21:22:43 +0000437
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200438static const unsigned char sha1_test_sum[3][20] = {
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
440 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
441 { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
442 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
443 { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
444 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
445};
446
447/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000448 * Checkup routine
449 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200450int mbedtls_sha1_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000451{
Paul Bakker5b4af392014-06-26 12:09:34 +0200452 int i, j, buflen, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 unsigned char buf[1024];
454 unsigned char sha1sum[20];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455 mbedtls_sha1_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200457 mbedtls_sha1_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200458
Paul Bakker5121ce52009-01-03 21:22:43 +0000459 /*
460 * SHA-1
461 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200462 for (i = 0; i < 3; i++) {
463 if (verbose != 0)
464 mbedtls_printf(" SHA-1 test #%d: ", i + 1);
Paul Bakker5121ce52009-01-03 21:22:43 +0000465
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200466 if ((ret = mbedtls_sha1_starts(&ctx)) != 0)
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100467 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200469 if (i == 2) {
470 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000471
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200472 for (j = 0; j < 1000; j++) {
473 ret = mbedtls_sha1_update(&ctx, buf, buflen);
474 if (ret != 0)
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100475 goto fail;
476 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200477 } else {
478 ret = mbedtls_sha1_update(&ctx, sha1_test_buf[i],
479 sha1_test_buflen[i]);
480 if (ret != 0)
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100481 goto fail;
482 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000483
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200484 if ((ret = mbedtls_sha1_finish(&ctx, sha1sum)) != 0)
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100485 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000486
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200487 if (memcmp(sha1sum, sha1_test_sum[i], 20) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100488 ret = 1;
489 goto fail;
490 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200492 if (verbose != 0)
493 mbedtls_printf("passed\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000494 }
495
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200496 if (verbose != 0)
497 mbedtls_printf("\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000498
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100499 goto exit;
500
501fail:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200502 if (verbose != 0)
503 mbedtls_printf("failed\n");
Andres Amaya Garcia034ea7e2017-04-28 15:14:50 +0100504
Paul Bakker5b4af392014-06-26 12:09:34 +0200505exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200506 mbedtls_sha1_free(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200507
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200508 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000509}
510
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200511# endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000512
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200513#endif /* MBEDTLS_SHA1_C */