Inital import.
Initial fork from f2d678e6e89b6508147086610e985d4e8416e867 (1.0.2 beta).
(This change contains substantial changes from the original and
effectively starts a new history.)
diff --git a/crypto/digest/CMakeLists.txt b/crypto/digest/CMakeLists.txt
new file mode 100644
index 0000000..a7ea708
--- /dev/null
+++ b/crypto/digest/CMakeLists.txt
@@ -0,0 +1,11 @@
+include_directories(. .. ../../include)
+
+add_library(
+ digest
+
+ OBJECT
+
+ digest.c
+ digests.c
+ digest_error.c
+)
diff --git a/crypto/digest/digest.c b/crypto/digest/digest.c
new file mode 100644
index 0000000..2bfb0fa
--- /dev/null
+++ b/crypto/digest/digest.c
@@ -0,0 +1,269 @@
+/* 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/obj.h>
+#include <openssl/mem.h>
+
+#include "internal.h"
+
+
+int EVP_MD_type(const EVP_MD *md) { return md->type; }
+
+const char *EVP_MD_name(const EVP_MD *md) { return OBJ_nid2sn(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) { 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, EVP_MD_CTX_copy_ex,
+ 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);
+ memcpy(out, in, sizeof(EVP_MD_CTX));
+
+ 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, EVP_MD_CTX_copy_ex, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+ memcpy(out->md_data, in->md_data, in->digest->ctx_size);
+ }
+
+ assert(in->pctx == NULL || in->pctx_ops != NULL);
+ 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) {
+ OPENSSL_free(ctx->md_data);
+ }
+ ctx->digest = type;
+ if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
+ ctx->update = type->update;
+ ctx->md_data = OPENSSL_malloc(type->ctx_size);
+ if (ctx->md_data == NULL) {
+ OPENSSL_PUT_ERROR(DIGEST, EVP_DigestInit_ex, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+ }
+
+ assert(ctx->pctx == NULL || ctx->pctx_ops != NULL);
+ if (ctx->pctx_ops) {
+ if (!ctx->pctx_ops->begin_digest(ctx)) {
+ return 0;
+ }
+ }
+
+ if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) {
+ return 1;
+ }
+
+ return ctx->digest->init(ctx);
+}
+
+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) {
+ return ctx->update(ctx, data, len);
+}
+
+int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out, unsigned int *size) {
+ int ret;
+
+ assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
+ ret = ctx->digest->final(ctx, md_out);
+ if (size != NULL) {
+ *size = ctx->digest->md_size;
+ }
+ OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
+
+ return ret;
+}
+
+int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md, unsigned int *size) {
+ int ret = EVP_DigestFinal_ex(ctx, md, size);
+ EVP_MD_CTX_cleanup(ctx);
+ return ret;
+}
+
+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;
+}
+
+unsigned EVP_MD_CTX_size(const EVP_MD_CTX *ctx) {
+ return EVP_MD_size(EVP_MD_CTX_md(ctx));
+}
+
+unsigned 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));
+}
+
+void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, uint32_t flags) {
+ ctx->flags |= flags;
+}
+
+void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, uint32_t flags) {
+ ctx->flags &= ~flags;
+}
+
+uint32_t EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, uint32_t flags) {
+ return ctx->flags & flags;
+}
diff --git a/crypto/digest/digest.h b/crypto/digest/digest.h
new file mode 100644
index 0000000..9a91908
--- /dev/null
+++ b/crypto/digest/digest.h
@@ -0,0 +1,267 @@
+/* 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_H
+#define OPENSSL_HEADER_DIGEST_H
+
+#include <openssl/base.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* Digest functions.
+ *
+ * An EVP_MD abstracts the details of a specific hash function allowing code to
+ * deal with the concept of a "hash function" without needing to know exactly
+ * which hash function it is. */
+
+
+/* Hash algorithms.
+ *
+ * The following functions return |EVP_MD| objects that implement the named hash
+ * function. */
+
+const EVP_MD *EVP_md5(void);
+const EVP_MD *EVP_sha1(void);
+const EVP_MD *EVP_sha224(void);
+const EVP_MD *EVP_sha256(void);
+const EVP_MD *EVP_sha384(void);
+const EVP_MD *EVP_sha512(void);
+
+/* EVP_get_digestbynid returns an |EVP_MD| for the given NID, or NULL if no
+ * such digest is known. */
+const EVP_MD *EVP_get_digestbynid(int nid);
+
+/* EVP_get_digestbyobj returns an |EVP_MD| for the given |ASN1_OBJECT|, or NULL
+ * if no such digest is known. */
+const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj);
+
+
+/* Digest contexts.
+ *
+ * An EVP_MD_CTX represents the state of a specific digest operation in
+ * progress. */
+
+/* EVP_MD_CTX_init initialises an, already allocated, |EVP_MD_CTX|. */
+void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
+
+/* EVP_MD_CTX_create allocates and initialises a fresh |EVP_MD_CTX| and returns
+ * it, or NULL on allocation failure. */
+EVP_MD_CTX *EVP_MD_CTX_create(void);
+
+/* EVP_MD_CTX_cleanup frees any resources owned by |ctx| and resets it to a
+ * freshly initialised state. It does not free |ctx| itself. It returns one. */
+int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
+
+/* EVP_MD_CTX_destroy calls |EVP_MD_CTX_cleanup| and then frees |ctx| itself. */
+void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
+
+/* EVP_MD_CTX_copy_ex sets |out|, which must already be initialised, to be a
+ * copy of |in|. It returns one on success and zero on error. */
+int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in);
+
+
+/* Digest operations. */
+
+/* EVP_DigestInit_ex configures |ctx|, which must already have been
+ * initialised, for a fresh hashing operation using |type|. It returns one on
+ * success and zero otherwise. */
+int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine);
+
+/* EVP_DigestInit acts like |EVP_DigestInit_ex| except that |ctx| is
+ * initialised before use. */
+int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+
+/* EVP_DigestUpdate hashes |len| bytes from |data| into the hashing operation
+ * in |ctx|. It returns one on success and zero otherwise. */
+int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t len);
+
+/* EVP_MAX_MD_SIZE is the largest digest size supported. Functions that output
+ * a digest generally require the buffer have at least this much space. */
+#define EVP_MAX_MD_SIZE 64 /* SHA-512 is the longest so far. */
+
+/* EVP_DigestFinal_ex finishes the digest in |ctx| and writes the output to
+ * |md_out|. At most |EVP_MAX_MD_SIZE| bytes are written. If |out_size| is not
+ * NULL then |*out_size| is set to the number of bytes written. It returns one
+ * on success and zero otherwise. After this call, the hash cannot be updated
+ * or finished again until |EVP_DigestFinal_ex| is called to start another
+ * hashing operation. */
+int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out,
+ unsigned int *out_size);
+
+/* EVP_DigestFinal acts like |EVP_DigestFinal_ex| except that
+ * |EVP_MD_CTX_cleanup| is called on |ctx| before returning. */
+int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md_out, unsigned int *out_size);
+
+/* EVP_Digest performs a complete hashing operation in one call. It hashes
+ * |len| bytes from |data| and writes the digest to |md_out|. At most
+ * |EVP_MAX_MD_SIZE| bytes are written. If |out_size| is not NULL then
+ * |*out_size| is set to the number of bytes written. It returns one on success
+ * and zero otherwise. */
+int EVP_Digest(const void *data, size_t len, uint8_t *md_out,
+ unsigned int *md_out_size, const EVP_MD *type, ENGINE *impl);
+
+
+/* Digest function accessors.
+ *
+ * These functions allow code to learn details about an abstract hash
+ * function. */
+
+/* EVP_MD_type returns a NID identifing |md|. (For example, |NID_md5|.) */
+int EVP_MD_type(const EVP_MD *md);
+
+/* EVP_MD_name returns the short name for |md| or NULL if no name is known. */
+const char *EVP_MD_name(const EVP_MD *md);
+
+/* EVP_MD_flags returns the flags for |md|, which is a set of |EVP_MD_FLAG_*|
+ * values, ORed together. */
+uint32_t EVP_MD_flags(const EVP_MD *md);
+
+/* EVP_MD_size returns the digest size of |md|, in bytes. */
+size_t EVP_MD_size(const EVP_MD *md);
+
+/* EVP_MD_block_size returns the native block-size of |md|. */
+size_t EVP_MD_block_size(const EVP_MD *md);
+
+/* EVP_MD_FLAG_PKEY_DIGEST indicates the the digest function is used with a
+ * specific public key in order to verify signatures. (For example,
+ * EVP_dss1.) */
+#define EVP_MD_FLAG_PKEY_DIGEST 1
+
+/* EVP_MD_FLAG_DIGALGID_ABSENT indicates that the parameter type in an X.509
+ * DigestAlgorithmIdentifier representing this digest function should be
+ * undefined rather than NULL. */
+#define EVP_MD_FLAG_DIGALGID_ABSENT 2
+
+
+/* Deprecated functions. */
+
+/* EVP_MD_CTX_copy sets |out|, which must /not/ be initialised, to be a copy of
+ * |in|. It returns one on success and zero on error. */
+int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in);
+
+
+/* Digest operation accessors. */
+
+/* EVP_MD_CTX_md returns the underlying digest function, or NULL if one has not
+ * been set. */
+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
+
+/* EVP_MD_CTX_size returns the digest size of |ctx|. It will crash if a digest
+ * hasn't been set on |ctx|. */
+unsigned EVP_MD_CTX_size(const EVP_MD_CTX *ctx);
+
+/* EVP_MD_CTX_block_size returns the block size of the digest function used by
+ * |ctx|. It will crash if a digest hasn't been set on |ctx|. */
+unsigned EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx);
+
+/* EVP_MD_CTX_type returns a NID describing the digest function used by |ctx|.
+ * (For example, |NID_md5|.) It will crash if a digest hasn't been set on
+ * |ctx|. */
+int EVP_MD_CTX_type(const EVP_MD_CTX *ctx);
+
+/* EVP_MD_CTX_set_flags ORs |flags| into the flags member of |ctx|. */
+void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, uint32_t flags);
+
+/* EVP_MD_CTX_clear_flags clears any bits from the flags member of |ctx| that
+ * are set in |flags|. */
+void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, uint32_t flags);
+
+/* EVP_MD_CTX_test_flags returns the AND of |flags| and the flags member of
+ * |ctx|. */
+uint32_t EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, uint32_t flags);
+
+
+struct evp_md_pctx_ops;
+
+struct env_md_ctx_st {
+ /* digest is the underlying digest function, or NULL if not set. */
+ const EVP_MD *digest;
+ /* flags is the OR of a number of |EVP_MD_CTX_FLAG_*| values. */
+ uint32_t flags;
+ /* md_data points to a block of memory that contains the hash-specific
+ * context. */
+ void *md_data;
+ /* update is usually copied from |digest->update| but can differ in some
+ * cases, i.e. HMAC. */
+ int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count);
+
+ /* pctx is an opaque (at this layer) pointer to additional context that
+ * EVP_PKEY functions may store in this object. */
+ EVP_PKEY_CTX *pctx;
+
+ /* pctx_ops, if not NULL, points to a vtable that contains functions to
+ * manipulate |pctx|. */
+ const struct evp_md_pctx_ops *pctx_ops;
+} /* EVP_MD_CTX */;
+
+/* EVP_MD_CTX_FLAG_NO_INIT causes the |EVP_MD|'s |init| function not to be
+ * called, the |update| member not to be copied from the |EVP_MD| in
+ * |EVP_DigestInit_ex| and for |md_data| not to be initialised. */
+#define EVP_MD_CTX_FLAG_NO_INIT 1
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#define DIGEST_F_EVP_DigestInit_ex 100
+#define DIGEST_F_EVP_MD_CTX_copy_ex 101
+#define DIGEST_R_INPUT_NOT_INITIALIZED 100
+
+#endif /* OPENSSL_HEADER_DIGEST_H */
diff --git a/crypto/digest/digest_error.c b/crypto/digest/digest_error.c
new file mode 100644
index 0000000..e80a5df
--- /dev/null
+++ b/crypto/digest/digest_error.c
@@ -0,0 +1,24 @@
+/* Copyright (c) 2014, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/err.h>
+
+#include "digest.h"
+
+const ERR_STRING_DATA DIGEST_error_string_data[] = {
+ {ERR_PACK(ERR_LIB_DIGEST, DIGEST_F_EVP_DigestInit_ex, 0), "EVP_DigestInit_ex"},
+ {ERR_PACK(ERR_LIB_DIGEST, DIGEST_F_EVP_MD_CTX_copy_ex, 0), "EVP_MD_CTX_copy_ex"},
+ {ERR_PACK(ERR_LIB_DIGEST, 0, DIGEST_R_INPUT_NOT_INITIALIZED), "INPUT_NOT_INITIALIZED"},
+ {0, NULL},
+};
diff --git a/crypto/digest/digests.c b/crypto/digest/digests.c
new file mode 100644
index 0000000..b757ea8
--- /dev/null
+++ b/crypto/digest/digests.c
@@ -0,0 +1,215 @@
+/* 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 <openssl/md5.h>
+#include <openssl/obj.h>
+#include <openssl/sha.h>
+
+#include "internal.h"
+
+
+static int md5_init(EVP_MD_CTX *ctx) { return MD5_Init(ctx->md_data); }
+
+static int md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+ return MD5_Update(ctx->md_data, data, count);
+}
+
+static int md5_final(EVP_MD_CTX *ctx, unsigned char *out) {
+ return MD5_Final(out, ctx->md_data);
+}
+
+static const EVP_MD md5_md = {
+ NID_md5, MD5_DIGEST_LENGTH, 0 /* flags */, md5_init,
+ md5_update, md5_final, 64 /* block size */, sizeof(MD5_CTX),
+};
+
+const EVP_MD *EVP_md5(void) { return &md5_md; }
+
+
+static int sha1_init(EVP_MD_CTX *ctx) { return SHA1_Init(ctx->md_data); }
+
+static int sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+ return SHA1_Update(ctx->md_data, data, count);
+}
+
+static int sha1_final(EVP_MD_CTX *ctx, unsigned char *md) {
+ return SHA1_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha1_md = {
+ NID_sha1, SHA_DIGEST_LENGTH, 0 /* flags */, sha1_init,
+ sha1_update, sha1_final, 64 /* block size */, sizeof(SHA_CTX),
+};
+
+const EVP_MD *EVP_sha1(void) { return &sha1_md; }
+
+
+static int sha224_init(EVP_MD_CTX *ctx) { return SHA224_Init(ctx->md_data); }
+
+static int sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+ return SHA224_Update(ctx->md_data, data, count);
+}
+
+static int sha224_final(EVP_MD_CTX *ctx, unsigned char *md) {
+ return SHA224_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha224_md = {
+ NID_sha224, SHA224_DIGEST_LENGTH, 0 /* flags */,
+ sha224_init, sha224_update, sha224_final,
+ 64 /* block size */, sizeof(SHA256_CTX),
+};
+
+const EVP_MD *EVP_sha224(void) { return &sha224_md; }
+
+
+static int sha256_init(EVP_MD_CTX *ctx) { return SHA256_Init(ctx->md_data); }
+
+static int sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+ return SHA256_Update(ctx->md_data, data, count);
+}
+
+static int sha256_final(EVP_MD_CTX *ctx, unsigned char *md) {
+ return SHA256_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha256_md = {
+ NID_sha256, SHA256_DIGEST_LENGTH, 0 /* flags */,
+ sha256_init, sha256_update, sha256_final,
+ 64 /* block size */, sizeof(SHA256_CTX),
+};
+
+const EVP_MD *EVP_sha256(void) { return &sha256_md; }
+
+
+static int sha384_init(EVP_MD_CTX *ctx) { return SHA384_Init(ctx->md_data); }
+
+static int sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+ return SHA384_Update(ctx->md_data, data, count);
+}
+
+static int sha384_final(EVP_MD_CTX *ctx, unsigned char *md) {
+ return SHA384_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha384_md = {
+ NID_sha384, SHA384_DIGEST_LENGTH, 0 /* flags */,
+ sha384_init, sha384_update, sha384_final,
+ 128 /* block size */, sizeof(SHA512_CTX),
+};
+
+const EVP_MD *EVP_sha384(void) { return &sha384_md; }
+
+
+static int sha512_init(EVP_MD_CTX *ctx) { return SHA512_Init(ctx->md_data); }
+
+static int sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+ return SHA512_Update(ctx->md_data, data, count);
+}
+
+static int sha512_final(EVP_MD_CTX *ctx, unsigned char *md) {
+ return SHA512_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha512_md = {
+ NID_sha512, SHA512_DIGEST_LENGTH, 0 /* flags */,
+ sha512_init, sha512_update, sha512_final,
+ 128 /* block size */, sizeof(SHA512_CTX),
+};
+
+const EVP_MD *EVP_sha512(void) { return &sha512_md; }
+
+struct nid_to_digest {
+ int nid;
+ const EVP_MD *(*md_func)();
+};
+
+static const struct nid_to_digest nid_to_digest_mapping[] = {
+ { NID_md5, EVP_md5 },
+ { NID_sha1, EVP_sha1 },
+ { NID_sha224, EVP_sha224 },
+ { NID_sha256, EVP_sha256 },
+ { NID_sha384, EVP_sha384 },
+ { NID_sha512, EVP_sha512 },
+ { NID_dsaWithSHA, EVP_sha1 },
+ { NID_dsaWithSHA1, EVP_sha1 },
+ { NID_ecdsa_with_SHA1, EVP_sha1 },
+ { NID_md5WithRSAEncryption, EVP_md5 },
+ { NID_sha1WithRSAEncryption, EVP_sha1 },
+ { NID_sha224WithRSAEncryption, EVP_sha224 },
+ { NID_sha256WithRSAEncryption, EVP_sha256 },
+ { NID_sha384WithRSAEncryption, EVP_sha384 },
+ { NID_sha512WithRSAEncryption, EVP_sha512 },
+};
+
+const EVP_MD* EVP_get_digestbynid(int nid) {
+ unsigned i;
+
+ for (i = 0; i < sizeof(nid_to_digest_mapping) / sizeof(struct nid_to_digest);
+ i++) {
+ if (nid_to_digest_mapping[i].nid == nid) {
+ return nid_to_digest_mapping[i].md_func();
+ }
+ }
+
+ return NULL;
+}
+
+const EVP_MD* EVP_get_digestbyobj(const ASN1_OBJECT *obj) {
+ return EVP_get_digestbynid(OBJ_obj2nid(obj));
+}
diff --git a/crypto/digest/internal.h b/crypto/digest/internal.h
new file mode 100644
index 0000000..94dbfaa
--- /dev/null
+++ b/crypto/digest/internal.h
@@ -0,0 +1,117 @@
+/* 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|. It returns one on success
+ * and zero otherwise. */
+ int (*init)(EVP_MD_CTX *ctx);
+
+ /* update hashes |len| bytes of |data| into the state in |ctx->md_data|. */
+ int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count);
+
+ /* final completes the hash and writes |md_size| bytes of digest to |out|. */
+ int (*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 laying 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);
+
+ /* begin_digest is called when a new digest operation is started. It returns
+ * one on success and zero otherwise. */
+ int (*begin_digest) (EVP_MD_CTX *ctx);
+};
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_DIGEST_INTERNAL */
diff --git a/crypto/digest/md32_common.h b/crypto/digest/md32_common.h
new file mode 100644
index 0000000..d9e8432
--- /dev/null
+++ b/crypto/digest/md32_common.h
@@ -0,0 +1,370 @@
+/* ====================================================================
+ * 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.
+ * ==================================================================== */
+
+#ifndef OPENSSL_HEADER_MD32_COMMON_H
+#define OPENSSL_HEADER_MD32_COMMON_H
+
+#include <openssl/base.h>
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define asm __asm__
+
+/* This is a generic 32 bit "collector" for message digest algorithms.
+ * Whenever needed it collects input character stream into chunks of
+ * 32 bit values and invokes a block function that performs actual hash
+ * calculations.
+ *
+ * Porting guide.
+ *
+ * Obligatory macros:
+ *
+ * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
+ * this macro defines byte order of input stream.
+ * HASH_CBLOCK
+ * size of a unit chunk HASH_BLOCK operates on.
+ * HASH_LONG
+ * has to be at lest 32 bit wide, if it's wider, then
+ * HASH_LONG_LOG2 *has to* be defined along
+ * HASH_CTX
+ * context structure that at least contains following
+ * members:
+ * typedef struct {
+ * ...
+ * HASH_LONG Nl,Nh;
+ * either {
+ * HASH_LONG data[HASH_LBLOCK];
+ * unsigned char data[HASH_CBLOCK];
+ * };
+ * unsigned int num;
+ * ...
+ * } HASH_CTX;
+ * data[] vector is expected to be zeroed upon first call to
+ * HASH_UPDATE.
+ * HASH_UPDATE
+ * name of "Update" function, implemented here.
+ * HASH_TRANSFORM
+ * name of "Transform" function, implemented here.
+ * HASH_FINAL
+ * name of "Final" function, implemented here.
+ * HASH_BLOCK_DATA_ORDER
+ * name of "block" function capable of treating *unaligned* input
+ * message in original (data) byte order, implemented externally.
+ * HASH_MAKE_STRING
+ * macro convering context variables to an ASCII hash string.
+ *
+ * MD5 example:
+ *
+ * #define DATA_ORDER_IS_LITTLE_ENDIAN
+ *
+ * #define HASH_LONG MD5_LONG
+ * #define HASH_LONG_LOG2 MD5_LONG_LOG2
+ * #define HASH_CTX MD5_CTX
+ * #define HASH_CBLOCK MD5_CBLOCK
+ * #define HASH_UPDATE MD5_Update
+ * #define HASH_TRANSFORM MD5_Transform
+ * #define HASH_FINAL MD5_Final
+ * #define HASH_BLOCK_DATA_ORDER md5_block_data_order
+ *
+ * <appro@fy.chalmers.se>
+ */
+
+#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_LONG
+#error "HASH_LONG 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
+
+/*
+ * Engage compiler specific rotate intrinsic function if available.
+ */
+#undef ROTATE
+# if defined(_MSC_VER)
+# define ROTATE(a,n) _lrotl(a,n)
+# elif defined(__ICC)
+# define ROTATE(a,n) _rotl(a,n)
+# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM)
+ /*
+ * Some GNU C inline assembler templates. Note that these are
+ * rotates by *constant* number of bits! But that's exactly
+ * what we need here...
+ * <appro@fy.chalmers.se>
+ */
+# if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
+# define ROTATE(a,n) ({ register unsigned int ret; \
+ asm ( \
+ "roll %1,%0" \
+ : "=r"(ret) \
+ : "I"(n), "0"((unsigned int)(a)) \
+ : "cc"); \
+ ret; \
+ })
+# endif
+#endif /* PEDANTIC */
+
+#ifndef ROTATE
+#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
+#endif
+
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+
+#ifndef PEDANTIC
+# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM)
+# if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
+ /*
+ * This gives ~30-40% performance improvement in SHA-256 compiled
+ * with gcc [on P4]. Well, first macro to be frank. We can pull
+ * this trick on x86* platforms only, because these CPUs can fetch
+ * unaligned data without raising an exception.
+ */
+# define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \
+ asm ("bswapl %0":"=r"(r):"0"(r)); \
+ (c)+=4; (l)=r; })
+# define HOST_l2c(l,c) ({ unsigned int r=(l); \
+ asm ("bswapl %0":"=r"(r):"0"(r)); \
+ *((unsigned int *)(c))=r; (c)+=4; r; })
+# elif defined(__aarch64__)
+# if defined(__BYTE_ORDER__)
+# if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
+# define HOST_c2l(c,l) ({ unsigned int r; \
+ asm ("rev %w0,%w1" \
+ :"=r"(r) \
+ :"r"(*((const unsigned int *)(c))));\
+ (c)+=4; (l)=r; })
+# define HOST_l2c(l,c) ({ unsigned int r; \
+ asm ("rev %w0,%w1" \
+ :"=r"(r) \
+ :"r"((unsigned int)(l)));\
+ *((unsigned int *)(c))=r; (c)+=4; r; })
+# elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
+# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
+# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#ifndef HOST_c2l
+#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++))) ), \
+ l)
+#endif
+#ifndef HOST_l2c
+#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff), \
+ l)
+#endif
+
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+
+#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
+ /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
+# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l)
+# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l)
+#endif
+
+#ifndef HOST_c2l
+#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<<24), \
+ l)
+#endif
+#ifndef HOST_l2c
+#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ l)
+#endif
+
+#endif
+
+int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len)
+ {
+ const unsigned char *data=data_;
+ unsigned char *p;
+ HASH_LONG l;
+ size_t n;
+
+ if (len==0) return 1;
+
+ l=(c->Nl+(((HASH_LONG)len)<<3))&0xffffffffUL;
+ /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
+ * Wei Dai <weidai@eskimo.com> for pointing it out. */
+ if (l < c->Nl) /* overflow */
+ c->Nh++;
+ c->Nh+=(HASH_LONG)(len>>29); /* might cause compiler warning on 16-bit */
+ c->Nl=l;
+
+ n = c->num;
+ if (n != 0)
+ {
+ p=(unsigned char *)c->data;
+
+ if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK)
+ {
+ memcpy (p+n,data,HASH_CBLOCK-n);
+ HASH_BLOCK_DATA_ORDER (c,p,1);
+ n = HASH_CBLOCK-n;
+ data += n;
+ len -= n;
+ c->num = 0;
+ memset (p,0,HASH_CBLOCK); /* keep it zeroed */
+ }
+ else
+ {
+ memcpy (p+n,data,len);
+ c->num += (unsigned int)len;
+ return 1;
+ }
+ }
+
+ n = len/HASH_CBLOCK;
+ if (n > 0)
+ {
+ HASH_BLOCK_DATA_ORDER (c,data,n);
+ n *= HASH_CBLOCK;
+ data += n;
+ len -= n;
+ }
+
+ if (len != 0)
+ {
+ p = (unsigned char *)c->data;
+ c->num = (unsigned int)len;
+ memcpy (p,data,len);
+ }
+ return 1;
+ }
+
+
+void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
+ {
+ HASH_BLOCK_DATA_ORDER (c,data,1);
+ }
+
+
+int HASH_FINAL (unsigned char *md, HASH_CTX *c)
+ {
+ unsigned char *p = (unsigned char *)c->data;
+ size_t n = c->num;
+
+ p[n] = 0x80; /* there is always room for one */
+ n++;
+
+ if (n > (HASH_CBLOCK-8))
+ {
+ memset (p+n,0,HASH_CBLOCK-n);
+ n=0;
+ HASH_BLOCK_DATA_ORDER (c,p,1);
+ }
+ memset (p+n,0,HASH_CBLOCK-8-n);
+
+ p += HASH_CBLOCK-8;
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+ (void)HOST_l2c(c->Nh,p);
+ (void)HOST_l2c(c->Nl,p);
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+ (void)HOST_l2c(c->Nl,p);
+ (void)HOST_l2c(c->Nh,p);
+#endif
+ p -= HASH_CBLOCK;
+ HASH_BLOCK_DATA_ORDER (c,p,1);
+ c->num=0;
+ memset (p,0,HASH_CBLOCK);
+
+#ifndef HASH_MAKE_STRING
+#error "HASH_MAKE_STRING must be defined!"
+#else
+ HASH_MAKE_STRING(c,md);
+#endif
+
+ return 1;
+ }
+
+#ifndef MD32_REG_T
+#define MD32_REG_T int
+#endif
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_MD32_COMMON_H */