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
61 void
isc_sha224_init(isc_sha224_t * context)62 isc_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
73 void
isc_sha224_update(isc_sha224_t * context,const uint8_t * data,size_t len)74 isc_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
89 void
isc_sha224_final(uint8_t digest[ISC_SHA224_DIGESTLENGTH],isc_sha224_t * context)90 isc_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
103 void
isc_sha256_init(isc_sha256_t * context)104 isc_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
115 void
isc_sha256_update(isc_sha256_t * context,const uint8_t * data,size_t len)116 isc_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
131 void
isc_sha256_final(uint8_t digest[ISC_SHA256_DIGESTLENGTH],isc_sha256_t * context)132 isc_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
145 void
isc_sha512_init(isc_sha512_t * context)146 isc_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
isc_sha512_update(isc_sha512_t * context,const uint8_t * data,size_t len)157 void 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
isc_sha512_final(uint8_t digest[ISC_SHA512_DIGESTLENGTH],isc_sha512_t * context)172 void 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
185 void
isc_sha384_init(isc_sha384_t * context)186 isc_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
197 void
isc_sha384_update(isc_sha384_t * context,const uint8_t * data,size_t len)198 isc_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
213 void
isc_sha384_final(uint8_t digest[ISC_SHA384_DIGESTLENGTH],isc_sha384_t * context)214 isc_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