1/*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/* $Id: sha2.c,v 1.5 2024/05/17 09:36:48 tb Exp $ */
18
19/*	$FreeBSD: src/sys/crypto/sha2/sha2.c,v 1.2.2.2 2002/03/05 08:36:47 ume Exp $	*/
20/*	$KAME: sha2.c,v 1.8 2001/11/08 01:07:52 itojun Exp $	*/
21
22/*
23 * sha2.c
24 *
25 * Version 1.0.0beta1
26 *
27 * Written by Aaron D. Gifford <me@aarongifford.com>
28 *
29 * Copyright 2000 Aaron D. Gifford.  All rights reserved.
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
33 * are met:
34 * 1. Redistributions of source code must retain the above copyright
35 *    notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 *    notice, this list of conditions and the following disclaimer in the
38 *    documentation and/or other materials provided with the distribution.
39 * 3. Neither the name of the copyright holder nor the names of contributors
40 *    may be used to endorse or promote products derived from this software
41 *    without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * SUCH DAMAGE.
54 *
55 */
56
57#include <isc/sha2.h>
58#include <string.h>
59#include <isc/util.h>
60
61void
62isc_sha224_init(isc_sha224_t *context) {
63	if (context == (isc_sha224_t *)0) {
64		return;
65	}
66	context->ctx = EVP_MD_CTX_new();
67	RUNTIME_CHECK(context->ctx != NULL);
68	if (EVP_DigestInit(context->ctx, EVP_sha224()) != 1) {
69		FATAL_ERROR(__FILE__, __LINE__, "Cannot initialize SHA224.");
70	}
71}
72
73void
74isc_sha224_update(isc_sha224_t *context, const uint8_t* data, size_t len) {
75	if (len == 0U) {
76		/* Calling with no data is valid - we do nothing */
77		return;
78	}
79
80	/* Sanity check: */
81	REQUIRE(context != (isc_sha224_t *)0);
82	REQUIRE(context->ctx != (EVP_MD_CTX *)0);
83	REQUIRE(data != (uint8_t*)0);
84
85	RUNTIME_CHECK(EVP_DigestUpdate(context->ctx,
86				       (const void *) data, len) == 1);
87}
88
89void
90isc_sha224_final(uint8_t digest[ISC_SHA224_DIGESTLENGTH], isc_sha224_t *context) {
91	/* Sanity check: */
92	REQUIRE(context != (isc_sha224_t *)0);
93	REQUIRE(context->ctx != (EVP_MD_CTX *)0);
94
95	/* If no digest buffer is passed, we don't bother doing this: */
96	if (digest != (uint8_t*)0)
97		RUNTIME_CHECK(EVP_DigestFinal(context->ctx,
98					      digest, NULL) == 1);
99	EVP_MD_CTX_free(context->ctx);
100	context->ctx = NULL;
101}
102
103void
104isc_sha256_init(isc_sha256_t *context) {
105	if (context == (isc_sha256_t *)0) {
106		return;
107	}
108	context->ctx = EVP_MD_CTX_new();
109	RUNTIME_CHECK(context->ctx != NULL);
110	if (EVP_DigestInit(context->ctx, EVP_sha256()) != 1) {
111		FATAL_ERROR(__FILE__, __LINE__, "Cannot initialize SHA256.");
112	}
113}
114
115void
116isc_sha256_update(isc_sha256_t *context, const uint8_t *data, size_t len) {
117	if (len == 0U) {
118		/* Calling with no data is valid - we do nothing */
119		return;
120	}
121
122	/* Sanity check: */
123	REQUIRE(context != (isc_sha256_t *)0);
124	REQUIRE(context->ctx != (EVP_MD_CTX *)0);
125	REQUIRE(data != (uint8_t*)0);
126
127	RUNTIME_CHECK(EVP_DigestUpdate(context->ctx,
128				       (const void *) data, len) == 1);
129}
130
131void
132isc_sha256_final(uint8_t digest[ISC_SHA256_DIGESTLENGTH], isc_sha256_t *context) {
133	/* Sanity check: */
134	REQUIRE(context != (isc_sha256_t *)0);
135	REQUIRE(context->ctx != (EVP_MD_CTX *)0);
136
137	/* If no digest buffer is passed, we don't bother doing this: */
138	if (digest != (uint8_t*)0)
139		RUNTIME_CHECK(EVP_DigestFinal(context->ctx,
140					      digest, NULL) == 1);
141	EVP_MD_CTX_free(context->ctx);
142	context->ctx = NULL;
143}
144
145void
146isc_sha512_init(isc_sha512_t *context) {
147	if (context == (isc_sha512_t *)0) {
148		return;
149	}
150	context->ctx = EVP_MD_CTX_new();
151	RUNTIME_CHECK(context->ctx != NULL);
152	if (EVP_DigestInit(context->ctx, EVP_sha512()) != 1) {
153		FATAL_ERROR(__FILE__, __LINE__, "Cannot initialize SHA512.");
154	}
155}
156
157void isc_sha512_update(isc_sha512_t *context, const uint8_t *data, size_t len) {
158	if (len == 0U) {
159		/* Calling with no data is valid - we do nothing */
160		return;
161	}
162
163	/* Sanity check: */
164	REQUIRE(context != (isc_sha512_t *)0);
165	REQUIRE(context->ctx != (EVP_MD_CTX *)0);
166	REQUIRE(data != (uint8_t*)0);
167
168	RUNTIME_CHECK(EVP_DigestUpdate(context->ctx,
169				       (const void *) data, len) == 1);
170}
171
172void isc_sha512_final(uint8_t digest[ISC_SHA512_DIGESTLENGTH], isc_sha512_t *context) {
173	/* Sanity check: */
174	REQUIRE(context != (isc_sha512_t *)0);
175	REQUIRE(context->ctx != (EVP_MD_CTX *)0);
176
177	/* If no digest buffer is passed, we don't bother doing this: */
178	if (digest != (uint8_t*)0)
179		RUNTIME_CHECK(EVP_DigestFinal(context->ctx,
180					      digest, NULL) == 1);
181	EVP_MD_CTX_free(context->ctx);
182	context->ctx = NULL;
183}
184
185void
186isc_sha384_init(isc_sha384_t *context) {
187	if (context == (isc_sha384_t *)0) {
188		return;
189	}
190	context->ctx = EVP_MD_CTX_new();
191	RUNTIME_CHECK(context->ctx != NULL);
192	if (EVP_DigestInit(context->ctx, EVP_sha384()) != 1) {
193		FATAL_ERROR(__FILE__, __LINE__, "Cannot initialize SHA384.");
194	}
195}
196
197void
198isc_sha384_update(isc_sha384_t *context, const uint8_t* data, size_t len) {
199	if (len == 0U) {
200		/* Calling with no data is valid - we do nothing */
201		return;
202	}
203
204	/* Sanity check: */
205	REQUIRE(context != (isc_sha512_t *)0);
206	REQUIRE(context->ctx != (EVP_MD_CTX *)0);
207	REQUIRE(data != (uint8_t*)0);
208
209	RUNTIME_CHECK(EVP_DigestUpdate(context->ctx,
210				       (const void *) data, len) == 1);
211}
212
213void
214isc_sha384_final(uint8_t digest[ISC_SHA384_DIGESTLENGTH], isc_sha384_t *context) {
215	/* Sanity check: */
216	REQUIRE(context != (isc_sha384_t *)0);
217	REQUIRE(context->ctx != (EVP_MD_CTX *)0);
218
219	/* If no digest buffer is passed, we don't bother doing this: */
220	if (digest != (uint8_t*)0)
221		RUNTIME_CHECK(EVP_DigestFinal(context->ctx,
222					      digest, NULL) == 1);
223	EVP_MD_CTX_free(context->ctx);
224	context->ctx = NULL;
225}
226