diff options
author | BoringSSL Robot <boringsslrobot@gmail.com> | 2017-07-31 17:34:22 +0000 |
---|---|---|
committer | BoringSSL Robot <boringsslrobot@gmail.com> | 2017-07-31 17:34:22 +0000 |
commit | 99060c9294530d514fdef853ff1ea32d255bbeae (patch) | |
tree | 9dd6c936410ce2b5b64cd1b02f3ea72d1a6f27e2 /src/crypto/fipsmodule/digest | |
parent | 8d8d1ca8e1f1a34a2167f59e2b0ca09c623b160f (diff) | |
parent | 68f84f5c40644e029ed066999448696b01caba7a (diff) | |
download | boringssl-99060c9294530d514fdef853ff1ea32d255bbeae.zip boringssl-99060c9294530d514fdef853ff1ea32d255bbeae.tar.gz boringssl-99060c9294530d514fdef853ff1ea32d255bbeae.tar.bz2 |
update chromium-stable-with-bazel from chromium-stable branch
Diffstat (limited to 'src/crypto/fipsmodule/digest')
-rw-r--r-- | src/crypto/fipsmodule/digest/digest.c | 251 | ||||
-rw-r--r-- | src/crypto/fipsmodule/digest/digests.c | 280 | ||||
-rw-r--r-- | src/crypto/fipsmodule/digest/internal.h | 112 | ||||
-rw-r--r-- | src/crypto/fipsmodule/digest/md32_common.h | 269 |
4 files changed, 912 insertions, 0 deletions
diff --git a/src/crypto/fipsmodule/digest/digest.c b/src/crypto/fipsmodule/digest/digest.c new file mode 100644 index 0000000..00e6d4b --- /dev/null +++ b/src/crypto/fipsmodule/digest/digest.c @@ -0,0 +1,251 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include <openssl/digest.h> + +#include <assert.h> +#include <string.h> + +#include <openssl/err.h> +#include <openssl/mem.h> + +#include "internal.h" +#include "../../internal.h" + + +int EVP_MD_type(const EVP_MD *md) { return md->type; } + +uint32_t EVP_MD_flags(const EVP_MD *md) { return md->flags; } + +size_t EVP_MD_size(const EVP_MD *md) { return md->md_size; } + +size_t EVP_MD_block_size(const EVP_MD *md) { return md->block_size; } + + +void EVP_MD_CTX_init(EVP_MD_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_MD_CTX)); +} + +EVP_MD_CTX *EVP_MD_CTX_create(void) { + EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_MD_CTX)); + + if (ctx) { + EVP_MD_CTX_init(ctx); + } + + return ctx; +} + +int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { + if (ctx->digest && ctx->digest->ctx_size && ctx->md_data) { + OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); + OPENSSL_free(ctx->md_data); + } + + assert(ctx->pctx == NULL || ctx->pctx_ops != NULL); + if (ctx->pctx_ops) { + ctx->pctx_ops->free(ctx->pctx); + } + + EVP_MD_CTX_init(ctx); + + return 1; +} + +void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) { + if (!ctx) { + return; + } + + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) { + uint8_t *tmp_buf = NULL; + + if (in == NULL || in->digest == NULL) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_INPUT_NOT_INITIALIZED); + return 0; + } + + if (out->digest == in->digest) { + /* |md_data| will be the correct size in this case so it's removed from + * |out| at this point so that |EVP_MD_CTX_cleanup| doesn't free it and + * then it's reused. */ + tmp_buf = out->md_data; + out->md_data = NULL; + } + + EVP_MD_CTX_cleanup(out); + + out->digest = in->digest; + if (in->md_data && in->digest->ctx_size) { + if (tmp_buf) { + out->md_data = tmp_buf; + } else { + out->md_data = OPENSSL_malloc(in->digest->ctx_size); + if (!out->md_data) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + } + OPENSSL_memcpy(out->md_data, in->md_data, in->digest->ctx_size); + } + + assert(in->pctx == NULL || in->pctx_ops != NULL); + out->pctx_ops = in->pctx_ops; + if (in->pctx && in->pctx_ops) { + out->pctx = in->pctx_ops->dup(in->pctx); + if (!out->pctx) { + EVP_MD_CTX_cleanup(out); + return 0; + } + } + + return 1; +} + +int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) { + EVP_MD_CTX_init(out); + return EVP_MD_CTX_copy_ex(out, in); +} + +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine) { + if (ctx->digest != type) { + if (ctx->digest && ctx->digest->ctx_size > 0) { + OPENSSL_free(ctx->md_data); + ctx->md_data = NULL; + } + ctx->digest = type; + if (type->ctx_size > 0) { + ctx->md_data = OPENSSL_malloc(type->ctx_size); + if (ctx->md_data == NULL) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + } + } + + assert(ctx->pctx == NULL || ctx->pctx_ops != NULL); + + ctx->digest->init(ctx); + return 1; +} + +int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) { + EVP_MD_CTX_init(ctx); + return EVP_DigestInit_ex(ctx, type, NULL); +} + +int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + ctx->digest->update(ctx, data, len); + return 1; +} + +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out, unsigned int *size) { + assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); + ctx->digest->final(ctx, md_out); + if (size != NULL) { + *size = ctx->digest->md_size; + } + OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); + return 1; +} + +int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md, unsigned int *size) { + (void)EVP_DigestFinal_ex(ctx, md, size); + EVP_MD_CTX_cleanup(ctx); + return 1; +} + +int EVP_Digest(const void *data, size_t count, uint8_t *out_md, + unsigned int *out_size, const EVP_MD *type, ENGINE *impl) { + EVP_MD_CTX ctx; + int ret; + + EVP_MD_CTX_init(&ctx); + ret = EVP_DigestInit_ex(&ctx, type, impl) && + EVP_DigestUpdate(&ctx, data, count) && + EVP_DigestFinal_ex(&ctx, out_md, out_size); + EVP_MD_CTX_cleanup(&ctx); + + return ret; +} + + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx) { + if (ctx == NULL) { + return NULL; + } + return ctx->digest; +} + +size_t EVP_MD_CTX_size(const EVP_MD_CTX *ctx) { + return EVP_MD_size(EVP_MD_CTX_md(ctx)); +} + +size_t EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx) { + return EVP_MD_block_size(EVP_MD_CTX_md(ctx)); +} + +int EVP_MD_CTX_type(const EVP_MD_CTX *ctx) { + return EVP_MD_type(EVP_MD_CTX_md(ctx)); +} + +int EVP_add_digest(const EVP_MD *digest) { + return 1; +} diff --git a/src/crypto/fipsmodule/digest/digests.c b/src/crypto/fipsmodule/digest/digests.c new file mode 100644 index 0000000..f2fa349 --- /dev/null +++ b/src/crypto/fipsmodule/digest/digests.c @@ -0,0 +1,280 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include <openssl/digest.h> + +#include <assert.h> +#include <string.h> + +#include <openssl/md4.h> +#include <openssl/md5.h> +#include <openssl/nid.h> +#include <openssl/sha.h> + +#include "internal.h" +#include "../delocate.h" +#include "../../internal.h" + +#if defined(NDEBUG) +#define CHECK(x) (void) (x) +#else +#define CHECK(x) assert(x) +#endif + + +static void md4_init(EVP_MD_CTX *ctx) { + CHECK(MD4_Init(ctx->md_data)); +} + +static void md4_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(MD4_Update(ctx->md_data, data, count)); +} + +static void md4_final(EVP_MD_CTX *ctx, uint8_t *out) { + CHECK(MD4_Final(out, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md4) { + out->type = NID_md4; + out->md_size = MD4_DIGEST_LENGTH; + out->flags = 0; + out->init = md4_init; + out->update = md4_update; + out->final = md4_final; + out->block_size = 64; + out->ctx_size = sizeof(MD4_CTX); +} + + +static void md5_init(EVP_MD_CTX *ctx) { + CHECK(MD5_Init(ctx->md_data)); +} + +static void md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(MD5_Update(ctx->md_data, data, count)); +} + +static void md5_final(EVP_MD_CTX *ctx, uint8_t *out) { + CHECK(MD5_Final(out, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5) { + out->type = NID_md5; + out->md_size = MD5_DIGEST_LENGTH; + out->flags = 0; + out->init = md5_init; + out->update = md5_update; + out->final = md5_final; + out->block_size = 64; + out->ctx_size = sizeof(MD5_CTX); +} + + +static void sha1_init(EVP_MD_CTX *ctx) { + CHECK(SHA1_Init(ctx->md_data)); +} + +static void sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA1_Update(ctx->md_data, data, count)); +} + +static void sha1_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA1_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha1) { + out->type = NID_sha1; + out->md_size = SHA_DIGEST_LENGTH; + out->flags = 0; + out->init = sha1_init; + out->update = sha1_update; + out->final = sha1_final; + out->block_size = 64; + out->ctx_size = sizeof(SHA_CTX); +} + + +static void sha224_init(EVP_MD_CTX *ctx) { + CHECK(SHA224_Init(ctx->md_data)); +} + +static void sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA224_Update(ctx->md_data, data, count)); +} + +static void sha224_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA224_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha224) { + out->type = NID_sha224; + out->md_size = SHA224_DIGEST_LENGTH; + out->flags = 0; + out->init = sha224_init; + out->update = sha224_update; + out->final = sha224_final; + out->block_size = 64; + out->ctx_size = sizeof(SHA256_CTX); +} + + +static void sha256_init(EVP_MD_CTX *ctx) { + CHECK(SHA256_Init(ctx->md_data)); +} + +static void sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA256_Update(ctx->md_data, data, count)); +} + +static void sha256_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA256_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha256) { + out->type = NID_sha256; + out->md_size = SHA256_DIGEST_LENGTH; + out->flags = 0; + out->init = sha256_init; + out->update = sha256_update; + out->final = sha256_final; + out->block_size = 64; + out->ctx_size = sizeof(SHA256_CTX); +} + + +static void sha384_init(EVP_MD_CTX *ctx) { + CHECK(SHA384_Init(ctx->md_data)); +} + +static void sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA384_Update(ctx->md_data, data, count)); +} + +static void sha384_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA384_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha384) { + out->type = NID_sha384; + out->md_size = SHA384_DIGEST_LENGTH; + out->flags = 0; + out->init = sha384_init; + out->update = sha384_update; + out->final = sha384_final; + out->block_size = 128; + out->ctx_size = sizeof(SHA512_CTX); +} + + +static void sha512_init(EVP_MD_CTX *ctx) { + CHECK(SHA512_Init(ctx->md_data)); +} + +static void sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA512_Update(ctx->md_data, data, count)); +} + +static void sha512_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA512_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512) { + out->type = NID_sha512; + out->md_size = SHA512_DIGEST_LENGTH; + out->flags = 0; + out->init = sha512_init; + out->update = sha512_update; + out->final = sha512_final; + out->block_size = 128; + out->ctx_size = sizeof(SHA512_CTX); +} + + +typedef struct { + MD5_CTX md5; + SHA_CTX sha1; +} MD5_SHA1_CTX; + +static void md5_sha1_init(EVP_MD_CTX *md_ctx) { + MD5_SHA1_CTX *ctx = md_ctx->md_data; + CHECK(MD5_Init(&ctx->md5) && SHA1_Init(&ctx->sha1)); +} + +static void md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data, + size_t count) { + MD5_SHA1_CTX *ctx = md_ctx->md_data; + CHECK(MD5_Update(&ctx->md5, data, count) && + SHA1_Update(&ctx->sha1, data, count)); +} + +static void md5_sha1_final(EVP_MD_CTX *md_ctx, uint8_t *out) { + MD5_SHA1_CTX *ctx = md_ctx->md_data; + CHECK(MD5_Final(out, &ctx->md5) && + SHA1_Final(out + MD5_DIGEST_LENGTH, &ctx->sha1)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5_sha1) { + out->type = NID_md5_sha1; + out->md_size = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH; + out->flags = 0; + out->init = md5_sha1_init; + out->update = md5_sha1_update; + out->final = md5_sha1_final; + out->block_size = 64; + out->ctx_size = sizeof(MD5_SHA1_CTX); +} + +#undef CHECK diff --git a/src/crypto/fipsmodule/digest/internal.h b/src/crypto/fipsmodule/digest/internal.h new file mode 100644 index 0000000..e3d812a --- /dev/null +++ b/src/crypto/fipsmodule/digest/internal.h @@ -0,0 +1,112 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#ifndef OPENSSL_HEADER_DIGEST_INTERNAL_H +#define OPENSSL_HEADER_DIGEST_INTERNAL_H + +#include <openssl/base.h> + +#if defined(__cplusplus) +extern "C" { +#endif + + +struct env_md_st { + /* type contains a NID identifing the digest function. (For example, + * NID_md5.) */ + int type; + + /* md_size contains the size, in bytes, of the resulting digest. */ + unsigned md_size; + + /* flags contains the OR of |EVP_MD_FLAG_*| values. */ + uint32_t flags; + + /* init initialises the state in |ctx->md_data|. */ + void (*init)(EVP_MD_CTX *ctx); + + /* update hashes |len| bytes of |data| into the state in |ctx->md_data|. */ + void (*update)(EVP_MD_CTX *ctx, const void *data, size_t count); + + /* final completes the hash and writes |md_size| bytes of digest to |out|. */ + void (*final)(EVP_MD_CTX *ctx, uint8_t *out); + + /* block_size contains the hash's native block size. */ + unsigned block_size; + + /* ctx_size contains the size, in bytes, of the state of the hash function. */ + unsigned ctx_size; +}; + +/* evp_md_pctx_ops contains function pointers to allow the |pctx| member of + * |EVP_MD_CTX| to be manipulated without breaking layering by calling EVP + * functions. */ +struct evp_md_pctx_ops { + /* free is called when an |EVP_MD_CTX| is being freed and the |pctx| also + * needs to be freed. */ + void (*free) (EVP_PKEY_CTX *pctx); + + /* dup is called when an |EVP_MD_CTX| is copied and so the |pctx| also needs + * to be copied. */ + EVP_PKEY_CTX* (*dup) (EVP_PKEY_CTX *pctx); +}; + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_DIGEST_INTERNAL */ diff --git a/src/crypto/fipsmodule/digest/md32_common.h b/src/crypto/fipsmodule/digest/md32_common.h new file mode 100644 index 0000000..7371629 --- /dev/null +++ b/src/crypto/fipsmodule/digest/md32_common.h @@ -0,0 +1,269 @@ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. 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. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS 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 <openssl/base.h> + +#include <assert.h> + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* This is a generic 32-bit "collector" for message digest algorithms. It + * collects input character stream into chunks of 32-bit values and invokes the + * block function that performs the actual hash calculations. To make use of + * this mechanism, the following macros must be defined before including + * md32_common.h. + * + * One of |DATA_ORDER_IS_BIG_ENDIAN| or |DATA_ORDER_IS_LITTLE_ENDIAN| must be + * defined to specify the byte order of the input stream. + * + * |HASH_CBLOCK| must be defined as the integer block size, in bytes. + * + * |HASH_CTX| must be defined as the name of the context structure, which must + * have at least the following members: + * + * typedef struct <name>_state_st { + * uint32_t h[<chaining length> / sizeof(uint32_t)]; + * uint32_t Nl, Nh; + * uint8_t data[HASH_CBLOCK]; + * unsigned num; + * ... + * } <NAME>_CTX; + * + * <chaining length> is the output length of the hash in bytes, before + * any truncation (e.g. 64 for SHA-224 and SHA-256, 128 for SHA-384 and + * SHA-512). + * + * |HASH_UPDATE| must be defined as the name of the "Update" function to + * generate. + * + * |HASH_TRANSFORM| must be defined as the the name of the "Transform" + * function to generate. + * + * |HASH_FINAL| must be defined as the name of "Final" function to generate. + * + * |HASH_BLOCK_DATA_ORDER| must be defined as the name of the "Block" function. + * That function must be implemented manually. It must be capable of operating + * on *unaligned* input data in its original (data) byte order. It must have + * this signature: + * + * void HASH_BLOCK_DATA_ORDER(uint32_t *state, const uint8_t *data, + * size_t num); + * + * It must update the hash state |state| with |num| blocks of data from |data|, + * where each block is |HASH_CBLOCK| bytes; i.e. |data| points to a array of + * |HASH_CBLOCK * num| bytes. |state| points to the |h| member of a |HASH_CTX|, + * and so will have |<chaining length> / sizeof(uint32_t)| elements. + * + * |HASH_MAKE_STRING(c, s)| must be defined as a block statement that converts + * the hash state |c->h| into the output byte order, storing the result in |s|. + */ + +#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) +#error "DATA_ORDER must be defined!" +#endif + +#ifndef HASH_CBLOCK +#error "HASH_CBLOCK must be defined!" +#endif +#ifndef HASH_CTX +#error "HASH_CTX must be defined!" +#endif + +#ifndef HASH_UPDATE +#error "HASH_UPDATE must be defined!" +#endif +#ifndef HASH_TRANSFORM +#error "HASH_TRANSFORM must be defined!" +#endif +#ifndef HASH_FINAL +#error "HASH_FINAL must be defined!" +#endif + +#ifndef HASH_BLOCK_DATA_ORDER +#error "HASH_BLOCK_DATA_ORDER must be defined!" +#endif + +#ifndef HASH_MAKE_STRING +#error "HASH_MAKE_STRING must be defined!" +#endif + +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + +#define HOST_c2l(c, l) \ + do { \ + (l) = (((uint32_t)(*((c)++))) << 24); \ + (l) |= (((uint32_t)(*((c)++))) << 16); \ + (l) |= (((uint32_t)(*((c)++))) << 8); \ + (l) |= (((uint32_t)(*((c)++)))); \ + } while (0) + +#define HOST_l2c(l, c) \ + do { \ + *((c)++) = (uint8_t)(((l) >> 24) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 16) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 8) & 0xff); \ + *((c)++) = (uint8_t)(((l)) & 0xff); \ + } while (0) + +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + +#define HOST_c2l(c, l) \ + do { \ + (l) = (((uint32_t)(*((c)++)))); \ + (l) |= (((uint32_t)(*((c)++))) << 8); \ + (l) |= (((uint32_t)(*((c)++))) << 16); \ + (l) |= (((uint32_t)(*((c)++))) << 24); \ + } while (0) + +#define HOST_l2c(l, c) \ + do { \ + *((c)++) = (uint8_t)(((l)) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 8) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 16) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 24) & 0xff); \ + } while (0) + +#endif /* DATA_ORDER */ + +int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) { + const uint8_t *data = data_; + + if (len == 0) { + return 1; + } + + uint32_t l = c->Nl + (((uint32_t)len) << 3); + if (l < c->Nl) { + /* Handle carries. */ + c->Nh++; + } + c->Nh += (uint32_t)(len >> 29); + c->Nl = l; + + size_t n = c->num; + if (n != 0) { + if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { + OPENSSL_memcpy(c->data + n, data, HASH_CBLOCK - n); + HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); + n = HASH_CBLOCK - n; + data += n; + len -= n; + c->num = 0; + /* Keep |c->data| zeroed when unused. */ + OPENSSL_memset(c->data, 0, HASH_CBLOCK); + } else { + OPENSSL_memcpy(c->data + n, data, len); + c->num += (unsigned)len; + return 1; + } + } + + n = len / HASH_CBLOCK; + if (n > 0) { + HASH_BLOCK_DATA_ORDER(c->h, data, n); + n *= HASH_CBLOCK; + data += n; + len -= n; + } + + if (len != 0) { + c->num = (unsigned)len; + OPENSSL_memcpy(c->data, data, len); + } + return 1; +} + + +void HASH_TRANSFORM(HASH_CTX *c, const uint8_t *data) { + HASH_BLOCK_DATA_ORDER(c->h, data, 1); +} + + +int HASH_FINAL(uint8_t *md, HASH_CTX *c) { + /* |c->data| always has room for at least one byte. A full block would have + * been consumed. */ + size_t n = c->num; + assert(n < HASH_CBLOCK); + c->data[n] = 0x80; + n++; + + /* Fill the block with zeros if there isn't room for a 64-bit length. */ + if (n > (HASH_CBLOCK - 8)) { + OPENSSL_memset(c->data + n, 0, HASH_CBLOCK - n); + n = 0; + HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); + } + OPENSSL_memset(c->data + n, 0, HASH_CBLOCK - 8 - n); + + /* Append a 64-bit length to the block and process it. */ + uint8_t *p = c->data + HASH_CBLOCK - 8; +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + HOST_l2c(c->Nh, p); + HOST_l2c(c->Nl, p); +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + HOST_l2c(c->Nl, p); + HOST_l2c(c->Nh, p); +#endif + assert(p == c->data + HASH_CBLOCK); + HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); + c->num = 0; + OPENSSL_memset(c->data, 0, HASH_CBLOCK); + + HASH_MAKE_STRING(c, md); + return 1; +} + + +#if defined(__cplusplus) +} /* extern C */ +#endif |