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 */