diff options
| author | auth12 <[email protected]> | 2020-07-22 08:34:12 -0700 |
|---|---|---|
| committer | auth12 <[email protected]> | 2020-07-22 08:34:12 -0700 |
| commit | 5015ddb9b1eee748efc24056e46f81888c975f7a (patch) | |
| tree | a810f6ee90f8bfe0e934fdd9142198e6b3862957 /wolfcrypt/src/port/devcrypto/devcrypto_hash.c | |
| download | wolfssl_windows-5015ddb9b1eee748efc24056e46f81888c975f7a.tar.xz wolfssl_windows-5015ddb9b1eee748efc24056e46f81888c975f7a.zip | |
Initial commit
Diffstat (limited to 'wolfcrypt/src/port/devcrypto/devcrypto_hash.c')
| -rw-r--r-- | wolfcrypt/src/port/devcrypto/devcrypto_hash.c | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c new file mode 100644 index 0000000..f73224d --- /dev/null +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c @@ -0,0 +1,248 @@ +/* devcrypto_hash.c + * + * Copyright (C) 2006-2020 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include <config.h> +#endif + +#include <wolfssl/wolfcrypt/settings.h> + +#if defined(WOLFSSL_DEVCRYPTO_HASH) + +#include <wolfssl/wolfcrypt/error-crypt.h> +#include <wolfssl/wolfcrypt/logging.h> +#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h> + +#if !defined(NO_SHA256) +#include <wolfssl/wolfcrypt/sha256.h> +#endif + +/* dereference structure based on type to get cryptodev context pointer + * can return NULL on fail case */ +static WC_CRYPTODEV* GetHashContext(void* ctx, int type) +{ + switch (type) { + case CRYPTO_SHA2_256: + return &((wc_Sha256*)ctx)->ctx; + + default: + return NULL; + } + + return NULL; +} + + +/* generic hash initialization + * key is for hmac algorithms and keySz is for the size of key buffer + * key should be null in the case of non hmac algorithms + * return 0 on success */ +static int HashInit(void* ctx, int type, byte* key, word32 keySz) +{ + WC_CRYPTODEV* cdev; + + if ((cdev = GetHashContext(ctx, type)) == NULL) { + WOLFSSL_MSG("Unsupported hash type"); + return BAD_FUNC_ARG; + } + + return wc_DevCryptoCreate(cdev, type, key, keySz); +} + + +/* generic function for updated hash structure + * returns 0 on success */ +static int HashUpdate(void* ctx, int type, const byte* input, word32 inputSz) +{ + WC_CRYPTODEV* dev; + struct crypt_op crt; + byte digest[64]; + + if (inputSz == 0) { + return 0; + } + + if ((dev = GetHashContext(ctx, type)) == NULL) { + WOLFSSL_MSG("Unsupported hash type"); + return BAD_FUNC_ARG; + } + + wc_SetupCrypt(&crt, dev, (byte*)input, inputSz, NULL, digest, COP_FLAG_UPDATE); + if (ioctl(dev->cfd, CIOCCRYPT, &crt)) { + WOLFSSL_MSG("Error with call to ioctl"); + return WC_DEVCRYPTO_E; + } + + return 0; +} + + +/* generic function for getting final digest value */ +static int GetDigest(void* ctx, int type, byte* out) +{ + WC_CRYPTODEV* dev; + struct crypt_op crt; + + if ((dev = GetHashContext(ctx, type)) == NULL) { + WOLFSSL_MSG("Unsupported hash type"); + return BAD_FUNC_ARG; + } + + wc_SetupCrypt(&crt, dev, NULL, 0, NULL, out, COP_FLAG_FINAL); + if (ioctl(dev->cfd, CIOCCRYPT, &crt)) { + WOLFSSL_MSG("Error with call to ioctl"); + return WC_DEVCRYPTO_E; + } + + return 0; +} + +#if !defined(NO_SHA256) + +int wc_InitSha256_ex(wc_Sha256* sha, void* heap, int devId) +{ + if (sha == NULL) { + return BAD_FUNC_ARG; + } + + (void)devId; /* no async for now */ + XMEMSET(sha, 0, sizeof(wc_Sha256)); + sha->heap = heap; + + return HashInit((void*)sha, CRYPTO_SHA2_256, NULL, 0); +} + + +int wc_Sha256Update(wc_Sha256* sha, const byte* in, word32 sz) +{ + if (sha == NULL || (sz > 0 && in == NULL)) { + return BAD_FUNC_ARG; + } + +#ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP + /* keep full message to hash at end instead of incremental updates */ + if (sha->len < sha->used + sz) { + if (sha->msg == NULL) { + sha->msg = (byte*)XMALLOC(sha->used + sz, sha->heap, + DYNAMIC_TYPE_TMP_BUFFER); + } else { + byte* pt = (byte*)XREALLOC(sha->msg, sha->used + sz, sha->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (pt == NULL) { + return MEMORY_E; + } + sha->msg = pt; + } + if (sha->msg == NULL) { + return MEMORY_E; + } + sha->len = sha->used + sz; + } + XMEMCPY(sha->msg + sha->used, in, sz); + sha->used += sz; + return 0; +#else + return HashUpdate(sha, CRYPTO_SHA2_256, in, sz); +#endif +} + + +int wc_Sha256Final(wc_Sha256* sha, byte* hash) +{ + int ret; + + if (sha == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + /* help static analysis tools out */ + XMEMSET(hash, 0, WC_SHA256_DIGEST_SIZE); +#ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP + /* keep full message to hash at end instead of incremental updates */ + if ((ret = HashUpdate(sha, CRYPTO_SHA2_256, sha->msg, sha->used)) < 0) { + return ret; + } + XFREE(sha->msg, sha->heap, DYNAMIC_TYPE_TMP_BUFFER); + sha->msg = NULL; +#endif + ret = GetDigest(sha, CRYPTO_SHA2_256, hash); + if (ret != 0) { + return ret; + } + + wc_Sha256Free(sha); + return wc_InitSha256_ex(sha, sha->heap, 0); +} + + +int wc_Sha256GetHash(wc_Sha256* sha, byte* hash) +{ + if (sha == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + +#ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP + { + int ret; + wc_Sha256 cpy; + wc_Sha256Copy(sha, &cpy); + + if ((ret = HashUpdate(&cpy, CRYPTO_SHA2_256, cpy.msg, cpy.used)) == 0) { + /* help static analysis tools out */ + XMEMSET(hash, 0, WC_SHA256_DIGEST_SIZE); + ret = GetDigest(&cpy, CRYPTO_SHA2_256, hash); + } + wc_Sha256Free(&cpy); + return ret; + } +#else + (void)sha; + (void)hash; + + WOLFSSL_MSG("Compile with WOLFSSL_DEVCRYPTO_HASH_KEEP for this feature"); + return NOT_COMPILED_IN; +#endif +} + +int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) +{ + if (src == NULL || dst == NULL) { + return BAD_FUNC_ARG; + } + + wc_InitSha256_ex(dst, src->heap, 0); +#ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP + dst->len = src->len; + dst->used = src->used; + dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (dst->msg == NULL) { + return MEMORY_E; + } + XMEMCPY(dst->msg, src->msg, src->len); +#endif + + return 0; +} + +#endif /* !NO_SHA256 */ + +#endif /* WOLFSSL_DEVCRYPTO */ |