From: Tobias Heider Date: Mon, 25 Sep 2023 08:49:00 +0000 (+0200) Subject: Support libcrypto for hmac and sha256 (#223) X-Git-Tag: v10.0.3~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8e316164a831e2480ae22a1ebc953dc4d6973d7a;p=thirdparty%2Fdhcpcd.git Support libcrypto for hmac and sha256 (#223) * compat: Add OpenSSL libcrypto compatibility layer Detect libcrypto in configure script. Only fall back to using libcrypto when /usr libs are allowed and no other compatible implementation is available or when --with-openssl is passed explicitly. Make sure libcrypto and libmd are never linked at the same time. Add OpenSSL based SHA256 and HMAC compat shims in compat/crypt_openssl. Depeding on version and build flags, libcrypto ships with a compatible SHA256 API in "openssl/sha.h". OpenSSL 3 has deprecated the SHA API, so if it is not detected we fall back to an EVP_DIGEST based version. Because the API might still be in use in OpenSSL internally, the compatibility wrappers have a dhcpcd_ prefix to avoid symbol conflicts. * Add sha256 tests based on the existing hmac-md5 tests. --- diff --git a/compat/crypt_openssl/hmac.c b/compat/crypt_openssl/hmac.c new file mode 100644 index 00000000..5f55cc30 --- /dev/null +++ b/compat/crypt_openssl/hmac.c @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2023 Canonical Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include "config.h" + +#include "openssl/hmac.h" + +ssize_t +hmac(const char *name, + const void *key, size_t klen, + const void *text, size_t tlen, + void *digest, size_t dlen) +{ + const EVP_MD *md; + unsigned int outlen; + + if (strcmp(name, "md5") == 0) + md = EVP_md5(); + else if (strcmp(name, "sha256") == 0) + md = EVP_sha1(); + else + return -1; + + HMAC(md, key, (int)klen, text, tlen, digest, &outlen); + if (dlen != outlen) + return -1; + + return (ssize_t)outlen; +} diff --git a/compat/crypt_openssl/hmac.h b/compat/crypt_openssl/hmac.h new file mode 100644 index 00000000..5729ed5b --- /dev/null +++ b/compat/crypt_openssl/hmac.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2023 Canonical Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef HMAC_H +#define HMAC_H + +#include + +ssize_t hmac(const char *, const void *, size_t, const void *, size_t, void *, + size_t); + +#endif diff --git a/compat/crypt_openssl/sha256.c b/compat/crypt_openssl/sha256.c new file mode 100644 index 00000000..a1595835 --- /dev/null +++ b/compat/crypt_openssl/sha256.c @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2023 Canonical Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" +#include "sha256.h" + +#include "openssl/evp.h" + +/* SHA-256 initialization. Begins a SHA-256 operation. */ +void +dhcpcd_SHA256_Init(SHA256_CTX *ctx) +{ + ctx->c = EVP_MD_CTX_new(); + EVP_DigestInit_ex2(ctx->c, EVP_sha256(), NULL); +} + +/* Add bytes into the hash */ +void +dhcpcd_SHA256_Update(SHA256_CTX *ctx, const void *in, size_t len) +{ + EVP_DigestUpdate(ctx->c, in, len); +} + +/* + * SHA-256 finalization. Pads the input data, exports the hash value, + * and clears the context state. + */ +void +dhcpcd_SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx) +{ + EVP_DigestFinal_ex(ctx->c, digest, NULL); + EVP_MD_CTX_free(ctx->c); +} diff --git a/compat/crypt_openssl/sha256.h b/compat/crypt_openssl/sha256.h new file mode 100644 index 00000000..74fabab7 --- /dev/null +++ b/compat/crypt_openssl/sha256.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2023 Canonical Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef SHA256_H_ +#define SHA256_H_ + +#define SHA256_DIGEST_LENGTH 32 + +#include "openssl/evp.h" +typedef struct dhcpcd_SHA256Context { + EVP_MD_CTX *c; +} dhcpcd_SHA256_CTX; + +void dhcpcd_SHA256_Init(dhcpcd_SHA256_CTX *); +void dhcpcd_SHA256_Update(dhcpcd_SHA256_CTX *, const void *, size_t); +void dhcpcd_SHA256_Final(unsigned char [32], dhcpcd_SHA256_CTX *); + +#define SHA256_Init dhcpcd_SHA256_Init +#define SHA256_Update dhcpcd_SHA256_Update +#define SHA256_Final dhcpcd_SHA256_Final +#define SHA256_CTX dhcpcd_SHA256_CTX + +#endif diff --git a/configure b/configure index 4fb29b06..3d130a04 100755 --- a/configure +++ b/configure @@ -37,6 +37,7 @@ POLL= SMALL= SANITIZE=no STATUSARG= +OPENSSL= DHCPCD_DEFS=dhcpcd-definitions.conf @@ -110,6 +111,8 @@ for x do --with-udev) DEV=yes; UDEV=yes;; --without-udev) UDEV=no;; --with-poll) POLL="$var";; + --with-openssl) OPENSSL=yes;; + --without-openssl) OPENSSL=no;; --sanitise|--sanitize) SANITIZEADDRESS="yes";; --serviceexists) SERVICEEXISTS=$var;; --servicecmd) SERVICECMD=$var;; @@ -1350,14 +1353,6 @@ if [ "$FLS64" = yes ]; then echo "#define HAVE_SYS_BITOPS_H" >>$CONFIG_H fi -# Workaround for DragonFlyBSD import -if [ "$OS" = dragonfly ]; then - echo "#ifdef USE_PRIVATECRYPTO" >>$CONFIG_H - echo "#define HAVE_MD5_H" >>$CONFIG_H - echo "#define SHA2_H " >>$CONFIG_H - echo "#else" >>$CONFIG_H -fi - if [ -z "$MD5" ]; then MD5_LIB= printf "Testing for MD5Init ... " @@ -1388,14 +1383,6 @@ EOF echo "$MD5" rm -f _md5.c _md5 fi -if [ "$MD5" = no ]; then - echo "#include \"compat/crypt/md5.h\"" >>$CONFIG_H - echo "MD5_SRC= compat/crypt/md5.c" >>$CONFIG_MK -else - echo "MD5_SRC=" >>$CONFIG_MK - echo "#define HAVE_MD5_H" >>$CONFIG_H - [ -n "$MD5_LIB" ] && echo "LDADD+= $MD5_LIB" >>$CONFIG_MK -fi if [ -z "$SHA2_H" ]; then if [ -z "$SHA2" ] || [ "$SHA2" != no ]; then @@ -1481,23 +1468,6 @@ EOF rm -f _sha256.c _sha256 fi fi -if [ "$SHA2" = no ]; then - echo "#include \"compat/crypt/sha256.h\"" >>$CONFIG_H - echo "SHA256_SRC= compat/crypt/sha256.c" >>$CONFIG_MK -else - echo "SHA256_SRC=" >>$CONFIG_MK - echo "#define SHA2_H <$SHA2_H>" >>$CONFIG_H - if [ "$SHA2_RENAMED" = yes ]; then - echo "#define SHA256_CTX SHA2_CTX" >>$CONFIG_H - echo "#define SHA256_Init SHA256Init" >>$CONFIG_H - echo "#define SHA256_Update SHA256Update" >>$CONFIG_H - echo "#define SHA256_Final SHA256Final" >>$CONFIG_H - fi - [ -n "$SHA2_LIB" ] && echo "LDADD+= $SHA2_LIB" >>$CONFIG_MK -fi - -# Workarond for DragonFlyBSD import -[ "$OS" = dragonfly ] && echo "#endif" >>$CONFIG_H if [ -z "$HMAC" ]; then HMAC_LIB= @@ -1530,7 +1500,108 @@ EOF echo "$HMAC" rm -f _hmac.c _hmac fi -if [ "$HMAC" = no ]; then + +if [ "$OPENSSL" = yes ] || + { [ -z "$OPENSSL" ] && [ "$ALLOW_USR_LIBS" = true ] && + [ "$SHA2" = no ] && [ "$HMAC" = no ]; + }; then + printf "Testing for openssl ... " + if type "$PKG_CONFIG" >/dev/null 2>&1; then + LIBCRYPTO_CFLAGS=$("$PKG_CONFIG" --cflags libcrypto 2>&3) + LIBCRYPTO_LIBS=$("$PKG_CONFIG" --libs libcrypto 2>&3) + fi + + cat <_openssl.c +#include +#include +int main(void) { + return OPENSSL_init_crypto(0, NULL) == 1; +} +EOF + if $XCC $LIBCRYPTO_CFLAGS _openssl.c -o _openssl $LIBCRYPTO_LIBS 2>&3; + then + OPENSSL=yes + MD5=yes + MD5_LIB= + if [ -n "$LIBCRYPTO_CFLAGS" ]; then + echo "CFLAGS+= $LIBCRYPTO_CFLAGS" >>$CONFIG_MK + fi + echo "LDADD+= $LIBCRYPTO_LIBS" >>$CONFIG_MK + echo "#define HAVE_OPENSSL" >>$CONFIG_H + else + OPENSSL=no + fi + echo "$OPENSSL" + rm -f _openssl.c _openssl +fi + +if [ "$OPENSSL" = yes ]; then + printf "Testing for openssl/sha.h ... " + cat <_openssl_sha.c +#include +#include + +int main(void) { + SHA256_CTX ctx; + SHA256_Init(&ctx); + return 0; +} +EOF + if $XCC $LIBCRYPTO_CFLAGS _openssl_sha.c -o _openssl_sha \ + $LIBCRYPTO_LIBS 2>&3; then + SHA2_H=openssl/sha.h + SHA2="yes (-lcrypto)" + else + SHA2=no + fi + SHA2_LIB= + SHA2_RENAMED= + echo "$SHA2" + rm -f _openssl_sha.c _openssl_sha +fi + +# Workaround for DragonFlyBSD import +if [ "$OS" = dragonfly ]; then + echo "#ifdef USE_PRIVATECRYPTO" >>$CONFIG_H + echo "#define HAVE_MD5_H" >>$CONFIG_H + echo "#define SHA2_H " >>$CONFIG_H + echo "#else" >>$CONFIG_H +fi + +if [ "$MD5" = no ]; then + echo "#include \"compat/crypt/md5.h\"" >>$CONFIG_H + echo "MD5_SRC= compat/crypt/md5.c" >>$CONFIG_MK +else + echo "MD5_SRC=" >>$CONFIG_MK + [ "$OPENSSL" != yes ] && echo "#define HAVE_MD5_H" >>$CONFIG_H + [ -n "$MD5_LIB" ] && echo "LDADD+= $MD5_LIB" >>$CONFIG_MK +fi + +if [ "$OPENSSL" = yes ] && [ "$SHA2" = no ]; then + echo "#include \"compat/crypt_openssl/sha256.h\"" >>$CONFIG_H + echo "SHA256_SRC= compat/crypt_openssl/sha256.c" >>$CONFIG_MK +elif [ "$SHA2" = no ]; then + echo "#include \"compat/crypt/sha256.h\"" >>$CONFIG_H + echo "SHA256_SRC= compat/crypt/sha256.c" >>$CONFIG_MK +else + echo "SHA256_SRC=" >>$CONFIG_MK + echo "#define SHA2_H <$SHA2_H>" >>$CONFIG_H + if [ "$SHA2_RENAMED" = yes ]; then + echo "#define SHA256_CTX SHA2_CTX" >>$CONFIG_H + echo "#define SHA256_Init SHA256Init" >>$CONFIG_H + echo "#define SHA256_Update SHA256Update" >>$CONFIG_H + echo "#define SHA256_Final SHA256Final" >>$CONFIG_H + fi + [ -n "$SHA2_LIB" ] && echo "LDADD+= $SHA2_LIB" >>$CONFIG_MK +fi + +# Workarond for DragonFlyBSD import +[ "$OS" = dragonfly ] && echo "#endif" >>$CONFIG_H + +if [ "$OPENSSL" = yes ]; then + echo "#include \"compat/crypt_openssl/hmac.h\"" >>$CONFIG_H + echo "HMAC_SRC= compat/crypt_openssl/hmac.c" >>$CONFIG_MK +elif [ "$HMAC" = no ]; then echo "#include \"compat/crypt/hmac.h\"" >>$CONFIG_H echo "HMAC_SRC= compat/crypt/hmac.c" >>$CONFIG_MK else diff --git a/src/dhcpcd.c b/src/dhcpcd.c index 688a3a6d..cc5dfb58 100644 --- a/src/dhcpcd.c +++ b/src/dhcpcd.c @@ -75,6 +75,9 @@ static const char dhcpcd_copyright[] = "Copyright (c) 2006-2023 Roy Marples"; #ifdef HAVE_CAPSICUM #include #endif +#ifdef HAVE_OPENSSL +#include +#endif #ifdef HAVE_UTIL_H #include #endif @@ -2197,6 +2200,11 @@ printpidfile: } #endif +#ifdef HAVE_OPENSSL + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | + OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL); +#endif + #ifdef PRIVSEP ps_init(&ctx); #endif diff --git a/tests/crypt/Makefile b/tests/crypt/Makefile index dd676f4b..c3df1a31 100644 --- a/tests/crypt/Makefile +++ b/tests/crypt/Makefile @@ -3,7 +3,7 @@ include ${TOP}/iconfig.mk PROG= run-test SRCS= run-test.c -SRCS+= test_hmac_md5.c +SRCS+= test_hmac_md5.c test_sha256.c CFLAGS?= -O2 CSTD?= c99 diff --git a/tests/crypt/run-test.c b/tests/crypt/run-test.c index 42f52d1f..91cc8983 100644 --- a/tests/crypt/run-test.c +++ b/tests/crypt/run-test.c @@ -33,6 +33,8 @@ int main(void) if (test_hmac_md5()) r = -1; + if (test_sha256()) + r = -1; return r; } diff --git a/tests/crypt/test.h b/tests/crypt/test.h index 4f716f12..3c9070a5 100644 --- a/tests/crypt/test.h +++ b/tests/crypt/test.h @@ -28,5 +28,6 @@ #ifndef TEST_H int test_hmac_md5(void); +int test_sha256(void); #endif diff --git a/tests/crypt/test_sha256.c b/tests/crypt/test_sha256.c new file mode 100644 index 00000000..986e0513 --- /dev/null +++ b/tests/crypt/test_sha256.c @@ -0,0 +1,138 @@ +/* + * dhcpcd - DHCP client daemon + * Copyright (c) 2023 Tobias Heider + * Copyright (c) 2006-2018 Roy Marples + * All rights reserved + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "config.h" +#include "test.h" + +#ifdef SHA2_H +#include SHA2_H +#endif + +# ifndef SHA256_DIGEST_LENGTH +# define SHA256_DIGEST_LENGTH 32 +# endif + +static void +print_md(FILE *stream, const uint8_t *md) +{ + int i; + + fprintf(stream, "digest = 0x"); + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) + fprintf(stream, "%02x", *md++); + fprintf(stream, "\n"); +} + +static void +test_md(const uint8_t *md, const uint8_t *tst) +{ + print_md(stdout, md); + if (memcmp(md, tst, SHA256_DIGEST_LENGTH) == 0) + return; + fprintf(stderr, "FAILED!\nExpected\t\t\t"); + print_md(stderr, tst); + exit(EXIT_FAILURE); +} + +static void +sha256_test1(void) +{ + const uint8_t text[] = "Hi There"; + const uint8_t expect[SHA256_DIGEST_LENGTH] = { + 0xcc, 0x6d, 0x58, 0x96, 0xd7, 0x70, 0x10, 0x1e, + 0xf0, 0x28, 0x0c, 0x94, 0x3a, 0x2d, 0x3c, 0x3f, + 0x24, 0xcd ,0x5b, 0x11, 0x46, 0x4a, 0x51, 0x86, + 0xda, 0xf7, 0xa2, 0x38, 0x47, 0x71, 0x62, 0xac + }; + uint8_t digest[SHA256_DIGEST_LENGTH]; + SHA256_CTX ctx; + + printf ("SHA256 Test 1:\t\t"); + SHA256_Init(&ctx); + SHA256_Update(&ctx, text, 8); + SHA256_Final(digest, &ctx); + test_md(digest, expect); +} + +static void +sha256_test2(void) +{ + const uint8_t text[] = "what do ya want for nothing?"; + const uint8_t expect[SHA256_DIGEST_LENGTH] = { + 0xb3, 0x81, 0xe7, 0xfe, 0xc6, 0x53, 0xfc, 0x3a, + 0xb9, 0xb1, 0x78, 0x27, 0x23, 0x66, 0xb8, 0xac, + 0x87, 0xfe, 0xd8, 0xd3, 0x1c, 0xb2, 0x5e, 0xd1, + 0xd0, 0xe1, 0xf3, 0x31, 0x86, 0x44, 0xc8, 0x9c, + }; + uint8_t digest[SHA256_DIGEST_LENGTH]; + SHA256_CTX ctx; + + printf ("SHA256 Test 2:\t\t"); + SHA256_Init(&ctx); + SHA256_Update(&ctx, text, 28); + SHA256_Final(digest, &ctx); + test_md(digest, expect); +} + +static void +sha256_test3(void) +{ + const uint8_t expect[SHA256_DIGEST_LENGTH] = { + 0x5c, 0xf6, 0x18, 0xb5, 0xb6, 0xd3, 0x8b, 0xd1, + 0x6c, 0x2e, 0x55, 0x8e, 0xef, 0x4d, 0x4b, 0x6d, + 0x52, 0x82, 0x84, 0x54, 0x7f, 0xd4, 0xa0, 0x9d, + 0xa2, 0xab, 0xb6, 0xf0, 0x98, 0xec, 0x61, 0x93, + }; + uint8_t digest[SHA256_DIGEST_LENGTH]; + uint8_t text[50]; + int i; + SHA256_CTX ctx; + + printf ("SHA256 Test 3:\t\t"); + for (i = 0; i < 50; i++) + text[i] = 0xdd; + SHA256_Init(&ctx); + SHA256_Update(&ctx, text, 50); + SHA256_Final(digest, &ctx); + test_md(digest, expect); +} + +int test_sha256(void) +{ + printf ("Starting SHA256 tests...\n\n"); + sha256_test1(); + sha256_test2(); + sha256_test3(); + printf("\nAll tests pass.\n"); + return 0; +}