15185a700Sflorian /*
25185a700Sflorian * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
35185a700Sflorian *
45185a700Sflorian * Permission to use, copy, modify, and/or distribute this software for any
55185a700Sflorian * purpose with or without fee is hereby granted, provided that the above
65185a700Sflorian * copyright notice and this permission notice appear in all copies.
75185a700Sflorian *
85185a700Sflorian * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
95185a700Sflorian * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
105185a700Sflorian * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
115185a700Sflorian * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
125185a700Sflorian * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
135185a700Sflorian * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
145185a700Sflorian * PERFORMANCE OF THIS SOFTWARE.
155185a700Sflorian */
165185a700Sflorian
17*fea1e5fdStb /* $Id: sha2.c,v 1.5 2024/05/17 09:36:48 tb Exp $ */
185185a700Sflorian
195185a700Sflorian /* $FreeBSD: src/sys/crypto/sha2/sha2.c,v 1.2.2.2 2002/03/05 08:36:47 ume Exp $ */
205185a700Sflorian /* $KAME: sha2.c,v 1.8 2001/11/08 01:07:52 itojun Exp $ */
215185a700Sflorian
225185a700Sflorian /*
235185a700Sflorian * sha2.c
245185a700Sflorian *
255185a700Sflorian * Version 1.0.0beta1
265185a700Sflorian *
275185a700Sflorian * Written by Aaron D. Gifford <me@aarongifford.com>
285185a700Sflorian *
295185a700Sflorian * Copyright 2000 Aaron D. Gifford. All rights reserved.
305185a700Sflorian *
315185a700Sflorian * Redistribution and use in source and binary forms, with or without
325185a700Sflorian * modification, are permitted provided that the following conditions
335185a700Sflorian * are met:
345185a700Sflorian * 1. Redistributions of source code must retain the above copyright
355185a700Sflorian * notice, this list of conditions and the following disclaimer.
365185a700Sflorian * 2. Redistributions in binary form must reproduce the above copyright
375185a700Sflorian * notice, this list of conditions and the following disclaimer in the
385185a700Sflorian * documentation and/or other materials provided with the distribution.
395185a700Sflorian * 3. Neither the name of the copyright holder nor the names of contributors
405185a700Sflorian * may be used to endorse or promote products derived from this software
415185a700Sflorian * without specific prior written permission.
425185a700Sflorian *
435185a700Sflorian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND
445185a700Sflorian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
455185a700Sflorian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
465185a700Sflorian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE
475185a700Sflorian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
485185a700Sflorian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
495185a700Sflorian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
505185a700Sflorian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
515185a700Sflorian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
525185a700Sflorian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
535185a700Sflorian * SUCH DAMAGE.
545185a700Sflorian *
555185a700Sflorian */
565185a700Sflorian
575185a700Sflorian #include <isc/sha2.h>
585185a700Sflorian #include <string.h>
595185a700Sflorian #include <isc/util.h>
605185a700Sflorian
615185a700Sflorian void
isc_sha224_init(isc_sha224_t * context)625185a700Sflorian isc_sha224_init(isc_sha224_t *context) {
635185a700Sflorian if (context == (isc_sha224_t *)0) {
645185a700Sflorian return;
655185a700Sflorian }
665185a700Sflorian context->ctx = EVP_MD_CTX_new();
675185a700Sflorian RUNTIME_CHECK(context->ctx != NULL);
685185a700Sflorian if (EVP_DigestInit(context->ctx, EVP_sha224()) != 1) {
695185a700Sflorian FATAL_ERROR(__FILE__, __LINE__, "Cannot initialize SHA224.");
705185a700Sflorian }
715185a700Sflorian }
725185a700Sflorian
735185a700Sflorian void
isc_sha224_update(isc_sha224_t * context,const uint8_t * data,size_t len)745185a700Sflorian isc_sha224_update(isc_sha224_t *context, const uint8_t* data, size_t len) {
755185a700Sflorian if (len == 0U) {
765185a700Sflorian /* Calling with no data is valid - we do nothing */
775185a700Sflorian return;
785185a700Sflorian }
795185a700Sflorian
805185a700Sflorian /* Sanity check: */
815185a700Sflorian REQUIRE(context != (isc_sha224_t *)0);
825185a700Sflorian REQUIRE(context->ctx != (EVP_MD_CTX *)0);
835185a700Sflorian REQUIRE(data != (uint8_t*)0);
845185a700Sflorian
855185a700Sflorian RUNTIME_CHECK(EVP_DigestUpdate(context->ctx,
865185a700Sflorian (const void *) data, len) == 1);
875185a700Sflorian }
885185a700Sflorian
895185a700Sflorian void
isc_sha224_final(uint8_t digest[ISC_SHA224_DIGESTLENGTH],isc_sha224_t * context)90*fea1e5fdStb isc_sha224_final(uint8_t digest[ISC_SHA224_DIGESTLENGTH], isc_sha224_t *context) {
915185a700Sflorian /* Sanity check: */
925185a700Sflorian REQUIRE(context != (isc_sha224_t *)0);
935185a700Sflorian REQUIRE(context->ctx != (EVP_MD_CTX *)0);
945185a700Sflorian
955185a700Sflorian /* If no digest buffer is passed, we don't bother doing this: */
965185a700Sflorian if (digest != (uint8_t*)0)
975185a700Sflorian RUNTIME_CHECK(EVP_DigestFinal(context->ctx,
985185a700Sflorian digest, NULL) == 1);
995185a700Sflorian EVP_MD_CTX_free(context->ctx);
1005185a700Sflorian context->ctx = NULL;
1015185a700Sflorian }
1025185a700Sflorian
1035185a700Sflorian void
isc_sha256_init(isc_sha256_t * context)1045185a700Sflorian isc_sha256_init(isc_sha256_t *context) {
1055185a700Sflorian if (context == (isc_sha256_t *)0) {
1065185a700Sflorian return;
1075185a700Sflorian }
1085185a700Sflorian context->ctx = EVP_MD_CTX_new();
1095185a700Sflorian RUNTIME_CHECK(context->ctx != NULL);
1105185a700Sflorian if (EVP_DigestInit(context->ctx, EVP_sha256()) != 1) {
1115185a700Sflorian FATAL_ERROR(__FILE__, __LINE__, "Cannot initialize SHA256.");
1125185a700Sflorian }
1135185a700Sflorian }
1145185a700Sflorian
1155185a700Sflorian void
isc_sha256_update(isc_sha256_t * context,const uint8_t * data,size_t len)1165185a700Sflorian isc_sha256_update(isc_sha256_t *context, const uint8_t *data, size_t len) {
1175185a700Sflorian if (len == 0U) {
1185185a700Sflorian /* Calling with no data is valid - we do nothing */
1195185a700Sflorian return;
1205185a700Sflorian }
1215185a700Sflorian
1225185a700Sflorian /* Sanity check: */
1235185a700Sflorian REQUIRE(context != (isc_sha256_t *)0);
1245185a700Sflorian REQUIRE(context->ctx != (EVP_MD_CTX *)0);
1255185a700Sflorian REQUIRE(data != (uint8_t*)0);
1265185a700Sflorian
1275185a700Sflorian RUNTIME_CHECK(EVP_DigestUpdate(context->ctx,
1285185a700Sflorian (const void *) data, len) == 1);
1295185a700Sflorian }
1305185a700Sflorian
1315185a700Sflorian void
isc_sha256_final(uint8_t digest[ISC_SHA256_DIGESTLENGTH],isc_sha256_t * context)132*fea1e5fdStb isc_sha256_final(uint8_t digest[ISC_SHA256_DIGESTLENGTH], isc_sha256_t *context) {
1335185a700Sflorian /* Sanity check: */
1345185a700Sflorian REQUIRE(context != (isc_sha256_t *)0);
1355185a700Sflorian REQUIRE(context->ctx != (EVP_MD_CTX *)0);
1365185a700Sflorian
1375185a700Sflorian /* If no digest buffer is passed, we don't bother doing this: */
1385185a700Sflorian if (digest != (uint8_t*)0)
1395185a700Sflorian RUNTIME_CHECK(EVP_DigestFinal(context->ctx,
1405185a700Sflorian digest, NULL) == 1);
1415185a700Sflorian EVP_MD_CTX_free(context->ctx);
1425185a700Sflorian context->ctx = NULL;
1435185a700Sflorian }
1445185a700Sflorian
1455185a700Sflorian void
isc_sha512_init(isc_sha512_t * context)1465185a700Sflorian isc_sha512_init(isc_sha512_t *context) {
1475185a700Sflorian if (context == (isc_sha512_t *)0) {
1485185a700Sflorian return;
1495185a700Sflorian }
1505185a700Sflorian context->ctx = EVP_MD_CTX_new();
1515185a700Sflorian RUNTIME_CHECK(context->ctx != NULL);
1525185a700Sflorian if (EVP_DigestInit(context->ctx, EVP_sha512()) != 1) {
1535185a700Sflorian FATAL_ERROR(__FILE__, __LINE__, "Cannot initialize SHA512.");
1545185a700Sflorian }
1555185a700Sflorian }
1565185a700Sflorian
isc_sha512_update(isc_sha512_t * context,const uint8_t * data,size_t len)1575185a700Sflorian void isc_sha512_update(isc_sha512_t *context, const uint8_t *data, size_t len) {
1585185a700Sflorian if (len == 0U) {
1595185a700Sflorian /* Calling with no data is valid - we do nothing */
1605185a700Sflorian return;
1615185a700Sflorian }
1625185a700Sflorian
1635185a700Sflorian /* Sanity check: */
1645185a700Sflorian REQUIRE(context != (isc_sha512_t *)0);
1655185a700Sflorian REQUIRE(context->ctx != (EVP_MD_CTX *)0);
1665185a700Sflorian REQUIRE(data != (uint8_t*)0);
1675185a700Sflorian
1685185a700Sflorian RUNTIME_CHECK(EVP_DigestUpdate(context->ctx,
1695185a700Sflorian (const void *) data, len) == 1);
1705185a700Sflorian }
1715185a700Sflorian
isc_sha512_final(uint8_t digest[ISC_SHA512_DIGESTLENGTH],isc_sha512_t * context)172*fea1e5fdStb void isc_sha512_final(uint8_t digest[ISC_SHA512_DIGESTLENGTH], isc_sha512_t *context) {
1735185a700Sflorian /* Sanity check: */
1745185a700Sflorian REQUIRE(context != (isc_sha512_t *)0);
1755185a700Sflorian REQUIRE(context->ctx != (EVP_MD_CTX *)0);
1765185a700Sflorian
1775185a700Sflorian /* If no digest buffer is passed, we don't bother doing this: */
1785185a700Sflorian if (digest != (uint8_t*)0)
1795185a700Sflorian RUNTIME_CHECK(EVP_DigestFinal(context->ctx,
1805185a700Sflorian digest, NULL) == 1);
1815185a700Sflorian EVP_MD_CTX_free(context->ctx);
1825185a700Sflorian context->ctx = NULL;
1835185a700Sflorian }
1845185a700Sflorian
1855185a700Sflorian void
isc_sha384_init(isc_sha384_t * context)1865185a700Sflorian isc_sha384_init(isc_sha384_t *context) {
1875185a700Sflorian if (context == (isc_sha384_t *)0) {
1885185a700Sflorian return;
1895185a700Sflorian }
1905185a700Sflorian context->ctx = EVP_MD_CTX_new();
1915185a700Sflorian RUNTIME_CHECK(context->ctx != NULL);
1925185a700Sflorian if (EVP_DigestInit(context->ctx, EVP_sha384()) != 1) {
1935185a700Sflorian FATAL_ERROR(__FILE__, __LINE__, "Cannot initialize SHA384.");
1945185a700Sflorian }
1955185a700Sflorian }
1965185a700Sflorian
1975185a700Sflorian void
isc_sha384_update(isc_sha384_t * context,const uint8_t * data,size_t len)1985185a700Sflorian isc_sha384_update(isc_sha384_t *context, const uint8_t* data, size_t len) {
1995185a700Sflorian if (len == 0U) {
2005185a700Sflorian /* Calling with no data is valid - we do nothing */
2015185a700Sflorian return;
2025185a700Sflorian }
2035185a700Sflorian
2045185a700Sflorian /* Sanity check: */
2055185a700Sflorian REQUIRE(context != (isc_sha512_t *)0);
2065185a700Sflorian REQUIRE(context->ctx != (EVP_MD_CTX *)0);
2075185a700Sflorian REQUIRE(data != (uint8_t*)0);
2085185a700Sflorian
2095185a700Sflorian RUNTIME_CHECK(EVP_DigestUpdate(context->ctx,
2105185a700Sflorian (const void *) data, len) == 1);
2115185a700Sflorian }
2125185a700Sflorian
2135185a700Sflorian void
isc_sha384_final(uint8_t digest[ISC_SHA384_DIGESTLENGTH],isc_sha384_t * context)214*fea1e5fdStb isc_sha384_final(uint8_t digest[ISC_SHA384_DIGESTLENGTH], isc_sha384_t *context) {
2155185a700Sflorian /* Sanity check: */
2165185a700Sflorian REQUIRE(context != (isc_sha384_t *)0);
2175185a700Sflorian REQUIRE(context->ctx != (EVP_MD_CTX *)0);
2185185a700Sflorian
2195185a700Sflorian /* If no digest buffer is passed, we don't bother doing this: */
2205185a700Sflorian if (digest != (uint8_t*)0)
2215185a700Sflorian RUNTIME_CHECK(EVP_DigestFinal(context->ctx,
2225185a700Sflorian digest, NULL) == 1);
2235185a700Sflorian EVP_MD_CTX_free(context->ctx);
2245185a700Sflorian context->ctx = NULL;
2255185a700Sflorian }
226