xref: /openbsd/usr.bin/dig/lib/isc/sha2.c (revision 09467b48)
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.4 2020/02/24 13:49:38 jsg 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
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
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
90 isc_sha224_final(uint8_t digest[], 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
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
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
132 isc_sha256_final(uint8_t digest[], 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
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 
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 
172 void isc_sha512_final(uint8_t digest[], 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
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
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
214 isc_sha384_final(uint8_t digest[], 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