summaryrefslogtreecommitdiff
path: root/Cryptlib/OpenSSL/crypto/evp
diff options
context:
space:
mode:
Diffstat (limited to 'Cryptlib/OpenSSL/crypto/evp')
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/bio_b64.c573
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/bio_enc.c428
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/bio_md.c272
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/bio_ok.c624
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/c_all.c90
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/c_allc.c241
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/c_alld.c114
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/digest.c408
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_aes.c2024
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c1008
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c985
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_bf.c87
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_camellia.c394
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_cast.c89
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_des.c269
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_des3.c495
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_idea.c119
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_null.c100
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_old.c164
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_rc2.c235
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_rc4.c133
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_rc4_hmac_md5.c308
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_rc5.c122
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_seed.c82
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/e_xcbc_d.c130
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/encode.c460
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_acnf.c73
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_cnf.c118
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_enc.c666
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_err.c254
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_key.c197
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_lib.c391
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_locl.h373
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_pbe.c312
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/evp_pkey.c229
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_dss.c104
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_dss1.c105
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_ecdsa.c154
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_md2.c106
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_md4.c108
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_md5.c107
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_mdc2.c108
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_null.c98
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_ripemd.c107
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_sha.c106
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_sha1.c235
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_sigver.c203
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/m_wp.c48
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/names.c215
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p5_crpt.c149
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p5_crpt2.c334
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_dec.c87
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_enc.c87
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_lib.c456
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_open.c129
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_seal.c121
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_sign.c133
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/p_verify.c116
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/pmeth_fn.c346
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/pmeth_gn.c220
-rw-r--r--Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c613
61 files changed, 17162 insertions, 0 deletions
diff --git a/Cryptlib/OpenSSL/crypto/evp/bio_b64.c b/Cryptlib/OpenSSL/crypto/evp/bio_b64.c
new file mode 100644
index 00000000..538b5202
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/bio_b64.c
@@ -0,0 +1,573 @@
+/* crypto/evp/bio_b64.c */
+/* 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 <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+
+static int b64_write(BIO *h, const char *buf, int num);
+static int b64_read(BIO *h, char *buf, int size);
+static int b64_puts(BIO *h, const char *str);
+/*
+ * static int b64_gets(BIO *h, char *str, int size);
+ */
+static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int b64_new(BIO *h);
+static int b64_free(BIO *data);
+static long b64_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+#define B64_BLOCK_SIZE 1024
+#define B64_BLOCK_SIZE2 768
+#define B64_NONE 0
+#define B64_ENCODE 1
+#define B64_DECODE 2
+
+typedef struct b64_struct {
+ /*
+ * BIO *bio; moved to the BIO structure
+ */
+ int buf_len;
+ int buf_off;
+ int tmp_len; /* used to find the start when decoding */
+ int tmp_nl; /* If true, scan until '\n' */
+ int encode;
+ int start; /* have we started decoding yet? */
+ int cont; /* <= 0 when finished */
+ EVP_ENCODE_CTX base64;
+ char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10];
+ char tmp[B64_BLOCK_SIZE];
+} BIO_B64_CTX;
+
+static BIO_METHOD methods_b64 = {
+ BIO_TYPE_BASE64, "base64 encoding",
+ b64_write,
+ b64_read,
+ b64_puts,
+ NULL, /* b64_gets, */
+ b64_ctrl,
+ b64_new,
+ b64_free,
+ b64_callback_ctrl,
+};
+
+BIO_METHOD *BIO_f_base64(void)
+{
+ return (&methods_b64);
+}
+
+static int b64_new(BIO *bi)
+{
+ BIO_B64_CTX *ctx;
+
+ ctx = (BIO_B64_CTX *)OPENSSL_malloc(sizeof(BIO_B64_CTX));
+ if (ctx == NULL)
+ return (0);
+
+ ctx->buf_len = 0;
+ ctx->tmp_len = 0;
+ ctx->tmp_nl = 0;
+ ctx->buf_off = 0;
+ ctx->cont = 1;
+ ctx->start = 1;
+ ctx->encode = 0;
+
+ bi->init = 1;
+ bi->ptr = (char *)ctx;
+ bi->flags = 0;
+ bi->num = 0;
+ return (1);
+}
+
+static int b64_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ OPENSSL_free(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return (1);
+}
+
+static int b64_read(BIO *b, char *out, int outl)
+{
+ int ret = 0, i, ii, j, k, x, n, num, ret_code = 0;
+ BIO_B64_CTX *ctx;
+ unsigned char *p, *q;
+
+ if (out == NULL)
+ return (0);
+ ctx = (BIO_B64_CTX *)b->ptr;
+
+ if ((ctx == NULL) || (b->next_bio == NULL))
+ return (0);
+
+ BIO_clear_retry_flags(b);
+
+ if (ctx->encode != B64_DECODE) {
+ ctx->encode = B64_DECODE;
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->tmp_len = 0;
+ EVP_DecodeInit(&(ctx->base64));
+ }
+
+ /* First check if there are bytes decoded/encoded */
+ if (ctx->buf_len > 0) {
+ OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+ i = ctx->buf_len - ctx->buf_off;
+ if (i > outl)
+ i = outl;
+ OPENSSL_assert(ctx->buf_off + i < (int)sizeof(ctx->buf));
+ memcpy(out, &(ctx->buf[ctx->buf_off]), i);
+ ret = i;
+ out += i;
+ outl -= i;
+ ctx->buf_off += i;
+ if (ctx->buf_len == ctx->buf_off) {
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ }
+
+ /*
+ * At this point, we have room of outl bytes and an empty buffer, so we
+ * should read in some more.
+ */
+
+ ret_code = 0;
+ while (outl > 0) {
+ if (ctx->cont <= 0)
+ break;
+
+ i = BIO_read(b->next_bio, &(ctx->tmp[ctx->tmp_len]),
+ B64_BLOCK_SIZE - ctx->tmp_len);
+
+ if (i <= 0) {
+ ret_code = i;
+
+ /* Should we continue next time we are called? */
+ if (!BIO_should_retry(b->next_bio)) {
+ ctx->cont = i;
+ /* If buffer empty break */
+ if (ctx->tmp_len == 0)
+ break;
+ /* Fall through and process what we have */
+ else
+ i = 0;
+ }
+ /* else we retry and add more data to buffer */
+ else
+ break;
+ }
+ i += ctx->tmp_len;
+ ctx->tmp_len = i;
+
+ /*
+ * We need to scan, a line at a time until we have a valid line if we
+ * are starting.
+ */
+ if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) {
+ /* ctx->start=1; */
+ ctx->tmp_len = 0;
+ } else if (ctx->start) {
+ q = p = (unsigned char *)ctx->tmp;
+ num = 0;
+ for (j = 0; j < i; j++) {
+ if (*(q++) != '\n')
+ continue;
+
+ /*
+ * due to a previous very long line, we need to keep on
+ * scanning for a '\n' before we even start looking for
+ * base64 encoded stuff.
+ */
+ if (ctx->tmp_nl) {
+ p = q;
+ ctx->tmp_nl = 0;
+ continue;
+ }
+
+ k = EVP_DecodeUpdate(&(ctx->base64),
+ (unsigned char *)ctx->buf,
+ &num, p, q - p);
+ if ((k <= 0) && (num == 0) && (ctx->start))
+ EVP_DecodeInit(&ctx->base64);
+ else {
+ if (p != (unsigned char *)
+ &(ctx->tmp[0])) {
+ i -= (p - (unsigned char *)
+ &(ctx->tmp[0]));
+ for (x = 0; x < i; x++)
+ ctx->tmp[x] = p[x];
+ }
+ EVP_DecodeInit(&ctx->base64);
+ ctx->start = 0;
+ break;
+ }
+ p = q;
+ }
+
+ /* we fell off the end without starting */
+ if ((j == i) && (num == 0)) {
+ /*
+ * Is this is one long chunk?, if so, keep on reading until a
+ * new line.
+ */
+ if (p == (unsigned char *)&(ctx->tmp[0])) {
+ /* Check buffer full */
+ if (i == B64_BLOCK_SIZE) {
+ ctx->tmp_nl = 1;
+ ctx->tmp_len = 0;
+ }
+ } else if (p != q) { /* finished on a '\n' */
+ n = q - p;
+ for (ii = 0; ii < n; ii++)
+ ctx->tmp[ii] = p[ii];
+ ctx->tmp_len = n;
+ }
+ /* else finished on a '\n' */
+ continue;
+ } else {
+ ctx->tmp_len = 0;
+ }
+ } else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) {
+ /*
+ * If buffer isn't full and we can retry then restart to read in
+ * more data.
+ */
+ continue;
+ }
+
+ if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
+ int z, jj;
+
+#if 0
+ jj = (i >> 2) << 2;
+#else
+ jj = i & ~3; /* process per 4 */
+#endif
+ z = EVP_DecodeBlock((unsigned char *)ctx->buf,
+ (unsigned char *)ctx->tmp, jj);
+ if (jj > 2) {
+ if (ctx->tmp[jj - 1] == '=') {
+ z--;
+ if (ctx->tmp[jj - 2] == '=')
+ z--;
+ }
+ }
+ /*
+ * z is now number of output bytes and jj is the number consumed
+ */
+ if (jj != i) {
+ memmove(ctx->tmp, &ctx->tmp[jj], i - jj);
+ ctx->tmp_len = i - jj;
+ }
+ ctx->buf_len = 0;
+ if (z > 0) {
+ ctx->buf_len = z;
+ }
+ i = z;
+ } else {
+ i = EVP_DecodeUpdate(&(ctx->base64),
+ (unsigned char *)ctx->buf, &ctx->buf_len,
+ (unsigned char *)ctx->tmp, i);
+ ctx->tmp_len = 0;
+ }
+ ctx->buf_off = 0;
+ if (i < 0) {
+ ret_code = 0;
+ ctx->buf_len = 0;
+ break;
+ }
+
+ if (ctx->buf_len <= outl)
+ i = ctx->buf_len;
+ else
+ i = outl;
+
+ memcpy(out, ctx->buf, i);
+ ret += i;
+ ctx->buf_off = i;
+ if (ctx->buf_off == ctx->buf_len) {
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ outl -= i;
+ out += i;
+ }
+ /* BIO_clear_retry_flags(b); */
+ BIO_copy_next_retry(b);
+ return ((ret == 0) ? ret_code : ret);
+}
+
+static int b64_write(BIO *b, const char *in, int inl)
+{
+ int ret = 0;
+ int n;
+ int i;
+ BIO_B64_CTX *ctx;
+
+ ctx = (BIO_B64_CTX *)b->ptr;
+ BIO_clear_retry_flags(b);
+
+ if (ctx->encode != B64_ENCODE) {
+ ctx->encode = B64_ENCODE;
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->tmp_len = 0;
+ EVP_EncodeInit(&(ctx->base64));
+ }
+
+ OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf));
+ OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+ OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+ n = ctx->buf_len - ctx->buf_off;
+ while (n > 0) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ return (i);
+ }
+ OPENSSL_assert(i <= n);
+ ctx->buf_off += i;
+ OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
+ OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+ n -= i;
+ }
+ /* at this point all pending data has been written */
+ ctx->buf_off = 0;
+ ctx->buf_len = 0;
+
+ if ((in == NULL) || (inl <= 0))
+ return (0);
+
+ while (inl > 0) {
+ n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl;
+
+ if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
+ if (ctx->tmp_len > 0) {
+ OPENSSL_assert(ctx->tmp_len <= 3);
+ n = 3 - ctx->tmp_len;
+ /*
+ * There's a theoretical possibility for this
+ */
+ if (n > inl)
+ n = inl;
+ memcpy(&(ctx->tmp[ctx->tmp_len]), in, n);
+ ctx->tmp_len += n;
+ ret += n;
+ if (ctx->tmp_len < 3)
+ break;
+ ctx->buf_len =
+ EVP_EncodeBlock((unsigned char *)ctx->buf,
+ (unsigned char *)ctx->tmp, ctx->tmp_len);
+ OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+ OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+ /*
+ * Since we're now done using the temporary buffer, the
+ * length should be 0'd
+ */
+ ctx->tmp_len = 0;
+ } else {
+ if (n < 3) {
+ memcpy(ctx->tmp, in, n);
+ ctx->tmp_len = n;
+ ret += n;
+ break;
+ }
+ n -= n % 3;
+ ctx->buf_len =
+ EVP_EncodeBlock((unsigned char *)ctx->buf,
+ (const unsigned char *)in, n);
+ OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+ OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+ ret += n;
+ }
+ } else {
+ EVP_EncodeUpdate(&(ctx->base64),
+ (unsigned char *)ctx->buf, &ctx->buf_len,
+ (unsigned char *)in, n);
+ OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+ OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+ ret += n;
+ }
+ inl -= n;
+ in += n;
+
+ ctx->buf_off = 0;
+ n = ctx->buf_len;
+ while (n > 0) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ return ((ret == 0) ? i : ret);
+ }
+ OPENSSL_assert(i <= n);
+ n -= i;
+ ctx->buf_off += i;
+ OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
+ OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+ }
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ return (ret);
+}
+
+static long b64_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO_B64_CTX *ctx;
+ long ret = 1;
+ int i;
+
+ ctx = (BIO_B64_CTX *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ctx->cont = 1;
+ ctx->start = 1;
+ ctx->encode = B64_NONE;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_EOF: /* More to read */
+ if (ctx->cont <= 0)
+ ret = 1;
+ else
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_WPENDING: /* More to write in buffer */
+ OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+ ret = ctx->buf_len - ctx->buf_off;
+ if ((ret == 0) && (ctx->encode != B64_NONE)
+ && (ctx->base64.num != 0))
+ ret = 1;
+ else if (ret <= 0)
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_PENDING: /* More to read in buffer */
+ OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+ ret = ctx->buf_len - ctx->buf_off;
+ if (ret <= 0)
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_FLUSH:
+ /* do a final write */
+ again:
+ while (ctx->buf_len != ctx->buf_off) {
+ i = b64_write(b, NULL, 0);
+ if (i < 0)
+ return i;
+ }
+ if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
+ if (ctx->tmp_len != 0) {
+ ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf,
+ (unsigned char *)ctx->tmp,
+ ctx->tmp_len);
+ ctx->buf_off = 0;
+ ctx->tmp_len = 0;
+ goto again;
+ }
+ } else if (ctx->encode != B64_NONE && ctx->base64.num != 0) {
+ ctx->buf_off = 0;
+ EVP_EncodeFinal(&(ctx->base64),
+ (unsigned char *)ctx->buf, &(ctx->buf_len));
+ /* push out the bytes */
+ goto again;
+ }
+ /* Finally flush the underlying BIO */
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+
+ case BIO_CTRL_DUP:
+ break;
+ case BIO_CTRL_INFO:
+ case BIO_CTRL_GET:
+ case BIO_CTRL_SET:
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return (ret);
+}
+
+static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return (0);
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return (ret);
+}
+
+static int b64_puts(BIO *b, const char *str)
+{
+ return b64_write(b, str, strlen(str));
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/bio_enc.c b/Cryptlib/OpenSSL/crypto/evp/bio_enc.c
new file mode 100644
index 00000000..363e0246
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/bio_enc.c
@@ -0,0 +1,428 @@
+/* crypto/evp/bio_enc.c */
+/* 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 <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+
+static int enc_write(BIO *h, const char *buf, int num);
+static int enc_read(BIO *h, char *buf, int size);
+/*
+ * static int enc_puts(BIO *h, const char *str);
+ */
+/*
+ * static int enc_gets(BIO *h, char *str, int size);
+ */
+static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int enc_new(BIO *h);
+static int enc_free(BIO *data);
+static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
+#define ENC_BLOCK_SIZE (1024*4)
+#define BUF_OFFSET (EVP_MAX_BLOCK_LENGTH*2)
+
+typedef struct enc_struct {
+ int buf_len;
+ int buf_off;
+ int cont; /* <= 0 when finished */
+ int finished;
+ int ok; /* bad decrypt */
+ EVP_CIPHER_CTX cipher;
+ /*
+ * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return
+ * up to a block more data than is presented to it
+ */
+ char buf[ENC_BLOCK_SIZE + BUF_OFFSET + 2];
+} BIO_ENC_CTX;
+
+static BIO_METHOD methods_enc = {
+ BIO_TYPE_CIPHER, "cipher",
+ enc_write,
+ enc_read,
+ NULL, /* enc_puts, */
+ NULL, /* enc_gets, */
+ enc_ctrl,
+ enc_new,
+ enc_free,
+ enc_callback_ctrl,
+};
+
+BIO_METHOD *BIO_f_cipher(void)
+{
+ return (&methods_enc);
+}
+
+static int enc_new(BIO *bi)
+{
+ BIO_ENC_CTX *ctx;
+
+ ctx = (BIO_ENC_CTX *)OPENSSL_malloc(sizeof(BIO_ENC_CTX));
+ if (ctx == NULL)
+ return (0);
+ EVP_CIPHER_CTX_init(&ctx->cipher);
+
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->cont = 1;
+ ctx->finished = 0;
+ ctx->ok = 1;
+
+ bi->init = 0;
+ bi->ptr = (char *)ctx;
+ bi->flags = 0;
+ return (1);
+}
+
+static int enc_free(BIO *a)
+{
+ BIO_ENC_CTX *b;
+
+ if (a == NULL)
+ return (0);
+ b = (BIO_ENC_CTX *)a->ptr;
+ EVP_CIPHER_CTX_cleanup(&(b->cipher));
+ OPENSSL_cleanse(a->ptr, sizeof(BIO_ENC_CTX));
+ OPENSSL_free(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return (1);
+}
+
+static int enc_read(BIO *b, char *out, int outl)
+{
+ int ret = 0, i;
+ BIO_ENC_CTX *ctx;
+
+ if (out == NULL)
+ return (0);
+ ctx = (BIO_ENC_CTX *)b->ptr;
+
+ if ((ctx == NULL) || (b->next_bio == NULL))
+ return (0);
+
+ /* First check if there are bytes decoded/encoded */
+ if (ctx->buf_len > 0) {
+ i = ctx->buf_len - ctx->buf_off;
+ if (i > outl)
+ i = outl;
+ memcpy(out, &(ctx->buf[ctx->buf_off]), i);
+ ret = i;
+ out += i;
+ outl -= i;
+ ctx->buf_off += i;
+ if (ctx->buf_len == ctx->buf_off) {
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ }
+
+ /*
+ * At this point, we have room of outl bytes and an empty buffer, so we
+ * should read in some more.
+ */
+
+ while (outl > 0) {
+ if (ctx->cont <= 0)
+ break;
+
+ /*
+ * read in at IV offset, read the EVP_Cipher documentation about why
+ */
+ i = BIO_read(b->next_bio, &(ctx->buf[BUF_OFFSET]), ENC_BLOCK_SIZE);
+
+ if (i <= 0) {
+ /* Should be continue next time we are called? */
+ if (!BIO_should_retry(b->next_bio)) {
+ ctx->cont = i;
+ i = EVP_CipherFinal_ex(&(ctx->cipher),
+ (unsigned char *)ctx->buf,
+ &(ctx->buf_len));
+ ctx->ok = i;
+ ctx->buf_off = 0;
+ } else {
+ ret = (ret == 0) ? i : ret;
+ break;
+ }
+ } else {
+ EVP_CipherUpdate(&(ctx->cipher),
+ (unsigned char *)ctx->buf, &ctx->buf_len,
+ (unsigned char *)&(ctx->buf[BUF_OFFSET]), i);
+ ctx->cont = 1;
+ /*
+ * Note: it is possible for EVP_CipherUpdate to decrypt zero
+ * bytes because this is or looks like the final block: if this
+ * happens we should retry and either read more data or decrypt
+ * the final block
+ */
+ if (ctx->buf_len == 0)
+ continue;
+ }
+
+ if (ctx->buf_len <= outl)
+ i = ctx->buf_len;
+ else
+ i = outl;
+ if (i <= 0)
+ break;
+ memcpy(out, ctx->buf, i);
+ ret += i;
+ ctx->buf_off = i;
+ outl -= i;
+ out += i;
+ }
+
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return ((ret == 0) ? ctx->cont : ret);
+}
+
+static int enc_write(BIO *b, const char *in, int inl)
+{
+ int ret = 0, n, i;
+ BIO_ENC_CTX *ctx;
+
+ ctx = (BIO_ENC_CTX *)b->ptr;
+ ret = inl;
+
+ BIO_clear_retry_flags(b);
+ n = ctx->buf_len - ctx->buf_off;
+ while (n > 0) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ return (i);
+ }
+ ctx->buf_off += i;
+ n -= i;
+ }
+ /* at this point all pending data has been written */
+
+ if ((in == NULL) || (inl <= 0))
+ return (0);
+
+ ctx->buf_off = 0;
+ while (inl > 0) {
+ n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl;
+ EVP_CipherUpdate(&(ctx->cipher),
+ (unsigned char *)ctx->buf, &ctx->buf_len,
+ (unsigned char *)in, n);
+ inl -= n;
+ in += n;
+
+ ctx->buf_off = 0;
+ n = ctx->buf_len;
+ while (n > 0) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ return (ret == inl) ? i : ret - inl;
+ }
+ n -= i;
+ ctx->buf_off += i;
+ }
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ BIO_copy_next_retry(b);
+ return (ret);
+}
+
+static long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO *dbio;
+ BIO_ENC_CTX *ctx, *dctx;
+ long ret = 1;
+ int i;
+ EVP_CIPHER_CTX **c_ctx;
+
+ ctx = (BIO_ENC_CTX *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ctx->ok = 1;
+ ctx->finished = 0;
+ EVP_CipherInit_ex(&(ctx->cipher), NULL, NULL, NULL, NULL,
+ ctx->cipher.encrypt);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_EOF: /* More to read */
+ if (ctx->cont <= 0)
+ ret = 1;
+ else
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_WPENDING:
+ ret = ctx->buf_len - ctx->buf_off;
+ if (ret <= 0)
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_PENDING: /* More to read in buffer */
+ ret = ctx->buf_len - ctx->buf_off;
+ if (ret <= 0)
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_FLUSH:
+ /* do a final write */
+ again:
+ while (ctx->buf_len != ctx->buf_off) {
+ i = enc_write(b, NULL, 0);
+ if (i < 0)
+ return i;
+ }
+
+ if (!ctx->finished) {
+ ctx->finished = 1;
+ ctx->buf_off = 0;
+ ret = EVP_CipherFinal_ex(&(ctx->cipher),
+ (unsigned char *)ctx->buf,
+ &(ctx->buf_len));
+ ctx->ok = (int)ret;
+ if (ret <= 0)
+ break;
+
+ /* push out the bytes */
+ goto again;
+ }
+
+ /* Finally flush the underlying BIO */
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_C_GET_CIPHER_STATUS:
+ ret = (long)ctx->ok;
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+ case BIO_C_GET_CIPHER_CTX:
+ c_ctx = (EVP_CIPHER_CTX **)ptr;
+ (*c_ctx) = &(ctx->cipher);
+ b->init = 1;
+ break;
+ case BIO_CTRL_DUP:
+ dbio = (BIO *)ptr;
+ dctx = (BIO_ENC_CTX *)dbio->ptr;
+ EVP_CIPHER_CTX_init(&dctx->cipher);
+ ret = EVP_CIPHER_CTX_copy(&dctx->cipher, &ctx->cipher);
+ if (ret)
+ dbio->init = 1;
+ break;
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return (ret);
+}
+
+static long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return (0);
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return (ret);
+}
+
+/*-
+void BIO_set_cipher_ctx(b,c)
+BIO *b;
+EVP_CIPHER_ctx *c;
+ {
+ if (b == NULL) return;
+
+ if ((b->callback != NULL) &&
+ (b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
+ return;
+
+ b->init=1;
+ ctx=(BIO_ENC_CTX *)b->ptr;
+ memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
+
+ if (b->callback != NULL)
+ b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
+ }
+*/
+
+void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
+ const unsigned char *i, int e)
+{
+ BIO_ENC_CTX *ctx;
+
+ if (b == NULL)
+ return;
+
+ if ((b->callback != NULL) &&
+ (b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 0L) <=
+ 0))
+ return;
+
+ b->init = 1;
+ ctx = (BIO_ENC_CTX *)b->ptr;
+ EVP_CipherInit_ex(&(ctx->cipher), c, NULL, k, i, e);
+
+ if (b->callback != NULL)
+ b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/bio_md.c b/Cryptlib/OpenSSL/crypto/evp/bio_md.c
new file mode 100644
index 00000000..f0b0c0c0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/bio_md.c
@@ -0,0 +1,272 @@
+/* crypto/evp/bio_md.c */
+/* 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 <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+
+/*
+ * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
+ */
+
+static int md_write(BIO *h, char const *buf, int num);
+static int md_read(BIO *h, char *buf, int size);
+/*
+ * static int md_puts(BIO *h, const char *str);
+ */
+static int md_gets(BIO *h, char *str, int size);
+static long md_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int md_new(BIO *h);
+static int md_free(BIO *data);
+static long md_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static BIO_METHOD methods_md = {
+ BIO_TYPE_MD, "message digest",
+ md_write,
+ md_read,
+ NULL, /* md_puts, */
+ md_gets,
+ md_ctrl,
+ md_new,
+ md_free,
+ md_callback_ctrl,
+};
+
+BIO_METHOD *BIO_f_md(void)
+{
+ return (&methods_md);
+}
+
+static int md_new(BIO *bi)
+{
+ EVP_MD_CTX *ctx;
+
+ ctx = EVP_MD_CTX_create();
+ if (ctx == NULL)
+ return (0);
+
+ bi->init = 0;
+ bi->ptr = (char *)ctx;
+ bi->flags = 0;
+ return (1);
+}
+
+static int md_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ EVP_MD_CTX_destroy(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return (1);
+}
+
+static int md_read(BIO *b, char *out, int outl)
+{
+ int ret = 0;
+ EVP_MD_CTX *ctx;
+
+ if (out == NULL)
+ return (0);
+ ctx = b->ptr;
+
+ if ((ctx == NULL) || (b->next_bio == NULL))
+ return (0);
+
+ ret = BIO_read(b->next_bio, out, outl);
+ if (b->init) {
+ if (ret > 0) {
+ if (EVP_DigestUpdate(ctx, (unsigned char *)out,
+ (unsigned int)ret) <= 0)
+ return (-1);
+ }
+ }
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return (ret);
+}
+
+static int md_write(BIO *b, const char *in, int inl)
+{
+ int ret = 0;
+ EVP_MD_CTX *ctx;
+
+ if ((in == NULL) || (inl <= 0))
+ return (0);
+ ctx = b->ptr;
+
+ if ((ctx != NULL) && (b->next_bio != NULL))
+ ret = BIO_write(b->next_bio, in, inl);
+ if (b->init) {
+ if (ret > 0) {
+ if (!EVP_DigestUpdate(ctx, (const unsigned char *)in,
+ (unsigned int)ret)) {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ }
+ }
+ if (b->next_bio != NULL) {
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ }
+ return (ret);
+}
+
+static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ EVP_MD_CTX *ctx, *dctx, **pctx;
+ const EVP_MD **ppmd;
+ EVP_MD *md;
+ long ret = 1;
+ BIO *dbio;
+
+ ctx = b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ if (b->init)
+ ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL);
+ else
+ ret = 0;
+ if (ret > 0)
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_C_GET_MD:
+ if (b->init) {
+ ppmd = ptr;
+ *ppmd = ctx->digest;
+ } else
+ ret = 0;
+ break;
+ case BIO_C_GET_MD_CTX:
+ pctx = ptr;
+ *pctx = ctx;
+ b->init = 1;
+ break;
+ case BIO_C_SET_MD_CTX:
+ if (b->init)
+ b->ptr = ptr;
+ else
+ ret = 0;
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+
+ case BIO_C_SET_MD:
+ md = ptr;
+ ret = EVP_DigestInit_ex(ctx, md, NULL);
+ if (ret > 0)
+ b->init = 1;
+ break;
+ case BIO_CTRL_DUP:
+ dbio = ptr;
+ dctx = dbio->ptr;
+ if (!EVP_MD_CTX_copy_ex(dctx, ctx))
+ return 0;
+ b->init = 1;
+ break;
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return (ret);
+}
+
+static long md_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return (0);
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return (ret);
+}
+
+static int md_gets(BIO *bp, char *buf, int size)
+{
+ EVP_MD_CTX *ctx;
+ unsigned int ret;
+
+ ctx = bp->ptr;
+ if (size < ctx->digest->md_size)
+ return (0);
+ if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0)
+ return -1;
+
+ return ((int)ret);
+}
+
+/*-
+static int md_puts(bp,str)
+BIO *bp;
+char *str;
+ {
+ return(-1);
+ }
+*/
diff --git a/Cryptlib/OpenSSL/crypto/evp/bio_ok.c b/Cryptlib/OpenSSL/crypto/evp/bio_ok.c
new file mode 100644
index 00000000..5c32e35e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/bio_ok.c
@@ -0,0 +1,624 @@
+/* crypto/evp/bio_ok.c */
+/* 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.]
+ */
+
+/*-
+ From: Arne Ansper <arne@cyber.ee>
+
+ Why BIO_f_reliable?
+
+ I wrote function which took BIO* as argument, read data from it
+ and processed it. Then I wanted to store the input file in
+ encrypted form. OK I pushed BIO_f_cipher to the BIO stack
+ and everything was OK. BUT if user types wrong password
+ BIO_f_cipher outputs only garbage and my function crashes. Yes
+ I can and I should fix my function, but BIO_f_cipher is
+ easy way to add encryption support to many existing applications
+ and it's hard to debug and fix them all.
+
+ So I wanted another BIO which would catch the incorrect passwords and
+ file damages which cause garbage on BIO_f_cipher's output.
+
+ The easy way is to push the BIO_f_md and save the checksum at
+ the end of the file. However there are several problems with this
+ approach:
+
+ 1) you must somehow separate checksum from actual data.
+ 2) you need lot's of memory when reading the file, because you
+ must read to the end of the file and verify the checksum before
+ letting the application to read the data.
+
+ BIO_f_reliable tries to solve both problems, so that you can
+ read and write arbitrary long streams using only fixed amount
+ of memory.
+
+ BIO_f_reliable splits data stream into blocks. Each block is prefixed
+ with it's length and suffixed with it's digest. So you need only
+ several Kbytes of memory to buffer single block before verifying
+ it's digest.
+
+ BIO_f_reliable goes further and adds several important capabilities:
+
+ 1) the digest of the block is computed over the whole stream
+ -- so nobody can rearrange the blocks or remove or replace them.
+
+ 2) to detect invalid passwords right at the start BIO_f_reliable
+ adds special prefix to the stream. In order to avoid known plain-text
+ attacks this prefix is generated as follows:
+
+ *) digest is initialized with random seed instead of
+ standardized one.
+ *) same seed is written to output
+ *) well-known text is then hashed and the output
+ of the digest is also written to output.
+
+ reader can now read the seed from stream, hash the same string
+ and then compare the digest output.
+
+ Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I
+ initially wrote and tested this code on x86 machine and wrote the
+ digests out in machine-dependent order :( There are people using
+ this code and I cannot change this easily without making existing
+ data files unreadable.
+
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+
+static int ok_write(BIO *h, const char *buf, int num);
+static int ok_read(BIO *h, char *buf, int size);
+static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int ok_new(BIO *h);
+static int ok_free(BIO *data);
+static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static int sig_out(BIO *b);
+static int sig_in(BIO *b);
+static int block_out(BIO *b);
+static int block_in(BIO *b);
+#define OK_BLOCK_SIZE (1024*4)
+#define OK_BLOCK_BLOCK 4
+#define IOBS (OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE)
+#define WELLKNOWN "The quick brown fox jumped over the lazy dog's back."
+
+typedef struct ok_struct {
+ size_t buf_len;
+ size_t buf_off;
+ size_t buf_len_save;
+ size_t buf_off_save;
+ int cont; /* <= 0 when finished */
+ int finished;
+ EVP_MD_CTX md;
+ int blockout; /* output block is ready */
+ int sigio; /* must process signature */
+ unsigned char buf[IOBS];
+} BIO_OK_CTX;
+
+static BIO_METHOD methods_ok = {
+ BIO_TYPE_CIPHER, "reliable",
+ ok_write,
+ ok_read,
+ NULL, /* ok_puts, */
+ NULL, /* ok_gets, */
+ ok_ctrl,
+ ok_new,
+ ok_free,
+ ok_callback_ctrl,
+};
+
+BIO_METHOD *BIO_f_reliable(void)
+{
+ return (&methods_ok);
+}
+
+static int ok_new(BIO *bi)
+{
+ BIO_OK_CTX *ctx;
+
+ ctx = (BIO_OK_CTX *)OPENSSL_malloc(sizeof(BIO_OK_CTX));
+ if (ctx == NULL)
+ return (0);
+
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->buf_len_save = 0;
+ ctx->buf_off_save = 0;
+ ctx->cont = 1;
+ ctx->finished = 0;
+ ctx->blockout = 0;
+ ctx->sigio = 1;
+
+ EVP_MD_CTX_init(&ctx->md);
+
+ bi->init = 0;
+ bi->ptr = (char *)ctx;
+ bi->flags = 0;
+ return (1);
+}
+
+static int ok_free(BIO *a)
+{
+ if (a == NULL)
+ return (0);
+ EVP_MD_CTX_cleanup(&((BIO_OK_CTX *)a->ptr)->md);
+ OPENSSL_cleanse(a->ptr, sizeof(BIO_OK_CTX));
+ OPENSSL_free(a->ptr);
+ a->ptr = NULL;
+ a->init = 0;
+ a->flags = 0;
+ return (1);
+}
+
+static int ok_read(BIO *b, char *out, int outl)
+{
+ int ret = 0, i, n;
+ BIO_OK_CTX *ctx;
+
+ if (out == NULL)
+ return (0);
+ ctx = (BIO_OK_CTX *)b->ptr;
+
+ if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0))
+ return (0);
+
+ while (outl > 0) {
+
+ /* copy clean bytes to output buffer */
+ if (ctx->blockout) {
+ i = ctx->buf_len - ctx->buf_off;
+ if (i > outl)
+ i = outl;
+ memcpy(out, &(ctx->buf[ctx->buf_off]), i);
+ ret += i;
+ out += i;
+ outl -= i;
+ ctx->buf_off += i;
+
+ /* all clean bytes are out */
+ if (ctx->buf_len == ctx->buf_off) {
+ ctx->buf_off = 0;
+
+ /*
+ * copy start of the next block into proper place
+ */
+ if (ctx->buf_len_save - ctx->buf_off_save > 0) {
+ ctx->buf_len = ctx->buf_len_save - ctx->buf_off_save;
+ memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]),
+ ctx->buf_len);
+ } else {
+ ctx->buf_len = 0;
+ }
+ ctx->blockout = 0;
+ }
+ }
+
+ /* output buffer full -- cancel */
+ if (outl == 0)
+ break;
+
+ /* no clean bytes in buffer -- fill it */
+ n = IOBS - ctx->buf_len;
+ i = BIO_read(b->next_bio, &(ctx->buf[ctx->buf_len]), n);
+
+ if (i <= 0)
+ break; /* nothing new */
+
+ ctx->buf_len += i;
+
+ /* no signature yet -- check if we got one */
+ if (ctx->sigio == 1) {
+ if (!sig_in(b)) {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ }
+
+ /* signature ok -- check if we got block */
+ if (ctx->sigio == 0) {
+ if (!block_in(b)) {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ }
+
+ /* invalid block -- cancel */
+ if (ctx->cont <= 0)
+ break;
+
+ }
+
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return (ret);
+}
+
+static int ok_write(BIO *b, const char *in, int inl)
+{
+ int ret = 0, n, i;
+ BIO_OK_CTX *ctx;
+
+ if (inl <= 0)
+ return inl;
+
+ ctx = (BIO_OK_CTX *)b->ptr;
+ ret = inl;
+
+ if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0))
+ return (0);
+
+ if (ctx->sigio && !sig_out(b))
+ return 0;
+
+ do {
+ BIO_clear_retry_flags(b);
+ n = ctx->buf_len - ctx->buf_off;
+ while (ctx->blockout && n > 0) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ if (!BIO_should_retry(b))
+ ctx->cont = 0;
+ return (i);
+ }
+ ctx->buf_off += i;
+ n -= i;
+ }
+
+ /* at this point all pending data has been written */
+ ctx->blockout = 0;
+ if (ctx->buf_len == ctx->buf_off) {
+ ctx->buf_len = OK_BLOCK_BLOCK;
+ ctx->buf_off = 0;
+ }
+
+ if ((in == NULL) || (inl <= 0))
+ return (0);
+
+ n = (inl + ctx->buf_len > OK_BLOCK_SIZE + OK_BLOCK_BLOCK) ?
+ (int)(OK_BLOCK_SIZE + OK_BLOCK_BLOCK - ctx->buf_len) : inl;
+
+ memcpy((unsigned char *)(&(ctx->buf[ctx->buf_len])),
+ (unsigned char *)in, n);
+ ctx->buf_len += n;
+ inl -= n;
+ in += n;
+
+ if (ctx->buf_len >= OK_BLOCK_SIZE + OK_BLOCK_BLOCK) {
+ if (!block_out(b)) {
+ BIO_clear_retry_flags(b);
+ return 0;
+ }
+ }
+ } while (inl > 0);
+
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return (ret);
+}
+
+static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO_OK_CTX *ctx;
+ EVP_MD *md;
+ const EVP_MD **ppmd;
+ long ret = 1;
+ int i;
+
+ ctx = b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->buf_len_save = 0;
+ ctx->buf_off_save = 0;
+ ctx->cont = 1;
+ ctx->finished = 0;
+ ctx->blockout = 0;
+ ctx->sigio = 1;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_EOF: /* More to read */
+ if (ctx->cont <= 0)
+ ret = 1;
+ else
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_PENDING: /* More to read in buffer */
+ case BIO_CTRL_WPENDING: /* More to read in buffer */
+ ret = ctx->blockout ? ctx->buf_len - ctx->buf_off : 0;
+ if (ret <= 0)
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_FLUSH:
+ /* do a final write */
+ if (ctx->blockout == 0)
+ if (!block_out(b))
+ return 0;
+
+ while (ctx->blockout) {
+ i = ok_write(b, NULL, 0);
+ if (i < 0) {
+ ret = i;
+ break;
+ }
+ }
+
+ ctx->finished = 1;
+ ctx->buf_off = ctx->buf_len = 0;
+ ctx->cont = (int)ret;
+
+ /* Finally flush the underlying BIO */
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+ case BIO_CTRL_INFO:
+ ret = (long)ctx->cont;
+ break;
+ case BIO_C_SET_MD:
+ md = ptr;
+ if (!EVP_DigestInit_ex(&ctx->md, md, NULL))
+ return 0;
+ b->init = 1;
+ break;
+ case BIO_C_GET_MD:
+ if (b->init) {
+ ppmd = ptr;
+ *ppmd = ctx->md.digest;
+ } else
+ ret = 0;
+ break;
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return (ret);
+}
+
+static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ long ret = 1;
+
+ if (b->next_bio == NULL)
+ return (0);
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return (ret);
+}
+
+static void longswap(void *_ptr, size_t len)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+
+ if (is_endian.little) {
+ size_t i;
+ unsigned char *p = _ptr, c;
+
+ for (i = 0; i < len; i += 4) {
+ c = p[0], p[0] = p[3], p[3] = c;
+ c = p[1], p[1] = p[2], p[2] = c;
+ }
+ }
+}
+
+static int sig_out(BIO *b)
+{
+ BIO_OK_CTX *ctx;
+ EVP_MD_CTX *md;
+
+ ctx = b->ptr;
+ md = &ctx->md;
+
+ if (ctx->buf_len + 2 * md->digest->md_size > OK_BLOCK_SIZE)
+ return 1;
+
+ if (!EVP_DigestInit_ex(md, md->digest, NULL))
+ goto berr;
+ /*
+ * FIXME: there's absolutely no guarantee this makes any sense at all,
+ * particularly now EVP_MD_CTX has been restructured.
+ */
+ if (RAND_pseudo_bytes(md->md_data, md->digest->md_size) < 0)
+ goto berr;
+ memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size);
+ longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
+ ctx->buf_len += md->digest->md_size;
+
+ if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
+ goto berr;
+ ctx->buf_len += md->digest->md_size;
+ ctx->blockout = 1;
+ ctx->sigio = 0;
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
+}
+
+static int sig_in(BIO *b)
+{
+ BIO_OK_CTX *ctx;
+ EVP_MD_CTX *md;
+ unsigned char tmp[EVP_MAX_MD_SIZE];
+ int ret = 0;
+
+ ctx = b->ptr;
+ md = &ctx->md;
+
+ if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md->digest->md_size)
+ return 1;
+
+ if (!EVP_DigestInit_ex(md, md->digest, NULL))
+ goto berr;
+ memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size);
+ longswap(md->md_data, md->digest->md_size);
+ ctx->buf_off += md->digest->md_size;
+
+ if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, tmp, NULL))
+ goto berr;
+ ret = memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0;
+ ctx->buf_off += md->digest->md_size;
+ if (ret == 1) {
+ ctx->sigio = 0;
+ if (ctx->buf_len != ctx->buf_off) {
+ memmove(ctx->buf, &(ctx->buf[ctx->buf_off]),
+ ctx->buf_len - ctx->buf_off);
+ }
+ ctx->buf_len -= ctx->buf_off;
+ ctx->buf_off = 0;
+ } else {
+ ctx->cont = 0;
+ }
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
+}
+
+static int block_out(BIO *b)
+{
+ BIO_OK_CTX *ctx;
+ EVP_MD_CTX *md;
+ unsigned long tl;
+
+ ctx = b->ptr;
+ md = &ctx->md;
+
+ tl = ctx->buf_len - OK_BLOCK_BLOCK;
+ ctx->buf[0] = (unsigned char)(tl >> 24);
+ ctx->buf[1] = (unsigned char)(tl >> 16);
+ ctx->buf[2] = (unsigned char)(tl >> 8);
+ ctx->buf[3] = (unsigned char)(tl);
+ if (!EVP_DigestUpdate(md,
+ (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
+ goto berr;
+ ctx->buf_len += md->digest->md_size;
+ ctx->blockout = 1;
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
+}
+
+static int block_in(BIO *b)
+{
+ BIO_OK_CTX *ctx;
+ EVP_MD_CTX *md;
+ unsigned long tl = 0;
+ unsigned char tmp[EVP_MAX_MD_SIZE];
+
+ ctx = b->ptr;
+ md = &ctx->md;
+
+ assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */
+ tl = ctx->buf[0];
+ tl <<= 8;
+ tl |= ctx->buf[1];
+ tl <<= 8;
+ tl |= ctx->buf[2];
+ tl <<= 8;
+ tl |= ctx->buf[3];
+
+ if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md->digest->md_size)
+ return 1;
+
+ if (!EVP_DigestUpdate(md,
+ (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
+ goto berr;
+ if (!EVP_DigestFinal_ex(md, tmp, NULL))
+ goto berr;
+ if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md->digest->md_size) ==
+ 0) {
+ /* there might be parts from next block lurking around ! */
+ ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md->digest->md_size;
+ ctx->buf_len_save = ctx->buf_len;
+ ctx->buf_off = OK_BLOCK_BLOCK;
+ ctx->buf_len = tl + OK_BLOCK_BLOCK;
+ ctx->blockout = 1;
+ } else {
+ ctx->cont = 0;
+ }
+ return 1;
+ berr:
+ BIO_clear_retry_flags(b);
+ return 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/c_all.c b/Cryptlib/OpenSSL/crypto/evp/c_all.c
new file mode 100644
index 00000000..a3ed00d4
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/c_all.c
@@ -0,0 +1,90 @@
+/* crypto/evp/c_all.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+#if 0
+# undef OpenSSL_add_all_algorithms
+
+void OpenSSL_add_all_algorithms(void)
+{
+ OPENSSL_add_all_algorithms_noconf();
+}
+#endif
+
+void OPENSSL_add_all_algorithms_noconf(void)
+{
+ /*
+ * For the moment OPENSSL_cpuid_setup does something
+ * only on IA-32, but we reserve the option for all
+ * platforms...
+ */
+ OPENSSL_cpuid_setup();
+ OpenSSL_add_all_ciphers();
+ OpenSSL_add_all_digests();
+#ifndef OPENSSL_NO_ENGINE
+# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
+ ENGINE_setup_bsd_cryptodev();
+# endif
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/c_allc.c b/Cryptlib/OpenSSL/crypto/evp/c_allc.c
new file mode 100644
index 00000000..280e5840
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/c_allc.c
@@ -0,0 +1,241 @@
+/* crypto/evp/c_allc.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+#include <openssl/objects.h>
+
+void OpenSSL_add_all_ciphers(void)
+{
+
+#ifndef OPENSSL_NO_DES
+ EVP_add_cipher(EVP_des_cfb());
+ EVP_add_cipher(EVP_des_cfb1());
+ EVP_add_cipher(EVP_des_cfb8());
+ EVP_add_cipher(EVP_des_ede_cfb());
+ EVP_add_cipher(EVP_des_ede3_cfb());
+ EVP_add_cipher(EVP_des_ede3_cfb1());
+ EVP_add_cipher(EVP_des_ede3_cfb8());
+
+ EVP_add_cipher(EVP_des_ofb());
+ EVP_add_cipher(EVP_des_ede_ofb());
+ EVP_add_cipher(EVP_des_ede3_ofb());
+
+ EVP_add_cipher(EVP_desx_cbc());
+ EVP_add_cipher_alias(SN_desx_cbc, "DESX");
+ EVP_add_cipher_alias(SN_desx_cbc, "desx");
+
+ EVP_add_cipher(EVP_des_cbc());
+ EVP_add_cipher_alias(SN_des_cbc, "DES");
+ EVP_add_cipher_alias(SN_des_cbc, "des");
+ EVP_add_cipher(EVP_des_ede_cbc());
+ EVP_add_cipher(EVP_des_ede3_cbc());
+ EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3");
+ EVP_add_cipher_alias(SN_des_ede3_cbc, "des3");
+
+ EVP_add_cipher(EVP_des_ecb());
+ EVP_add_cipher(EVP_des_ede());
+ EVP_add_cipher(EVP_des_ede3());
+ EVP_add_cipher(EVP_des_ede3_wrap());
+#endif
+
+#ifndef OPENSSL_NO_RC4
+ EVP_add_cipher(EVP_rc4());
+ EVP_add_cipher(EVP_rc4_40());
+# ifndef OPENSSL_NO_MD5
+ EVP_add_cipher(EVP_rc4_hmac_md5());
+# endif
+#endif
+
+#ifndef OPENSSL_NO_IDEA
+ EVP_add_cipher(EVP_idea_ecb());
+ EVP_add_cipher(EVP_idea_cfb());
+ EVP_add_cipher(EVP_idea_ofb());
+ EVP_add_cipher(EVP_idea_cbc());
+ EVP_add_cipher_alias(SN_idea_cbc, "IDEA");
+ EVP_add_cipher_alias(SN_idea_cbc, "idea");
+#endif
+
+#ifndef OPENSSL_NO_SEED
+ EVP_add_cipher(EVP_seed_ecb());
+ EVP_add_cipher(EVP_seed_cfb());
+ EVP_add_cipher(EVP_seed_ofb());
+ EVP_add_cipher(EVP_seed_cbc());
+ EVP_add_cipher_alias(SN_seed_cbc, "SEED");
+ EVP_add_cipher_alias(SN_seed_cbc, "seed");
+#endif
+
+#ifndef OPENSSL_NO_RC2
+ EVP_add_cipher(EVP_rc2_ecb());
+ EVP_add_cipher(EVP_rc2_cfb());
+ EVP_add_cipher(EVP_rc2_ofb());
+ EVP_add_cipher(EVP_rc2_cbc());
+ EVP_add_cipher(EVP_rc2_40_cbc());
+ EVP_add_cipher(EVP_rc2_64_cbc());
+ EVP_add_cipher_alias(SN_rc2_cbc, "RC2");
+ EVP_add_cipher_alias(SN_rc2_cbc, "rc2");
+#endif
+
+#ifndef OPENSSL_NO_BF
+ EVP_add_cipher(EVP_bf_ecb());
+ EVP_add_cipher(EVP_bf_cfb());
+ EVP_add_cipher(EVP_bf_ofb());
+ EVP_add_cipher(EVP_bf_cbc());
+ EVP_add_cipher_alias(SN_bf_cbc, "BF");
+ EVP_add_cipher_alias(SN_bf_cbc, "bf");
+ EVP_add_cipher_alias(SN_bf_cbc, "blowfish");
+#endif
+
+#ifndef OPENSSL_NO_CAST
+ EVP_add_cipher(EVP_cast5_ecb());
+ EVP_add_cipher(EVP_cast5_cfb());
+ EVP_add_cipher(EVP_cast5_ofb());
+ EVP_add_cipher(EVP_cast5_cbc());
+ EVP_add_cipher_alias(SN_cast5_cbc, "CAST");
+ EVP_add_cipher_alias(SN_cast5_cbc, "cast");
+ EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc");
+ EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc");
+#endif
+
+#ifndef OPENSSL_NO_RC5
+ EVP_add_cipher(EVP_rc5_32_12_16_ecb());
+ EVP_add_cipher(EVP_rc5_32_12_16_cfb());
+ EVP_add_cipher(EVP_rc5_32_12_16_ofb());
+ EVP_add_cipher(EVP_rc5_32_12_16_cbc());
+ EVP_add_cipher_alias(SN_rc5_cbc, "rc5");
+ EVP_add_cipher_alias(SN_rc5_cbc, "RC5");
+#endif
+
+#ifndef OPENSSL_NO_AES
+ EVP_add_cipher(EVP_aes_128_ecb());
+ EVP_add_cipher(EVP_aes_128_cbc());
+ EVP_add_cipher(EVP_aes_128_cfb());
+ EVP_add_cipher(EVP_aes_128_cfb1());
+ EVP_add_cipher(EVP_aes_128_cfb8());
+ EVP_add_cipher(EVP_aes_128_ofb());
+ EVP_add_cipher(EVP_aes_128_ctr());
+ EVP_add_cipher(EVP_aes_128_gcm());
+ EVP_add_cipher(EVP_aes_128_xts());
+ EVP_add_cipher(EVP_aes_128_ccm());
+ EVP_add_cipher(EVP_aes_128_wrap());
+ EVP_add_cipher_alias(SN_aes_128_cbc, "AES128");
+ EVP_add_cipher_alias(SN_aes_128_cbc, "aes128");
+ EVP_add_cipher(EVP_aes_192_ecb());
+ EVP_add_cipher(EVP_aes_192_cbc());
+ EVP_add_cipher(EVP_aes_192_cfb());
+ EVP_add_cipher(EVP_aes_192_cfb1());
+ EVP_add_cipher(EVP_aes_192_cfb8());
+ EVP_add_cipher(EVP_aes_192_ofb());
+ EVP_add_cipher(EVP_aes_192_ctr());
+ EVP_add_cipher(EVP_aes_192_gcm());
+ EVP_add_cipher(EVP_aes_192_ccm());
+ EVP_add_cipher(EVP_aes_192_wrap());
+ EVP_add_cipher_alias(SN_aes_192_cbc, "AES192");
+ EVP_add_cipher_alias(SN_aes_192_cbc, "aes192");
+ EVP_add_cipher(EVP_aes_256_ecb());
+ EVP_add_cipher(EVP_aes_256_cbc());
+ EVP_add_cipher(EVP_aes_256_cfb());
+ EVP_add_cipher(EVP_aes_256_cfb1());
+ EVP_add_cipher(EVP_aes_256_cfb8());
+ EVP_add_cipher(EVP_aes_256_ofb());
+ EVP_add_cipher(EVP_aes_256_ctr());
+ EVP_add_cipher(EVP_aes_256_gcm());
+ EVP_add_cipher(EVP_aes_256_xts());
+ EVP_add_cipher(EVP_aes_256_ccm());
+ EVP_add_cipher(EVP_aes_256_wrap());
+ EVP_add_cipher_alias(SN_aes_256_cbc, "AES256");
+ EVP_add_cipher_alias(SN_aes_256_cbc, "aes256");
+# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+ EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
+ EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
+# endif
+# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256)
+ EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256());
+ EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256());
+# endif
+#endif
+
+#ifndef OPENSSL_NO_CAMELLIA
+ EVP_add_cipher(EVP_camellia_128_ecb());
+ EVP_add_cipher(EVP_camellia_128_cbc());
+ EVP_add_cipher(EVP_camellia_128_cfb());
+ EVP_add_cipher(EVP_camellia_128_cfb1());
+ EVP_add_cipher(EVP_camellia_128_cfb8());
+ EVP_add_cipher(EVP_camellia_128_ofb());
+ EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128");
+ EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128");
+ EVP_add_cipher(EVP_camellia_192_ecb());
+ EVP_add_cipher(EVP_camellia_192_cbc());
+ EVP_add_cipher(EVP_camellia_192_cfb());
+ EVP_add_cipher(EVP_camellia_192_cfb1());
+ EVP_add_cipher(EVP_camellia_192_cfb8());
+ EVP_add_cipher(EVP_camellia_192_ofb());
+ EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192");
+ EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192");
+ EVP_add_cipher(EVP_camellia_256_ecb());
+ EVP_add_cipher(EVP_camellia_256_cbc());
+ EVP_add_cipher(EVP_camellia_256_cfb());
+ EVP_add_cipher(EVP_camellia_256_cfb1());
+ EVP_add_cipher(EVP_camellia_256_cfb8());
+ EVP_add_cipher(EVP_camellia_256_ofb());
+ EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256");
+ EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256");
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/c_alld.c b/Cryptlib/OpenSSL/crypto/evp/c_alld.c
new file mode 100644
index 00000000..fdbe3ee0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/c_alld.c
@@ -0,0 +1,114 @@
+/* crypto/evp/c_alld.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+#include <openssl/objects.h>
+
+void OpenSSL_add_all_digests(void)
+{
+#ifndef OPENSSL_NO_MD4
+ EVP_add_digest(EVP_md4());
+#endif
+#ifndef OPENSSL_NO_MD5
+ EVP_add_digest(EVP_md5());
+ EVP_add_digest_alias(SN_md5, "ssl2-md5");
+ EVP_add_digest_alias(SN_md5, "ssl3-md5");
+#endif
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0)
+ EVP_add_digest(EVP_sha());
+# ifndef OPENSSL_NO_DSA
+ EVP_add_digest(EVP_dss());
+# endif
+#endif
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+ EVP_add_digest(EVP_sha1());
+ EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
+ EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
+# ifndef OPENSSL_NO_DSA
+ EVP_add_digest(EVP_dss1());
+ EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2);
+ EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1");
+ EVP_add_digest_alias(SN_dsaWithSHA1, "dss1");
+# endif
+# ifndef OPENSSL_NO_ECDSA
+ EVP_add_digest(EVP_ecdsa());
+# endif
+#endif
+#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
+ EVP_add_digest(EVP_mdc2());
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+ EVP_add_digest(EVP_ripemd160());
+ EVP_add_digest_alias(SN_ripemd160, "ripemd");
+ EVP_add_digest_alias(SN_ripemd160, "rmd160");
+#endif
+#ifndef OPENSSL_NO_SHA256
+ EVP_add_digest(EVP_sha224());
+ EVP_add_digest(EVP_sha256());
+#endif
+#ifndef OPENSSL_NO_SHA512
+ EVP_add_digest(EVP_sha384());
+ EVP_add_digest(EVP_sha512());
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+ EVP_add_digest(EVP_whirlpool());
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/digest.c b/Cryptlib/OpenSSL/crypto/evp/digest.c
new file mode 100644
index 00000000..5b642b23
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/digest.c
@@ -0,0 +1,408 @@
+/* crypto/evp/digest.c */
+/* 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.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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
+ * openssl-core@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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+# include "evp_locl.h"
+#endif
+
+void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
+{
+ memset(ctx, '\0', sizeof *ctx);
+}
+
+EVP_MD_CTX *EVP_MD_CTX_create(void)
+{
+ EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
+
+ if (ctx)
+ EVP_MD_CTX_init(ctx);
+
+ return 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_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
+{
+ EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
+#ifdef OPENSSL_FIPS
+ /* If FIPS mode switch to approved implementation if possible */
+ if (FIPS_mode()) {
+ const EVP_MD *fipsmd;
+ if (type) {
+ fipsmd = evp_get_fips_md(type);
+ if (fipsmd)
+ type = fipsmd;
+ }
+ }
+#endif
+#ifndef OPENSSL_NO_ENGINE
+ /*
+ * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
+ * this context may already have an ENGINE! Try to avoid releasing the
+ * previous handle, re-querying for an ENGINE, and having a
+ * reinitialisation, when it may all be unecessary.
+ */
+ if (ctx->engine && ctx->digest && (!type ||
+ (type
+ && (type->type ==
+ ctx->digest->type))))
+ goto skip_to_init;
+ if (type) {
+ /*
+ * Ensure an ENGINE left lying around from last time is cleared (the
+ * previous check attempted to avoid this if the same ENGINE and
+ * EVP_MD could be used).
+ */
+ if (ctx->engine)
+ ENGINE_finish(ctx->engine);
+ if (impl) {
+ if (!ENGINE_init(impl)) {
+ EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
+ return 0;
+ }
+ } else
+ /* Ask if an ENGINE is reserved for this job */
+ impl = ENGINE_get_digest_engine(type->type);
+ if (impl) {
+ /* There's an ENGINE for this job ... (apparently) */
+ const EVP_MD *d = ENGINE_get_digest(impl, type->type);
+ if (!d) {
+ /* Same comment from evp_enc.c */
+ EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
+ ENGINE_finish(impl);
+ return 0;
+ }
+ /* We'll use the ENGINE's private digest definition */
+ type = d;
+ /*
+ * Store the ENGINE functional reference so we know 'type' came
+ * from an ENGINE and we need to release it when done.
+ */
+ ctx->engine = impl;
+ } else
+ ctx->engine = NULL;
+ } else {
+ if (!ctx->digest) {
+ EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET);
+ return 0;
+ }
+ type = ctx->digest;
+ }
+#endif
+ if (ctx->digest != type) {
+ if (ctx->digest && ctx->digest->ctx_size) {
+ OPENSSL_free(ctx->md_data);
+ ctx->md_data = NULL;
+ }
+ 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) {
+ EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+ }
+#ifndef OPENSSL_NO_ENGINE
+ skip_to_init:
+#endif
+ if (ctx->pctx) {
+ int r;
+ r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
+ EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
+ if (r <= 0 && (r != -2))
+ return 0;
+ }
+ if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
+ return 1;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode()) {
+ if (FIPS_digestinit(ctx, type))
+ return 1;
+ OPENSSL_free(ctx->md_data);
+ ctx->md_data = NULL;
+ return 0;
+ }
+#endif
+ return ctx->digest->init(ctx);
+}
+
+int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+#ifdef OPENSSL_FIPS
+ return FIPS_digestupdate(ctx, data, count);
+#else
+ return ctx->update(ctx, data, count);
+#endif
+}
+
+/* The caller can assume that this removes any secret data from the context */
+int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
+{
+ int ret;
+ ret = EVP_DigestFinal_ex(ctx, md, size);
+ EVP_MD_CTX_cleanup(ctx);
+ return ret;
+}
+
+/* The caller can assume that this removes any secret data from the context */
+int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
+{
+#ifdef OPENSSL_FIPS
+ return FIPS_digestfinal(ctx, md, size);
+#else
+ int ret;
+
+ OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
+ ret = ctx->digest->final(ctx, md);
+ if (size != NULL)
+ *size = ctx->digest->md_size;
+ if (ctx->digest->cleanup) {
+ ctx->digest->cleanup(ctx);
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
+ }
+ memset(ctx->md_data, 0, ctx->digest->ctx_size);
+ return ret;
+#endif
+}
+
+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_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
+{
+ unsigned char *tmp_buf;
+ if ((in == NULL) || (in->digest == NULL)) {
+ EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED);
+ return 0;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ /* Make sure it's safe to copy a digest context using an ENGINE */
+ if (in->engine && !ENGINE_init(in->engine)) {
+ EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB);
+ return 0;
+ }
+#endif
+
+ if (out->digest == in->digest) {
+ tmp_buf = out->md_data;
+ EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE);
+ } else
+ tmp_buf = NULL;
+ EVP_MD_CTX_cleanup(out);
+ memcpy(out, in, sizeof *out);
+
+ if (in->md_data && out->digest->ctx_size) {
+ if (tmp_buf)
+ out->md_data = tmp_buf;
+ else {
+ out->md_data = OPENSSL_malloc(out->digest->ctx_size);
+ if (!out->md_data) {
+ EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+ memcpy(out->md_data, in->md_data, out->digest->ctx_size);
+ }
+
+ out->update = in->update;
+
+ if (in->pctx) {
+ out->pctx = EVP_PKEY_CTX_dup(in->pctx);
+ if (!out->pctx) {
+ EVP_MD_CTX_cleanup(out);
+ return 0;
+ }
+ }
+
+ if (out->digest->copy)
+ return out->digest->copy(out, in);
+
+ return 1;
+}
+
+int EVP_Digest(const void *data, size_t count,
+ unsigned char *md, unsigned int *size, const EVP_MD *type,
+ ENGINE *impl)
+{
+ EVP_MD_CTX ctx;
+ int ret;
+
+ EVP_MD_CTX_init(&ctx);
+ EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT);
+ ret = EVP_DigestInit_ex(&ctx, type, impl)
+ && EVP_DigestUpdate(&ctx, data, count)
+ && EVP_DigestFinal_ex(&ctx, md, size);
+ EVP_MD_CTX_cleanup(&ctx);
+
+ return ret;
+}
+
+void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
+{
+ if (ctx) {
+ EVP_MD_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+ }
+}
+
+/* This call frees resources associated with the context */
+int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
+{
+#ifndef OPENSSL_FIPS
+ /*
+ * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
+ * sometimes only copies of the context are ever finalised.
+ */
+ if (ctx->digest && ctx->digest->cleanup
+ && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
+ ctx->digest->cleanup(ctx);
+ if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
+ && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
+ OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
+ OPENSSL_free(ctx->md_data);
+ }
+#endif
+ if (ctx->pctx)
+ EVP_PKEY_CTX_free(ctx->pctx);
+#ifndef OPENSSL_NO_ENGINE
+ if (ctx->engine)
+ /*
+ * The EVP_MD we used belongs to an ENGINE, release the functional
+ * reference we held for this reason.
+ */
+ ENGINE_finish(ctx->engine);
+#endif
+#ifdef OPENSSL_FIPS
+ FIPS_md_ctx_cleanup(ctx);
+#endif
+ memset(ctx, '\0', sizeof *ctx);
+
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_aes.c b/Cryptlib/OpenSSL/crypto/evp/e_aes.c
new file mode 100644
index 00000000..1734a823
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_aes.c
@@ -0,0 +1,2024 @@
+/* ====================================================================
+ * Copyright (c) 2001-2011 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
+ * openssl-core@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/opensslconf.h>
+#ifndef OPENSSL_NO_AES
+#include <openssl/crypto.h>
+# include <openssl/evp.h>
+# include <openssl/err.h>
+# include <string.h>
+# include <assert.h>
+# include <openssl/aes.h>
+# include "evp_locl.h"
+# include "modes_lcl.h"
+# include <openssl/rand.h>
+
+# undef EVP_CIPH_FLAG_FIPS
+# define EVP_CIPH_FLAG_FIPS 0
+
+typedef struct {
+ union {
+ double align;
+ AES_KEY ks;
+ } ks;
+ block128_f block;
+ union {
+ cbc128_f cbc;
+ ctr128_f ctr;
+ } stream;
+} EVP_AES_KEY;
+
+typedef struct {
+ union {
+ double align;
+ AES_KEY ks;
+ } ks; /* AES key schedule to use */
+ int key_set; /* Set if key initialised */
+ int iv_set; /* Set if an iv is set */
+ GCM128_CONTEXT gcm;
+ unsigned char *iv; /* Temporary IV store */
+ int ivlen; /* IV length */
+ int taglen;
+ int iv_gen; /* It is OK to generate IVs */
+ int tls_aad_len; /* TLS AAD length */
+ ctr128_f ctr;
+} EVP_AES_GCM_CTX;
+
+typedef struct {
+ union {
+ double align;
+ AES_KEY ks;
+ } ks1, ks2; /* AES key schedules to use */
+ XTS128_CONTEXT xts;
+ void (*stream) (const unsigned char *in,
+ unsigned char *out, size_t length,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+} EVP_AES_XTS_CTX;
+
+typedef struct {
+ union {
+ double align;
+ AES_KEY ks;
+ } ks; /* AES key schedule to use */
+ int key_set; /* Set if key initialised */
+ int iv_set; /* Set if an iv is set */
+ int tag_set; /* Set if tag is valid */
+ int len_set; /* Set if message length set */
+ int L, M; /* L and M parameters from RFC3610 */
+ CCM128_CONTEXT ccm;
+ ccm128_f str;
+} EVP_AES_CCM_CTX;
+
+# define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4))
+
+# ifdef VPAES_ASM
+int vpaes_set_encrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+int vpaes_set_decrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+
+void vpaes_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void vpaes_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+
+void vpaes_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key, unsigned char *ivec, int enc);
+# endif
+# ifdef BSAES_ASM
+void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char ivec[16], int enc);
+void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ const unsigned char ivec[16]);
+void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out,
+ size_t len, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char iv[16]);
+void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out,
+ size_t len, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char iv[16]);
+# endif
+# ifdef AES_CTR_ASM
+void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key,
+ const unsigned char ivec[AES_BLOCK_SIZE]);
+# endif
+# ifdef AES_XTS_ASM
+void AES_xts_encrypt(const char *inp, char *out, size_t len,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+void AES_xts_decrypt(const char *inp, char *out, size_t len,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+# endif
+
+# if defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
+# include "ppc_arch.h"
+# ifdef VPAES_ASM
+# define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC)
+# endif
+# define HWAES_CAPABLE (OPENSSL_ppccap_P & PPC_CRYPTO207)
+# define HWAES_set_encrypt_key aes_p8_set_encrypt_key
+# define HWAES_set_decrypt_key aes_p8_set_decrypt_key
+# define HWAES_encrypt aes_p8_encrypt
+# define HWAES_decrypt aes_p8_decrypt
+# define HWAES_cbc_encrypt aes_p8_cbc_encrypt
+# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks
+# endif
+
+# if defined(AES_ASM) && !defined(I386_ONLY) && ( \
+ ((defined(__i386) || defined(__i386__) || \
+ defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) )
+
+extern unsigned int OPENSSL_ia32cap_P[];
+
+# ifdef VPAES_ASM
+# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
+# endif
+# ifdef BSAES_ASM
+# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
+# endif
+/*
+ * AES-NI section
+ */
+# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32)))
+
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+
+void aesni_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void aesni_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+
+void aesni_ecb_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length, const AES_KEY *key, int enc);
+void aesni_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key, unsigned char *ivec, int enc);
+
+void aesni_ctr32_encrypt_blocks(const unsigned char *in,
+ unsigned char *out,
+ size_t blocks,
+ const void *key, const unsigned char *ivec);
+
+void aesni_xts_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+
+void aesni_xts_decrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key1, const AES_KEY *key2,
+ const unsigned char iv[16]);
+
+void aesni_ccm64_encrypt_blocks(const unsigned char *in,
+ unsigned char *out,
+ size_t blocks,
+ const void *key,
+ const unsigned char ivec[16],
+ unsigned char cmac[16]);
+
+void aesni_ccm64_decrypt_blocks(const unsigned char *in,
+ unsigned char *out,
+ size_t blocks,
+ const void *key,
+ const unsigned char ivec[16],
+ unsigned char cmac[16]);
+
+# if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
+size_t aesni_gcm_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t len,
+ const void *key, unsigned char ivec[16], u64 *Xi);
+# define AES_gcm_encrypt aesni_gcm_encrypt
+size_t aesni_gcm_decrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t len,
+ const void *key, unsigned char ivec[16], u64 *Xi);
+# define AES_gcm_decrypt aesni_gcm_decrypt
+void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *in,
+ size_t len);
+# define AES_GCM_ASM(gctx) (gctx->ctr==aesni_ctr32_encrypt_blocks && \
+ gctx->gcm.ghash==gcm_ghash_avx)
+# define AES_GCM_ASM2(gctx) (gctx->gcm.block==(block128_f)aesni_encrypt && \
+ gctx->gcm.ghash==gcm_ghash_avx)
+# undef AES_GCM_ASM2 /* minor size optimization */
+# endif
+
+static int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ int ret, mode;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc) {
+ ret = aesni_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
+ dat->block = (block128_f) aesni_decrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) aesni_cbc_encrypt : NULL;
+ } else {
+ ret = aesni_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
+ dat->block = (block128_f) aesni_encrypt;
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) aesni_cbc_encrypt;
+ else if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
+ else
+ dat->stream.cbc = NULL;
+ }
+
+ if (ret < 0) {
+ EVPerr(EVP_F_AESNI_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ aesni_cbc_encrypt(in, out, len, ctx->cipher_data, ctx->iv, ctx->encrypt);
+
+ return 1;
+}
+
+static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ size_t bl = ctx->cipher->block_size;
+
+ if (len < bl)
+ return 1;
+
+ aesni_ecb_encrypt(in, out, len, ctx->cipher_data, ctx->encrypt);
+
+ return 1;
+}
+
+# define aesni_ofb_cipher aes_ofb_cipher
+static int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aesni_cfb_cipher aes_cfb_cipher
+static int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aesni_cfb8_cipher aes_cfb8_cipher
+static int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aesni_cfb1_cipher aes_cfb1_cipher
+static int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aesni_ctr_cipher aes_ctr_cipher
+static int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f) aesni_encrypt);
+ gctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
+ /*
+ * If we have an iv can set it directly, otherwise use saved IV.
+ */
+ if (iv == NULL && gctx->iv_set)
+ iv = gctx->iv;
+ if (iv) {
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ }
+ gctx->key_set = 1;
+ } else {
+ /* If key set use IV, otherwise copy */
+ if (gctx->key_set)
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ else
+ memcpy(gctx->iv, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ gctx->iv_gen = 0;
+ }
+ return 1;
+}
+
+# define aesni_gcm_cipher aes_gcm_cipher
+static int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+
+ if (key) {
+ /* key_len is two AES keys */
+ if (enc) {
+ aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) aesni_encrypt;
+ xctx->stream = aesni_xts_encrypt;
+ } else {
+ aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) aesni_decrypt;
+ xctx->stream = aesni_xts_decrypt;
+ }
+
+ aesni_set_encrypt_key(key + ctx->key_len / 2,
+ ctx->key_len * 4, &xctx->ks2.ks);
+ xctx->xts.block2 = (block128_f) aesni_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ }
+
+ if (iv) {
+ xctx->xts.key2 = &xctx->ks2;
+ memcpy(ctx->iv, iv, 16);
+ }
+
+ return 1;
+}
+
+# define aesni_xts_cipher aes_xts_cipher
+static int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f) aesni_encrypt);
+ cctx->str = enc ? (ccm128_f) aesni_ccm64_encrypt_blocks :
+ (ccm128_f) aesni_ccm64_decrypt_blocks;
+ cctx->key_set = 1;
+ }
+ if (iv) {
+ memcpy(ctx->iv, iv, 15 - cctx->L);
+ cctx->iv_set = 1;
+ }
+ return 1;
+}
+
+# define aesni_ccm_cipher aes_ccm_cipher
+static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER aesni_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aesni_init_key, \
+ aesni_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize, \
+ keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_init_key, \
+ aes_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
+static const EVP_CIPHER aesni_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aesni_##mode##_init_key, \
+ aesni_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_##mode##_init_key, \
+ aes_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+# elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
+
+# include "sparc_arch.h"
+
+extern unsigned int OPENSSL_sparcv9cap_P[];
+
+# define SPARC_AES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_AES)
+
+void aes_t4_set_encrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
+void aes_t4_set_decrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
+void aes_t4_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void aes_t4_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+/*
+ * Key-length specific subroutines were chosen for following reason.
+ * Each SPARC T4 core can execute up to 8 threads which share core's
+ * resources. Loading as much key material to registers allows to
+ * minimize references to shared memory interface, as well as amount
+ * of instructions in inner loops [much needed on T4]. But then having
+ * non-key-length specific routines would require conditional branches
+ * either in inner loops or on subroutines' entries. Former is hardly
+ * acceptable, while latter means code size increase to size occupied
+ * by multiple key-length specfic subroutines, so why fight?
+ */
+void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ unsigned char *ivec);
+void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ unsigned char *ivec);
+void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ unsigned char *ivec);
+void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ unsigned char *ivec);
+void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ unsigned char *ivec);
+void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ unsigned char *ivec);
+void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key,
+ unsigned char *ivec);
+void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key,
+ unsigned char *ivec);
+void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key,
+ unsigned char *ivec);
+void aes128_t4_xts_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char *ivec);
+void aes128_t4_xts_decrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char *ivec);
+void aes256_t4_xts_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char *ivec);
+void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const AES_KEY *key1,
+ const AES_KEY *key2, const unsigned char *ivec);
+
+static int aes_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ int ret, mode, bits;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ bits = ctx->key_len * 8;
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc) {
+ ret = 0;
+ aes_t4_set_decrypt_key(key, bits, ctx->cipher_data);
+ dat->block = (block128_f) aes_t4_decrypt;
+ switch (bits) {
+ case 128:
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) aes128_t4_cbc_decrypt : NULL;
+ break;
+ case 192:
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) aes192_t4_cbc_decrypt : NULL;
+ break;
+ case 256:
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) aes256_t4_cbc_decrypt : NULL;
+ break;
+ default:
+ ret = -1;
+ }
+ } else {
+ ret = 0;
+ aes_t4_set_encrypt_key(key, bits, ctx->cipher_data);
+ dat->block = (block128_f) aes_t4_encrypt;
+ switch (bits) {
+ case 128:
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) aes128_t4_cbc_encrypt;
+ else if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) aes128_t4_ctr32_encrypt;
+ else
+ dat->stream.cbc = NULL;
+ break;
+ case 192:
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) aes192_t4_cbc_encrypt;
+ else if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) aes192_t4_ctr32_encrypt;
+ else
+ dat->stream.cbc = NULL;
+ break;
+ case 256:
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) aes256_t4_cbc_encrypt;
+ else if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) aes256_t4_ctr32_encrypt;
+ else
+ dat->stream.cbc = NULL;
+ break;
+ default:
+ ret = -1;
+ }
+ }
+
+ if (ret < 0) {
+ EVPerr(EVP_F_AES_T4_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
+ return 0;
+ }
+
+ return 1;
+}
+
+# define aes_t4_cbc_cipher aes_cbc_cipher
+static int aes_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aes_t4_ecb_cipher aes_ecb_cipher
+static int aes_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aes_t4_ofb_cipher aes_ofb_cipher
+static int aes_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aes_t4_cfb_cipher aes_cfb_cipher
+static int aes_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aes_t4_cfb8_cipher aes_cfb8_cipher
+static int aes_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aes_t4_cfb1_cipher aes_cfb1_cipher
+static int aes_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define aes_t4_ctr_cipher aes_ctr_cipher
+static int aes_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aes_t4_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ int bits = ctx->key_len * 8;
+ aes_t4_set_encrypt_key(key, bits, &gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+ (block128_f) aes_t4_encrypt);
+ switch (bits) {
+ case 128:
+ gctx->ctr = (ctr128_f) aes128_t4_ctr32_encrypt;
+ break;
+ case 192:
+ gctx->ctr = (ctr128_f) aes192_t4_ctr32_encrypt;
+ break;
+ case 256:
+ gctx->ctr = (ctr128_f) aes256_t4_ctr32_encrypt;
+ break;
+ default:
+ return 0;
+ }
+ /*
+ * If we have an iv can set it directly, otherwise use saved IV.
+ */
+ if (iv == NULL && gctx->iv_set)
+ iv = gctx->iv;
+ if (iv) {
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ }
+ gctx->key_set = 1;
+ } else {
+ /* If key set use IV, otherwise copy */
+ if (gctx->key_set)
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ else
+ memcpy(gctx->iv, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ gctx->iv_gen = 0;
+ }
+ return 1;
+}
+
+# define aes_t4_gcm_cipher aes_gcm_cipher
+static int aes_t4_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+
+ if (key) {
+ int bits = ctx->key_len * 4;
+ xctx->stream = NULL;
+ /* key_len is two AES keys */
+ if (enc) {
+ aes_t4_set_encrypt_key(key, bits, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) aes_t4_encrypt;
+ switch (bits) {
+ case 128:
+ xctx->stream = aes128_t4_xts_encrypt;
+ break;
+# if 0 /* not yet */
+ case 192:
+ xctx->stream = aes192_t4_xts_encrypt;
+ break;
+# endif
+ case 256:
+ xctx->stream = aes256_t4_xts_encrypt;
+ break;
+ default:
+ return 0;
+ }
+ } else {
+ aes_t4_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) aes_t4_decrypt;
+ switch (bits) {
+ case 128:
+ xctx->stream = aes128_t4_xts_decrypt;
+ break;
+# if 0 /* not yet */
+ case 192:
+ xctx->stream = aes192_t4_xts_decrypt;
+ break;
+# endif
+ case 256:
+ xctx->stream = aes256_t4_xts_decrypt;
+ break;
+ default:
+ return 0;
+ }
+ }
+
+ aes_t4_set_encrypt_key(key + ctx->key_len / 2,
+ ctx->key_len * 4, &xctx->ks2.ks);
+ xctx->xts.block2 = (block128_f) aes_t4_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ }
+
+ if (iv) {
+ xctx->xts.key2 = &xctx->ks2;
+ memcpy(ctx->iv, iv, 16);
+ }
+
+ return 1;
+}
+
+# define aes_t4_xts_cipher aes_xts_cipher
+static int aes_t4_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+static int aes_t4_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ int bits = ctx->key_len * 8;
+ aes_t4_set_encrypt_key(key, bits, &cctx->ks.ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f) aes_t4_encrypt);
+# if 0 /* not yet */
+ switch (bits) {
+ case 128:
+ cctx->str = enc ? (ccm128_f) aes128_t4_ccm64_encrypt :
+ (ccm128_f) ae128_t4_ccm64_decrypt;
+ break;
+ case 192:
+ cctx->str = enc ? (ccm128_f) aes192_t4_ccm64_encrypt :
+ (ccm128_f) ae192_t4_ccm64_decrypt;
+ break;
+ case 256:
+ cctx->str = enc ? (ccm128_f) aes256_t4_ccm64_encrypt :
+ (ccm128_f) ae256_t4_ccm64_decrypt;
+ break;
+ default:
+ return 0;
+ }
+# else
+ cctx->str = NULL;
+# endif
+ cctx->key_set = 1;
+ }
+ if (iv) {
+ memcpy(ctx->iv, iv, 15 - cctx->L);
+ cctx->iv_set = 1;
+ }
+ return 1;
+}
+
+# define aes_t4_ccm_cipher aes_ccm_cipher
+static int aes_t4_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_t4_init_key, \
+ aes_t4_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize, \
+ keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_init_key, \
+ aes_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
+static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_t4_##mode##_init_key, \
+ aes_t4_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_##mode##_init_key, \
+ aes_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+# else
+
+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_init_key, \
+ aes_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_AES_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return &aes_##keylen##_##mode; }
+
+# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+ nid##_##keylen##_##mode,blocksize, \
+ (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ aes_##mode##_init_key, \
+ aes_##mode##_cipher, \
+ aes_##mode##_cleanup, \
+ sizeof(EVP_AES_##MODE##_CTX), \
+ NULL,NULL,aes_##mode##_ctrl,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return &aes_##keylen##_##mode; }
+# endif
+
+# if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__))
+# include "arm_arch.h"
+# if __ARM_MAX_ARCH__>=7
+# if defined(BSAES_ASM)
+# define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
+# endif
+# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES)
+# define HWAES_set_encrypt_key aes_v8_set_encrypt_key
+# define HWAES_set_decrypt_key aes_v8_set_decrypt_key
+# define HWAES_encrypt aes_v8_encrypt
+# define HWAES_decrypt aes_v8_decrypt
+# define HWAES_cbc_encrypt aes_v8_cbc_encrypt
+# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks
+# endif
+# endif
+
+# if defined(HWAES_CAPABLE)
+int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key);
+int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key);
+void HWAES_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void HWAES_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char *ivec, const int enc);
+void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
+ size_t len, const AES_KEY *key,
+ const unsigned char ivec[16]);
+# endif
+
+# define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags)
+
+static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ int ret, mode;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc)
+# ifdef HWAES_CAPABLE
+ if (HWAES_CAPABLE) {
+ ret = HWAES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) HWAES_decrypt;
+ dat->stream.cbc = NULL;
+# ifdef HWAES_cbc_encrypt
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) HWAES_cbc_encrypt;
+# endif
+ } else
+# endif
+# ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE && mode == EVP_CIPH_CBC_MODE) {
+ ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) AES_decrypt;
+ dat->stream.cbc = (cbc128_f) bsaes_cbc_encrypt;
+ } else
+# endif
+# ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE) {
+ ret = vpaes_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) vpaes_decrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) vpaes_cbc_encrypt : NULL;
+ } else
+# endif
+ {
+ ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) AES_decrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) AES_cbc_encrypt : NULL;
+ } else
+# ifdef HWAES_CAPABLE
+ if (HWAES_CAPABLE) {
+ ret = HWAES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) HWAES_encrypt;
+ dat->stream.cbc = NULL;
+# ifdef HWAES_cbc_encrypt
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) HWAES_cbc_encrypt;
+ else
+# endif
+# ifdef HWAES_ctr32_encrypt_blocks
+ if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) HWAES_ctr32_encrypt_blocks;
+ else
+# endif
+ (void)0; /* terminate potentially open 'else' */
+ } else
+# endif
+# ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE && mode == EVP_CIPH_CTR_MODE) {
+ ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) AES_encrypt;
+ dat->stream.ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks;
+ } else
+# endif
+# ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE) {
+ ret = vpaes_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) vpaes_encrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) vpaes_cbc_encrypt : NULL;
+ } else
+# endif
+ {
+ ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
+ dat->block = (block128_f) AES_encrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) AES_cbc_encrypt : NULL;
+# ifdef AES_CTR_ASM
+ if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) AES_ctr32_encrypt;
+# endif
+ }
+
+ if (ret < 0) {
+ EVPerr(EVP_F_AES_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ if (dat->stream.cbc)
+ (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt);
+ else if (ctx->encrypt)
+ CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
+ else
+ CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
+
+ return 1;
+}
+
+static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ size_t bl = ctx->cipher->block_size;
+ size_t i;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ if (len < bl)
+ return 1;
+
+ for (i = 0, len -= bl; i <= len; i += bl)
+ (*dat->block) (in + i, out + i, &dat->ks);
+
+ return 1;
+}
+
+static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ CRYPTO_ofb128_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, dat->block);
+ return 1;
+}
+
+static int aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ CRYPTO_cfb128_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ return 1;
+}
+
+static int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ return 1;
+}
+
+static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ if (ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) {
+ CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ return 1;
+ }
+
+ while (len >= MAXBITCHUNK) {
+ CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ len -= MAXBITCHUNK;
+ }
+ if (len)
+ CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+
+ return 1;
+}
+
+static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ unsigned int num = ctx->num;
+ EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+
+ if (dat->stream.ctr)
+ CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
+ ctx->iv, ctx->buf, &num, dat->stream.ctr);
+ else
+ CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
+ ctx->iv, ctx->buf, &num, dat->block);
+ ctx->num = (size_t)num;
+ return 1;
+}
+
+BLOCK_CIPHER_generic_pack(NID_aes, 128, EVP_CIPH_FLAG_FIPS)
+ BLOCK_CIPHER_generic_pack(NID_aes, 192, EVP_CIPH_FLAG_FIPS)
+ BLOCK_CIPHER_generic_pack(NID_aes, 256, EVP_CIPH_FLAG_FIPS)
+
+static int aes_gcm_cleanup(EVP_CIPHER_CTX *c)
+{
+ EVP_AES_GCM_CTX *gctx = c->cipher_data;
+ OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
+ if (gctx->iv != c->iv)
+ OPENSSL_free(gctx->iv);
+ return 1;
+}
+
+/* increment counter (64-bit int) by 1 */
+static void ctr64_inc(unsigned char *counter)
+{
+ int n = 8;
+ unsigned char c;
+
+ do {
+ --n;
+ c = counter[n];
+ ++c;
+ counter[n] = c;
+ if (c)
+ return;
+ } while (n);
+}
+
+static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ EVP_AES_GCM_CTX *gctx = c->cipher_data;
+ switch (type) {
+ case EVP_CTRL_INIT:
+ gctx->key_set = 0;
+ gctx->iv_set = 0;
+ gctx->ivlen = c->cipher->iv_len;
+ gctx->iv = c->iv;
+ gctx->taglen = -1;
+ gctx->iv_gen = 0;
+ gctx->tls_aad_len = -1;
+ return 1;
+
+ case EVP_CTRL_GCM_SET_IVLEN:
+ if (arg <= 0)
+ return 0;
+ /* Allocate memory for IV if needed */
+ if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) {
+ if (gctx->iv != c->iv)
+ OPENSSL_free(gctx->iv);
+ gctx->iv = OPENSSL_malloc(arg);
+ if (!gctx->iv)
+ return 0;
+ }
+ gctx->ivlen = arg;
+ return 1;
+
+ case EVP_CTRL_GCM_SET_TAG:
+ if (arg <= 0 || arg > 16 || c->encrypt)
+ return 0;
+ memcpy(c->buf, ptr, arg);
+ gctx->taglen = arg;
+ return 1;
+
+ case EVP_CTRL_GCM_GET_TAG:
+ if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0)
+ return 0;
+ memcpy(ptr, c->buf, arg);
+ return 1;
+
+ case EVP_CTRL_GCM_SET_IV_FIXED:
+ /* Special case: -1 length restores whole IV */
+ if (arg == -1) {
+ memcpy(gctx->iv, ptr, gctx->ivlen);
+ gctx->iv_gen = 1;
+ return 1;
+ }
+ /*
+ * Fixed field must be at least 4 bytes and invocation field at least
+ * 8.
+ */
+ if ((arg < 4) || (gctx->ivlen - arg) < 8)
+ return 0;
+ if (arg)
+ memcpy(gctx->iv, ptr, arg);
+ if (c->encrypt && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0)
+ return 0;
+ gctx->iv_gen = 1;
+ return 1;
+
+ case EVP_CTRL_GCM_IV_GEN:
+ if (gctx->iv_gen == 0 || gctx->key_set == 0)
+ return 0;
+ CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+ if (arg <= 0 || arg > gctx->ivlen)
+ arg = gctx->ivlen;
+ memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
+ /*
+ * Invocation field will be at least 8 bytes in size and so no need
+ * to check wrap around or increment more than last 8 bytes.
+ */
+ ctr64_inc(gctx->iv + gctx->ivlen - 8);
+ gctx->iv_set = 1;
+ return 1;
+
+ case EVP_CTRL_GCM_SET_IV_INV:
+ if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt)
+ return 0;
+ memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
+ CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ return 1;
+
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ /* Save the AAD for later use */
+ if (arg != EVP_AEAD_TLS1_AAD_LEN)
+ return 0;
+ memcpy(c->buf, ptr, arg);
+ gctx->tls_aad_len = arg;
+ {
+ unsigned int len = c->buf[arg - 2] << 8 | c->buf[arg - 1];
+ /* Correct length for explicit IV */
+ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ /* If decrypting correct for tag too */
+ if (!c->encrypt)
+ len -= EVP_GCM_TLS_TAG_LEN;
+ c->buf[arg - 2] = len >> 8;
+ c->buf[arg - 1] = len & 0xff;
+ }
+ /* Extra padding: tag appended to record */
+ return EVP_GCM_TLS_TAG_LEN;
+
+ case EVP_CTRL_COPY:
+ {
+ EVP_CIPHER_CTX *out = ptr;
+ EVP_AES_GCM_CTX *gctx_out = out->cipher_data;
+ if (gctx->gcm.key) {
+ if (gctx->gcm.key != &gctx->ks)
+ return 0;
+ gctx_out->gcm.key = &gctx_out->ks;
+ }
+ if (gctx->iv == c->iv)
+ gctx_out->iv = out->iv;
+ else {
+ gctx_out->iv = OPENSSL_malloc(gctx->ivlen);
+ if (!gctx_out->iv)
+ return 0;
+ memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
+ }
+ return 1;
+ }
+
+ default:
+ return -1;
+
+ }
+}
+
+static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ do {
+# ifdef HWAES_CAPABLE
+ if (HWAES_CAPABLE) {
+ HWAES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+ (block128_f) HWAES_encrypt);
+# ifdef HWAES_ctr32_encrypt_blocks
+ gctx->ctr = (ctr128_f) HWAES_ctr32_encrypt_blocks;
+# else
+ gctx->ctr = NULL;
+# endif
+ break;
+ } else
+# endif
+# ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE) {
+ AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+ (block128_f) AES_encrypt);
+ gctx->ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks;
+ break;
+ } else
+# endif
+# ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE) {
+ vpaes_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+ (block128_f) vpaes_encrypt);
+ gctx->ctr = NULL;
+ break;
+ } else
+# endif
+ (void)0; /* terminate potentially open 'else' */
+
+ AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
+ CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+ (block128_f) AES_encrypt);
+# ifdef AES_CTR_ASM
+ gctx->ctr = (ctr128_f) AES_ctr32_encrypt;
+# else
+ gctx->ctr = NULL;
+# endif
+ } while (0);
+
+ /*
+ * If we have an iv can set it directly, otherwise use saved IV.
+ */
+ if (iv == NULL && gctx->iv_set)
+ iv = gctx->iv;
+ if (iv) {
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ }
+ gctx->key_set = 1;
+ } else {
+ /* If key set use IV, otherwise copy */
+ if (gctx->key_set)
+ CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ else
+ memcpy(gctx->iv, iv, gctx->ivlen);
+ gctx->iv_set = 1;
+ gctx->iv_gen = 0;
+ }
+ return 1;
+}
+
+/*
+ * Handle TLS GCM packet format. This consists of the last portion of the IV
+ * followed by the payload and finally the tag. On encrypt generate IV,
+ * encrypt payload and write the tag. On verify retrieve IV, decrypt payload
+ * and verify tag.
+ */
+
+static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ int rv = -1;
+ /* Encrypt/decrypt must be performed in place */
+ if (out != in
+ || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN))
+ return -1;
+ /*
+ * Set IV from start of buffer or generate IV and write to start of
+ * buffer.
+ */
+ if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ?
+ EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV,
+ EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0)
+ goto err;
+ /* Use saved AAD */
+ if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len))
+ goto err;
+ /* Fix buffer and length to point to payload */
+ in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ out += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
+ if (ctx->encrypt) {
+ /* Encrypt payload */
+ if (gctx->ctr) {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM)
+ if (len >= 32 && AES_GCM_ASM(gctx)) {
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm, NULL, NULL, 0))
+ return -1;
+
+ bulk = AES_gcm_encrypt(in, out, len,
+ gctx->gcm.key,
+ gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ }
+# endif
+ if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
+ in + bulk,
+ out + bulk,
+ len - bulk, gctx->ctr))
+ goto err;
+ } else {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM2)
+ if (len >= 32 && AES_GCM_ASM2(gctx)) {
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm, NULL, NULL, 0))
+ return -1;
+
+ bulk = AES_gcm_encrypt(in, out, len,
+ gctx->gcm.key,
+ gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ }
+# endif
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm,
+ in + bulk, out + bulk, len - bulk))
+ goto err;
+ }
+ out += len;
+ /* Finally write tag */
+ CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN);
+ rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
+ } else {
+ /* Decrypt */
+ if (gctx->ctr) {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM)
+ if (len >= 16 && AES_GCM_ASM(gctx)) {
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm, NULL, NULL, 0))
+ return -1;
+
+ bulk = AES_gcm_decrypt(in, out, len,
+ gctx->gcm.key,
+ gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ }
+# endif
+ if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
+ in + bulk,
+ out + bulk,
+ len - bulk, gctx->ctr))
+ goto err;
+ } else {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM2)
+ if (len >= 16 && AES_GCM_ASM2(gctx)) {
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm, NULL, NULL, 0))
+ return -1;
+
+ bulk = AES_gcm_decrypt(in, out, len,
+ gctx->gcm.key,
+ gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ }
+# endif
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm,
+ in + bulk, out + bulk, len - bulk))
+ goto err;
+ }
+ /* Retrieve tag */
+ CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN);
+ /* If tag mismatch wipe buffer */
+ if (CRYPTO_memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) {
+ OPENSSL_cleanse(out, len);
+ goto err;
+ }
+ rv = len;
+ }
+
+ err:
+ gctx->iv_set = 0;
+ gctx->tls_aad_len = -1;
+ return rv;
+}
+
+static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ /* If not set up, return error */
+ if (!gctx->key_set)
+ return -1;
+
+ if (gctx->tls_aad_len >= 0)
+ return aes_gcm_tls_cipher(ctx, out, in, len);
+
+ if (!gctx->iv_set)
+ return -1;
+ if (in) {
+ if (out == NULL) {
+ if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
+ return -1;
+ } else if (ctx->encrypt) {
+ if (gctx->ctr) {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM)
+ if (len >= 32 && AES_GCM_ASM(gctx)) {
+ size_t res = (16 - gctx->gcm.mres) % 16;
+
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res))
+ return -1;
+
+ bulk = AES_gcm_encrypt(in + res,
+ out + res, len - res,
+ gctx->gcm.key, gctx->gcm.Yi.c,
+ gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ bulk += res;
+ }
+# endif
+ if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
+ in + bulk,
+ out + bulk,
+ len - bulk, gctx->ctr))
+ return -1;
+ } else {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM2)
+ if (len >= 32 && AES_GCM_ASM2(gctx)) {
+ size_t res = (16 - gctx->gcm.mres) % 16;
+
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res))
+ return -1;
+
+ bulk = AES_gcm_encrypt(in + res,
+ out + res, len - res,
+ gctx->gcm.key, gctx->gcm.Yi.c,
+ gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ bulk += res;
+ }
+# endif
+ if (CRYPTO_gcm128_encrypt(&gctx->gcm,
+ in + bulk, out + bulk, len - bulk))
+ return -1;
+ }
+ } else {
+ if (gctx->ctr) {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM)
+ if (len >= 16 && AES_GCM_ASM(gctx)) {
+ size_t res = (16 - gctx->gcm.mres) % 16;
+
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res))
+ return -1;
+
+ bulk = AES_gcm_decrypt(in + res,
+ out + res, len - res,
+ gctx->gcm.key,
+ gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ bulk += res;
+ }
+# endif
+ if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
+ in + bulk,
+ out + bulk,
+ len - bulk, gctx->ctr))
+ return -1;
+ } else {
+ size_t bulk = 0;
+# if defined(AES_GCM_ASM2)
+ if (len >= 16 && AES_GCM_ASM2(gctx)) {
+ size_t res = (16 - gctx->gcm.mres) % 16;
+
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res))
+ return -1;
+
+ bulk = AES_gcm_decrypt(in + res,
+ out + res, len - res,
+ gctx->gcm.key,
+ gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+ gctx->gcm.len.u[1] += bulk;
+ bulk += res;
+ }
+# endif
+ if (CRYPTO_gcm128_decrypt(&gctx->gcm,
+ in + bulk, out + bulk, len - bulk))
+ return -1;
+ }
+ }
+ return len;
+ } else {
+ if (!ctx->encrypt) {
+ if (gctx->taglen < 0)
+ return -1;
+ if (CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen) != 0)
+ return -1;
+ gctx->iv_set = 0;
+ return 0;
+ }
+ CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16);
+ gctx->taglen = 16;
+ /* Don't reuse the IV */
+ gctx->iv_set = 0;
+ return 0;
+ }
+
+}
+
+# define CUSTOM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
+ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
+ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
+ | EVP_CIPH_CUSTOM_COPY)
+
+BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM,
+ EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER |
+ CUSTOM_FLAGS)
+ BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, gcm, GCM,
+ EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER |
+ CUSTOM_FLAGS)
+ BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, gcm, GCM,
+ EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER |
+ CUSTOM_FLAGS)
+
+static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ EVP_AES_XTS_CTX *xctx = c->cipher_data;
+ if (type == EVP_CTRL_COPY) {
+ EVP_CIPHER_CTX *out = ptr;
+ EVP_AES_XTS_CTX *xctx_out = out->cipher_data;
+ if (xctx->xts.key1) {
+ if (xctx->xts.key1 != &xctx->ks1)
+ return 0;
+ xctx_out->xts.key1 = &xctx_out->ks1;
+ }
+ if (xctx->xts.key2) {
+ if (xctx->xts.key2 != &xctx->ks2)
+ return 0;
+ xctx_out->xts.key2 = &xctx_out->ks2;
+ }
+ return 1;
+ } else if (type != EVP_CTRL_INIT)
+ return -1;
+ /* key1 and key2 are used as an indicator both key and IV are set */
+ xctx->xts.key1 = NULL;
+ xctx->xts.key2 = NULL;
+ return 1;
+}
+
+static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+
+ if (key)
+ do {
+# ifdef AES_XTS_ASM
+ xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt;
+# else
+ xctx->stream = NULL;
+# endif
+ /* key_len is two AES keys */
+# ifdef HWAES_CAPABLE
+ if (HWAES_CAPABLE) {
+ if (enc) {
+ HWAES_set_encrypt_key(key, ctx->key_len * 4,
+ &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) HWAES_encrypt;
+ } else {
+ HWAES_set_decrypt_key(key, ctx->key_len * 4,
+ &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) HWAES_decrypt;
+ }
+
+ HWAES_set_encrypt_key(key + ctx->key_len / 2,
+ ctx->key_len * 4, &xctx->ks2.ks);
+ xctx->xts.block2 = (block128_f) HWAES_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ break;
+ } else
+# endif
+# ifdef BSAES_CAPABLE
+ if (BSAES_CAPABLE)
+ xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt;
+ else
+# endif
+# ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE) {
+ if (enc) {
+ vpaes_set_encrypt_key(key, ctx->key_len * 4,
+ &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) vpaes_encrypt;
+ } else {
+ vpaes_set_decrypt_key(key, ctx->key_len * 4,
+ &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) vpaes_decrypt;
+ }
+
+ vpaes_set_encrypt_key(key + ctx->key_len / 2,
+ ctx->key_len * 4, &xctx->ks2.ks);
+ xctx->xts.block2 = (block128_f) vpaes_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ break;
+ } else
+# endif
+ (void)0; /* terminate potentially open 'else' */
+
+ if (enc) {
+ AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) AES_encrypt;
+ } else {
+ AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) AES_decrypt;
+ }
+
+ AES_set_encrypt_key(key + ctx->key_len / 2,
+ ctx->key_len * 4, &xctx->ks2.ks);
+ xctx->xts.block2 = (block128_f) AES_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ } while (0);
+
+ if (iv) {
+ xctx->xts.key2 = &xctx->ks2;
+ memcpy(ctx->iv, iv, 16);
+ }
+
+ return 1;
+}
+
+static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!xctx->xts.key1 || !xctx->xts.key2)
+ return 0;
+ if (!out || !in || len < AES_BLOCK_SIZE)
+ return 0;
+ if (xctx->stream)
+ (*xctx->stream) (in, out, len,
+ xctx->xts.key1, xctx->xts.key2, ctx->iv);
+ else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len,
+ ctx->encrypt))
+ return 0;
+ return 1;
+}
+
+# define aes_xts_cleanup NULL
+
+# define XTS_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \
+ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
+ | EVP_CIPH_CUSTOM_COPY)
+
+BLOCK_CIPHER_custom(NID_aes, 128, 1, 16, xts, XTS,
+ EVP_CIPH_FLAG_FIPS | XTS_FLAGS)
+ BLOCK_CIPHER_custom(NID_aes, 256, 1, 16, xts, XTS,
+ EVP_CIPH_FLAG_FIPS | XTS_FLAGS)
+
+static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ EVP_AES_CCM_CTX *cctx = c->cipher_data;
+ switch (type) {
+ case EVP_CTRL_INIT:
+ cctx->key_set = 0;
+ cctx->iv_set = 0;
+ cctx->L = 8;
+ cctx->M = 12;
+ cctx->tag_set = 0;
+ cctx->len_set = 0;
+ return 1;
+
+ case EVP_CTRL_CCM_SET_IVLEN:
+ arg = 15 - arg;
+ case EVP_CTRL_CCM_SET_L:
+ if (arg < 2 || arg > 8)
+ return 0;
+ cctx->L = arg;
+ return 1;
+
+ case EVP_CTRL_CCM_SET_TAG:
+ if ((arg & 1) || arg < 4 || arg > 16)
+ return 0;
+ if (c->encrypt && ptr)
+ return 0;
+ if (ptr) {
+ cctx->tag_set = 1;
+ memcpy(c->buf, ptr, arg);
+ }
+ cctx->M = arg;
+ return 1;
+
+ case EVP_CTRL_CCM_GET_TAG:
+ if (!c->encrypt || !cctx->tag_set)
+ return 0;
+ if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
+ return 0;
+ cctx->tag_set = 0;
+ cctx->iv_set = 0;
+ cctx->len_set = 0;
+ return 1;
+
+ case EVP_CTRL_COPY:
+ {
+ EVP_CIPHER_CTX *out = ptr;
+ EVP_AES_CCM_CTX *cctx_out = out->cipher_data;
+ if (cctx->ccm.key) {
+ if (cctx->ccm.key != &cctx->ks)
+ return 0;
+ cctx_out->ccm.key = &cctx_out->ks;
+ }
+ return 1;
+ }
+
+ default:
+ return -1;
+
+ }
+}
+
+static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key)
+ do {
+# ifdef HWAES_CAPABLE
+ if (HWAES_CAPABLE) {
+ HWAES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks);
+
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f) HWAES_encrypt);
+ cctx->str = NULL;
+ cctx->key_set = 1;
+ break;
+ } else
+# endif
+# ifdef VPAES_CAPABLE
+ if (VPAES_CAPABLE) {
+ vpaes_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f) vpaes_encrypt);
+ cctx->str = NULL;
+ cctx->key_set = 1;
+ break;
+ }
+# endif
+ AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks);
+ CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+ &cctx->ks, (block128_f) AES_encrypt);
+ cctx->str = NULL;
+ cctx->key_set = 1;
+ } while (0);
+ if (iv) {
+ memcpy(ctx->iv, iv, 15 - cctx->L);
+ cctx->iv_set = 1;
+ }
+ return 1;
+}
+
+static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
+ CCM128_CONTEXT *ccm = &cctx->ccm;
+ /* If not set up, return error */
+ if (!cctx->iv_set && !cctx->key_set)
+ return -1;
+ if (!ctx->encrypt && !cctx->tag_set)
+ return -1;
+ if (!out) {
+ if (!in) {
+ if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len))
+ return -1;
+ cctx->len_set = 1;
+ return len;
+ }
+ /* If have AAD need message length */
+ if (!cctx->len_set && len)
+ return -1;
+ CRYPTO_ccm128_aad(ccm, in, len);
+ return len;
+ }
+ /* EVP_*Final() doesn't return any data */
+ if (!in)
+ return 0;
+ /* If not set length yet do it */
+ if (!cctx->len_set) {
+ if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len))
+ return -1;
+ cctx->len_set = 1;
+ }
+ if (ctx->encrypt) {
+ if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
+ cctx->str) :
+ CRYPTO_ccm128_encrypt(ccm, in, out, len))
+ return -1;
+ cctx->tag_set = 1;
+ return len;
+ } else {
+ int rv = -1;
+ if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
+ cctx->str) :
+ !CRYPTO_ccm128_decrypt(ccm, in, out, len)) {
+ unsigned char tag[16];
+ if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) {
+ if (!CRYPTO_memcmp(tag, ctx->buf, cctx->M))
+ rv = len;
+ }
+ }
+ if (rv == -1)
+ OPENSSL_cleanse(out, len);
+ cctx->iv_set = 0;
+ cctx->tag_set = 0;
+ cctx->len_set = 0;
+ return rv;
+ }
+
+}
+
+# define aes_ccm_cleanup NULL
+
+BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM,
+ EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS)
+ BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM,
+ EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS)
+ BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM,
+ EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS)
+#endif
+typedef struct {
+ union {
+ double align;
+ AES_KEY ks;
+ } ks;
+ /* Indicates if IV has been set */
+ unsigned char *iv;
+} EVP_AES_WRAP_CTX;
+
+static int aes_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_WRAP_CTX *wctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ if (ctx->encrypt)
+ AES_set_encrypt_key(key, ctx->key_len * 8, &wctx->ks.ks);
+ else
+ AES_set_decrypt_key(key, ctx->key_len * 8, &wctx->ks.ks);
+ if (!iv)
+ wctx->iv = NULL;
+ }
+ if (iv) {
+ memcpy(ctx->iv, iv, 8);
+ wctx->iv = ctx->iv;
+ }
+ return 1;
+}
+
+static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inlen)
+{
+ EVP_AES_WRAP_CTX *wctx = ctx->cipher_data;
+ size_t rv;
+ if (!in)
+ return 0;
+ if (inlen % 8)
+ return -1;
+ if (ctx->encrypt && inlen < 8)
+ return -1;
+ if (!ctx->encrypt && inlen < 16)
+ return -1;
+ if (!out) {
+ if (ctx->encrypt)
+ return inlen + 8;
+ else
+ return inlen - 8;
+ }
+ if (ctx->encrypt)
+ rv = CRYPTO_128_wrap(&wctx->ks.ks, wctx->iv, out, in, inlen,
+ (block128_f) AES_encrypt);
+ else
+ rv = CRYPTO_128_unwrap(&wctx->ks.ks, wctx->iv, out, in, inlen,
+ (block128_f) AES_decrypt);
+ return rv ? (int)rv : -1;
+}
+
+#define WRAP_FLAGS (EVP_CIPH_WRAP_MODE \
+ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
+ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1)
+
+static const EVP_CIPHER aes_128_wrap = {
+ NID_id_aes128_wrap,
+ 8, 16, 8, WRAP_FLAGS,
+ aes_wrap_init_key, aes_wrap_cipher,
+ NULL,
+ sizeof(EVP_AES_WRAP_CTX),
+ NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_aes_128_wrap(void)
+{
+ return &aes_128_wrap;
+}
+
+static const EVP_CIPHER aes_192_wrap = {
+ NID_id_aes192_wrap,
+ 8, 24, 8, WRAP_FLAGS,
+ aes_wrap_init_key, aes_wrap_cipher,
+ NULL,
+ sizeof(EVP_AES_WRAP_CTX),
+ NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_aes_192_wrap(void)
+{
+ return &aes_192_wrap;
+}
+
+static const EVP_CIPHER aes_256_wrap = {
+ NID_id_aes256_wrap,
+ 8, 32, 8, WRAP_FLAGS,
+ aes_wrap_init_key, aes_wrap_cipher,
+ NULL,
+ sizeof(EVP_AES_WRAP_CTX),
+ NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_aes_256_wrap(void)
+{
+ return &aes_256_wrap;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c b/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c
new file mode 100644
index 00000000..6dfd590a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha1.c
@@ -0,0 +1,1008 @@
+/* ====================================================================
+ * Copyright (c) 2011-2013 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/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1)
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/aes.h>
+# include <openssl/sha.h>
+# include <openssl/rand.h>
+# include "modes_lcl.h"
+# include "constant_time_locl.h"
+
+# ifndef EVP_CIPH_FLAG_AEAD_CIPHER
+# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
+# define EVP_CTRL_AEAD_TLS1_AAD 0x16
+# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
+# endif
+
+# if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1)
+# define EVP_CIPH_FLAG_DEFAULT_ASN1 0
+# endif
+
+# if !defined(EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)
+# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0
+# endif
+
+# define TLS1_1_VERSION 0x0302
+
+typedef struct {
+ AES_KEY ks;
+ SHA_CTX head, tail, md;
+ size_t payload_length; /* AAD length in decrypt case */
+ union {
+ unsigned int tls_ver;
+ unsigned char tls_aad[16]; /* 13 used */
+ } aux;
+} EVP_AES_HMAC_SHA1;
+
+# define NO_PAYLOAD_LENGTH ((size_t)-1)
+
+# if defined(AES_ASM) && ( \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) )
+
+extern unsigned int OPENSSL_ia32cap_P[];
+# define AESNI_CAPABLE (1<<(57-32))
+
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+
+void aesni_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key, unsigned char *ivec, int enc);
+
+void aesni_cbc_sha1_enc(const void *inp, void *out, size_t blocks,
+ const AES_KEY *key, unsigned char iv[16],
+ SHA_CTX *ctx, const void *in0);
+
+void aesni256_cbc_sha1_dec(const void *inp, void *out, size_t blocks,
+ const AES_KEY *key, unsigned char iv[16],
+ SHA_CTX *ctx, const void *in0);
+
+# define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data)
+
+static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
+ const unsigned char *inkey,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_HMAC_SHA1 *key = data(ctx);
+ int ret;
+
+ if (enc)
+ ret = aesni_set_encrypt_key(inkey, ctx->key_len * 8, &key->ks);
+ else
+ ret = aesni_set_decrypt_key(inkey, ctx->key_len * 8, &key->ks);
+
+ SHA1_Init(&key->head); /* handy when benchmarking */
+ key->tail = key->head;
+ key->md = key->head;
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return ret < 0 ? 0 : 1;
+}
+
+# define STITCHED_CALL
+# undef STITCHED_DECRYPT_CALL
+
+# if !defined(STITCHED_CALL)
+# define aes_off 0
+# endif
+
+void sha1_block_data_order(void *c, const void *p, size_t len);
+
+static void sha1_update(SHA_CTX *c, const void *data, size_t len)
+{
+ const unsigned char *ptr = data;
+ size_t res;
+
+ if ((res = c->num)) {
+ res = SHA_CBLOCK - res;
+ if (len < res)
+ res = len;
+ SHA1_Update(c, ptr, res);
+ ptr += res;
+ len -= res;
+ }
+
+ res = len % SHA_CBLOCK;
+ len -= res;
+
+ if (len) {
+ sha1_block_data_order(c, ptr, len / SHA_CBLOCK);
+
+ ptr += len;
+ c->Nh += len >> 29;
+ c->Nl += len <<= 3;
+ if (c->Nl < (unsigned int)len)
+ c->Nh++;
+ }
+
+ if (res)
+ SHA1_Update(c, ptr, res);
+}
+
+# ifdef SHA1_Update
+# undef SHA1_Update
+# endif
+# define SHA1_Update sha1_update
+
+# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+
+typedef struct {
+ unsigned int A[8], B[8], C[8], D[8], E[8];
+} SHA1_MB_CTX;
+typedef struct {
+ const unsigned char *ptr;
+ int blocks;
+} HASH_DESC;
+
+void sha1_multi_block(SHA1_MB_CTX *, const HASH_DESC *, int);
+
+typedef struct {
+ const unsigned char *inp;
+ unsigned char *out;
+ int blocks;
+ u64 iv[2];
+} CIPH_DESC;
+
+void aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int);
+
+static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA1 *key,
+ unsigned char *out,
+ const unsigned char *inp,
+ size_t inp_len, int n4x)
+{ /* n4x is 1 or 2 */
+ HASH_DESC hash_d[8], edges[8];
+ CIPH_DESC ciph_d[8];
+ unsigned char storage[sizeof(SHA1_MB_CTX) + 32];
+ union {
+ u64 q[16];
+ u32 d[32];
+ u8 c[128];
+ } blocks[8];
+ SHA1_MB_CTX *ctx;
+ unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed =
+ 0;
+ size_t ret = 0;
+ u8 *IVs;
+# if defined(BSWAP8)
+ u64 seqnum;
+# endif
+
+ /* ask for IVs in bulk */
+ if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0)
+ return 0;
+
+ ctx = (SHA1_MB_CTX *) (storage + 32 - ((size_t)storage % 32)); /* align */
+
+ frag = (unsigned int)inp_len >> (1 + n4x);
+ last = (unsigned int)inp_len + frag - (frag << (1 + n4x));
+ if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) {
+ frag++;
+ last -= x4 - 1;
+ }
+
+ packlen = 5 + 16 + ((frag + 20 + 16) & -16);
+
+ /* populate descriptors with pointers and IVs */
+ hash_d[0].ptr = inp;
+ ciph_d[0].inp = inp;
+ /* 5+16 is place for header and explicit IV */
+ ciph_d[0].out = out + 5 + 16;
+ memcpy(ciph_d[0].out - 16, IVs, 16);
+ memcpy(ciph_d[0].iv, IVs, 16);
+ IVs += 16;
+
+ for (i = 1; i < x4; i++) {
+ ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag;
+ ciph_d[i].out = ciph_d[i - 1].out + packlen;
+ memcpy(ciph_d[i].out - 16, IVs, 16);
+ memcpy(ciph_d[i].iv, IVs, 16);
+ IVs += 16;
+ }
+
+# if defined(BSWAP8)
+ memcpy(blocks[0].c, key->md.data, 8);
+ seqnum = BSWAP8(blocks[0].q[0]);
+# endif
+ for (i = 0; i < x4; i++) {
+ unsigned int len = (i == (x4 - 1) ? last : frag);
+# if !defined(BSWAP8)
+ unsigned int carry, j;
+# endif
+
+ ctx->A[i] = key->md.h0;
+ ctx->B[i] = key->md.h1;
+ ctx->C[i] = key->md.h2;
+ ctx->D[i] = key->md.h3;
+ ctx->E[i] = key->md.h4;
+
+ /* fix seqnum */
+# if defined(BSWAP8)
+ blocks[i].q[0] = BSWAP8(seqnum + i);
+# else
+ for (carry = i, j = 8; j--;) {
+ blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry;
+ carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1);
+ }
+# endif
+ blocks[i].c[8] = ((u8 *)key->md.data)[8];
+ blocks[i].c[9] = ((u8 *)key->md.data)[9];
+ blocks[i].c[10] = ((u8 *)key->md.data)[10];
+ /* fix length */
+ blocks[i].c[11] = (u8)(len >> 8);
+ blocks[i].c[12] = (u8)(len);
+
+ memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13);
+ hash_d[i].ptr += 64 - 13;
+ hash_d[i].blocks = (len - (64 - 13)) / 64;
+
+ edges[i].ptr = blocks[i].c;
+ edges[i].blocks = 1;
+ }
+
+ /* hash 13-byte headers and first 64-13 bytes of inputs */
+ sha1_multi_block(ctx, edges, n4x);
+ /* hash bulk inputs */
+# define MAXCHUNKSIZE 2048
+# if MAXCHUNKSIZE%64
+# error "MAXCHUNKSIZE is not divisible by 64"
+# elif MAXCHUNKSIZE
+ /*
+ * goal is to minimize pressure on L1 cache by moving in shorter steps,
+ * so that hashed data is still in the cache by the time we encrypt it
+ */
+ minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64;
+ if (minblocks > MAXCHUNKSIZE / 64) {
+ for (i = 0; i < x4; i++) {
+ edges[i].ptr = hash_d[i].ptr;
+ edges[i].blocks = MAXCHUNKSIZE / 64;
+ ciph_d[i].blocks = MAXCHUNKSIZE / 16;
+ }
+ do {
+ sha1_multi_block(ctx, edges, n4x);
+ aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
+
+ for (i = 0; i < x4; i++) {
+ edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE;
+ hash_d[i].blocks -= MAXCHUNKSIZE / 64;
+ edges[i].blocks = MAXCHUNKSIZE / 64;
+ ciph_d[i].inp += MAXCHUNKSIZE;
+ ciph_d[i].out += MAXCHUNKSIZE;
+ ciph_d[i].blocks = MAXCHUNKSIZE / 16;
+ memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16);
+ }
+ processed += MAXCHUNKSIZE;
+ minblocks -= MAXCHUNKSIZE / 64;
+ } while (minblocks > MAXCHUNKSIZE / 64);
+ }
+# endif
+# undef MAXCHUNKSIZE
+ sha1_multi_block(ctx, hash_d, n4x);
+
+ memset(blocks, 0, sizeof(blocks));
+ for (i = 0; i < x4; i++) {
+ unsigned int len = (i == (x4 - 1) ? last : frag),
+ off = hash_d[i].blocks * 64;
+ const unsigned char *ptr = hash_d[i].ptr + off;
+
+ off = (len - processed) - (64 - 13) - off; /* remainder actually */
+ memcpy(blocks[i].c, ptr, off);
+ blocks[i].c[off] = 0x80;
+ len += 64 + 13; /* 64 is HMAC header */
+ len *= 8; /* convert to bits */
+ if (off < (64 - 8)) {
+# ifdef BSWAP4
+ blocks[i].d[15] = BSWAP4(len);
+# else
+ PUTU32(blocks[i].c + 60, len);
+# endif
+ edges[i].blocks = 1;
+ } else {
+# ifdef BSWAP4
+ blocks[i].d[31] = BSWAP4(len);
+# else
+ PUTU32(blocks[i].c + 124, len);
+# endif
+ edges[i].blocks = 2;
+ }
+ edges[i].ptr = blocks[i].c;
+ }
+
+ /* hash input tails and finalize */
+ sha1_multi_block(ctx, edges, n4x);
+
+ memset(blocks, 0, sizeof(blocks));
+ for (i = 0; i < x4; i++) {
+# ifdef BSWAP4
+ blocks[i].d[0] = BSWAP4(ctx->A[i]);
+ ctx->A[i] = key->tail.h0;
+ blocks[i].d[1] = BSWAP4(ctx->B[i]);
+ ctx->B[i] = key->tail.h1;
+ blocks[i].d[2] = BSWAP4(ctx->C[i]);
+ ctx->C[i] = key->tail.h2;
+ blocks[i].d[3] = BSWAP4(ctx->D[i]);
+ ctx->D[i] = key->tail.h3;
+ blocks[i].d[4] = BSWAP4(ctx->E[i]);
+ ctx->E[i] = key->tail.h4;
+ blocks[i].c[20] = 0x80;
+ blocks[i].d[15] = BSWAP4((64 + 20) * 8);
+# else
+ PUTU32(blocks[i].c + 0, ctx->A[i]);
+ ctx->A[i] = key->tail.h0;
+ PUTU32(blocks[i].c + 4, ctx->B[i]);
+ ctx->B[i] = key->tail.h1;
+ PUTU32(blocks[i].c + 8, ctx->C[i]);
+ ctx->C[i] = key->tail.h2;
+ PUTU32(blocks[i].c + 12, ctx->D[i]);
+ ctx->D[i] = key->tail.h3;
+ PUTU32(blocks[i].c + 16, ctx->E[i]);
+ ctx->E[i] = key->tail.h4;
+ blocks[i].c[20] = 0x80;
+ PUTU32(blocks[i].c + 60, (64 + 20) * 8);
+# endif
+ edges[i].ptr = blocks[i].c;
+ edges[i].blocks = 1;
+ }
+
+ /* finalize MACs */
+ sha1_multi_block(ctx, edges, n4x);
+
+ for (i = 0; i < x4; i++) {
+ unsigned int len = (i == (x4 - 1) ? last : frag), pad, j;
+ unsigned char *out0 = out;
+
+ memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed);
+ ciph_d[i].inp = ciph_d[i].out;
+
+ out += 5 + 16 + len;
+
+ /* write MAC */
+ PUTU32(out + 0, ctx->A[i]);
+ PUTU32(out + 4, ctx->B[i]);
+ PUTU32(out + 8, ctx->C[i]);
+ PUTU32(out + 12, ctx->D[i]);
+ PUTU32(out + 16, ctx->E[i]);
+ out += 20;
+ len += 20;
+
+ /* pad */
+ pad = 15 - len % 16;
+ for (j = 0; j <= pad; j++)
+ *(out++) = pad;
+ len += pad + 1;
+
+ ciph_d[i].blocks = (len - processed) / 16;
+ len += 16; /* account for explicit iv */
+
+ /* arrange header */
+ out0[0] = ((u8 *)key->md.data)[8];
+ out0[1] = ((u8 *)key->md.data)[9];
+ out0[2] = ((u8 *)key->md.data)[10];
+ out0[3] = (u8)(len >> 8);
+ out0[4] = (u8)(len);
+
+ ret += len + 5;
+ inp += frag;
+ }
+
+ aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
+
+ OPENSSL_cleanse(blocks, sizeof(blocks));
+ OPENSSL_cleanse(ctx, sizeof(*ctx));
+
+ return ret;
+}
+# endif
+
+static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_HMAC_SHA1 *key = data(ctx);
+ unsigned int l;
+ size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and
+ * later */
+ sha_off = 0;
+# if defined(STITCHED_CALL)
+ size_t aes_off = 0, blocks;
+
+ sha_off = SHA_CBLOCK - key->md.num;
+# endif
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ if (len % AES_BLOCK_SIZE)
+ return 0;
+
+ if (ctx->encrypt) {
+ if (plen == NO_PAYLOAD_LENGTH)
+ plen = len;
+ else if (len !=
+ ((plen + SHA_DIGEST_LENGTH +
+ AES_BLOCK_SIZE) & -AES_BLOCK_SIZE))
+ return 0;
+ else if (key->aux.tls_ver >= TLS1_1_VERSION)
+ iv = AES_BLOCK_SIZE;
+
+# if defined(STITCHED_CALL)
+ if (plen > (sha_off + iv)
+ && (blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) {
+ SHA1_Update(&key->md, in + iv, sha_off);
+
+ aesni_cbc_sha1_enc(in, out, blocks, &key->ks,
+ ctx->iv, &key->md, in + iv + sha_off);
+ blocks *= SHA_CBLOCK;
+ aes_off += blocks;
+ sha_off += blocks;
+ key->md.Nh += blocks >> 29;
+ key->md.Nl += blocks <<= 3;
+ if (key->md.Nl < (unsigned int)blocks)
+ key->md.Nh++;
+ } else {
+ sha_off = 0;
+ }
+# endif
+ sha_off += iv;
+ SHA1_Update(&key->md, in + sha_off, plen - sha_off);
+
+ if (plen != len) { /* "TLS" mode of operation */
+ if (in != out)
+ memcpy(out + aes_off, in + aes_off, plen - aes_off);
+
+ /* calculate HMAC and append it to payload */
+ SHA1_Final(out + plen, &key->md);
+ key->md = key->tail;
+ SHA1_Update(&key->md, out + plen, SHA_DIGEST_LENGTH);
+ SHA1_Final(out + plen, &key->md);
+
+ /* pad the payload|hmac */
+ plen += SHA_DIGEST_LENGTH;
+ for (l = len - plen - 1; plen < len; plen++)
+ out[plen] = l;
+ /* encrypt HMAC|padding at once */
+ aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off,
+ &key->ks, ctx->iv, 1);
+ } else {
+ aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off,
+ &key->ks, ctx->iv, 1);
+ }
+ } else {
+ union {
+ unsigned int u[SHA_DIGEST_LENGTH / sizeof(unsigned int)];
+ unsigned char c[32 + SHA_DIGEST_LENGTH];
+ } mac, *pmac;
+
+ /* arrange cache line alignment */
+ pmac = (void *)(((size_t)mac.c + 31) & ((size_t)0 - 32));
+
+ if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
+ size_t inp_len, mask, j, i;
+ unsigned int res, maxpad, pad, bitlen;
+ int ret = 1;
+ union {
+ unsigned int u[SHA_LBLOCK];
+ unsigned char c[SHA_CBLOCK];
+ } *data = (void *)key->md.data;
+# if defined(STITCHED_DECRYPT_CALL)
+ unsigned char tail_iv[AES_BLOCK_SIZE];
+ int stitch = 0;
+# endif
+
+ if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3])
+ >= TLS1_1_VERSION) {
+ if (len < (AES_BLOCK_SIZE + SHA_DIGEST_LENGTH + 1))
+ return 0;
+
+ /* omit explicit iv */
+ memcpy(ctx->iv, in, AES_BLOCK_SIZE);
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ len -= AES_BLOCK_SIZE;
+ } else if (len < (SHA_DIGEST_LENGTH + 1))
+ return 0;
+
+# if defined(STITCHED_DECRYPT_CALL)
+ if (len >= 1024 && ctx->key_len == 32) {
+ /* decrypt last block */
+ memcpy(tail_iv, in + len - 2 * AES_BLOCK_SIZE,
+ AES_BLOCK_SIZE);
+ aesni_cbc_encrypt(in + len - AES_BLOCK_SIZE,
+ out + len - AES_BLOCK_SIZE, AES_BLOCK_SIZE,
+ &key->ks, tail_iv, 0);
+ stitch = 1;
+ } else
+# endif
+ /* decrypt HMAC|padding at once */
+ aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0);
+
+ /* figure out payload length */
+ pad = out[len - 1];
+ maxpad = len - (SHA_DIGEST_LENGTH + 1);
+ maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
+ maxpad &= 255;
+
+ ret &= constant_time_ge(maxpad, pad);
+
+ inp_len = len - (SHA_DIGEST_LENGTH + pad + 1);
+ mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1)));
+ inp_len &= mask;
+ ret &= (int)mask;
+
+ key->aux.tls_aad[plen - 2] = inp_len >> 8;
+ key->aux.tls_aad[plen - 1] = inp_len;
+
+ /* calculate HMAC */
+ key->md = key->head;
+ SHA1_Update(&key->md, key->aux.tls_aad, plen);
+
+# if defined(STITCHED_DECRYPT_CALL)
+ if (stitch) {
+ blocks = (len - (256 + 32 + SHA_CBLOCK)) / SHA_CBLOCK;
+ aes_off = len - AES_BLOCK_SIZE - blocks * SHA_CBLOCK;
+ sha_off = SHA_CBLOCK - plen;
+
+ aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0);
+
+ SHA1_Update(&key->md, out, sha_off);
+ aesni256_cbc_sha1_dec(in + aes_off,
+ out + aes_off, blocks, &key->ks,
+ ctx->iv, &key->md, out + sha_off);
+
+ sha_off += blocks *= SHA_CBLOCK;
+ out += sha_off;
+ len -= sha_off;
+ inp_len -= sha_off;
+
+ key->md.Nl += (blocks << 3); /* at most 18 bits */
+ memcpy(ctx->iv, tail_iv, AES_BLOCK_SIZE);
+ }
+# endif
+
+# if 1
+ len -= SHA_DIGEST_LENGTH; /* amend mac */
+ if (len >= (256 + SHA_CBLOCK)) {
+ j = (len - (256 + SHA_CBLOCK)) & (0 - SHA_CBLOCK);
+ j += SHA_CBLOCK - key->md.num;
+ SHA1_Update(&key->md, out, j);
+ out += j;
+ len -= j;
+ inp_len -= j;
+ }
+
+ /* but pretend as if we hashed padded payload */
+ bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */
+# ifdef BSWAP4
+ bitlen = BSWAP4(bitlen);
+# else
+ mac.c[0] = 0;
+ mac.c[1] = (unsigned char)(bitlen >> 16);
+ mac.c[2] = (unsigned char)(bitlen >> 8);
+ mac.c[3] = (unsigned char)bitlen;
+ bitlen = mac.u[0];
+# endif
+
+ pmac->u[0] = 0;
+ pmac->u[1] = 0;
+ pmac->u[2] = 0;
+ pmac->u[3] = 0;
+ pmac->u[4] = 0;
+
+ for (res = key->md.num, j = 0; j < len; j++) {
+ size_t c = out[j];
+ mask = (j - inp_len) >> (sizeof(j) * 8 - 8);
+ c &= mask;
+ c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8));
+ data->c[res++] = (unsigned char)c;
+
+ if (res != SHA_CBLOCK)
+ continue;
+
+ /* j is not incremented yet */
+ mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1));
+ data->u[SHA_LBLOCK - 1] |= bitlen & mask;
+ sha1_block_data_order(&key->md, data, 1);
+ mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1));
+ pmac->u[0] |= key->md.h0 & mask;
+ pmac->u[1] |= key->md.h1 & mask;
+ pmac->u[2] |= key->md.h2 & mask;
+ pmac->u[3] |= key->md.h3 & mask;
+ pmac->u[4] |= key->md.h4 & mask;
+ res = 0;
+ }
+
+ for (i = res; i < SHA_CBLOCK; i++, j++)
+ data->c[i] = 0;
+
+ if (res > SHA_CBLOCK - 8) {
+ mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1));
+ data->u[SHA_LBLOCK - 1] |= bitlen & mask;
+ sha1_block_data_order(&key->md, data, 1);
+ mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
+ pmac->u[0] |= key->md.h0 & mask;
+ pmac->u[1] |= key->md.h1 & mask;
+ pmac->u[2] |= key->md.h2 & mask;
+ pmac->u[3] |= key->md.h3 & mask;
+ pmac->u[4] |= key->md.h4 & mask;
+
+ memset(data, 0, SHA_CBLOCK);
+ j += 64;
+ }
+ data->u[SHA_LBLOCK - 1] = bitlen;
+ sha1_block_data_order(&key->md, data, 1);
+ mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
+ pmac->u[0] |= key->md.h0 & mask;
+ pmac->u[1] |= key->md.h1 & mask;
+ pmac->u[2] |= key->md.h2 & mask;
+ pmac->u[3] |= key->md.h3 & mask;
+ pmac->u[4] |= key->md.h4 & mask;
+
+# ifdef BSWAP4
+ pmac->u[0] = BSWAP4(pmac->u[0]);
+ pmac->u[1] = BSWAP4(pmac->u[1]);
+ pmac->u[2] = BSWAP4(pmac->u[2]);
+ pmac->u[3] = BSWAP4(pmac->u[3]);
+ pmac->u[4] = BSWAP4(pmac->u[4]);
+# else
+ for (i = 0; i < 5; i++) {
+ res = pmac->u[i];
+ pmac->c[4 * i + 0] = (unsigned char)(res >> 24);
+ pmac->c[4 * i + 1] = (unsigned char)(res >> 16);
+ pmac->c[4 * i + 2] = (unsigned char)(res >> 8);
+ pmac->c[4 * i + 3] = (unsigned char)res;
+ }
+# endif
+ len += SHA_DIGEST_LENGTH;
+# else
+ SHA1_Update(&key->md, out, inp_len);
+ res = key->md.num;
+ SHA1_Final(pmac->c, &key->md);
+
+ {
+ unsigned int inp_blocks, pad_blocks;
+
+ /* but pretend as if we hashed padded payload */
+ inp_blocks =
+ 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
+ res += (unsigned int)(len - inp_len);
+ pad_blocks = res / SHA_CBLOCK;
+ res %= SHA_CBLOCK;
+ pad_blocks +=
+ 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
+ for (; inp_blocks < pad_blocks; inp_blocks++)
+ sha1_block_data_order(&key->md, data, 1);
+ }
+# endif
+ key->md = key->tail;
+ SHA1_Update(&key->md, pmac->c, SHA_DIGEST_LENGTH);
+ SHA1_Final(pmac->c, &key->md);
+
+ /* verify HMAC */
+ out += inp_len;
+ len -= inp_len;
+# if 1
+ {
+ unsigned char *p = out + len - 1 - maxpad - SHA_DIGEST_LENGTH;
+ size_t off = out - p;
+ unsigned int c, cmask;
+
+ maxpad += SHA_DIGEST_LENGTH;
+ for (res = 0, i = 0, j = 0; j < maxpad; j++) {
+ c = p[j];
+ cmask =
+ ((int)(j - off - SHA_DIGEST_LENGTH)) >> (sizeof(int) *
+ 8 - 1);
+ res |= (c ^ pad) & ~cmask; /* ... and padding */
+ cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1);
+ res |= (c ^ pmac->c[i]) & cmask;
+ i += 1 & cmask;
+ }
+ maxpad -= SHA_DIGEST_LENGTH;
+
+ res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+ ret &= (int)~res;
+ }
+# else
+ for (res = 0, i = 0; i < SHA_DIGEST_LENGTH; i++)
+ res |= out[i] ^ pmac->c[i];
+ res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+ ret &= (int)~res;
+
+ /* verify padding */
+ pad = (pad & ~res) | (maxpad & res);
+ out = out + len - 1 - pad;
+ for (res = 0, i = 0; i < pad; i++)
+ res |= out[i] ^ pad;
+
+ res = (0 - res) >> (sizeof(res) * 8 - 1);
+ ret &= (int)~res;
+# endif
+ return ret;
+ } else {
+# if defined(STITCHED_DECRYPT_CALL)
+ if (len >= 1024 && ctx->key_len == 32) {
+ if (sha_off %= SHA_CBLOCK)
+ blocks = (len - 3 * SHA_CBLOCK) / SHA_CBLOCK;
+ else
+ blocks = (len - 2 * SHA_CBLOCK) / SHA_CBLOCK;
+ aes_off = len - blocks * SHA_CBLOCK;
+
+ aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0);
+ SHA1_Update(&key->md, out, sha_off);
+ aesni256_cbc_sha1_dec(in + aes_off,
+ out + aes_off, blocks, &key->ks,
+ ctx->iv, &key->md, out + sha_off);
+
+ sha_off += blocks *= SHA_CBLOCK;
+ out += sha_off;
+ len -= sha_off;
+
+ key->md.Nh += blocks >> 29;
+ key->md.Nl += blocks <<= 3;
+ if (key->md.Nl < (unsigned int)blocks)
+ key->md.Nh++;
+ } else
+# endif
+ /* decrypt HMAC|padding at once */
+ aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0);
+
+ SHA1_Update(&key->md, out, len);
+ }
+ }
+
+ return 1;
+}
+
+static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
+ void *ptr)
+{
+ EVP_AES_HMAC_SHA1 *key = data(ctx);
+
+ switch (type) {
+ case EVP_CTRL_AEAD_SET_MAC_KEY:
+ {
+ unsigned int i;
+ unsigned char hmac_key[64];
+
+ memset(hmac_key, 0, sizeof(hmac_key));
+
+ if (arg > (int)sizeof(hmac_key)) {
+ SHA1_Init(&key->head);
+ SHA1_Update(&key->head, ptr, arg);
+ SHA1_Final(hmac_key, &key->head);
+ } else {
+ memcpy(hmac_key, ptr, arg);
+ }
+
+ for (i = 0; i < sizeof(hmac_key); i++)
+ hmac_key[i] ^= 0x36; /* ipad */
+ SHA1_Init(&key->head);
+ SHA1_Update(&key->head, hmac_key, sizeof(hmac_key));
+
+ for (i = 0; i < sizeof(hmac_key); i++)
+ hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */
+ SHA1_Init(&key->tail);
+ SHA1_Update(&key->tail, hmac_key, sizeof(hmac_key));
+
+ OPENSSL_cleanse(hmac_key, sizeof(hmac_key));
+
+ return 1;
+ }
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ {
+ unsigned char *p = ptr;
+ unsigned int len;
+
+ if (arg != EVP_AEAD_TLS1_AAD_LEN)
+ return -1;
+
+ len = p[arg - 2] << 8 | p[arg - 1];
+
+ if (ctx->encrypt) {
+ key->payload_length = len;
+ if ((key->aux.tls_ver =
+ p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
+ len -= AES_BLOCK_SIZE;
+ p[arg - 2] = len >> 8;
+ p[arg - 1] = len;
+ }
+ key->md = key->head;
+ SHA1_Update(&key->md, p, arg);
+
+ return (int)(((len + SHA_DIGEST_LENGTH +
+ AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)
+ - len);
+ } else {
+ memcpy(key->aux.tls_aad, ptr, arg);
+ key->payload_length = arg;
+
+ return SHA_DIGEST_LENGTH;
+ }
+ }
+# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE:
+ return (int)(5 + 16 + ((arg + 20 + 16) & -16));
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD:
+ {
+ EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
+ (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
+ unsigned int n4x = 1, x4;
+ unsigned int frag, last, packlen, inp_len;
+
+ if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM))
+ return -1;
+
+ inp_len = param->inp[11] << 8 | param->inp[12];
+
+ if (ctx->encrypt) {
+ if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION)
+ return -1;
+
+ if (inp_len) {
+ if (inp_len < 4096)
+ return 0; /* too short */
+
+ if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5))
+ n4x = 2; /* AVX2 */
+ } else if ((n4x = param->interleave / 4) && n4x <= 2)
+ inp_len = param->len;
+ else
+ return -1;
+
+ key->md = key->head;
+ SHA1_Update(&key->md, param->inp, 13);
+
+ x4 = 4 * n4x;
+ n4x += 1;
+
+ frag = inp_len >> n4x;
+ last = inp_len + frag - (frag << n4x);
+ if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) {
+ frag++;
+ last -= x4 - 1;
+ }
+
+ packlen = 5 + 16 + ((frag + 20 + 16) & -16);
+ packlen = (packlen << n4x) - packlen;
+ packlen += 5 + 16 + ((last + 20 + 16) & -16);
+
+ param->interleave = x4;
+
+ return (int)packlen;
+ } else
+ return -1; /* not yet */
+ }
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT:
+ {
+ EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
+ (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
+
+ return (int)tls1_1_multi_block_encrypt(key, param->out,
+ param->inp, param->len,
+ param->interleave / 4);
+ }
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT:
+# endif
+ default:
+ return -1;
+ }
+}
+
+static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher = {
+# ifdef NID_aes_128_cbc_hmac_sha1
+ NID_aes_128_cbc_hmac_sha1,
+# else
+ NID_undef,
+# endif
+ 16, 16, 16,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+ aesni_cbc_hmac_sha1_init_key,
+ aesni_cbc_hmac_sha1_cipher,
+ NULL,
+ sizeof(EVP_AES_HMAC_SHA1),
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
+ aesni_cbc_hmac_sha1_ctrl,
+ NULL
+};
+
+static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher = {
+# ifdef NID_aes_256_cbc_hmac_sha1
+ NID_aes_256_cbc_hmac_sha1,
+# else
+ NID_undef,
+# endif
+ 16, 32, 16,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+ aesni_cbc_hmac_sha1_init_key,
+ aesni_cbc_hmac_sha1_cipher,
+ NULL,
+ sizeof(EVP_AES_HMAC_SHA1),
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
+ aesni_cbc_hmac_sha1_ctrl,
+ NULL
+};
+
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
+{
+ return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ?
+ &aesni_128_cbc_hmac_sha1_cipher : NULL);
+}
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
+{
+ return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ?
+ &aesni_256_cbc_hmac_sha1_cipher : NULL);
+}
+# else
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
+{
+ return NULL;
+}
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
+{
+ return NULL;
+}
+# endif
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c b/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c
new file mode 100644
index 00000000..46c9d033
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_aes_cbc_hmac_sha256.c
@@ -0,0 +1,985 @@
+/* ====================================================================
+ * Copyright (c) 2011-2013 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/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA256)
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/aes.h>
+# include <openssl/sha.h>
+# include <openssl/rand.h>
+# include "modes_lcl.h"
+# include "constant_time_locl.h"
+
+# ifndef EVP_CIPH_FLAG_AEAD_CIPHER
+# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
+# define EVP_CTRL_AEAD_TLS1_AAD 0x16
+# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
+# endif
+
+# if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1)
+# define EVP_CIPH_FLAG_DEFAULT_ASN1 0
+# endif
+
+# if !defined(EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)
+# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0
+# endif
+
+# define TLS1_1_VERSION 0x0302
+
+typedef struct {
+ AES_KEY ks;
+ SHA256_CTX head, tail, md;
+ size_t payload_length; /* AAD length in decrypt case */
+ union {
+ unsigned int tls_ver;
+ unsigned char tls_aad[16]; /* 13 used */
+ } aux;
+} EVP_AES_HMAC_SHA256;
+
+# define NO_PAYLOAD_LENGTH ((size_t)-1)
+
+# if defined(AES_ASM) && ( \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) )
+
+extern unsigned int OPENSSL_ia32cap_P[];
+# define AESNI_CAPABLE (1<<(57-32))
+
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+
+void aesni_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key, unsigned char *ivec, int enc);
+
+int aesni_cbc_sha256_enc(const void *inp, void *out, size_t blocks,
+ const AES_KEY *key, unsigned char iv[16],
+ SHA256_CTX *ctx, const void *in0);
+
+# define data(ctx) ((EVP_AES_HMAC_SHA256 *)(ctx)->cipher_data)
+
+static int aesni_cbc_hmac_sha256_init_key(EVP_CIPHER_CTX *ctx,
+ const unsigned char *inkey,
+ const unsigned char *iv, int enc)
+{
+ EVP_AES_HMAC_SHA256 *key = data(ctx);
+ int ret;
+
+ if (enc)
+ memset(&key->ks, 0, sizeof(key->ks.rd_key)),
+ ret = aesni_set_encrypt_key(inkey, ctx->key_len * 8, &key->ks);
+ else
+ ret = aesni_set_decrypt_key(inkey, ctx->key_len * 8, &key->ks);
+
+ SHA256_Init(&key->head); /* handy when benchmarking */
+ key->tail = key->head;
+ key->md = key->head;
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return ret < 0 ? 0 : 1;
+}
+
+# define STITCHED_CALL
+
+# if !defined(STITCHED_CALL)
+# define aes_off 0
+# endif
+
+void sha256_block_data_order(void *c, const void *p, size_t len);
+
+static void sha256_update(SHA256_CTX *c, const void *data, size_t len)
+{
+ const unsigned char *ptr = data;
+ size_t res;
+
+ if ((res = c->num)) {
+ res = SHA256_CBLOCK - res;
+ if (len < res)
+ res = len;
+ SHA256_Update(c, ptr, res);
+ ptr += res;
+ len -= res;
+ }
+
+ res = len % SHA256_CBLOCK;
+ len -= res;
+
+ if (len) {
+ sha256_block_data_order(c, ptr, len / SHA256_CBLOCK);
+
+ ptr += len;
+ c->Nh += len >> 29;
+ c->Nl += len <<= 3;
+ if (c->Nl < (unsigned int)len)
+ c->Nh++;
+ }
+
+ if (res)
+ SHA256_Update(c, ptr, res);
+}
+
+# ifdef SHA256_Update
+# undef SHA256_Update
+# endif
+# define SHA256_Update sha256_update
+
+# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+
+typedef struct {
+ unsigned int A[8], B[8], C[8], D[8], E[8], F[8], G[8], H[8];
+} SHA256_MB_CTX;
+typedef struct {
+ const unsigned char *ptr;
+ int blocks;
+} HASH_DESC;
+
+void sha256_multi_block(SHA256_MB_CTX *, const HASH_DESC *, int);
+
+typedef struct {
+ const unsigned char *inp;
+ unsigned char *out;
+ int blocks;
+ u64 iv[2];
+} CIPH_DESC;
+
+void aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int);
+
+static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA256 *key,
+ unsigned char *out,
+ const unsigned char *inp,
+ size_t inp_len, int n4x)
+{ /* n4x is 1 or 2 */
+ HASH_DESC hash_d[8], edges[8];
+ CIPH_DESC ciph_d[8];
+ unsigned char storage[sizeof(SHA256_MB_CTX) + 32];
+ union {
+ u64 q[16];
+ u32 d[32];
+ u8 c[128];
+ } blocks[8];
+ SHA256_MB_CTX *ctx;
+ unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed =
+ 0;
+ size_t ret = 0;
+ u8 *IVs;
+# if defined(BSWAP8)
+ u64 seqnum;
+# endif
+
+ /* ask for IVs in bulk */
+ if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0)
+ return 0;
+
+ /* align */
+ ctx = (SHA256_MB_CTX *) (storage + 32 - ((size_t)storage % 32));
+
+ frag = (unsigned int)inp_len >> (1 + n4x);
+ last = (unsigned int)inp_len + frag - (frag << (1 + n4x));
+ if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) {
+ frag++;
+ last -= x4 - 1;
+ }
+
+ packlen = 5 + 16 + ((frag + 32 + 16) & -16);
+
+ /* populate descriptors with pointers and IVs */
+ hash_d[0].ptr = inp;
+ ciph_d[0].inp = inp;
+ /* 5+16 is place for header and explicit IV */
+ ciph_d[0].out = out + 5 + 16;
+ memcpy(ciph_d[0].out - 16, IVs, 16);
+ memcpy(ciph_d[0].iv, IVs, 16);
+ IVs += 16;
+
+ for (i = 1; i < x4; i++) {
+ ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag;
+ ciph_d[i].out = ciph_d[i - 1].out + packlen;
+ memcpy(ciph_d[i].out - 16, IVs, 16);
+ memcpy(ciph_d[i].iv, IVs, 16);
+ IVs += 16;
+ }
+
+# if defined(BSWAP8)
+ memcpy(blocks[0].c, key->md.data, 8);
+ seqnum = BSWAP8(blocks[0].q[0]);
+# endif
+ for (i = 0; i < x4; i++) {
+ unsigned int len = (i == (x4 - 1) ? last : frag);
+# if !defined(BSWAP8)
+ unsigned int carry, j;
+# endif
+
+ ctx->A[i] = key->md.h[0];
+ ctx->B[i] = key->md.h[1];
+ ctx->C[i] = key->md.h[2];
+ ctx->D[i] = key->md.h[3];
+ ctx->E[i] = key->md.h[4];
+ ctx->F[i] = key->md.h[5];
+ ctx->G[i] = key->md.h[6];
+ ctx->H[i] = key->md.h[7];
+
+ /* fix seqnum */
+# if defined(BSWAP8)
+ blocks[i].q[0] = BSWAP8(seqnum + i);
+# else
+ for (carry = i, j = 8; j--;) {
+ blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry;
+ carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1);
+ }
+# endif
+ blocks[i].c[8] = ((u8 *)key->md.data)[8];
+ blocks[i].c[9] = ((u8 *)key->md.data)[9];
+ blocks[i].c[10] = ((u8 *)key->md.data)[10];
+ /* fix length */
+ blocks[i].c[11] = (u8)(len >> 8);
+ blocks[i].c[12] = (u8)(len);
+
+ memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13);
+ hash_d[i].ptr += 64 - 13;
+ hash_d[i].blocks = (len - (64 - 13)) / 64;
+
+ edges[i].ptr = blocks[i].c;
+ edges[i].blocks = 1;
+ }
+
+ /* hash 13-byte headers and first 64-13 bytes of inputs */
+ sha256_multi_block(ctx, edges, n4x);
+ /* hash bulk inputs */
+# define MAXCHUNKSIZE 2048
+# if MAXCHUNKSIZE%64
+# error "MAXCHUNKSIZE is not divisible by 64"
+# elif MAXCHUNKSIZE
+ /*
+ * goal is to minimize pressure on L1 cache by moving in shorter steps,
+ * so that hashed data is still in the cache by the time we encrypt it
+ */
+ minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64;
+ if (minblocks > MAXCHUNKSIZE / 64) {
+ for (i = 0; i < x4; i++) {
+ edges[i].ptr = hash_d[i].ptr;
+ edges[i].blocks = MAXCHUNKSIZE / 64;
+ ciph_d[i].blocks = MAXCHUNKSIZE / 16;
+ }
+ do {
+ sha256_multi_block(ctx, edges, n4x);
+ aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
+
+ for (i = 0; i < x4; i++) {
+ edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE;
+ hash_d[i].blocks -= MAXCHUNKSIZE / 64;
+ edges[i].blocks = MAXCHUNKSIZE / 64;
+ ciph_d[i].inp += MAXCHUNKSIZE;
+ ciph_d[i].out += MAXCHUNKSIZE;
+ ciph_d[i].blocks = MAXCHUNKSIZE / 16;
+ memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16);
+ }
+ processed += MAXCHUNKSIZE;
+ minblocks -= MAXCHUNKSIZE / 64;
+ } while (minblocks > MAXCHUNKSIZE / 64);
+ }
+# endif
+# undef MAXCHUNKSIZE
+ sha256_multi_block(ctx, hash_d, n4x);
+
+ memset(blocks, 0, sizeof(blocks));
+ for (i = 0; i < x4; i++) {
+ unsigned int len = (i == (x4 - 1) ? last : frag),
+ off = hash_d[i].blocks * 64;
+ const unsigned char *ptr = hash_d[i].ptr + off;
+
+ off = (len - processed) - (64 - 13) - off; /* remainder actually */
+ memcpy(blocks[i].c, ptr, off);
+ blocks[i].c[off] = 0x80;
+ len += 64 + 13; /* 64 is HMAC header */
+ len *= 8; /* convert to bits */
+ if (off < (64 - 8)) {
+# ifdef BSWAP4
+ blocks[i].d[15] = BSWAP4(len);
+# else
+ PUTU32(blocks[i].c + 60, len);
+# endif
+ edges[i].blocks = 1;
+ } else {
+# ifdef BSWAP4
+ blocks[i].d[31] = BSWAP4(len);
+# else
+ PUTU32(blocks[i].c + 124, len);
+# endif
+ edges[i].blocks = 2;
+ }
+ edges[i].ptr = blocks[i].c;
+ }
+
+ /* hash input tails and finalize */
+ sha256_multi_block(ctx, edges, n4x);
+
+ memset(blocks, 0, sizeof(blocks));
+ for (i = 0; i < x4; i++) {
+# ifdef BSWAP4
+ blocks[i].d[0] = BSWAP4(ctx->A[i]);
+ ctx->A[i] = key->tail.h[0];
+ blocks[i].d[1] = BSWAP4(ctx->B[i]);
+ ctx->B[i] = key->tail.h[1];
+ blocks[i].d[2] = BSWAP4(ctx->C[i]);
+ ctx->C[i] = key->tail.h[2];
+ blocks[i].d[3] = BSWAP4(ctx->D[i]);
+ ctx->D[i] = key->tail.h[3];
+ blocks[i].d[4] = BSWAP4(ctx->E[i]);
+ ctx->E[i] = key->tail.h[4];
+ blocks[i].d[5] = BSWAP4(ctx->F[i]);
+ ctx->F[i] = key->tail.h[5];
+ blocks[i].d[6] = BSWAP4(ctx->G[i]);
+ ctx->G[i] = key->tail.h[6];
+ blocks[i].d[7] = BSWAP4(ctx->H[i]);
+ ctx->H[i] = key->tail.h[7];
+ blocks[i].c[32] = 0x80;
+ blocks[i].d[15] = BSWAP4((64 + 32) * 8);
+# else
+ PUTU32(blocks[i].c + 0, ctx->A[i]);
+ ctx->A[i] = key->tail.h[0];
+ PUTU32(blocks[i].c + 4, ctx->B[i]);
+ ctx->B[i] = key->tail.h[1];
+ PUTU32(blocks[i].c + 8, ctx->C[i]);
+ ctx->C[i] = key->tail.h[2];
+ PUTU32(blocks[i].c + 12, ctx->D[i]);
+ ctx->D[i] = key->tail.h[3];
+ PUTU32(blocks[i].c + 16, ctx->E[i]);
+ ctx->E[i] = key->tail.h[4];
+ PUTU32(blocks[i].c + 20, ctx->F[i]);
+ ctx->F[i] = key->tail.h[5];
+ PUTU32(blocks[i].c + 24, ctx->G[i]);
+ ctx->G[i] = key->tail.h[6];
+ PUTU32(blocks[i].c + 28, ctx->H[i]);
+ ctx->H[i] = key->tail.h[7];
+ blocks[i].c[32] = 0x80;
+ PUTU32(blocks[i].c + 60, (64 + 32) * 8);
+# endif
+ edges[i].ptr = blocks[i].c;
+ edges[i].blocks = 1;
+ }
+
+ /* finalize MACs */
+ sha256_multi_block(ctx, edges, n4x);
+
+ for (i = 0; i < x4; i++) {
+ unsigned int len = (i == (x4 - 1) ? last : frag), pad, j;
+ unsigned char *out0 = out;
+
+ memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed);
+ ciph_d[i].inp = ciph_d[i].out;
+
+ out += 5 + 16 + len;
+
+ /* write MAC */
+ PUTU32(out + 0, ctx->A[i]);
+ PUTU32(out + 4, ctx->B[i]);
+ PUTU32(out + 8, ctx->C[i]);
+ PUTU32(out + 12, ctx->D[i]);
+ PUTU32(out + 16, ctx->E[i]);
+ PUTU32(out + 20, ctx->F[i]);
+ PUTU32(out + 24, ctx->G[i]);
+ PUTU32(out + 28, ctx->H[i]);
+ out += 32;
+ len += 32;
+
+ /* pad */
+ pad = 15 - len % 16;
+ for (j = 0; j <= pad; j++)
+ *(out++) = pad;
+ len += pad + 1;
+
+ ciph_d[i].blocks = (len - processed) / 16;
+ len += 16; /* account for explicit iv */
+
+ /* arrange header */
+ out0[0] = ((u8 *)key->md.data)[8];
+ out0[1] = ((u8 *)key->md.data)[9];
+ out0[2] = ((u8 *)key->md.data)[10];
+ out0[3] = (u8)(len >> 8);
+ out0[4] = (u8)(len);
+
+ ret += len + 5;
+ inp += frag;
+ }
+
+ aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
+
+ OPENSSL_cleanse(blocks, sizeof(blocks));
+ OPENSSL_cleanse(ctx, sizeof(*ctx));
+
+ return ret;
+}
+# endif
+
+static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx,
+ unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_AES_HMAC_SHA256 *key = data(ctx);
+ unsigned int l;
+ size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and
+ * later */
+ sha_off = 0;
+# if defined(STITCHED_CALL)
+ size_t aes_off = 0, blocks;
+
+ sha_off = SHA256_CBLOCK - key->md.num;
+# endif
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ if (len % AES_BLOCK_SIZE)
+ return 0;
+
+ if (ctx->encrypt) {
+ if (plen == NO_PAYLOAD_LENGTH)
+ plen = len;
+ else if (len !=
+ ((plen + SHA256_DIGEST_LENGTH +
+ AES_BLOCK_SIZE) & -AES_BLOCK_SIZE))
+ return 0;
+ else if (key->aux.tls_ver >= TLS1_1_VERSION)
+ iv = AES_BLOCK_SIZE;
+
+# if defined(STITCHED_CALL)
+ /*
+ * Assembly stitch handles AVX-capable processors, but its
+ * performance is not optimal on AMD Jaguar, ~40% worse, for
+ * unknown reasons. Incidentally processor in question supports
+ * AVX, but not AMD-specific XOP extension, which can be used
+ * to identify it and avoid stitch invocation. So that after we
+ * establish that current CPU supports AVX, we even see if it's
+ * either even XOP-capable Bulldozer-based or GenuineIntel one.
+ */
+ if (OPENSSL_ia32cap_P[1] & (1 << (60 - 32)) && /* AVX? */
+ ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */
+ | (OPENSSL_ia32cap_P[0] & (1<<30))) && /* "Intel CPU"? */
+ plen > (sha_off + iv) &&
+ (blocks = (plen - (sha_off + iv)) / SHA256_CBLOCK)) {
+ SHA256_Update(&key->md, in + iv, sha_off);
+
+ (void)aesni_cbc_sha256_enc(in, out, blocks, &key->ks,
+ ctx->iv, &key->md, in + iv + sha_off);
+ blocks *= SHA256_CBLOCK;
+ aes_off += blocks;
+ sha_off += blocks;
+ key->md.Nh += blocks >> 29;
+ key->md.Nl += blocks <<= 3;
+ if (key->md.Nl < (unsigned int)blocks)
+ key->md.Nh++;
+ } else {
+ sha_off = 0;
+ }
+# endif
+ sha_off += iv;
+ SHA256_Update(&key->md, in + sha_off, plen - sha_off);
+
+ if (plen != len) { /* "TLS" mode of operation */
+ if (in != out)
+ memcpy(out + aes_off, in + aes_off, plen - aes_off);
+
+ /* calculate HMAC and append it to payload */
+ SHA256_Final(out + plen, &key->md);
+ key->md = key->tail;
+ SHA256_Update(&key->md, out + plen, SHA256_DIGEST_LENGTH);
+ SHA256_Final(out + plen, &key->md);
+
+ /* pad the payload|hmac */
+ plen += SHA256_DIGEST_LENGTH;
+ for (l = len - plen - 1; plen < len; plen++)
+ out[plen] = l;
+ /* encrypt HMAC|padding at once */
+ aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off,
+ &key->ks, ctx->iv, 1);
+ } else {
+ aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off,
+ &key->ks, ctx->iv, 1);
+ }
+ } else {
+ union {
+ unsigned int u[SHA256_DIGEST_LENGTH / sizeof(unsigned int)];
+ unsigned char c[64 + SHA256_DIGEST_LENGTH];
+ } mac, *pmac;
+
+ /* arrange cache line alignment */
+ pmac = (void *)(((size_t)mac.c + 63) & ((size_t)0 - 64));
+
+ /* decrypt HMAC|padding at once */
+ aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0);
+
+ if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
+ size_t inp_len, mask, j, i;
+ unsigned int res, maxpad, pad, bitlen;
+ int ret = 1;
+ union {
+ unsigned int u[SHA_LBLOCK];
+ unsigned char c[SHA256_CBLOCK];
+ } *data = (void *)key->md.data;
+
+ if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3])
+ >= TLS1_1_VERSION)
+ iv = AES_BLOCK_SIZE;
+
+ if (len < (iv + SHA256_DIGEST_LENGTH + 1))
+ return 0;
+
+ /* omit explicit iv */
+ out += iv;
+ len -= iv;
+
+ /* figure out payload length */
+ pad = out[len - 1];
+ maxpad = len - (SHA256_DIGEST_LENGTH + 1);
+ maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
+ maxpad &= 255;
+
+ ret &= constant_time_ge(maxpad, pad);
+
+ inp_len = len - (SHA256_DIGEST_LENGTH + pad + 1);
+ mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1)));
+ inp_len &= mask;
+ ret &= (int)mask;
+
+ key->aux.tls_aad[plen - 2] = inp_len >> 8;
+ key->aux.tls_aad[plen - 1] = inp_len;
+
+ /* calculate HMAC */
+ key->md = key->head;
+ SHA256_Update(&key->md, key->aux.tls_aad, plen);
+
+# if 1
+ len -= SHA256_DIGEST_LENGTH; /* amend mac */
+ if (len >= (256 + SHA256_CBLOCK)) {
+ j = (len - (256 + SHA256_CBLOCK)) & (0 - SHA256_CBLOCK);
+ j += SHA256_CBLOCK - key->md.num;
+ SHA256_Update(&key->md, out, j);
+ out += j;
+ len -= j;
+ inp_len -= j;
+ }
+
+ /* but pretend as if we hashed padded payload */
+ bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */
+# ifdef BSWAP4
+ bitlen = BSWAP4(bitlen);
+# else
+ mac.c[0] = 0;
+ mac.c[1] = (unsigned char)(bitlen >> 16);
+ mac.c[2] = (unsigned char)(bitlen >> 8);
+ mac.c[3] = (unsigned char)bitlen;
+ bitlen = mac.u[0];
+# endif
+
+ pmac->u[0] = 0;
+ pmac->u[1] = 0;
+ pmac->u[2] = 0;
+ pmac->u[3] = 0;
+ pmac->u[4] = 0;
+ pmac->u[5] = 0;
+ pmac->u[6] = 0;
+ pmac->u[7] = 0;
+
+ for (res = key->md.num, j = 0; j < len; j++) {
+ size_t c = out[j];
+ mask = (j - inp_len) >> (sizeof(j) * 8 - 8);
+ c &= mask;
+ c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8));
+ data->c[res++] = (unsigned char)c;
+
+ if (res != SHA256_CBLOCK)
+ continue;
+
+ /* j is not incremented yet */
+ mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1));
+ data->u[SHA_LBLOCK - 1] |= bitlen & mask;
+ sha256_block_data_order(&key->md, data, 1);
+ mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1));
+ pmac->u[0] |= key->md.h[0] & mask;
+ pmac->u[1] |= key->md.h[1] & mask;
+ pmac->u[2] |= key->md.h[2] & mask;
+ pmac->u[3] |= key->md.h[3] & mask;
+ pmac->u[4] |= key->md.h[4] & mask;
+ pmac->u[5] |= key->md.h[5] & mask;
+ pmac->u[6] |= key->md.h[6] & mask;
+ pmac->u[7] |= key->md.h[7] & mask;
+ res = 0;
+ }
+
+ for (i = res; i < SHA256_CBLOCK; i++, j++)
+ data->c[i] = 0;
+
+ if (res > SHA256_CBLOCK - 8) {
+ mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1));
+ data->u[SHA_LBLOCK - 1] |= bitlen & mask;
+ sha256_block_data_order(&key->md, data, 1);
+ mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
+ pmac->u[0] |= key->md.h[0] & mask;
+ pmac->u[1] |= key->md.h[1] & mask;
+ pmac->u[2] |= key->md.h[2] & mask;
+ pmac->u[3] |= key->md.h[3] & mask;
+ pmac->u[4] |= key->md.h[4] & mask;
+ pmac->u[5] |= key->md.h[5] & mask;
+ pmac->u[6] |= key->md.h[6] & mask;
+ pmac->u[7] |= key->md.h[7] & mask;
+
+ memset(data, 0, SHA256_CBLOCK);
+ j += 64;
+ }
+ data->u[SHA_LBLOCK - 1] = bitlen;
+ sha256_block_data_order(&key->md, data, 1);
+ mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
+ pmac->u[0] |= key->md.h[0] & mask;
+ pmac->u[1] |= key->md.h[1] & mask;
+ pmac->u[2] |= key->md.h[2] & mask;
+ pmac->u[3] |= key->md.h[3] & mask;
+ pmac->u[4] |= key->md.h[4] & mask;
+ pmac->u[5] |= key->md.h[5] & mask;
+ pmac->u[6] |= key->md.h[6] & mask;
+ pmac->u[7] |= key->md.h[7] & mask;
+
+# ifdef BSWAP4
+ pmac->u[0] = BSWAP4(pmac->u[0]);
+ pmac->u[1] = BSWAP4(pmac->u[1]);
+ pmac->u[2] = BSWAP4(pmac->u[2]);
+ pmac->u[3] = BSWAP4(pmac->u[3]);
+ pmac->u[4] = BSWAP4(pmac->u[4]);
+ pmac->u[5] = BSWAP4(pmac->u[5]);
+ pmac->u[6] = BSWAP4(pmac->u[6]);
+ pmac->u[7] = BSWAP4(pmac->u[7]);
+# else
+ for (i = 0; i < 8; i++) {
+ res = pmac->u[i];
+ pmac->c[4 * i + 0] = (unsigned char)(res >> 24);
+ pmac->c[4 * i + 1] = (unsigned char)(res >> 16);
+ pmac->c[4 * i + 2] = (unsigned char)(res >> 8);
+ pmac->c[4 * i + 3] = (unsigned char)res;
+ }
+# endif
+ len += SHA256_DIGEST_LENGTH;
+# else
+ SHA256_Update(&key->md, out, inp_len);
+ res = key->md.num;
+ SHA256_Final(pmac->c, &key->md);
+
+ {
+ unsigned int inp_blocks, pad_blocks;
+
+ /* but pretend as if we hashed padded payload */
+ inp_blocks =
+ 1 + ((SHA256_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
+ res += (unsigned int)(len - inp_len);
+ pad_blocks = res / SHA256_CBLOCK;
+ res %= SHA256_CBLOCK;
+ pad_blocks +=
+ 1 + ((SHA256_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
+ for (; inp_blocks < pad_blocks; inp_blocks++)
+ sha1_block_data_order(&key->md, data, 1);
+ }
+# endif
+ key->md = key->tail;
+ SHA256_Update(&key->md, pmac->c, SHA256_DIGEST_LENGTH);
+ SHA256_Final(pmac->c, &key->md);
+
+ /* verify HMAC */
+ out += inp_len;
+ len -= inp_len;
+# if 1
+ {
+ unsigned char *p =
+ out + len - 1 - maxpad - SHA256_DIGEST_LENGTH;
+ size_t off = out - p;
+ unsigned int c, cmask;
+
+ maxpad += SHA256_DIGEST_LENGTH;
+ for (res = 0, i = 0, j = 0; j < maxpad; j++) {
+ c = p[j];
+ cmask =
+ ((int)(j - off - SHA256_DIGEST_LENGTH)) >>
+ (sizeof(int) * 8 - 1);
+ res |= (c ^ pad) & ~cmask; /* ... and padding */
+ cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1);
+ res |= (c ^ pmac->c[i]) & cmask;
+ i += 1 & cmask;
+ }
+ maxpad -= SHA256_DIGEST_LENGTH;
+
+ res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+ ret &= (int)~res;
+ }
+# else
+ for (res = 0, i = 0; i < SHA256_DIGEST_LENGTH; i++)
+ res |= out[i] ^ pmac->c[i];
+ res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+ ret &= (int)~res;
+
+ /* verify padding */
+ pad = (pad & ~res) | (maxpad & res);
+ out = out + len - 1 - pad;
+ for (res = 0, i = 0; i < pad; i++)
+ res |= out[i] ^ pad;
+
+ res = (0 - res) >> (sizeof(res) * 8 - 1);
+ ret &= (int)~res;
+# endif
+ return ret;
+ } else {
+ SHA256_Update(&key->md, out, len);
+ }
+ }
+
+ return 1;
+}
+
+static int aesni_cbc_hmac_sha256_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
+ void *ptr)
+{
+ EVP_AES_HMAC_SHA256 *key = data(ctx);
+
+ switch (type) {
+ case EVP_CTRL_AEAD_SET_MAC_KEY:
+ {
+ unsigned int i;
+ unsigned char hmac_key[64];
+
+ memset(hmac_key, 0, sizeof(hmac_key));
+
+ if (arg > (int)sizeof(hmac_key)) {
+ SHA256_Init(&key->head);
+ SHA256_Update(&key->head, ptr, arg);
+ SHA256_Final(hmac_key, &key->head);
+ } else {
+ memcpy(hmac_key, ptr, arg);
+ }
+
+ for (i = 0; i < sizeof(hmac_key); i++)
+ hmac_key[i] ^= 0x36; /* ipad */
+ SHA256_Init(&key->head);
+ SHA256_Update(&key->head, hmac_key, sizeof(hmac_key));
+
+ for (i = 0; i < sizeof(hmac_key); i++)
+ hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */
+ SHA256_Init(&key->tail);
+ SHA256_Update(&key->tail, hmac_key, sizeof(hmac_key));
+
+ OPENSSL_cleanse(hmac_key, sizeof(hmac_key));
+
+ return 1;
+ }
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ {
+ unsigned char *p = ptr;
+ unsigned int len = p[arg - 2] << 8 | p[arg - 1];
+
+ if (arg != EVP_AEAD_TLS1_AAD_LEN)
+ return -1;
+
+ if (ctx->encrypt) {
+ key->payload_length = len;
+ if ((key->aux.tls_ver =
+ p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
+ len -= AES_BLOCK_SIZE;
+ p[arg - 2] = len >> 8;
+ p[arg - 1] = len;
+ }
+ key->md = key->head;
+ SHA256_Update(&key->md, p, arg);
+
+ return (int)(((len + SHA256_DIGEST_LENGTH +
+ AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)
+ - len);
+ } else {
+ memcpy(key->aux.tls_aad, ptr, arg);
+ key->payload_length = arg;
+
+ return SHA256_DIGEST_LENGTH;
+ }
+ }
+# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE:
+ return (int)(5 + 16 + ((arg + 32 + 16) & -16));
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD:
+ {
+ EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
+ (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
+ unsigned int n4x = 1, x4;
+ unsigned int frag, last, packlen, inp_len;
+
+ if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM))
+ return -1;
+
+ inp_len = param->inp[11] << 8 | param->inp[12];
+
+ if (ctx->encrypt) {
+ if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION)
+ return -1;
+
+ if (inp_len) {
+ if (inp_len < 4096)
+ return 0; /* too short */
+
+ if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5))
+ n4x = 2; /* AVX2 */
+ } else if ((n4x = param->interleave / 4) && n4x <= 2)
+ inp_len = param->len;
+ else
+ return -1;
+
+ key->md = key->head;
+ SHA256_Update(&key->md, param->inp, 13);
+
+ x4 = 4 * n4x;
+ n4x += 1;
+
+ frag = inp_len >> n4x;
+ last = inp_len + frag - (frag << n4x);
+ if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) {
+ frag++;
+ last -= x4 - 1;
+ }
+
+ packlen = 5 + 16 + ((frag + 32 + 16) & -16);
+ packlen = (packlen << n4x) - packlen;
+ packlen += 5 + 16 + ((last + 32 + 16) & -16);
+
+ param->interleave = x4;
+
+ return (int)packlen;
+ } else
+ return -1; /* not yet */
+ }
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT:
+ {
+ EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
+ (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
+
+ return (int)tls1_1_multi_block_encrypt(key, param->out,
+ param->inp, param->len,
+ param->interleave / 4);
+ }
+ case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT:
+# endif
+ default:
+ return -1;
+ }
+}
+
+static EVP_CIPHER aesni_128_cbc_hmac_sha256_cipher = {
+# ifdef NID_aes_128_cbc_hmac_sha256
+ NID_aes_128_cbc_hmac_sha256,
+# else
+ NID_undef,
+# endif
+ 16, 16, 16,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+ aesni_cbc_hmac_sha256_init_key,
+ aesni_cbc_hmac_sha256_cipher,
+ NULL,
+ sizeof(EVP_AES_HMAC_SHA256),
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
+ aesni_cbc_hmac_sha256_ctrl,
+ NULL
+};
+
+static EVP_CIPHER aesni_256_cbc_hmac_sha256_cipher = {
+# ifdef NID_aes_256_cbc_hmac_sha256
+ NID_aes_256_cbc_hmac_sha256,
+# else
+ NID_undef,
+# endif
+ 16, 32, 16,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+ aesni_cbc_hmac_sha256_init_key,
+ aesni_cbc_hmac_sha256_cipher,
+ NULL,
+ sizeof(EVP_AES_HMAC_SHA256),
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
+ EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
+ aesni_cbc_hmac_sha256_ctrl,
+ NULL
+};
+
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void)
+{
+ return ((OPENSSL_ia32cap_P[1] & AESNI_CAPABLE) &&
+ aesni_cbc_sha256_enc(NULL, NULL, 0, NULL, NULL, NULL, NULL) ?
+ &aesni_128_cbc_hmac_sha256_cipher : NULL);
+}
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void)
+{
+ return ((OPENSSL_ia32cap_P[1] & AESNI_CAPABLE) &&
+ aesni_cbc_sha256_enc(NULL, NULL, 0, NULL, NULL, NULL, NULL) ?
+ &aesni_256_cbc_hmac_sha256_cipher : NULL);
+}
+# else
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void)
+{
+ return NULL;
+}
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void)
+{
+ return NULL;
+}
+# endif
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_bf.c b/Cryptlib/OpenSSL/crypto/evp/e_bf.c
new file mode 100644
index 00000000..d6a01782
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_bf.c
@@ -0,0 +1,87 @@
+/* crypto/evp/e_bf.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#ifndef OPENSSL_NO_BF
+# include <openssl/evp.h>
+# include "evp_locl.h"
+# include <openssl/objects.h>
+# include <openssl/blowfish.h>
+
+static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+typedef struct {
+ BF_KEY ks;
+} EVP_BF_KEY;
+
+# define data(ctx) EVP_C_DATA(EVP_BF_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(bf, ks, BF, EVP_BF_KEY, NID_bf, 8, 16, 8, 64,
+ EVP_CIPH_VARIABLE_LENGTH, bf_init_key, NULL,
+ EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+
+static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ BF_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
+ return 1;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_camellia.c b/Cryptlib/OpenSSL/crypto/evp/e_camellia.c
new file mode 100644
index 00000000..f273f9c9
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_camellia.c
@@ -0,0 +1,394 @@
+/* crypto/evp/e_camellia.c */
+/* ====================================================================
+ * Copyright (c) 2006 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
+ * openssl-core@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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_CAMELLIA
+# include <openssl/evp.h>
+# include <openssl/err.h>
+# include <string.h>
+# include <assert.h>
+# include <openssl/camellia.h>
+# include "evp_locl.h"
+# include "modes_lcl.h"
+
+static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+/* Camellia subkey Structure */
+typedef struct {
+ CAMELLIA_KEY ks;
+ block128_f block;
+ union {
+ cbc128_f cbc;
+ ctr128_f ctr;
+ } stream;
+} EVP_CAMELLIA_KEY;
+
+# define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4))
+
+/* Attribute operation for Camellia */
+# define data(ctx) EVP_C_DATA(EVP_CAMELLIA_KEY,ctx)
+
+# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
+/* ---------^^^ this is not a typo, just a way to detect that
+ * assembler support was in general requested... */
+# include "sparc_arch.h"
+
+extern unsigned int OPENSSL_sparcv9cap_P[];
+
+# define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA)
+
+void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks);
+void cmll_t4_encrypt(const unsigned char *in, unsigned char *out,
+ const CAMELLIA_KEY *key);
+void cmll_t4_decrypt(const unsigned char *in, unsigned char *out,
+ const CAMELLIA_KEY *key);
+
+void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const CAMELLIA_KEY *key,
+ unsigned char *ivec);
+void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const CAMELLIA_KEY *key,
+ unsigned char *ivec);
+void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const CAMELLIA_KEY *key,
+ unsigned char *ivec);
+void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const CAMELLIA_KEY *key,
+ unsigned char *ivec);
+void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const CAMELLIA_KEY *key,
+ unsigned char *ivec);
+void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+ size_t blocks, const CAMELLIA_KEY *key,
+ unsigned char *ivec);
+
+static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ int ret, mode, bits;
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ bits = ctx->key_len * 8;
+
+ cmll_t4_set_key(key, bits, &dat->ks);
+
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc) {
+ ret = 0;
+ dat->block = (block128_f) cmll_t4_decrypt;
+ switch (bits) {
+ case 128:
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) cmll128_t4_cbc_decrypt : NULL;
+ break;
+ case 192:
+ case 256:
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) cmll256_t4_cbc_decrypt : NULL;
+ break;
+ default:
+ ret = -1;
+ }
+ } else {
+ ret = 0;
+ dat->block = (block128_f) cmll_t4_encrypt;
+ switch (bits) {
+ case 128:
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) cmll128_t4_cbc_encrypt;
+ else if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) cmll128_t4_ctr32_encrypt;
+ else
+ dat->stream.cbc = NULL;
+ break;
+ case 192:
+ case 256:
+ if (mode == EVP_CIPH_CBC_MODE)
+ dat->stream.cbc = (cbc128_f) cmll256_t4_cbc_encrypt;
+ else if (mode == EVP_CIPH_CTR_MODE)
+ dat->stream.ctr = (ctr128_f) cmll256_t4_ctr32_encrypt;
+ else
+ dat->stream.cbc = NULL;
+ break;
+ default:
+ ret = -1;
+ }
+ }
+
+ if (ret < 0) {
+ EVPerr(EVP_F_CMLL_T4_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
+ return 0;
+ }
+
+ return 1;
+}
+
+# define cmll_t4_cbc_cipher camellia_cbc_cipher
+static int cmll_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define cmll_t4_ecb_cipher camellia_ecb_cipher
+static int cmll_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define cmll_t4_ofb_cipher camellia_ofb_cipher
+static int cmll_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define cmll_t4_cfb_cipher camellia_cfb_cipher
+static int cmll_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define cmll_t4_cfb8_cipher camellia_cfb8_cipher
+static int cmll_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define cmll_t4_cfb1_cipher camellia_cfb1_cipher
+static int cmll_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define cmll_t4_ctr_cipher camellia_ctr_cipher
+static int cmll_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len);
+
+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER cmll_t4_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ cmll_t4_init_key, \
+ cmll_t4_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_CAMELLIA_KEY), \
+ NULL,NULL,NULL,NULL }; \
+static const EVP_CIPHER camellia_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize, \
+ keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ camellia_init_key, \
+ camellia_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_CAMELLIA_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
+{ return SPARC_CMLL_CAPABLE?&cmll_t4_##keylen##_##mode:&camellia_##keylen##_##mode; }
+
+# else
+
+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER camellia_##keylen##_##mode = { \
+ nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+ flags|EVP_CIPH_##MODE##_MODE, \
+ camellia_init_key, \
+ camellia_##mode##_cipher, \
+ NULL, \
+ sizeof(EVP_CAMELLIA_KEY), \
+ NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
+{ return &camellia_##keylen##_##mode; }
+
+# endif
+
+# define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \
+ BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags)
+# if 0 /* not yet, missing NID */
+BLOCK_CIPHER_generic(nid, keylen, 1, 16, ctr, ctr, CTR, flags)
+# endif
+/* The subkey for Camellia is generated. */
+static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ int ret, mode;
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ ret = Camellia_set_key(key, ctx->key_len * 8, &dat->ks);
+ if (ret < 0) {
+ EVPerr(EVP_F_CAMELLIA_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
+ return 0;
+ }
+
+ mode = ctx->cipher->flags & EVP_CIPH_MODE;
+ if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+ && !enc) {
+ dat->block = (block128_f) Camellia_decrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) Camellia_cbc_encrypt : NULL;
+ } else {
+ dat->block = (block128_f) Camellia_encrypt;
+ dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+ (cbc128_f) Camellia_cbc_encrypt : NULL;
+ }
+
+ return 1;
+}
+
+static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ if (dat->stream.cbc)
+ (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt);
+ else if (ctx->encrypt)
+ CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
+ else
+ CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
+
+ return 1;
+}
+
+static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ size_t bl = ctx->cipher->block_size;
+ size_t i;
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ if (len < bl)
+ return 1;
+
+ for (i = 0, len -= bl; i <= len; i += bl)
+ (*dat->block) (in + i, out + i, &dat->ks);
+
+ return 1;
+}
+
+static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ CRYPTO_ofb128_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, dat->block);
+ return 1;
+}
+
+static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ CRYPTO_cfb128_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ return 1;
+}
+
+static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ return 1;
+}
+
+static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ if (ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) {
+ CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ return 1;
+ }
+
+ while (len >= MAXBITCHUNK) {
+ CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+ len -= MAXBITCHUNK;
+ }
+ if (len)
+ CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks,
+ ctx->iv, &ctx->num, ctx->encrypt, dat->block);
+
+ return 1;
+}
+
+# if 0 /* not yet, missing NID */
+static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ unsigned int num = ctx->num;
+ EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data;
+
+ if (dat->stream.ctr)
+ CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
+ ctx->iv, ctx->buf, &num, dat->stream.ctr);
+ else
+ CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
+ ctx->iv, ctx->buf, &num, dat->block);
+ ctx->num = (size_t)num;
+ return 1;
+}
+# endif
+
+BLOCK_CIPHER_generic_pack(NID_camellia, 128, 0)
+ BLOCK_CIPHER_generic_pack(NID_camellia, 192, 0)
+ BLOCK_CIPHER_generic_pack(NID_camellia, 256, 0)
+#else
+
+# ifdef PEDANTIC
+static void *dummy = &dummy;
+# endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_cast.c b/Cryptlib/OpenSSL/crypto/evp/e_cast.c
new file mode 100644
index 00000000..3f745485
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_cast.c
@@ -0,0 +1,89 @@
+/* crypto/evp/e_cast.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_CAST
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/cast.h>
+
+static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+typedef struct {
+ CAST_KEY ks;
+} EVP_CAST_KEY;
+
+# define data(ctx) EVP_C_DATA(EVP_CAST_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(cast5, ks, CAST, EVP_CAST_KEY,
+ NID_cast5, 8, CAST_KEY_LENGTH, 8, 64,
+ EVP_CIPH_VARIABLE_LENGTH, cast_init_key, NULL,
+ EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+
+static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ CAST_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
+ return 1;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_des.c b/Cryptlib/OpenSSL/crypto/evp/e_des.c
new file mode 100644
index 00000000..8ca65cd0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_des.c
@@ -0,0 +1,269 @@
+/* crypto/evp/e_des.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#ifndef OPENSSL_NO_DES
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/des.h>
+# include <openssl/rand.h>
+
+typedef struct {
+ union {
+ double align;
+ DES_key_schedule ks;
+ } ks;
+ union {
+ void (*cbc) (const void *, void *, size_t,
+ const DES_key_schedule *, unsigned char *);
+ } stream;
+} EVP_DES_KEY;
+
+# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
+/* ----------^^^ this is not a typo, just a way to detect that
+ * assembler support was in general requested... */
+# include "sparc_arch.h"
+
+extern unsigned int OPENSSL_sparcv9cap_P[];
+
+# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES)
+
+void des_t4_key_expand(const void *key, DES_key_schedule *ks);
+void des_t4_cbc_encrypt(const void *inp, void *out, size_t len,
+ const DES_key_schedule *ks, unsigned char iv[8]);
+void des_t4_cbc_decrypt(const void *inp, void *out, size_t len,
+ const DES_key_schedule *ks, unsigned char iv[8]);
+# endif
+
+static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+/*
+ * Because of various casts and different names can't use
+ * IMPLEMENT_BLOCK_CIPHER
+ */
+
+static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ BLOCK_CIPHER_ecb_loop()
+ DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i),
+ ctx->cipher_data, ctx->encrypt);
+ return 1;
+}
+
+static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ while (inl >= EVP_MAXCHUNK) {
+ DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+ (DES_cblock *)ctx->iv, &ctx->num);
+ inl -= EVP_MAXCHUNK;
+ in += EVP_MAXCHUNK;
+ out += EVP_MAXCHUNK;
+ }
+ if (inl)
+ DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data,
+ (DES_cblock *)ctx->iv, &ctx->num);
+ return 1;
+}
+
+static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data;
+
+ if (dat->stream.cbc != NULL) {
+ (*dat->stream.cbc) (in, out, inl, &dat->ks.ks, ctx->iv);
+ return 1;
+ }
+ while (inl >= EVP_MAXCHUNK) {
+ DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+ (DES_cblock *)ctx->iv, ctx->encrypt);
+ inl -= EVP_MAXCHUNK;
+ in += EVP_MAXCHUNK;
+ out += EVP_MAXCHUNK;
+ }
+ if (inl)
+ DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data,
+ (DES_cblock *)ctx->iv, ctx->encrypt);
+ return 1;
+}
+
+static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ while (inl >= EVP_MAXCHUNK) {
+ DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
+ (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+ inl -= EVP_MAXCHUNK;
+ in += EVP_MAXCHUNK;
+ out += EVP_MAXCHUNK;
+ }
+ if (inl)
+ DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data,
+ (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+ return 1;
+}
+
+/*
+ * Although we have a CFB-r implementation for DES, it doesn't pack the right
+ * way, so wrap it here
+ */
+static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ size_t n, chunk = EVP_MAXCHUNK / 8;
+ unsigned char c[1], d[1];
+
+ if (inl < chunk)
+ chunk = inl;
+
+ while (inl && inl >= chunk) {
+ for (n = 0; n < chunk * 8; ++n) {
+ c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
+ DES_cfb_encrypt(c, d, 1, 1, ctx->cipher_data,
+ (DES_cblock *)ctx->iv, ctx->encrypt);
+ out[n / 8] =
+ (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
+ ((d[0] & 0x80) >> (unsigned int)(n % 8));
+ }
+ inl -= chunk;
+ in += chunk;
+ out += chunk;
+ if (inl < chunk)
+ chunk = inl;
+ }
+
+ return 1;
+}
+
+static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ while (inl >= EVP_MAXCHUNK) {
+ DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, ctx->cipher_data,
+ (DES_cblock *)ctx->iv, ctx->encrypt);
+ inl -= EVP_MAXCHUNK;
+ in += EVP_MAXCHUNK;
+ out += EVP_MAXCHUNK;
+ }
+ if (inl)
+ DES_cfb_encrypt(in, out, 8, (long)inl, ctx->cipher_data,
+ (DES_cblock *)ctx->iv, ctx->encrypt);
+ return 1;
+}
+
+BLOCK_CIPHER_defs(des, EVP_DES_KEY, NID_des, 8, 8, 8, 64,
+ EVP_CIPH_RAND_KEY, des_init_key, NULL,
+ EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
+
+ BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 1,
+ EVP_CIPH_RAND_KEY, des_init_key, NULL,
+ EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
+
+ BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 8,
+ EVP_CIPH_RAND_KEY, des_init_key, NULL,
+ EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
+
+static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ DES_cblock *deskey = (DES_cblock *)key;
+ EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data;
+
+ dat->stream.cbc = NULL;
+# if defined(SPARC_DES_CAPABLE)
+ if (SPARC_DES_CAPABLE) {
+ int mode = ctx->cipher->flags & EVP_CIPH_MODE;
+
+ if (mode == EVP_CIPH_CBC_MODE) {
+ des_t4_key_expand(key, &dat->ks.ks);
+ dat->stream.cbc = enc ? des_t4_cbc_encrypt : des_t4_cbc_decrypt;
+ return 1;
+ }
+ }
+# endif
+# ifdef EVP_CHECK_DES_KEY
+ if (DES_set_key_checked(deskey, dat->ks.ks) != 0)
+ return 0;
+# else
+ DES_set_key_unchecked(deskey, ctx->cipher_data);
+# endif
+ return 1;
+}
+
+static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+
+ switch (type) {
+ case EVP_CTRL_RAND_KEY:
+ if (RAND_bytes(ptr, 8) <= 0)
+ return 0;
+ DES_set_odd_parity((DES_cblock *)ptr);
+ return 1;
+
+ default:
+ return -1;
+ }
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_des3.c b/Cryptlib/OpenSSL/crypto/evp/e_des3.c
new file mode 100644
index 00000000..0e910d6d
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_des3.c
@@ -0,0 +1,495 @@
+/* crypto/evp/e_des3.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#ifndef OPENSSL_NO_DES
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/des.h>
+# include <openssl/rand.h>
+
+/* Block use of implementations in FIPS mode */
+# undef EVP_CIPH_FLAG_FIPS
+# define EVP_CIPH_FLAG_FIPS 0
+
+typedef struct {
+ union {
+ double align;
+ DES_key_schedule ks[3];
+ } ks;
+ union {
+ void (*cbc) (const void *, void *, size_t,
+ const DES_key_schedule *, unsigned char *);
+ } stream;
+} DES_EDE_KEY;
+# define ks1 ks.ks[0]
+# define ks2 ks.ks[1]
+# define ks3 ks.ks[2]
+
+# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
+/* ---------^^^ this is not a typo, just a way to detect that
+ * assembler support was in general requested... */
+# include "sparc_arch.h"
+
+extern unsigned int OPENSSL_sparcv9cap_P[];
+
+# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES)
+
+void des_t4_key_expand(const void *key, DES_key_schedule *ks);
+void des_t4_ede3_cbc_encrypt(const void *inp, void *out, size_t len,
+ const DES_key_schedule ks[3], unsigned char iv[8]);
+void des_t4_ede3_cbc_decrypt(const void *inp, void *out, size_t len,
+ const DES_key_schedule ks[3], unsigned char iv[8]);
+# endif
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+# define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data)
+
+/*
+ * Because of various casts and different args can't use
+ * IMPLEMENT_BLOCK_CIPHER
+ */
+
+static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ BLOCK_CIPHER_ecb_loop()
+ DES_ecb3_encrypt((const_DES_cblock *)(in + i),
+ (DES_cblock *)(out + i),
+ &data(ctx)->ks1, &data(ctx)->ks2,
+ &data(ctx)->ks3, ctx->encrypt);
+ return 1;
+}
+
+static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ while (inl >= EVP_MAXCHUNK) {
+ DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
+ &data(ctx)->ks1, &data(ctx)->ks2,
+ &data(ctx)->ks3, (DES_cblock *)ctx->iv,
+ &ctx->num);
+ inl -= EVP_MAXCHUNK;
+ in += EVP_MAXCHUNK;
+ out += EVP_MAXCHUNK;
+ }
+ if (inl)
+ DES_ede3_ofb64_encrypt(in, out, (long)inl,
+ &data(ctx)->ks1, &data(ctx)->ks2,
+ &data(ctx)->ks3, (DES_cblock *)ctx->iv,
+ &ctx->num);
+
+ return 1;
+}
+
+static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ DES_EDE_KEY *dat = data(ctx);
+
+# ifdef KSSL_DEBUG
+ {
+ int i;
+ fprintf(stderr, "des_ede_cbc_cipher(ctx=%p, buflen=%d)\n", ctx,
+ ctx->buf_len);
+ fprintf(stderr, "\t iv= ");
+ for (i = 0; i < 8; i++)
+ fprintf(stderr, "%02X", ctx->iv[i]);
+ fprintf(stderr, "\n");
+ }
+# endif /* KSSL_DEBUG */
+ if (dat->stream.cbc) {
+ (*dat->stream.cbc) (in, out, inl, dat->ks.ks, ctx->iv);
+ return 1;
+ }
+
+ while (inl >= EVP_MAXCHUNK) {
+ DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
+ &dat->ks1, &dat->ks2, &dat->ks3,
+ (DES_cblock *)ctx->iv, ctx->encrypt);
+ inl -= EVP_MAXCHUNK;
+ in += EVP_MAXCHUNK;
+ out += EVP_MAXCHUNK;
+ }
+ if (inl)
+ DES_ede3_cbc_encrypt(in, out, (long)inl,
+ &dat->ks1, &dat->ks2, &dat->ks3,
+ (DES_cblock *)ctx->iv, ctx->encrypt);
+ return 1;
+}
+
+static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ while (inl >= EVP_MAXCHUNK) {
+ DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK,
+ &data(ctx)->ks1, &data(ctx)->ks2,
+ &data(ctx)->ks3, (DES_cblock *)ctx->iv,
+ &ctx->num, ctx->encrypt);
+ inl -= EVP_MAXCHUNK;
+ in += EVP_MAXCHUNK;
+ out += EVP_MAXCHUNK;
+ }
+ if (inl)
+ DES_ede3_cfb64_encrypt(in, out, (long)inl,
+ &data(ctx)->ks1, &data(ctx)->ks2,
+ &data(ctx)->ks3, (DES_cblock *)ctx->iv,
+ &ctx->num, ctx->encrypt);
+ return 1;
+}
+
+/*
+ * Although we have a CFB-r implementation for 3-DES, it doesn't pack the
+ * right way, so wrap it here
+ */
+static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ size_t n;
+ unsigned char c[1], d[1];
+
+ for (n = 0; n < inl; ++n) {
+ c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
+ DES_ede3_cfb_encrypt(c, d, 1, 1,
+ &data(ctx)->ks1, &data(ctx)->ks2,
+ &data(ctx)->ks3, (DES_cblock *)ctx->iv,
+ ctx->encrypt);
+ out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8)))
+ | ((d[0] & 0x80) >> (unsigned int)(n % 8));
+ }
+
+ return 1;
+}
+
+static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ while (inl >= EVP_MAXCHUNK) {
+ DES_ede3_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK,
+ &data(ctx)->ks1, &data(ctx)->ks2,
+ &data(ctx)->ks3, (DES_cblock *)ctx->iv,
+ ctx->encrypt);
+ inl -= EVP_MAXCHUNK;
+ in += EVP_MAXCHUNK;
+ out += EVP_MAXCHUNK;
+ }
+ if (inl)
+ DES_ede3_cfb_encrypt(in, out, 8, (long)inl,
+ &data(ctx)->ks1, &data(ctx)->ks2,
+ &data(ctx)->ks3, (DES_cblock *)ctx->iv,
+ ctx->encrypt);
+ return 1;
+}
+
+BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
+ EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1,
+ des_ede_init_key, NULL, NULL, NULL, des3_ctrl)
+# define des_ede3_cfb64_cipher des_ede_cfb64_cipher
+# define des_ede3_ofb_cipher des_ede_ofb_cipher
+# define des_ede3_cbc_cipher des_ede_cbc_cipher
+# define des_ede3_ecb_cipher des_ede_ecb_cipher
+ BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64,
+ EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_FIPS |
+ EVP_CIPH_FLAG_DEFAULT_ASN1, des_ede3_init_key, NULL, NULL, NULL,
+ des3_ctrl)
+
+ BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 1,
+ EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_FIPS |
+ EVP_CIPH_FLAG_DEFAULT_ASN1, des_ede3_init_key, NULL, NULL,
+ NULL, des3_ctrl)
+
+ BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 8,
+ EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_FIPS |
+ EVP_CIPH_FLAG_DEFAULT_ASN1, des_ede3_init_key, NULL, NULL,
+ NULL, des3_ctrl)
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ DES_cblock *deskey = (DES_cblock *)key;
+ DES_EDE_KEY *dat = data(ctx);
+
+ dat->stream.cbc = NULL;
+# if defined(SPARC_DES_CAPABLE)
+ if (SPARC_DES_CAPABLE) {
+ int mode = ctx->cipher->flags & EVP_CIPH_MODE;
+
+ if (mode == EVP_CIPH_CBC_MODE) {
+ des_t4_key_expand(&deskey[0], &dat->ks1);
+ des_t4_key_expand(&deskey[1], &dat->ks2);
+ memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1));
+ dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt :
+ des_t4_ede3_cbc_decrypt;
+ return 1;
+ }
+ }
+# endif
+# ifdef EVP_CHECK_DES_KEY
+ if (DES_set_key_checked(&deskey[0], &dat->ks1)
+ || DES_set_key_checked(&deskey[1], &dat->ks2))
+ return 0;
+# else
+ DES_set_key_unchecked(&deskey[0], &dat->ks1);
+ DES_set_key_unchecked(&deskey[1], &dat->ks2);
+# endif
+ memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1));
+ return 1;
+}
+
+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ DES_cblock *deskey = (DES_cblock *)key;
+ DES_EDE_KEY *dat = data(ctx);
+
+# ifdef KSSL_DEBUG
+ {
+ int i;
+ fprintf(stderr, "des_ede3_init_key(ctx=%p)\n", ctx);
+ fprintf(stderr, "\tKEY= ");
+ for (i = 0; i < 24; i++)
+ fprintf(stderr, "%02X", key[i]);
+ fprintf(stderr, "\n");
+ if (iv) {
+ fprintf(stderr, "\t IV= ");
+ for (i = 0; i < 8; i++)
+ fprintf(stderr, "%02X", iv[i]);
+ fprintf(stderr, "\n");
+ }
+ }
+# endif /* KSSL_DEBUG */
+
+ dat->stream.cbc = NULL;
+# if defined(SPARC_DES_CAPABLE)
+ if (SPARC_DES_CAPABLE) {
+ int mode = ctx->cipher->flags & EVP_CIPH_MODE;
+
+ if (mode == EVP_CIPH_CBC_MODE) {
+ des_t4_key_expand(&deskey[0], &dat->ks1);
+ des_t4_key_expand(&deskey[1], &dat->ks2);
+ des_t4_key_expand(&deskey[2], &dat->ks3);
+ dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt :
+ des_t4_ede3_cbc_decrypt;
+ return 1;
+ }
+ }
+# endif
+# ifdef EVP_CHECK_DES_KEY
+ if (DES_set_key_checked(&deskey[0], &dat->ks1)
+ || DES_set_key_checked(&deskey[1], &dat->ks2)
+ || DES_set_key_checked(&deskey[2], &dat->ks3))
+ return 0;
+# else
+ DES_set_key_unchecked(&deskey[0], &dat->ks1);
+ DES_set_key_unchecked(&deskey[1], &dat->ks2);
+ DES_set_key_unchecked(&deskey[2], &dat->ks3);
+# endif
+ return 1;
+}
+
+static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+
+ DES_cblock *deskey = ptr;
+
+ switch (type) {
+ case EVP_CTRL_RAND_KEY:
+ if (RAND_bytes(ptr, c->key_len) <= 0)
+ return 0;
+ DES_set_odd_parity(deskey);
+ if (c->key_len >= 16)
+ DES_set_odd_parity(deskey + 1);
+ if (c->key_len >= 24)
+ DES_set_odd_parity(deskey + 2);
+ return 1;
+
+ default:
+ return -1;
+ }
+}
+
+const EVP_CIPHER *EVP_des_ede(void)
+{
+ return &des_ede_ecb;
+}
+
+const EVP_CIPHER *EVP_des_ede3(void)
+{
+ return &des_ede3_ecb;
+}
+
+# ifndef OPENSSL_NO_SHA
+
+# include <openssl/sha.h>
+
+static const unsigned char wrap_iv[8] =
+ { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 };
+
+static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ unsigned char icv[8], iv[8], sha1tmp[SHA_DIGEST_LENGTH];
+ int rv = -1;
+ if (inl < 24)
+ return -1;
+ if (out == NULL)
+ return inl - 16;
+ memcpy(ctx->iv, wrap_iv, 8);
+ /* Decrypt first block which will end up as icv */
+ des_ede_cbc_cipher(ctx, icv, in, 8);
+ /* Decrypt central blocks */
+ /*
+ * If decrypting in place move whole output along a block so the next
+ * des_ede_cbc_cipher is in place.
+ */
+ if (out == in) {
+ memmove(out, out + 8, inl - 8);
+ in -= 8;
+ }
+ des_ede_cbc_cipher(ctx, out, in + 8, inl - 16);
+ /* Decrypt final block which will be IV */
+ des_ede_cbc_cipher(ctx, iv, in + inl - 8, 8);
+ /* Reverse order of everything */
+ BUF_reverse(icv, NULL, 8);
+ BUF_reverse(out, NULL, inl - 16);
+ BUF_reverse(ctx->iv, iv, 8);
+ /* Decrypt again using new IV */
+ des_ede_cbc_cipher(ctx, out, out, inl - 16);
+ des_ede_cbc_cipher(ctx, icv, icv, 8);
+ /* Work out SHA1 hash of first portion */
+ SHA1(out, inl - 16, sha1tmp);
+
+ if (!CRYPTO_memcmp(sha1tmp, icv, 8))
+ rv = inl - 16;
+ OPENSSL_cleanse(icv, 8);
+ OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH);
+ OPENSSL_cleanse(iv, 8);
+ OPENSSL_cleanse(ctx->iv, 8);
+ if (rv == -1)
+ OPENSSL_cleanse(out, inl - 16);
+
+ return rv;
+}
+
+static int des_ede3_wrap(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ unsigned char sha1tmp[SHA_DIGEST_LENGTH];
+ if (out == NULL)
+ return inl + 16;
+ /* Copy input to output buffer + 8 so we have space for IV */
+ memmove(out + 8, in, inl);
+ /* Work out ICV */
+ SHA1(in, inl, sha1tmp);
+ memcpy(out + inl + 8, sha1tmp, 8);
+ OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH);
+ /* Generate random IV */
+ if (RAND_bytes(ctx->iv, 8) <= 0)
+ return -1;
+ memcpy(out, ctx->iv, 8);
+ /* Encrypt everything after IV in place */
+ des_ede_cbc_cipher(ctx, out + 8, out + 8, inl + 8);
+ BUF_reverse(out, NULL, inl + 16);
+ memcpy(ctx->iv, wrap_iv, 8);
+ des_ede_cbc_cipher(ctx, out, out, inl + 16);
+ return inl + 16;
+}
+
+static int des_ede3_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ /*
+ * Sanity check input length: we typically only wrap keys so EVP_MAXCHUNK
+ * is more than will ever be needed. Also input length must be a multiple
+ * of 8 bits.
+ */
+ if (inl >= EVP_MAXCHUNK || inl % 8)
+ return -1;
+ if (ctx->encrypt)
+ return des_ede3_wrap(ctx, out, in, inl);
+ else
+ return des_ede3_unwrap(ctx, out, in, inl);
+}
+
+static const EVP_CIPHER des3_wrap = {
+ NID_id_smime_alg_CMS3DESwrap,
+ 8, 24, 0,
+ EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER
+ | EVP_CIPH_FLAG_DEFAULT_ASN1,
+ des_ede3_init_key, des_ede3_wrap_cipher,
+ NULL,
+ sizeof(DES_EDE_KEY),
+ NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_des_ede3_wrap(void)
+{
+ return &des3_wrap;
+}
+
+# endif
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_idea.c b/Cryptlib/OpenSSL/crypto/evp/e_idea.c
new file mode 100644
index 00000000..cac72b33
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_idea.c
@@ -0,0 +1,119 @@
+/* crypto/evp/e_idea.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_IDEA
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/idea.h>
+
+static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+/*
+ * NB idea_ecb_encrypt doesn't take an 'encrypt' argument so we treat it as a
+ * special case
+ */
+
+static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ BLOCK_CIPHER_ecb_loop()
+ idea_ecb_encrypt(in + i, out + i, ctx->cipher_data);
+ return 1;
+}
+
+/* Can't use IMPLEMENT_BLOCK_CIPHER because idea_ecb_encrypt is different */
+
+typedef struct {
+ IDEA_KEY_SCHEDULE ks;
+} EVP_IDEA_KEY;
+
+BLOCK_CIPHER_func_cbc(idea, idea, EVP_IDEA_KEY, ks)
+ BLOCK_CIPHER_func_ofb(idea, idea, 64, EVP_IDEA_KEY, ks)
+ BLOCK_CIPHER_func_cfb(idea, idea, 64, EVP_IDEA_KEY, ks)
+
+ BLOCK_CIPHER_defs(idea, IDEA_KEY_SCHEDULE, NID_idea, 8, 16, 8, 64,
+ 0, idea_init_key, NULL,
+ EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+
+static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ if (!enc) {
+ if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
+ enc = 1;
+ else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE)
+ enc = 1;
+ }
+ if (enc)
+ idea_set_encrypt_key(key, ctx->cipher_data);
+ else {
+ IDEA_KEY_SCHEDULE tmp;
+
+ idea_set_encrypt_key(key, &tmp);
+ idea_set_decrypt_key(&tmp, ctx->cipher_data);
+ OPENSSL_cleanse((unsigned char *)&tmp, sizeof(IDEA_KEY_SCHEDULE));
+ }
+ return 1;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_null.c b/Cryptlib/OpenSSL/crypto/evp/e_null.c
new file mode 100644
index 00000000..599fcb80
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_null.c
@@ -0,0 +1,100 @@
+/* crypto/evp/e_null.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+
+static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl);
+static const EVP_CIPHER n_cipher = {
+ NID_undef,
+ 1, 0, 0,
+ 0,
+ null_init_key,
+ null_cipher,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+const EVP_CIPHER *EVP_enc_null(void)
+{
+ return (&n_cipher);
+}
+
+static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ /* memset(&(ctx->c),0,sizeof(ctx->c)); */
+ return 1;
+}
+
+static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ if (in != out)
+ memcpy((char *)out, (const char *)in, inl);
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_old.c b/Cryptlib/OpenSSL/crypto/evp/e_old.c
new file mode 100644
index 00000000..a23d143b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_old.c
@@ -0,0 +1,164 @@
+/* crypto/evp/e_old.c */
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 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
+ * openssl-core@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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifdef OPENSSL_NO_DEPRECATED
+static void *dummy = &dummy;
+#else
+
+# include <openssl/evp.h>
+
+/*
+ * Define some deprecated functions, so older programs don't crash and burn
+ * too quickly. On Windows and VMS, these will never be used, since
+ * functions and variables in shared libraries are selected by entry point
+ * location, not by name.
+ */
+
+# ifndef OPENSSL_NO_BF
+# undef EVP_bf_cfb
+const EVP_CIPHER *EVP_bf_cfb(void);
+const EVP_CIPHER *EVP_bf_cfb(void)
+{
+ return EVP_bf_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_DES
+# undef EVP_des_cfb
+const EVP_CIPHER *EVP_des_cfb(void);
+const EVP_CIPHER *EVP_des_cfb(void)
+{
+ return EVP_des_cfb64();
+}
+
+# undef EVP_des_ede3_cfb
+const EVP_CIPHER *EVP_des_ede3_cfb(void);
+const EVP_CIPHER *EVP_des_ede3_cfb(void)
+{
+ return EVP_des_ede3_cfb64();
+}
+
+# undef EVP_des_ede_cfb
+const EVP_CIPHER *EVP_des_ede_cfb(void);
+const EVP_CIPHER *EVP_des_ede_cfb(void)
+{
+ return EVP_des_ede_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_IDEA
+# undef EVP_idea_cfb
+const EVP_CIPHER *EVP_idea_cfb(void);
+const EVP_CIPHER *EVP_idea_cfb(void)
+{
+ return EVP_idea_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_RC2
+# undef EVP_rc2_cfb
+const EVP_CIPHER *EVP_rc2_cfb(void);
+const EVP_CIPHER *EVP_rc2_cfb(void)
+{
+ return EVP_rc2_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_CAST
+# undef EVP_cast5_cfb
+const EVP_CIPHER *EVP_cast5_cfb(void);
+const EVP_CIPHER *EVP_cast5_cfb(void)
+{
+ return EVP_cast5_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_RC5
+# undef EVP_rc5_32_12_16_cfb
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void)
+{
+ return EVP_rc5_32_12_16_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_AES
+# undef EVP_aes_128_cfb
+const EVP_CIPHER *EVP_aes_128_cfb(void);
+const EVP_CIPHER *EVP_aes_128_cfb(void)
+{
+ return EVP_aes_128_cfb128();
+}
+
+# undef EVP_aes_192_cfb
+const EVP_CIPHER *EVP_aes_192_cfb(void);
+const EVP_CIPHER *EVP_aes_192_cfb(void)
+{
+ return EVP_aes_192_cfb128();
+}
+
+# undef EVP_aes_256_cfb
+const EVP_CIPHER *EVP_aes_256_cfb(void);
+const EVP_CIPHER *EVP_aes_256_cfb(void)
+{
+ return EVP_aes_256_cfb128();
+}
+# endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_rc2.c b/Cryptlib/OpenSSL/crypto/evp/e_rc2.c
new file mode 100644
index 00000000..718cc869
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_rc2.c
@@ -0,0 +1,235 @@
+/* crypto/evp/e_rc2.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RC2
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/rc2.h>
+
+static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx);
+static int rc2_magic_to_meth(int i);
+static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+typedef struct {
+ int key_bits; /* effective key bits */
+ RC2_KEY ks; /* key schedule */
+} EVP_RC2_KEY;
+
+# define data(ctx) ((EVP_RC2_KEY *)(ctx)->cipher_data)
+
+IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2,
+ 8,
+ RC2_KEY_LENGTH, 8, 64,
+ EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+ rc2_init_key, NULL,
+ rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv,
+ rc2_ctrl)
+# define RC2_40_MAGIC 0xa0
+# define RC2_64_MAGIC 0x78
+# define RC2_128_MAGIC 0x3a
+static const EVP_CIPHER r2_64_cbc_cipher = {
+ NID_rc2_64_cbc,
+ 8, 8 /* 64 bit */ , 8,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+ rc2_init_key,
+ rc2_cbc_cipher,
+ NULL,
+ sizeof(EVP_RC2_KEY),
+ rc2_set_asn1_type_and_iv,
+ rc2_get_asn1_type_and_iv,
+ rc2_ctrl,
+ NULL
+};
+
+static const EVP_CIPHER r2_40_cbc_cipher = {
+ NID_rc2_40_cbc,
+ 8, 5 /* 40 bit */ , 8,
+ EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+ rc2_init_key,
+ rc2_cbc_cipher,
+ NULL,
+ sizeof(EVP_RC2_KEY),
+ rc2_set_asn1_type_and_iv,
+ rc2_get_asn1_type_and_iv,
+ rc2_ctrl,
+ NULL
+};
+
+const EVP_CIPHER *EVP_rc2_64_cbc(void)
+{
+ return (&r2_64_cbc_cipher);
+}
+
+const EVP_CIPHER *EVP_rc2_40_cbc(void)
+{
+ return (&r2_40_cbc_cipher);
+}
+
+static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
+ key, data(ctx)->key_bits);
+ return 1;
+}
+
+static int rc2_meth_to_magic(EVP_CIPHER_CTX *e)
+{
+ int i;
+
+ EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i);
+ if (i == 128)
+ return (RC2_128_MAGIC);
+ else if (i == 64)
+ return (RC2_64_MAGIC);
+ else if (i == 40)
+ return (RC2_40_MAGIC);
+ else
+ return (0);
+}
+
+static int rc2_magic_to_meth(int i)
+{
+ if (i == RC2_128_MAGIC)
+ return 128;
+ else if (i == RC2_64_MAGIC)
+ return 64;
+ else if (i == RC2_40_MAGIC)
+ return 40;
+ else {
+ EVPerr(EVP_F_RC2_MAGIC_TO_METH, EVP_R_UNSUPPORTED_KEY_SIZE);
+ return (0);
+ }
+}
+
+static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+ long num = 0;
+ int i = 0;
+ int key_bits;
+ unsigned int l;
+ unsigned char iv[EVP_MAX_IV_LENGTH];
+
+ if (type != NULL) {
+ l = EVP_CIPHER_CTX_iv_length(c);
+ OPENSSL_assert(l <= sizeof(iv));
+ i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l);
+ if (i != (int)l)
+ return (-1);
+ key_bits = rc2_magic_to_meth((int)num);
+ if (!key_bits)
+ return (-1);
+ if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1))
+ return -1;
+ EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
+ EVP_CIPHER_CTX_set_key_length(c, key_bits / 8);
+ }
+ return (i);
+}
+
+static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+ long num;
+ int i = 0, j;
+
+ if (type != NULL) {
+ num = rc2_meth_to_magic(c);
+ j = EVP_CIPHER_CTX_iv_length(c);
+ i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j);
+ }
+ return (i);
+}
+
+static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ switch (type) {
+ case EVP_CTRL_INIT:
+ data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8;
+ return 1;
+
+ case EVP_CTRL_GET_RC2_KEY_BITS:
+ *(int *)ptr = data(c)->key_bits;
+ return 1;
+
+ case EVP_CTRL_SET_RC2_KEY_BITS:
+ if (arg > 0) {
+ data(c)->key_bits = arg;
+ return 1;
+ }
+ return 0;
+# ifdef PBE_PRF_TEST
+ case EVP_CTRL_PBE_PRF_NID:
+ *(int *)ptr = NID_hmacWithMD5;
+ return 1;
+# endif
+
+ default:
+ return -1;
+ }
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_rc4.c b/Cryptlib/OpenSSL/crypto/evp/e_rc4.c
new file mode 100644
index 00000000..08e48f39
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_rc4.c
@@ -0,0 +1,133 @@
+/* crypto/evp/e_rc4.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RC4
+
+# include <openssl/evp.h>
+# include "evp_locl.h"
+# include <openssl/objects.h>
+# include <openssl/rc4.h>
+
+/* FIXME: surely this is available elsewhere? */
+# define EVP_RC4_KEY_SIZE 16
+
+typedef struct {
+ RC4_KEY ks; /* working key */
+} EVP_RC4_KEY;
+
+# define data(ctx) ((EVP_RC4_KEY *)(ctx)->cipher_data)
+
+static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl);
+static const EVP_CIPHER r4_cipher = {
+ NID_rc4,
+ 1, EVP_RC4_KEY_SIZE, 0,
+ EVP_CIPH_VARIABLE_LENGTH,
+ rc4_init_key,
+ rc4_cipher,
+ NULL,
+ sizeof(EVP_RC4_KEY),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static const EVP_CIPHER r4_40_cipher = {
+ NID_rc4_40,
+ 1, 5 /* 40 bit */ , 0,
+ EVP_CIPH_VARIABLE_LENGTH,
+ rc4_init_key,
+ rc4_cipher,
+ NULL,
+ sizeof(EVP_RC4_KEY),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+const EVP_CIPHER *EVP_rc4(void)
+{
+ return (&r4_cipher);
+}
+
+const EVP_CIPHER *EVP_rc4_40(void)
+{
+ return (&r4_40_cipher);
+}
+
+static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ RC4_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
+ return 1;
+}
+
+static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ RC4(&data(ctx)->ks, inl, in, out);
+ return 1;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_rc4_hmac_md5.c b/Cryptlib/OpenSSL/crypto/evp/e_rc4_hmac_md5.c
new file mode 100644
index 00000000..2da11178
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_rc4_hmac_md5.c
@@ -0,0 +1,308 @@
+/* ====================================================================
+ * Copyright (c) 2011 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/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5)
+
+# include <openssl/crypto.h>
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/rc4.h>
+# include <openssl/md5.h>
+
+# ifndef EVP_CIPH_FLAG_AEAD_CIPHER
+# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
+# define EVP_CTRL_AEAD_TLS1_AAD 0x16
+# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
+# endif
+
+/* FIXME: surely this is available elsewhere? */
+# define EVP_RC4_KEY_SIZE 16
+
+typedef struct {
+ RC4_KEY ks;
+ MD5_CTX head, tail, md;
+ size_t payload_length;
+} EVP_RC4_HMAC_MD5;
+
+# define NO_PAYLOAD_LENGTH ((size_t)-1)
+
+void rc4_md5_enc(RC4_KEY *key, const void *in0, void *out,
+ MD5_CTX *ctx, const void *inp, size_t blocks);
+
+# define data(ctx) ((EVP_RC4_HMAC_MD5 *)(ctx)->cipher_data)
+
+static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx,
+ const unsigned char *inkey,
+ const unsigned char *iv, int enc)
+{
+ EVP_RC4_HMAC_MD5 *key = data(ctx);
+
+ RC4_set_key(&key->ks, EVP_CIPHER_CTX_key_length(ctx), inkey);
+
+ MD5_Init(&key->head); /* handy when benchmarking */
+ key->tail = key->head;
+ key->md = key->head;
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return 1;
+}
+
+# if !defined(OPENSSL_NO_ASM) && ( \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(__INTEL__) ) && \
+ !(defined(__APPLE__) && defined(__MACH__))
+# define STITCHED_CALL
+# endif
+
+# if !defined(STITCHED_CALL)
+# define rc4_off 0
+# define md5_off 0
+# endif
+
+static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_RC4_HMAC_MD5 *key = data(ctx);
+# if defined(STITCHED_CALL)
+ size_t rc4_off = 32 - 1 - (key->ks.x & (32 - 1)), /* 32 is $MOD from
+ * rc4_md5-x86_64.pl */
+ md5_off = MD5_CBLOCK - key->md.num, blocks;
+ unsigned int l;
+ extern unsigned int OPENSSL_ia32cap_P[];
+# endif
+ size_t plen = key->payload_length;
+
+ if (plen != NO_PAYLOAD_LENGTH && len != (plen + MD5_DIGEST_LENGTH))
+ return 0;
+
+ if (ctx->encrypt) {
+ if (plen == NO_PAYLOAD_LENGTH)
+ plen = len;
+# if defined(STITCHED_CALL)
+ /* cipher has to "fall behind" */
+ if (rc4_off > md5_off)
+ md5_off += MD5_CBLOCK;
+
+ if (plen > md5_off && (blocks = (plen - md5_off) / MD5_CBLOCK) &&
+ (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
+ MD5_Update(&key->md, in, md5_off);
+ RC4(&key->ks, rc4_off, in, out);
+
+ rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off,
+ &key->md, in + md5_off, blocks);
+ blocks *= MD5_CBLOCK;
+ rc4_off += blocks;
+ md5_off += blocks;
+ key->md.Nh += blocks >> 29;
+ key->md.Nl += blocks <<= 3;
+ if (key->md.Nl < (unsigned int)blocks)
+ key->md.Nh++;
+ } else {
+ rc4_off = 0;
+ md5_off = 0;
+ }
+# endif
+ MD5_Update(&key->md, in + md5_off, plen - md5_off);
+
+ if (plen != len) { /* "TLS" mode of operation */
+ if (in != out)
+ memcpy(out + rc4_off, in + rc4_off, plen - rc4_off);
+
+ /* calculate HMAC and append it to payload */
+ MD5_Final(out + plen, &key->md);
+ key->md = key->tail;
+ MD5_Update(&key->md, out + plen, MD5_DIGEST_LENGTH);
+ MD5_Final(out + plen, &key->md);
+ /* encrypt HMAC at once */
+ RC4(&key->ks, len - rc4_off, out + rc4_off, out + rc4_off);
+ } else {
+ RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off);
+ }
+ } else {
+ unsigned char mac[MD5_DIGEST_LENGTH];
+# if defined(STITCHED_CALL)
+ /* digest has to "fall behind" */
+ if (md5_off > rc4_off)
+ rc4_off += 2 * MD5_CBLOCK;
+ else
+ rc4_off += MD5_CBLOCK;
+
+ if (len > rc4_off && (blocks = (len - rc4_off) / MD5_CBLOCK) &&
+ (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
+ RC4(&key->ks, rc4_off, in, out);
+ MD5_Update(&key->md, out, md5_off);
+
+ rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off,
+ &key->md, out + md5_off, blocks);
+ blocks *= MD5_CBLOCK;
+ rc4_off += blocks;
+ md5_off += blocks;
+ l = (key->md.Nl + (blocks << 3)) & 0xffffffffU;
+ if (l < key->md.Nl)
+ key->md.Nh++;
+ key->md.Nl = l;
+ key->md.Nh += blocks >> 29;
+ } else {
+ md5_off = 0;
+ rc4_off = 0;
+ }
+# endif
+ /* decrypt HMAC at once */
+ RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off);
+ if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
+ MD5_Update(&key->md, out + md5_off, plen - md5_off);
+
+ /* calculate HMAC and verify it */
+ MD5_Final(mac, &key->md);
+ key->md = key->tail;
+ MD5_Update(&key->md, mac, MD5_DIGEST_LENGTH);
+ MD5_Final(mac, &key->md);
+
+ if (CRYPTO_memcmp(out + plen, mac, MD5_DIGEST_LENGTH))
+ return 0;
+ } else {
+ MD5_Update(&key->md, out + md5_off, len - md5_off);
+ }
+ }
+
+ key->payload_length = NO_PAYLOAD_LENGTH;
+
+ return 1;
+}
+
+static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
+ void *ptr)
+{
+ EVP_RC4_HMAC_MD5 *key = data(ctx);
+
+ switch (type) {
+ case EVP_CTRL_AEAD_SET_MAC_KEY:
+ {
+ unsigned int i;
+ unsigned char hmac_key[64];
+
+ memset(hmac_key, 0, sizeof(hmac_key));
+
+ if (arg > (int)sizeof(hmac_key)) {
+ MD5_Init(&key->head);
+ MD5_Update(&key->head, ptr, arg);
+ MD5_Final(hmac_key, &key->head);
+ } else {
+ memcpy(hmac_key, ptr, arg);
+ }
+
+ for (i = 0; i < sizeof(hmac_key); i++)
+ hmac_key[i] ^= 0x36; /* ipad */
+ MD5_Init(&key->head);
+ MD5_Update(&key->head, hmac_key, sizeof(hmac_key));
+
+ for (i = 0; i < sizeof(hmac_key); i++)
+ hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */
+ MD5_Init(&key->tail);
+ MD5_Update(&key->tail, hmac_key, sizeof(hmac_key));
+
+ return 1;
+ }
+ case EVP_CTRL_AEAD_TLS1_AAD:
+ {
+ unsigned char *p = ptr;
+ unsigned int len;
+
+ if (arg != EVP_AEAD_TLS1_AAD_LEN)
+ return -1;
+
+ len = p[arg - 2] << 8 | p[arg - 1];
+
+ if (!ctx->encrypt) {
+ len -= MD5_DIGEST_LENGTH;
+ p[arg - 2] = len >> 8;
+ p[arg - 1] = len;
+ }
+ key->payload_length = len;
+ key->md = key->head;
+ MD5_Update(&key->md, p, arg);
+
+ return MD5_DIGEST_LENGTH;
+ }
+ default:
+ return -1;
+ }
+}
+
+static EVP_CIPHER r4_hmac_md5_cipher = {
+# ifdef NID_rc4_hmac_md5
+ NID_rc4_hmac_md5,
+# else
+ NID_undef,
+# endif
+ 1, EVP_RC4_KEY_SIZE, 0,
+ EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH |
+ EVP_CIPH_FLAG_AEAD_CIPHER,
+ rc4_hmac_md5_init_key,
+ rc4_hmac_md5_cipher,
+ NULL,
+ sizeof(EVP_RC4_HMAC_MD5),
+ NULL,
+ NULL,
+ rc4_hmac_md5_ctrl,
+ NULL
+};
+
+const EVP_CIPHER *EVP_rc4_hmac_md5(void)
+{
+ return (&r4_hmac_md5_cipher);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_rc5.c b/Cryptlib/OpenSSL/crypto/evp/e_rc5.c
new file mode 100644
index 00000000..f17e99d0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_rc5.c
@@ -0,0 +1,122 @@
+/* crypto/evp/e_rc5.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RC5
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/rc5.h>
+
+static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+typedef struct {
+ int rounds; /* number of rounds */
+ RC5_32_KEY ks; /* key schedule */
+} EVP_RC5_KEY;
+
+# define data(ctx) EVP_C_DATA(EVP_RC5_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(rc5_32_12_16, ks, RC5_32, EVP_RC5_KEY, NID_rc5,
+ 8, RC5_32_KEY_LENGTH, 8, 64,
+ EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+ r_32_12_16_init_key, NULL, NULL, NULL, rc5_ctrl)
+
+static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ switch (type) {
+ case EVP_CTRL_INIT:
+ data(c)->rounds = RC5_12_ROUNDS;
+ return 1;
+
+ case EVP_CTRL_GET_RC5_ROUNDS:
+ *(int *)ptr = data(c)->rounds;
+ return 1;
+
+ case EVP_CTRL_SET_RC5_ROUNDS:
+ switch (arg) {
+ case RC5_8_ROUNDS:
+ case RC5_12_ROUNDS:
+ case RC5_16_ROUNDS:
+ data(c)->rounds = arg;
+ return 1;
+
+ default:
+ EVPerr(EVP_F_RC5_CTRL, EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS);
+ return 0;
+ }
+
+ default:
+ return -1;
+ }
+}
+
+static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ RC5_32_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
+ key, data(ctx)->rounds);
+ return 1;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_seed.c b/Cryptlib/OpenSSL/crypto/evp/e_seed.c
new file mode 100644
index 00000000..7249d1b1
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_seed.c
@@ -0,0 +1,82 @@
+/* crypto/evp/e_seed.c */
+/* ====================================================================
+ * Copyright (c) 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
+ * openssl-core@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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_SEED
+# include <openssl/evp.h>
+# include <openssl/err.h>
+# include <string.h>
+# include <assert.h>
+# include <openssl/seed.h>
+# include "evp_locl.h"
+
+static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+
+typedef struct {
+ SEED_KEY_SCHEDULE ks;
+} EVP_SEED_KEY;
+
+IMPLEMENT_BLOCK_CIPHER(seed, ks, SEED, EVP_SEED_KEY, NID_seed,
+ 16, 16, 16, 128, 0, seed_init_key, 0, 0, 0, 0)
+
+static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ SEED_set_key(key, ctx->cipher_data);
+ return 1;
+}
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/e_xcbc_d.c b/Cryptlib/OpenSSL/crypto/evp/e_xcbc_d.c
new file mode 100644
index 00000000..3430df9e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/e_xcbc_d.c
@@ -0,0 +1,130 @@
+/* crypto/evp/e_xcbc_d.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_DES
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/des.h>
+
+static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl);
+
+typedef struct {
+ DES_key_schedule ks; /* key schedule */
+ DES_cblock inw;
+ DES_cblock outw;
+} DESX_CBC_KEY;
+
+# define data(ctx) ((DESX_CBC_KEY *)(ctx)->cipher_data)
+
+static const EVP_CIPHER d_xcbc_cipher = {
+ NID_desx_cbc,
+ 8, 24, 8,
+ EVP_CIPH_CBC_MODE,
+ desx_cbc_init_key,
+ desx_cbc_cipher,
+ NULL,
+ sizeof(DESX_CBC_KEY),
+ EVP_CIPHER_set_asn1_iv,
+ EVP_CIPHER_get_asn1_iv,
+ NULL,
+ NULL
+};
+
+const EVP_CIPHER *EVP_desx_cbc(void)
+{
+ return (&d_xcbc_cipher);
+}
+
+static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ DES_cblock *deskey = (DES_cblock *)key;
+
+ DES_set_key_unchecked(deskey, &data(ctx)->ks);
+ memcpy(&data(ctx)->inw[0], &key[8], 8);
+ memcpy(&data(ctx)->outw[0], &key[16], 8);
+
+ return 1;
+}
+
+static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{
+ while (inl >= EVP_MAXCHUNK) {
+ DES_xcbc_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks,
+ (DES_cblock *)&(ctx->iv[0]),
+ &data(ctx)->inw, &data(ctx)->outw, ctx->encrypt);
+ inl -= EVP_MAXCHUNK;
+ in += EVP_MAXCHUNK;
+ out += EVP_MAXCHUNK;
+ }
+ if (inl)
+ DES_xcbc_encrypt(in, out, (long)inl, &data(ctx)->ks,
+ (DES_cblock *)&(ctx->iv[0]),
+ &data(ctx)->inw, &data(ctx)->outw, ctx->encrypt);
+ return 1;
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/encode.c b/Cryptlib/OpenSSL/crypto/evp/encode.c
new file mode 100644
index 00000000..c6c775e0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/encode.c
@@ -0,0 +1,460 @@
+/* crypto/evp/encode.c */
+/* 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 <stdio.h>
+#include <limits.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+
+static unsigned char conv_ascii2bin(unsigned char a);
+#ifndef CHARSET_EBCDIC
+# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f])
+#else
+/*
+ * We assume that PEM encoded files are EBCDIC files (i.e., printable text
+ * files). Convert them here while decoding. When encoding, output is EBCDIC
+ * (text) format again. (No need for conversion in the conv_bin2ascii macro,
+ * as the underlying textstring data_bin2ascii[] is already EBCDIC)
+ */
+# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f])
+#endif
+
+/*-
+ * 64 char lines
+ * pad input with 0
+ * left over chars are set to =
+ * 1 byte => xx==
+ * 2 bytes => xxx=
+ * 3 bytes => xxxx
+ */
+#define BIN_PER_LINE (64/4*3)
+#define CHUNKS_PER_LINE (64/4)
+#define CHAR_PER_LINE (64+1)
+
+static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+abcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/*-
+ * 0xF0 is a EOLN
+ * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
+ * 0xF2 is EOF
+ * 0xE0 is ignore at start of line.
+ * 0xFF is error
+ */
+
+#define B64_EOLN 0xF0
+#define B64_CR 0xF1
+#define B64_EOF 0xF2
+#define B64_WS 0xE0
+#define B64_ERROR 0xFF
+#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3)
+#define B64_BASE64(a) !B64_NOT_BASE64(a)
+
+static const unsigned char data_ascii2bin[128] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
+ 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
+ 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+ 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
+ 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+#ifndef CHARSET_EBCDIC
+static unsigned char conv_ascii2bin(unsigned char a)
+{
+ if (a & 0x80)
+ return B64_ERROR;
+ return data_ascii2bin[a];
+}
+#else
+static unsigned char conv_ascii2bin(unsigned char a)
+{
+ a = os_toascii[a];
+ if (a & 0x80)
+ return B64_ERROR;
+ return data_ascii2bin[a];
+}
+#endif
+
+void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
+{
+ ctx->length = 48;
+ ctx->num = 0;
+ ctx->line_num = 0;
+}
+
+void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl)
+{
+ int i, j;
+ size_t total = 0;
+
+ *outl = 0;
+ if (inl <= 0)
+ return;
+ OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
+ if (ctx->length - ctx->num > inl) {
+ memcpy(&(ctx->enc_data[ctx->num]), in, inl);
+ ctx->num += inl;
+ return;
+ }
+ if (ctx->num != 0) {
+ i = ctx->length - ctx->num;
+ memcpy(&(ctx->enc_data[ctx->num]), in, i);
+ in += i;
+ inl -= i;
+ j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
+ ctx->num = 0;
+ out += j;
+ *(out++) = '\n';
+ *out = '\0';
+ total = j + 1;
+ }
+ while (inl >= ctx->length && total <= INT_MAX) {
+ j = EVP_EncodeBlock(out, in, ctx->length);
+ in += ctx->length;
+ inl -= ctx->length;
+ out += j;
+ *(out++) = '\n';
+ *out = '\0';
+ total += j + 1;
+ }
+ if (total > INT_MAX) {
+ /* Too much output data! */
+ *outl = 0;
+ return;
+ }
+ if (inl != 0)
+ memcpy(&(ctx->enc_data[0]), in, inl);
+ ctx->num = inl;
+ *outl = total;
+}
+
+void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
+{
+ unsigned int ret = 0;
+
+ if (ctx->num != 0) {
+ ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
+ out[ret++] = '\n';
+ out[ret] = '\0';
+ ctx->num = 0;
+ }
+ *outl = ret;
+}
+
+int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
+{
+ int i, ret = 0;
+ unsigned long l;
+
+ for (i = dlen; i > 0; i -= 3) {
+ if (i >= 3) {
+ l = (((unsigned long)f[0]) << 16L) |
+ (((unsigned long)f[1]) << 8L) | f[2];
+ *(t++) = conv_bin2ascii(l >> 18L);
+ *(t++) = conv_bin2ascii(l >> 12L);
+ *(t++) = conv_bin2ascii(l >> 6L);
+ *(t++) = conv_bin2ascii(l);
+ } else {
+ l = ((unsigned long)f[0]) << 16L;
+ if (i == 2)
+ l |= ((unsigned long)f[1] << 8L);
+
+ *(t++) = conv_bin2ascii(l >> 18L);
+ *(t++) = conv_bin2ascii(l >> 12L);
+ *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L);
+ *(t++) = '=';
+ }
+ ret += 4;
+ f += 3;
+ }
+
+ *t = '\0';
+ return (ret);
+}
+
+void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
+{
+ /* Only ctx->num is used during decoding. */
+ ctx->num = 0;
+ ctx->length = 0;
+ ctx->line_num = 0;
+ ctx->expect_nl = 0;
+}
+
+/*-
+ * -1 for error
+ * 0 for last line
+ * 1 for full line
+ *
+ * Note: even though EVP_DecodeUpdate attempts to detect and report end of
+ * content, the context doesn't currently remember it and will accept more data
+ * in the next call. Therefore, the caller is responsible for checking and
+ * rejecting a 0 return value in the middle of content.
+ *
+ * Note: even though EVP_DecodeUpdate has historically tried to detect end of
+ * content based on line length, this has never worked properly. Therefore,
+ * we now return 0 when one of the following is true:
+ * - Padding or B64_EOF was detected and the last block is complete.
+ * - Input has zero-length.
+ * -1 is returned if:
+ * - Invalid characters are detected.
+ * - There is extra trailing padding, or data after padding.
+ * - B64_EOF is detected after an incomplete base64 block.
+ */
+int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl)
+{
+ int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len;
+ unsigned char *d;
+
+ n = ctx->num;
+ d = ctx->enc_data;
+
+ if (n > 0 && d[n - 1] == '=') {
+ eof++;
+ if (n > 1 && d[n - 2] == '=')
+ eof++;
+ }
+
+ /* Legacy behaviour: an empty input chunk signals end of input. */
+ if (inl == 0) {
+ rv = 0;
+ goto end;
+ }
+
+ for (i = 0; i < inl; i++) {
+ tmp = *(in++);
+ v = conv_ascii2bin(tmp);
+ if (v == B64_ERROR) {
+ rv = -1;
+ goto end;
+ }
+
+ if (tmp == '=') {
+ eof++;
+ } else if (eof > 0 && B64_BASE64(v)) {
+ /* More data after padding. */
+ rv = -1;
+ goto end;
+ }
+
+ if (eof > 2) {
+ rv = -1;
+ goto end;
+ }
+
+ if (v == B64_EOF) {
+ seof = 1;
+ goto tail;
+ }
+
+ /* Only save valid base64 characters. */
+ if (B64_BASE64(v)) {
+ if (n >= 64) {
+ /*
+ * We increment n once per loop, and empty the buffer as soon as
+ * we reach 64 characters, so this can only happen if someone's
+ * manually messed with the ctx. Refuse to write any more data.
+ */
+ rv = -1;
+ goto end;
+ }
+ OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
+ d[n++] = tmp;
+ }
+
+ if (n == 64) {
+ decoded_len = EVP_DecodeBlock(out, d, n);
+ n = 0;
+ if (decoded_len < 0 || eof > decoded_len) {
+ rv = -1;
+ goto end;
+ }
+ ret += decoded_len - eof;
+ out += decoded_len - eof;
+ }
+ }
+
+ /*
+ * Legacy behaviour: if the current line is a full base64-block (i.e., has
+ * 0 mod 4 base64 characters), it is processed immediately. We keep this
+ * behaviour as applications may not be calling EVP_DecodeFinal properly.
+ */
+tail:
+ if (n > 0) {
+ if ((n & 3) == 0) {
+ decoded_len = EVP_DecodeBlock(out, d, n);
+ n = 0;
+ if (decoded_len < 0 || eof > decoded_len) {
+ rv = -1;
+ goto end;
+ }
+ ret += (decoded_len - eof);
+ } else if (seof) {
+ /* EOF in the middle of a base64 block. */
+ rv = -1;
+ goto end;
+ }
+ }
+
+ rv = seof || (n == 0 && eof) ? 0 : 1;
+end:
+ /* Legacy behaviour. This should probably rather be zeroed on error. */
+ *outl = ret;
+ ctx->num = n;
+ return (rv);
+}
+
+int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
+{
+ int i, ret = 0, a, b, c, d;
+ unsigned long l;
+
+ /* trim white space from the start of the line. */
+ while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) {
+ f++;
+ n--;
+ }
+
+ /*
+ * strip off stuff at the end of the line ascii2bin values B64_WS,
+ * B64_EOLN, B64_EOLN and B64_EOF
+ */
+ while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1]))))
+ n--;
+
+ if (n % 4 != 0)
+ return (-1);
+
+ for (i = 0; i < n; i += 4) {
+ a = conv_ascii2bin(*(f++));
+ b = conv_ascii2bin(*(f++));
+ c = conv_ascii2bin(*(f++));
+ d = conv_ascii2bin(*(f++));
+ if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80))
+ return (-1);
+ l = ((((unsigned long)a) << 18L) |
+ (((unsigned long)b) << 12L) |
+ (((unsigned long)c) << 6L) | (((unsigned long)d)));
+ *(t++) = (unsigned char)(l >> 16L) & 0xff;
+ *(t++) = (unsigned char)(l >> 8L) & 0xff;
+ *(t++) = (unsigned char)(l) & 0xff;
+ ret += 3;
+ }
+ return (ret);
+}
+
+int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
+{
+ int i;
+
+ *outl = 0;
+ if (ctx->num != 0) {
+ i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
+ if (i < 0)
+ return (-1);
+ ctx->num = 0;
+ *outl = i;
+ return (1);
+ } else
+ return (1);
+}
+
+#ifdef undef
+int EVP_DecodeValid(unsigned char *buf, int len)
+{
+ int i, num = 0, bad = 0;
+
+ if (len == 0)
+ return (-1);
+ while (conv_ascii2bin(*buf) == B64_WS) {
+ buf++;
+ len--;
+ if (len == 0)
+ return (-1);
+ }
+
+ for (i = len; i >= 4; i -= 4) {
+ if ((conv_ascii2bin(buf[0]) >= 0x40) ||
+ (conv_ascii2bin(buf[1]) >= 0x40) ||
+ (conv_ascii2bin(buf[2]) >= 0x40) ||
+ (conv_ascii2bin(buf[3]) >= 0x40))
+ return (-1);
+ buf += 4;
+ num += 1 + (buf[2] != '=') + (buf[3] != '=');
+ }
+ if ((i == 1) && (conv_ascii2bin(buf[0]) == B64_EOLN))
+ return (num);
+ if ((i == 2) && (conv_ascii2bin(buf[0]) == B64_EOLN) &&
+ (conv_ascii2bin(buf[0]) == B64_EOLN))
+ return (num);
+ return (1);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_acnf.c b/Cryptlib/OpenSSL/crypto/evp/evp_acnf.c
new file mode 100644
index 00000000..9703116e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_acnf.c
@@ -0,0 +1,73 @@
+/* evp_acnf.c */
+/*
+ * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/conf.h>
+
+/*
+ * Load all algorithms and configure OpenSSL. This function is called
+ * automatically when OPENSSL_LOAD_CONF is set.
+ */
+
+void OPENSSL_add_all_algorithms_conf(void)
+{
+ OPENSSL_add_all_algorithms_noconf();
+ OPENSSL_config(NULL);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_cnf.c b/Cryptlib/OpenSSL/crypto/evp/evp_cnf.c
new file mode 100644
index 00000000..6fd3a6da
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_cnf.c
@@ -0,0 +1,118 @@
+/* evp_cnf.c */
+/*
+ * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project
+ * 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+/* Algorithm configuration module. */
+
+static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
+{
+ int i;
+ const char *oid_section;
+ STACK_OF(CONF_VALUE) *sktmp;
+ CONF_VALUE *oval;
+ oid_section = CONF_imodule_get_value(md);
+ if (!(sktmp = NCONF_get_section(cnf, oid_section))) {
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION);
+ return 0;
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
+ oval = sk_CONF_VALUE_value(sktmp, i);
+ if (!strcmp(oval->name, "fips_mode")) {
+ int m;
+ if (!X509V3_get_value_bool(oval, &m)) {
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE);
+ return 0;
+ }
+ if (m > 0) {
+#ifdef OPENSSL_FIPS
+ if (!FIPS_mode() && !FIPS_mode_set(1)) {
+ EVPerr(EVP_F_ALG_MODULE_INIT,
+ EVP_R_ERROR_SETTING_FIPS_MODE);
+ return 0;
+ }
+#else
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED);
+ return 0;
+#endif
+ }
+ } else {
+ EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION);
+ ERR_add_error_data(4, "name=", oval->name,
+ ", value=", oval->value);
+ }
+
+ }
+ return 1;
+}
+
+void EVP_add_alg_module(void)
+{
+ CONF_module_add("alg_section", alg_module_init, 0);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_enc.c b/Cryptlib/OpenSSL/crypto/evp/evp_enc.c
new file mode 100644
index 00000000..7d7be245
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_enc.c
@@ -0,0 +1,666 @@
+/* crypto/evp/evp_enc.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+#include "evp_locl.h"
+
+#ifdef OPENSSL_FIPS
+# define M_do_cipher(ctx, out, in, inl) FIPS_cipher(ctx, out, in, inl)
+#else
+# define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl)
+#endif
+
+const char EVP_version[] = "EVP" OPENSSL_VERSION_PTEXT;
+
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
+{
+ memset(ctx, 0, sizeof(EVP_CIPHER_CTX));
+ /* ctx->cipher=NULL; */
+}
+
+EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
+{
+ EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
+ if (ctx)
+ EVP_CIPHER_CTX_init(ctx);
+ return ctx;
+}
+
+int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key, const unsigned char *iv, int enc)
+{
+ if (cipher)
+ EVP_CIPHER_CTX_init(ctx);
+ return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc);
+}
+
+int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ ENGINE *impl, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ if (enc == -1)
+ enc = ctx->encrypt;
+ else {
+ if (enc)
+ enc = 1;
+ ctx->encrypt = enc;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ /*
+ * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
+ * this context may already have an ENGINE! Try to avoid releasing the
+ * previous handle, re-querying for an ENGINE, and having a
+ * reinitialisation, when it may all be unecessary.
+ */
+ if (ctx->engine && ctx->cipher && (!cipher ||
+ (cipher
+ && (cipher->nid ==
+ ctx->cipher->nid))))
+ goto skip_to_init;
+#endif
+ if (cipher) {
+ /*
+ * Ensure a context left lying around from last time is cleared (the
+ * previous check attempted to avoid this if the same ENGINE and
+ * EVP_CIPHER could be used).
+ */
+ if (ctx->cipher) {
+ unsigned long flags = ctx->flags;
+ EVP_CIPHER_CTX_cleanup(ctx);
+ /* Restore encrypt and flags */
+ ctx->encrypt = enc;
+ ctx->flags = flags;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ if (impl) {
+ if (!ENGINE_init(impl)) {
+ EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
+ return 0;
+ }
+ } else
+ /* Ask if an ENGINE is reserved for this job */
+ impl = ENGINE_get_cipher_engine(cipher->nid);
+ if (impl) {
+ /* There's an ENGINE for this job ... (apparently) */
+ const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
+ if (!c) {
+ /*
+ * One positive side-effect of US's export control history,
+ * is that we should at least be able to avoid using US
+ * mispellings of "initialisation"?
+ */
+ EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
+ return 0;
+ }
+ /* We'll use the ENGINE's private cipher definition */
+ cipher = c;
+ /*
+ * Store the ENGINE functional reference so we know 'cipher' came
+ * from an ENGINE and we need to release it when done.
+ */
+ ctx->engine = impl;
+ } else
+ ctx->engine = NULL;
+#endif
+
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode()) {
+ const EVP_CIPHER *fcipher;
+ if (cipher)
+ fcipher = evp_get_fips_cipher(cipher);
+ if (fcipher)
+ cipher = fcipher;
+ return FIPS_cipherinit(ctx, cipher, key, iv, enc);
+ }
+#endif
+ ctx->cipher = cipher;
+ if (ctx->cipher->ctx_size) {
+ ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size);
+ if (!ctx->cipher_data) {
+ EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ } else {
+ ctx->cipher_data = NULL;
+ }
+ ctx->key_len = cipher->key_len;
+ /* Preserve wrap enable flag, zero everything else */
+ ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW;
+ if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) {
+ EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
+ return 0;
+ }
+ }
+ } else if (!ctx->cipher) {
+ EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
+ return 0;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ skip_to_init:
+#endif
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_cipherinit(ctx, cipher, key, iv, enc);
+#endif
+ /* we assume block size is a power of 2 in *cryptUpdate */
+ OPENSSL_assert(ctx->cipher->block_size == 1
+ || ctx->cipher->block_size == 8
+ || ctx->cipher->block_size == 16);
+
+ if (!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW)
+ && EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_WRAP_MODE) {
+ EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_WRAP_MODE_NOT_ALLOWED);
+ return 0;
+ }
+
+ if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
+ switch (EVP_CIPHER_CTX_mode(ctx)) {
+
+ case EVP_CIPH_STREAM_CIPHER:
+ case EVP_CIPH_ECB_MODE:
+ break;
+
+ case EVP_CIPH_CFB_MODE:
+ case EVP_CIPH_OFB_MODE:
+
+ ctx->num = 0;
+ /* fall-through */
+
+ case EVP_CIPH_CBC_MODE:
+
+ OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
+ (int)sizeof(ctx->iv));
+ if (iv)
+ memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+ memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+ break;
+
+ case EVP_CIPH_CTR_MODE:
+ ctx->num = 0;
+ /* Don't reuse IV for CTR mode */
+ if (iv)
+ memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+ break;
+
+ default:
+ return 0;
+ break;
+ }
+ }
+
+ if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
+ if (!ctx->cipher->init(ctx, key, iv, enc))
+ return 0;
+ }
+ ctx->buf_len = 0;
+ ctx->final_used = 0;
+ ctx->block_mask = ctx->cipher->block_size - 1;
+ return 1;
+}
+
+int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl)
+{
+ if (ctx->encrypt)
+ return EVP_EncryptUpdate(ctx, out, outl, in, inl);
+ else
+ return EVP_DecryptUpdate(ctx, out, outl, in, inl);
+}
+
+int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ if (ctx->encrypt)
+ return EVP_EncryptFinal_ex(ctx, out, outl);
+ else
+ return EVP_DecryptFinal_ex(ctx, out, outl);
+}
+
+int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ if (ctx->encrypt)
+ return EVP_EncryptFinal(ctx, out, outl);
+ else
+ return EVP_DecryptFinal(ctx, out, outl);
+}
+
+int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key, const unsigned char *iv)
+{
+ return EVP_CipherInit(ctx, cipher, key, iv, 1);
+}
+
+int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ ENGINE *impl, const unsigned char *key,
+ const unsigned char *iv)
+{
+ return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
+}
+
+int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key, const unsigned char *iv)
+{
+ return EVP_CipherInit(ctx, cipher, key, iv, 0);
+}
+
+int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ ENGINE *impl, const unsigned char *key,
+ const unsigned char *iv)
+{
+ return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
+}
+
+int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl)
+{
+ int i, j, bl;
+
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+ i = M_do_cipher(ctx, out, in, inl);
+ if (i < 0)
+ return 0;
+ else
+ *outl = i;
+ return 1;
+ }
+
+ if (inl <= 0) {
+ *outl = 0;
+ return inl == 0;
+ }
+
+ if (ctx->buf_len == 0 && (inl & (ctx->block_mask)) == 0) {
+ if (M_do_cipher(ctx, out, in, inl)) {
+ *outl = inl;
+ return 1;
+ } else {
+ *outl = 0;
+ return 0;
+ }
+ }
+ i = ctx->buf_len;
+ bl = ctx->cipher->block_size;
+ OPENSSL_assert(bl <= (int)sizeof(ctx->buf));
+ if (i != 0) {
+ if (bl - i > inl) {
+ memcpy(&(ctx->buf[i]), in, inl);
+ ctx->buf_len += inl;
+ *outl = 0;
+ return 1;
+ } else {
+ j = bl - i;
+ memcpy(&(ctx->buf[i]), in, j);
+ if (!M_do_cipher(ctx, out, ctx->buf, bl))
+ return 0;
+ inl -= j;
+ in += j;
+ out += bl;
+ *outl = bl;
+ }
+ } else
+ *outl = 0;
+ i = inl & (bl - 1);
+ inl -= i;
+ if (inl > 0) {
+ if (!M_do_cipher(ctx, out, in, inl))
+ return 0;
+ *outl += inl;
+ }
+
+ if (i != 0)
+ memcpy(ctx->buf, &(in[inl]), i);
+ ctx->buf_len = i;
+ return 1;
+}
+
+int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ int ret;
+ ret = EVP_EncryptFinal_ex(ctx, out, outl);
+ return ret;
+}
+
+int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ int n, ret;
+ unsigned int i, b, bl;
+
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+ ret = M_do_cipher(ctx, out, NULL, 0);
+ if (ret < 0)
+ return 0;
+ else
+ *outl = ret;
+ return 1;
+ }
+
+ b = ctx->cipher->block_size;
+ OPENSSL_assert(b <= sizeof ctx->buf);
+ if (b == 1) {
+ *outl = 0;
+ return 1;
+ }
+ bl = ctx->buf_len;
+ if (ctx->flags & EVP_CIPH_NO_PADDING) {
+ if (bl) {
+ EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,
+ EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+ return 0;
+ }
+ *outl = 0;
+ return 1;
+ }
+
+ n = b - bl;
+ for (i = bl; i < b; i++)
+ ctx->buf[i] = n;
+ ret = M_do_cipher(ctx, out, ctx->buf, b);
+
+ if (ret)
+ *outl = b;
+
+ return ret;
+}
+
+int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl)
+{
+ int fix_len;
+ unsigned int b;
+
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+ fix_len = M_do_cipher(ctx, out, in, inl);
+ if (fix_len < 0) {
+ *outl = 0;
+ return 0;
+ } else
+ *outl = fix_len;
+ return 1;
+ }
+
+ if (inl <= 0) {
+ *outl = 0;
+ return inl == 0;
+ }
+
+ if (ctx->flags & EVP_CIPH_NO_PADDING)
+ return EVP_EncryptUpdate(ctx, out, outl, in, inl);
+
+ b = ctx->cipher->block_size;
+ OPENSSL_assert(b <= sizeof ctx->final);
+
+ if (ctx->final_used) {
+ memcpy(out, ctx->final, b);
+ out += b;
+ fix_len = 1;
+ } else
+ fix_len = 0;
+
+ if (!EVP_EncryptUpdate(ctx, out, outl, in, inl))
+ return 0;
+
+ /*
+ * if we have 'decrypted' a multiple of block size, make sure we have a
+ * copy of this last block
+ */
+ if (b > 1 && !ctx->buf_len) {
+ *outl -= b;
+ ctx->final_used = 1;
+ memcpy(ctx->final, &out[*outl], b);
+ } else
+ ctx->final_used = 0;
+
+ if (fix_len)
+ *outl += b;
+
+ return 1;
+}
+
+int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ int ret;
+ ret = EVP_DecryptFinal_ex(ctx, out, outl);
+ return ret;
+}
+
+int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ int i, n;
+ unsigned int b;
+ *outl = 0;
+
+ if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+ i = M_do_cipher(ctx, out, NULL, 0);
+ if (i < 0)
+ return 0;
+ else
+ *outl = i;
+ return 1;
+ }
+
+ b = ctx->cipher->block_size;
+ if (ctx->flags & EVP_CIPH_NO_PADDING) {
+ if (ctx->buf_len) {
+ EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,
+ EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+ return 0;
+ }
+ *outl = 0;
+ return 1;
+ }
+ if (b > 1) {
+ if (ctx->buf_len || !ctx->final_used) {
+ EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH);
+ return (0);
+ }
+ OPENSSL_assert(b <= sizeof ctx->final);
+
+ /*
+ * The following assumes that the ciphertext has been authenticated.
+ * Otherwise it provides a padding oracle.
+ */
+ n = ctx->final[b - 1];
+ if (n == 0 || n > (int)b) {
+ EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
+ return (0);
+ }
+ for (i = 0; i < n; i++) {
+ if (ctx->final[--b] != n) {
+ EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
+ return (0);
+ }
+ }
+ n = ctx->cipher->block_size - n;
+ for (i = 0; i < n; i++)
+ out[i] = ctx->final[i];
+ *outl = n;
+ } else
+ *outl = 0;
+ return (1);
+}
+
+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
+{
+ if (ctx) {
+ EVP_CIPHER_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+ }
+}
+
+int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
+{
+#ifndef OPENSSL_FIPS
+ if (c->cipher != NULL) {
+ if (c->cipher->cleanup && !c->cipher->cleanup(c))
+ return 0;
+ /* Cleanse cipher context data */
+ if (c->cipher_data)
+ OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
+ }
+ if (c->cipher_data)
+ OPENSSL_free(c->cipher_data);
+#endif
+#ifndef OPENSSL_NO_ENGINE
+ if (c->engine)
+ /*
+ * The EVP_CIPHER we used belongs to an ENGINE, release the
+ * functional reference we held for this reason.
+ */
+ ENGINE_finish(c->engine);
+#endif
+#ifdef OPENSSL_FIPS
+ FIPS_cipher_ctx_cleanup(c);
+#endif
+ memset(c, 0, sizeof(EVP_CIPHER_CTX));
+ return 1;
+}
+
+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
+{
+ if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
+ return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
+ if (c->key_len == keylen)
+ return 1;
+ if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) {
+ c->key_len = keylen;
+ return 1;
+ }
+ EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, EVP_R_INVALID_KEY_LENGTH);
+ return 0;
+}
+
+int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
+{
+ if (pad)
+ ctx->flags &= ~EVP_CIPH_NO_PADDING;
+ else
+ ctx->flags |= EVP_CIPH_NO_PADDING;
+ return 1;
+}
+
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+ int ret;
+ if (!ctx->cipher) {
+ EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
+ return 0;
+ }
+
+ if (!ctx->cipher->ctrl) {
+ EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
+ return 0;
+ }
+
+ ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
+ if (ret == -1) {
+ EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL,
+ EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
+ return 0;
+ }
+ return ret;
+}
+
+int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
+{
+ if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
+ return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
+ if (RAND_bytes(key, ctx->key_len) <= 0)
+ return 0;
+ return 1;
+}
+
+int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
+{
+ if ((in == NULL) || (in->cipher == NULL)) {
+ EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INPUT_NOT_INITIALIZED);
+ return 0;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ /* Make sure it's safe to copy a cipher context using an ENGINE */
+ if (in->engine && !ENGINE_init(in->engine)) {
+ EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_ENGINE_LIB);
+ return 0;
+ }
+#endif
+
+ EVP_CIPHER_CTX_cleanup(out);
+ memcpy(out, in, sizeof *out);
+
+ if (in->cipher_data && in->cipher->ctx_size) {
+ out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);
+ if (!out->cipher_data) {
+ EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
+ }
+
+ if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
+ return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
+ return 1;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_err.c b/Cryptlib/OpenSSL/crypto/evp/evp_err.c
new file mode 100644
index 00000000..15cf5532
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_err.c
@@ -0,0 +1,254 @@
+/* crypto/evp/evp_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2013 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
+ * openssl-core@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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+ * NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EVP,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EVP,0,reason)
+
+static ERR_STRING_DATA EVP_str_functs[] = {
+ {ERR_FUNC(EVP_F_AESNI_INIT_KEY), "AESNI_INIT_KEY"},
+ {ERR_FUNC(EVP_F_AESNI_XTS_CIPHER), "AESNI_XTS_CIPHER"},
+ {ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"},
+ {ERR_FUNC(EVP_F_AES_T4_INIT_KEY), "AES_T4_INIT_KEY"},
+ {ERR_FUNC(EVP_F_AES_XTS), "AES_XTS"},
+ {ERR_FUNC(EVP_F_AES_XTS_CIPHER), "AES_XTS_CIPHER"},
+ {ERR_FUNC(EVP_F_ALG_MODULE_INIT), "ALG_MODULE_INIT"},
+ {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "CAMELLIA_INIT_KEY"},
+ {ERR_FUNC(EVP_F_CMAC_INIT), "CMAC_INIT"},
+ {ERR_FUNC(EVP_F_CMLL_T4_INIT_KEY), "CMLL_T4_INIT_KEY"},
+ {ERR_FUNC(EVP_F_D2I_PKEY), "D2I_PKEY"},
+ {ERR_FUNC(EVP_F_DO_SIGVER_INIT), "DO_SIGVER_INIT"},
+ {ERR_FUNC(EVP_F_DSAPKEY2PKCS8), "DSAPKEY2PKCS8"},
+ {ERR_FUNC(EVP_F_DSA_PKEY2PKCS8), "DSA_PKEY2PKCS8"},
+ {ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8), "ECDSA_PKEY2PKCS8"},
+ {ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8), "ECKEY_PKEY2PKCS8"},
+ {ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"},
+ {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY), "EVP_CIPHER_CTX_copy"},
+ {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL), "EVP_CIPHER_CTX_ctrl"},
+ {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH),
+ "EVP_CIPHER_CTX_set_key_length"},
+ {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"},
+ {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"},
+ {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"},
+ {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"},
+ {ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_size"},
+ {ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"},
+ {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"},
+ {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE), "EVP_PBE_alg_add_type"},
+ {ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"},
+ {ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"},
+ {ERR_FUNC(EVP_F_EVP_PKCS82PKEY_BROKEN), "EVP_PKCS82PKEY_BROKEN"},
+ {ERR_FUNC(EVP_F_EVP_PKEY2PKCS8_BROKEN), "EVP_PKEY2PKCS8_broken"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL), "EVP_PKEY_CTX_ctrl"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR), "EVP_PKEY_CTX_ctrl_str"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_CTX_DUP), "EVP_PKEY_CTX_dup"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_INIT), "EVP_PKEY_decrypt_init"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD), "EVP_PKEY_decrypt_old"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE), "EVP_PKEY_derive"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT), "EVP_PKEY_derive_init"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER), "EVP_PKEY_derive_set_peer"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT), "EVP_PKEY_encrypt"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT), "EVP_PKEY_encrypt_init"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD), "EVP_PKEY_encrypt_old"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_GET1_DH), "EVP_PKEY_get1_DH"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_GET1_DSA), "EVP_PKEY_get1_DSA"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_GET1_ECDSA), "EVP_PKEY_GET1_ECDSA"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_GET1_EC_KEY), "EVP_PKEY_get1_EC_KEY"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_GET1_RSA), "EVP_PKEY_get1_RSA"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN), "EVP_PKEY_keygen"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT), "EVP_PKEY_keygen_init"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_NEW), "EVP_PKEY_new"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN), "EVP_PKEY_paramgen"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN_INIT), "EVP_PKEY_paramgen_init"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_SIGN), "EVP_PKEY_sign"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_SIGN_INIT), "EVP_PKEY_sign_init"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY), "EVP_PKEY_verify"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_INIT), "EVP_PKEY_verify_init"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER), "EVP_PKEY_verify_recover"},
+ {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT),
+ "EVP_PKEY_verify_recover_init"},
+ {ERR_FUNC(EVP_F_EVP_RIJNDAEL), "EVP_RIJNDAEL"},
+ {ERR_FUNC(EVP_F_EVP_SIGNFINAL), "EVP_SignFinal"},
+ {ERR_FUNC(EVP_F_EVP_VERIFYFINAL), "EVP_VerifyFinal"},
+ {ERR_FUNC(EVP_F_FIPS_CIPHERINIT), "FIPS_CIPHERINIT"},
+ {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_COPY), "FIPS_CIPHER_CTX_COPY"},
+ {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_CTRL), "FIPS_CIPHER_CTX_CTRL"},
+ {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH),
+ "FIPS_CIPHER_CTX_SET_KEY_LENGTH"},
+ {ERR_FUNC(EVP_F_FIPS_DIGESTINIT), "FIPS_DIGESTINIT"},
+ {ERR_FUNC(EVP_F_FIPS_MD_CTX_COPY), "FIPS_MD_CTX_COPY"},
+ {ERR_FUNC(EVP_F_HMAC_INIT_EX), "HMAC_Init_ex"},
+ {ERR_FUNC(EVP_F_INT_CTX_NEW), "INT_CTX_NEW"},
+ {ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"},
+ {ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"},
+ {ERR_FUNC(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN), "PKCS5_V2_PBKDF2_KEYIVGEN"},
+ {ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"},
+ {ERR_FUNC(EVP_F_PKEY_SET_TYPE), "PKEY_SET_TYPE"},
+ {ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"},
+ {ERR_FUNC(EVP_F_RC5_CTRL), "RC5_CTRL"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA EVP_str_reasons[] = {
+ {ERR_REASON(EVP_R_AES_IV_SETUP_FAILED), "aes iv setup failed"},
+ {ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED), "aes key setup failed"},
+ {ERR_REASON(EVP_R_ASN1_LIB), "asn1 lib"},
+ {ERR_REASON(EVP_R_BAD_BLOCK_LENGTH), "bad block length"},
+ {ERR_REASON(EVP_R_BAD_DECRYPT), "bad decrypt"},
+ {ERR_REASON(EVP_R_BAD_KEY_LENGTH), "bad key length"},
+ {ERR_REASON(EVP_R_BN_DECODE_ERROR), "bn decode error"},
+ {ERR_REASON(EVP_R_BN_PUBKEY_ERROR), "bn pubkey error"},
+ {ERR_REASON(EVP_R_BUFFER_TOO_SMALL), "buffer too small"},
+ {ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED),
+ "camellia key setup failed"},
+ {ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR), "cipher parameter error"},
+ {ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED), "command not supported"},
+ {ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED), "ctrl not implemented"},
+ {ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED),
+ "ctrl operation not implemented"},
+ {ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),
+ "data not multiple of block length"},
+ {ERR_REASON(EVP_R_DECODE_ERROR), "decode error"},
+ {ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES), "different key types"},
+ {ERR_REASON(EVP_R_DIFFERENT_PARAMETERS), "different parameters"},
+ {ERR_REASON(EVP_R_DISABLED_FOR_FIPS), "disabled for fips"},
+ {ERR_REASON(EVP_R_ENCODE_ERROR), "encode error"},
+ {ERR_REASON(EVP_R_ERROR_LOADING_SECTION), "error loading section"},
+ {ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE), "error setting fips mode"},
+ {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR), "evp pbe cipherinit error"},
+ {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY), "expecting an rsa key"},
+ {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY), "expecting a dh key"},
+ {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY), "expecting a dsa key"},
+ {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY), "expecting a ecdsa key"},
+ {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY), "expecting a ec key"},
+ {ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"},
+ {ERR_REASON(EVP_R_INITIALIZATION_ERROR), "initialization error"},
+ {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED), "input not initialized"},
+ {ERR_REASON(EVP_R_INVALID_DIGEST), "invalid digest"},
+ {ERR_REASON(EVP_R_INVALID_FIPS_MODE), "invalid fips mode"},
+ {ERR_REASON(EVP_R_INVALID_KEY_LENGTH), "invalid key length"},
+ {ERR_REASON(EVP_R_INVALID_OPERATION), "invalid operation"},
+ {ERR_REASON(EVP_R_IV_TOO_LARGE), "iv too large"},
+ {ERR_REASON(EVP_R_KEYGEN_FAILURE), "keygen failure"},
+ {ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL), "message digest is null"},
+ {ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED), "method not supported"},
+ {ERR_REASON(EVP_R_MISSING_PARAMETERS), "missing parameters"},
+ {ERR_REASON(EVP_R_NO_CIPHER_SET), "no cipher set"},
+ {ERR_REASON(EVP_R_NO_DEFAULT_DIGEST), "no default digest"},
+ {ERR_REASON(EVP_R_NO_DIGEST_SET), "no digest set"},
+ {ERR_REASON(EVP_R_NO_DSA_PARAMETERS), "no dsa parameters"},
+ {ERR_REASON(EVP_R_NO_KEY_SET), "no key set"},
+ {ERR_REASON(EVP_R_NO_OPERATION_SET), "no operation set"},
+ {ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED),
+ "no sign function configured"},
+ {ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),
+ "no verify function configured"},
+ {ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),
+ "operation not supported for this keytype"},
+ {ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"},
+ {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),
+ "pkcs8 unknown broken type"},
+ {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"},
+ {ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR), "private key encode error"},
+ {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"},
+ {ERR_REASON(EVP_R_TOO_LARGE), "too large"},
+ {ERR_REASON(EVP_R_UNKNOWN_CIPHER), "unknown cipher"},
+ {ERR_REASON(EVP_R_UNKNOWN_DIGEST), "unknown digest"},
+ {ERR_REASON(EVP_R_UNKNOWN_OPTION), "unknown option"},
+ {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM), "unknown pbe algorithm"},
+ {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),
+ "unsuported number of rounds"},
+ {ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"},
+ {ERR_REASON(EVP_R_UNSUPPORTED_CIPHER), "unsupported cipher"},
+ {ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH), "unsupported keylength"},
+ {ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),
+ "unsupported key derivation function"},
+ {ERR_REASON(EVP_R_UNSUPPORTED_KEY_SIZE), "unsupported key size"},
+ {ERR_REASON(EVP_R_UNSUPPORTED_PRF), "unsupported prf"},
+ {ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM),
+ "unsupported private key algorithm"},
+ {ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE), "unsupported salt type"},
+ {ERR_REASON(EVP_R_WRAP_MODE_NOT_ALLOWED), "wrap mode not allowed"},
+ {ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"},
+ {ERR_REASON(EVP_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_EVP_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, EVP_str_functs);
+ ERR_load_strings(0, EVP_str_reasons);
+ }
+#endif
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_key.c b/Cryptlib/OpenSSL/crypto/evp/evp_key.c
new file mode 100644
index 00000000..63c8866e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_key.c
@@ -0,0 +1,197 @@
+/* crypto/evp/evp_key.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/ui.h>
+
+#ifndef OPENSSL_NO_UI
+/* should be init to zeros. */
+static char prompt_string[80];
+
+void EVP_set_pw_prompt(const char *prompt)
+{
+ if (prompt == NULL)
+ prompt_string[0] = '\0';
+ else {
+ strncpy(prompt_string, prompt, 79);
+ prompt_string[79] = '\0';
+ }
+}
+
+char *EVP_get_pw_prompt(void)
+{
+ if (prompt_string[0] == '\0')
+ return (NULL);
+ else
+ return (prompt_string);
+}
+
+/*
+ * For historical reasons, the standard function for reading passwords is in
+ * the DES library -- if someone ever wants to disable DES, this function
+ * will fail
+ */
+int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify)
+{
+ return EVP_read_pw_string_min(buf, 0, len, prompt, verify);
+}
+
+int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt,
+ int verify)
+{
+ int ret;
+ char buff[BUFSIZ];
+ UI *ui;
+
+ if ((prompt == NULL) && (prompt_string[0] != '\0'))
+ prompt = prompt_string;
+ ui = UI_new();
+ if (ui == NULL)
+ return -1;
+ UI_add_input_string(ui, prompt, 0, buf, min,
+ (len >= BUFSIZ) ? BUFSIZ - 1 : len);
+ if (verify)
+ UI_add_verify_string(ui, prompt, 0,
+ buff, min, (len >= BUFSIZ) ? BUFSIZ - 1 : len,
+ buf);
+ ret = UI_process(ui);
+ UI_free(ui);
+ OPENSSL_cleanse(buff, BUFSIZ);
+ return ret;
+}
+#endif /* OPENSSL_NO_UI */
+
+int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
+ const unsigned char *salt, const unsigned char *data,
+ int datal, int count, unsigned char *key,
+ unsigned char *iv)
+{
+ EVP_MD_CTX c;
+ unsigned char md_buf[EVP_MAX_MD_SIZE];
+ int niv, nkey, addmd = 0;
+ unsigned int mds = 0, i;
+ int rv = 0;
+ nkey = type->key_len;
+ niv = type->iv_len;
+ OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
+ OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH);
+
+ if (data == NULL)
+ return (nkey);
+
+ EVP_MD_CTX_init(&c);
+ for (;;) {
+ if (!EVP_DigestInit_ex(&c, md, NULL))
+ goto err;
+ if (addmd++)
+ if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds))
+ goto err;
+ if (!EVP_DigestUpdate(&c, data, datal))
+ goto err;
+ if (salt != NULL)
+ if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN))
+ goto err;
+ if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds))
+ goto err;
+
+ for (i = 1; i < (unsigned int)count; i++) {
+ if (!EVP_DigestInit_ex(&c, md, NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds))
+ goto err;
+ if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds))
+ goto err;
+ }
+ i = 0;
+ if (nkey) {
+ for (;;) {
+ if (nkey == 0)
+ break;
+ if (i == mds)
+ break;
+ if (key != NULL)
+ *(key++) = md_buf[i];
+ nkey--;
+ i++;
+ }
+ }
+ if (niv && (i != mds)) {
+ for (;;) {
+ if (niv == 0)
+ break;
+ if (i == mds)
+ break;
+ if (iv != NULL)
+ *(iv++) = md_buf[i];
+ niv--;
+ i++;
+ }
+ }
+ if ((nkey == 0) && (niv == 0))
+ break;
+ }
+ rv = type->key_len;
+ err:
+ EVP_MD_CTX_cleanup(&c);
+ OPENSSL_cleanse(md_buf, sizeof(md_buf));
+ return rv;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_lib.c b/Cryptlib/OpenSSL/crypto/evp/evp_lib.c
new file mode 100644
index 00000000..7e0bab90
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_lib.c
@@ -0,0 +1,391 @@
+/* crypto/evp/evp_lib.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+# include "evp_locl.h"
+#endif
+
+int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+ int ret;
+
+ if (c->cipher->set_asn1_parameters != NULL)
+ ret = c->cipher->set_asn1_parameters(c, type);
+ else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
+ switch (EVP_CIPHER_CTX_mode(c)) {
+ case EVP_CIPH_WRAP_MODE:
+ if (EVP_CIPHER_CTX_nid(c) == NID_id_smime_alg_CMS3DESwrap)
+ ASN1_TYPE_set(type, V_ASN1_NULL, NULL);
+ ret = 1;
+ break;
+
+ case EVP_CIPH_GCM_MODE:
+ case EVP_CIPH_CCM_MODE:
+ case EVP_CIPH_XTS_MODE:
+ ret = -1;
+ break;
+
+ default:
+ ret = EVP_CIPHER_set_asn1_iv(c, type);
+ }
+ } else
+ ret = -1;
+ return (ret);
+}
+
+int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+ int ret;
+
+ if (c->cipher->get_asn1_parameters != NULL)
+ ret = c->cipher->get_asn1_parameters(c, type);
+ else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
+ switch (EVP_CIPHER_CTX_mode(c)) {
+
+ case EVP_CIPH_WRAP_MODE:
+ ret = 1;
+ break;
+
+ case EVP_CIPH_GCM_MODE:
+ case EVP_CIPH_CCM_MODE:
+ case EVP_CIPH_XTS_MODE:
+ ret = -1;
+ break;
+
+ default:
+ ret = EVP_CIPHER_get_asn1_iv(c, type);
+ break;
+ }
+ } else
+ ret = -1;
+ return (ret);
+}
+
+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+ int i = 0;
+ unsigned int l;
+
+ if (type != NULL) {
+ l = EVP_CIPHER_CTX_iv_length(c);
+ OPENSSL_assert(l <= sizeof(c->iv));
+ i = ASN1_TYPE_get_octetstring(type, c->oiv, l);
+ if (i != (int)l)
+ return (-1);
+ else if (i > 0)
+ memcpy(c->iv, c->oiv, l);
+ }
+ return (i);
+}
+
+int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+ int i = 0;
+ unsigned int j;
+
+ if (type != NULL) {
+ j = EVP_CIPHER_CTX_iv_length(c);
+ OPENSSL_assert(j <= sizeof(c->iv));
+ i = ASN1_TYPE_set_octetstring(type, c->oiv, j);
+ }
+ return (i);
+}
+
+/* Convert the various cipher NIDs and dummies to a proper OID NID */
+int EVP_CIPHER_type(const EVP_CIPHER *ctx)
+{
+ int nid;
+ ASN1_OBJECT *otmp;
+ nid = EVP_CIPHER_nid(ctx);
+
+ switch (nid) {
+
+ case NID_rc2_cbc:
+ case NID_rc2_64_cbc:
+ case NID_rc2_40_cbc:
+
+ return NID_rc2_cbc;
+
+ case NID_rc4:
+ case NID_rc4_40:
+
+ return NID_rc4;
+
+ case NID_aes_128_cfb128:
+ case NID_aes_128_cfb8:
+ case NID_aes_128_cfb1:
+
+ return NID_aes_128_cfb128;
+
+ case NID_aes_192_cfb128:
+ case NID_aes_192_cfb8:
+ case NID_aes_192_cfb1:
+
+ return NID_aes_192_cfb128;
+
+ case NID_aes_256_cfb128:
+ case NID_aes_256_cfb8:
+ case NID_aes_256_cfb1:
+
+ return NID_aes_256_cfb128;
+
+ case NID_des_cfb64:
+ case NID_des_cfb8:
+ case NID_des_cfb1:
+
+ return NID_des_cfb64;
+
+ case NID_des_ede3_cfb64:
+ case NID_des_ede3_cfb8:
+ case NID_des_ede3_cfb1:
+
+ return NID_des_cfb64;
+
+ default:
+ /* Check it has an OID and it is valid */
+ otmp = OBJ_nid2obj(nid);
+ if (!otmp || !otmp->data)
+ nid = NID_undef;
+ ASN1_OBJECT_free(otmp);
+ return nid;
+ }
+}
+
+int EVP_CIPHER_block_size(const EVP_CIPHER *e)
+{
+ return e->block_size;
+}
+
+int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
+{
+ return ctx->cipher->block_size;
+}
+
+int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, unsigned int inl)
+{
+ return ctx->cipher->do_cipher(ctx, out, in, inl);
+}
+
+const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx)
+{
+ return ctx->cipher;
+}
+
+unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
+{
+#ifdef OPENSSL_FIPS
+ const EVP_CIPHER *fcipher;
+ fcipher = evp_get_fips_cipher(cipher);
+ if (fcipher && fcipher->flags & EVP_CIPH_FLAG_FIPS)
+ return cipher->flags | EVP_CIPH_FLAG_FIPS;
+#endif
+ return cipher->flags;
+}
+
+unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
+{
+#ifdef OPENSSL_FIPS
+ return EVP_CIPHER_flags(ctx->cipher);
+#else
+ return ctx->cipher->flags;
+#endif
+}
+
+void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
+{
+ return ctx->app_data;
+}
+
+void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
+{
+ ctx->app_data = data;
+}
+
+int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
+{
+ return cipher->iv_len;
+}
+
+int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
+{
+ return ctx->cipher->iv_len;
+}
+
+int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
+{
+ return cipher->key_len;
+}
+
+int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
+{
+ return ctx->key_len;
+}
+
+int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
+{
+ return cipher->nid;
+}
+
+int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
+{
+ return ctx->cipher->nid;
+}
+
+int EVP_MD_block_size(const EVP_MD *md)
+{
+ return md->block_size;
+}
+
+int EVP_MD_type(const EVP_MD *md)
+{
+ return md->type;
+}
+
+int EVP_MD_pkey_type(const EVP_MD *md)
+{
+ return md->pkey_type;
+}
+
+int EVP_MD_size(const EVP_MD *md)
+{
+ if (!md) {
+ EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL);
+ return -1;
+ }
+ return md->md_size;
+}
+
+#ifdef OPENSSL_FIPS
+
+const EVP_MD *evp_get_fips_md(const EVP_MD *md)
+{
+ int nid = EVP_MD_type(md);
+ if (nid == NID_dsa)
+ return FIPS_evp_dss1();
+ else if (nid == NID_dsaWithSHA)
+ return FIPS_evp_dss();
+ else if (nid == NID_ecdsa_with_SHA1)
+ return FIPS_evp_ecdsa();
+ else
+ return FIPS_get_digestbynid(nid);
+}
+
+const EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher)
+{
+ int nid = cipher->nid;
+ if (nid == NID_undef)
+ return FIPS_evp_enc_null();
+ else
+ return FIPS_get_cipherbynid(nid);
+}
+
+#endif
+
+unsigned long EVP_MD_flags(const EVP_MD *md)
+{
+#ifdef OPENSSL_FIPS
+ const EVP_MD *fmd;
+ fmd = evp_get_fips_md(md);
+ if (fmd && fmd->flags & EVP_MD_FLAG_FIPS)
+ return md->flags | EVP_MD_FLAG_FIPS;
+#endif
+ return md->flags;
+}
+
+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
+{
+ if (!ctx)
+ return NULL;
+ return ctx->digest;
+}
+
+void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags)
+{
+ ctx->flags |= flags;
+}
+
+void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags)
+{
+ ctx->flags &= ~flags;
+}
+
+int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags)
+{
+ return (ctx->flags & flags);
+}
+
+void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags)
+{
+ ctx->flags |= flags;
+}
+
+void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags)
+{
+ ctx->flags &= ~flags;
+}
+
+int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
+{
+ return (ctx->flags & flags);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_locl.h b/Cryptlib/OpenSSL/crypto/evp/evp_locl.h
new file mode 100644
index 00000000..2bb709a0
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_locl.h
@@ -0,0 +1,373 @@
+/* evp_locl.h */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Macros to code block cipher wrappers */
+
+/* Wrapper functions for each cipher mode */
+
+#define BLOCK_CIPHER_ecb_loop() \
+ size_t i, bl; \
+ bl = ctx->cipher->block_size;\
+ if(inl < bl) return 1;\
+ inl -= bl; \
+ for(i=0; i <= inl; i+=bl)
+
+#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
+static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+ BLOCK_CIPHER_ecb_loop() \
+ cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\
+ return 1;\
+}
+
+#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2))
+
+#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \
+static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+ while(inl>=EVP_MAXCHUNK)\
+ {\
+ cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
+ inl-=EVP_MAXCHUNK;\
+ in +=EVP_MAXCHUNK;\
+ out+=EVP_MAXCHUNK;\
+ }\
+ if (inl)\
+ cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
+ return 1;\
+}
+
+#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
+static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+ while(inl>=EVP_MAXCHUNK) \
+ {\
+ cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
+ inl-=EVP_MAXCHUNK;\
+ in +=EVP_MAXCHUNK;\
+ out+=EVP_MAXCHUNK;\
+ }\
+ if (inl)\
+ cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
+ return 1;\
+}
+
+#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
+static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+ size_t chunk=EVP_MAXCHUNK;\
+ if (cbits==1) chunk>>=3;\
+ if (inl<chunk) chunk=inl;\
+ while(inl && inl>=chunk)\
+ {\
+ cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
+ inl-=chunk;\
+ in +=chunk;\
+ out+=chunk;\
+ if(inl<chunk) chunk=inl;\
+ }\
+ return 1;\
+}
+
+#define BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
+ BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
+ BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
+ BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
+ BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched)
+
+#define BLOCK_CIPHER_def1(cname, nmode, mode, MODE, kstruct, nid, block_size, \
+ key_len, iv_len, flags, init_key, cleanup, \
+ set_asn1, get_asn1, ctrl) \
+static const EVP_CIPHER cname##_##mode = { \
+ nid##_##nmode, block_size, key_len, iv_len, \
+ flags | EVP_CIPH_##MODE##_MODE, \
+ init_key, \
+ cname##_##mode##_cipher, \
+ cleanup, \
+ sizeof(kstruct), \
+ set_asn1, get_asn1,\
+ ctrl, \
+ NULL \
+}; \
+const EVP_CIPHER *EVP_##cname##_##mode(void) { return &cname##_##mode; }
+
+#define BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, \
+ iv_len, flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, cbc, cbc, CBC, kstruct, nid, block_size, key_len, \
+ iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, \
+ iv_len, cbits, flags, init_key, cleanup, \
+ set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, cfb##cbits, cfb##cbits, CFB, kstruct, nid, 1, \
+ key_len, iv_len, flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, \
+ iv_len, cbits, flags, init_key, cleanup, \
+ set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, ofb##cbits, ofb, OFB, kstruct, nid, 1, \
+ key_len, iv_len, flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, \
+ flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \
+ 0, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+#define BLOCK_CIPHER_defs(cname, kstruct, \
+ nid, block_size, key_len, iv_len, cbits, flags, \
+ init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, iv_len, flags, \
+ init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, iv_len, cbits, \
+ flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, iv_len, cbits, \
+ flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, flags, \
+ init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+/*-
+#define BLOCK_CIPHER_defs(cname, kstruct, \
+ nid, block_size, key_len, iv_len, flags,\
+ init_key, cleanup, set_asn1, get_asn1, ctrl)\
+static const EVP_CIPHER cname##_cbc = {\
+ nid##_cbc, block_size, key_len, iv_len, \
+ flags | EVP_CIPH_CBC_MODE,\
+ init_key,\
+ cname##_cbc_cipher,\
+ cleanup,\
+ sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+ sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+ set_asn1, get_asn1,\
+ ctrl, \
+ NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\
+static const EVP_CIPHER cname##_cfb = {\
+ nid##_cfb64, 1, key_len, iv_len, \
+ flags | EVP_CIPH_CFB_MODE,\
+ init_key,\
+ cname##_cfb_cipher,\
+ cleanup,\
+ sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+ sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+ set_asn1, get_asn1,\
+ ctrl,\
+ NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\
+static const EVP_CIPHER cname##_ofb = {\
+ nid##_ofb64, 1, key_len, iv_len, \
+ flags | EVP_CIPH_OFB_MODE,\
+ init_key,\
+ cname##_ofb_cipher,\
+ cleanup,\
+ sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+ sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+ set_asn1, get_asn1,\
+ ctrl,\
+ NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\
+static const EVP_CIPHER cname##_ecb = {\
+ nid##_ecb, block_size, key_len, iv_len, \
+ flags | EVP_CIPH_ECB_MODE,\
+ init_key,\
+ cname##_ecb_cipher,\
+ cleanup,\
+ sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+ sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+ set_asn1, get_asn1,\
+ ctrl,\
+ NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
+*/
+
+#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \
+ block_size, key_len, iv_len, cbits, \
+ flags, init_key, \
+ cleanup, set_asn1, get_asn1, ctrl) \
+ BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
+ BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \
+ cbits, flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl)
+
+#define EVP_C_DATA(kstruct, ctx) ((kstruct *)(ctx)->cipher_data)
+
+#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \
+ BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \
+ BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \
+ NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \
+ 0, cipher##_init_key, NULL, \
+ EVP_CIPHER_set_asn1_iv, \
+ EVP_CIPHER_get_asn1_iv, \
+ NULL)
+
+struct evp_pkey_ctx_st {
+ /* Method associated with this operation */
+ const EVP_PKEY_METHOD *pmeth;
+ /* Engine that implements this method or NULL if builtin */
+ ENGINE *engine;
+ /* Key: may be NULL */
+ EVP_PKEY *pkey;
+ /* Peer key for key agreement, may be NULL */
+ EVP_PKEY *peerkey;
+ /* Actual operation */
+ int operation;
+ /* Algorithm specific data */
+ void *data;
+ /* Application specific data */
+ void *app_data;
+ /* Keygen callback */
+ EVP_PKEY_gen_cb *pkey_gencb;
+ /* implementation specific keygen data */
+ int *keygen_info;
+ int keygen_info_count;
+} /* EVP_PKEY_CTX */ ;
+
+#define EVP_PKEY_FLAG_DYNAMIC 1
+
+struct evp_pkey_method_st {
+ int pkey_id;
+ int flags;
+ int (*init) (EVP_PKEY_CTX *ctx);
+ int (*copy) (EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
+ void (*cleanup) (EVP_PKEY_CTX *ctx);
+ int (*paramgen_init) (EVP_PKEY_CTX *ctx);
+ int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+ int (*keygen_init) (EVP_PKEY_CTX *ctx);
+ int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+ int (*sign_init) (EVP_PKEY_CTX *ctx);
+ int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs, size_t tbslen);
+ int (*verify_init) (EVP_PKEY_CTX *ctx);
+ int (*verify) (EVP_PKEY_CTX *ctx,
+ const unsigned char *sig, size_t siglen,
+ const unsigned char *tbs, size_t tbslen);
+ int (*verify_recover_init) (EVP_PKEY_CTX *ctx);
+ int (*verify_recover) (EVP_PKEY_CTX *ctx,
+ unsigned char *rout, size_t *routlen,
+ const unsigned char *sig, size_t siglen);
+ int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+ int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+ EVP_MD_CTX *mctx);
+ int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+ int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen,
+ EVP_MD_CTX *mctx);
+ int (*encrypt_init) (EVP_PKEY_CTX *ctx);
+ int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen);
+ int (*decrypt_init) (EVP_PKEY_CTX *ctx);
+ int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen);
+ int (*derive_init) (EVP_PKEY_CTX *ctx);
+ int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+ int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
+ int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value);
+} /* EVP_PKEY_METHOD */ ;
+
+void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
+
+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
+ int passlen, ASN1_TYPE *param,
+ const EVP_CIPHER *c, const EVP_MD *md,
+ int en_de);
+
+const EVP_MD *evp_get_fips_md(const EVP_MD *md);
+const EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher);
+
+#ifdef OPENSSL_FIPS
+
+# ifdef OPENSSL_DOING_MAKEDEPEND
+# undef SHA1_Init
+# undef SHA1_Update
+# undef SHA224_Init
+# undef SHA256_Init
+# undef SHA384_Init
+# undef SHA512_Init
+# undef DES_set_key_unchecked
+# endif
+
+# define RIPEMD160_Init private_RIPEMD160_Init
+# define WHIRLPOOL_Init private_WHIRLPOOL_Init
+# define MD5_Init private_MD5_Init
+# define MD4_Init private_MD4_Init
+# define MD2_Init private_MD2_Init
+# define MDC2_Init private_MDC2_Init
+# define SHA_Init private_SHA_Init
+# define SHA1_Init private_SHA1_Init
+# define SHA224_Init private_SHA224_Init
+# define SHA256_Init private_SHA256_Init
+# define SHA384_Init private_SHA384_Init
+# define SHA512_Init private_SHA512_Init
+
+# define BF_set_key private_BF_set_key
+# define CAST_set_key private_CAST_set_key
+# define idea_set_encrypt_key private_idea_set_encrypt_key
+# define SEED_set_key private_SEED_set_key
+# define RC2_set_key private_RC2_set_key
+# define RC4_set_key private_RC4_set_key
+# define DES_set_key_unchecked private_DES_set_key_unchecked
+# define Camellia_set_key private_Camellia_set_key
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_pbe.c b/Cryptlib/OpenSSL/crypto/evp/evp_pbe.c
new file mode 100644
index 00000000..7934c95f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_pbe.c
@@ -0,0 +1,312 @@
+/* evp_pbe.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+#include <openssl/x509.h>
+#include "evp_locl.h"
+
+/* Password based encryption (PBE) functions */
+
+DECLARE_STACK_OF(EVP_PBE_CTL)
+static STACK_OF(EVP_PBE_CTL) *pbe_algs;
+
+/* Setup a cipher context from a PBE algorithm */
+
+typedef struct {
+ int pbe_type;
+ int pbe_nid;
+ int cipher_nid;
+ int md_nid;
+ EVP_PBE_KEYGEN *keygen;
+} EVP_PBE_CTL;
+
+static const EVP_PBE_CTL builtin_pbe[] = {
+ {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC,
+ NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen},
+ {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC,
+ NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen},
+ {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
+ NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
+
+#ifndef OPENSSL_NO_HMAC
+ {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
+#endif
+
+ {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
+ NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
+ {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
+ NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen},
+ {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
+ NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+ {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC,
+ NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+ {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC,
+ NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+ {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC,
+ NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+
+#ifndef OPENSSL_NO_HMAC
+ {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
+#endif
+ {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC,
+ NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen},
+ {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC,
+ NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen},
+ {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC,
+ NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen},
+
+ {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0},
+ {EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0},
+ {EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0},
+ {EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0},
+ {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0},
+ {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0},
+ {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0},
+};
+
+#ifdef TEST
+int main(int argc, char **argv)
+{
+ int i, nid_md, nid_cipher;
+ EVP_PBE_CTL *tpbe, *tpbe2;
+ /*
+ * OpenSSL_add_all_algorithms();
+ */
+
+ for (i = 0; i < sizeof(builtin_pbe) / sizeof(EVP_PBE_CTL); i++) {
+ tpbe = builtin_pbe + i;
+ fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid,
+ OBJ_nid2sn(tpbe->pbe_nid));
+ if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid,
+ &nid_cipher, &nid_md, 0))
+ fprintf(stderr, "Found %s %s\n",
+ OBJ_nid2sn(nid_cipher), OBJ_nid2sn(nid_md));
+ else
+ fprintf(stderr, "Find ERROR!!\n");
+ }
+
+ return 0;
+}
+#endif
+
+int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
+ ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
+{
+ const EVP_CIPHER *cipher;
+ const EVP_MD *md;
+ int cipher_nid, md_nid;
+ EVP_PBE_KEYGEN *keygen;
+
+ if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
+ &cipher_nid, &md_nid, &keygen)) {
+ char obj_tmp[80];
+ EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_PBE_ALGORITHM);
+ if (!pbe_obj)
+ BUF_strlcpy(obj_tmp, "NULL", sizeof obj_tmp);
+ else
+ i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
+ ERR_add_error_data(2, "TYPE=", obj_tmp);
+ return 0;
+ }
+
+ if (!pass)
+ passlen = 0;
+ else if (passlen == -1)
+ passlen = strlen(pass);
+
+ if (cipher_nid == -1)
+ cipher = NULL;
+ else {
+ cipher = EVP_get_cipherbynid(cipher_nid);
+ if (!cipher) {
+ EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_CIPHER);
+ return 0;
+ }
+ }
+
+ if (md_nid == -1)
+ md = NULL;
+ else {
+ md = EVP_get_digestbynid(md_nid);
+ if (!md) {
+ EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_DIGEST);
+ return 0;
+ }
+ }
+
+ if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) {
+ EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_KEYGEN_FAILURE);
+ return 0;
+ }
+ return 1;
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
+
+static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2)
+{
+ int ret = pbe1->pbe_type - pbe2->pbe_type;
+ if (ret)
+ return ret;
+ else
+ return pbe1->pbe_nid - pbe2->pbe_nid;
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
+
+static int pbe_cmp(const EVP_PBE_CTL *const *a, const EVP_PBE_CTL *const *b)
+{
+ int ret = (*a)->pbe_type - (*b)->pbe_type;
+ if (ret)
+ return ret;
+ else
+ return (*a)->pbe_nid - (*b)->pbe_nid;
+}
+
+/* Add a PBE algorithm */
+
+int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid,
+ int md_nid, EVP_PBE_KEYGEN *keygen)
+{
+ EVP_PBE_CTL *pbe_tmp;
+
+ if (pbe_algs == NULL) {
+ pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp);
+ if (pbe_algs == NULL)
+ goto err;
+ }
+
+ if ((pbe_tmp = OPENSSL_malloc(sizeof(*pbe_tmp))) == NULL)
+ goto err;
+
+ pbe_tmp->pbe_type = pbe_type;
+ pbe_tmp->pbe_nid = pbe_nid;
+ pbe_tmp->cipher_nid = cipher_nid;
+ pbe_tmp->md_nid = md_nid;
+ pbe_tmp->keygen = keygen;
+
+ sk_EVP_PBE_CTL_push(pbe_algs, pbe_tmp);
+ return 1;
+
+ err:
+ EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE, ERR_R_MALLOC_FAILURE);
+ return 0;
+}
+
+int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+ EVP_PBE_KEYGEN *keygen)
+{
+ int cipher_nid, md_nid;
+ if (cipher)
+ cipher_nid = EVP_CIPHER_nid(cipher);
+ else
+ cipher_nid = -1;
+ if (md)
+ md_nid = EVP_MD_type(md);
+ else
+ md_nid = -1;
+
+ return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid,
+ cipher_nid, md_nid, keygen);
+}
+
+int EVP_PBE_find(int type, int pbe_nid,
+ int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
+{
+ EVP_PBE_CTL *pbetmp = NULL, pbelu;
+ int i;
+ if (pbe_nid == NID_undef)
+ return 0;
+
+ pbelu.pbe_type = type;
+ pbelu.pbe_nid = pbe_nid;
+
+ if (pbe_algs) {
+ i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
+ if (i != -1)
+ pbetmp = sk_EVP_PBE_CTL_value(pbe_algs, i);
+ }
+ if (pbetmp == NULL) {
+ pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe,
+ sizeof(builtin_pbe) / sizeof(EVP_PBE_CTL));
+ }
+ if (pbetmp == NULL)
+ return 0;
+ if (pcnid)
+ *pcnid = pbetmp->cipher_nid;
+ if (pmnid)
+ *pmnid = pbetmp->md_nid;
+ if (pkeygen)
+ *pkeygen = pbetmp->keygen;
+ return 1;
+}
+
+static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe)
+{
+ OPENSSL_freeFunc(pbe);
+}
+
+void EVP_PBE_cleanup(void)
+{
+ sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
+ pbe_algs = NULL;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_pkey.c b/Cryptlib/OpenSSL/crypto/evp/evp_pkey.c
new file mode 100644
index 00000000..6a456297
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_pkey.c
@@ -0,0 +1,229 @@
+/* evp_pkey.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+#include "asn1_locl.h"
+
+/* Extract a private key from a PKCS8 structure */
+
+EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
+{
+ EVP_PKEY *pkey = NULL;
+ ASN1_OBJECT *algoid;
+ char obj_tmp[80];
+
+ if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
+ return NULL;
+
+ if (!(pkey = EVP_PKEY_new())) {
+ EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
+ EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+ i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
+ ERR_add_error_data(2, "TYPE=", obj_tmp);
+ goto error;
+ }
+
+ if (pkey->ameth->priv_decode) {
+ if (!pkey->ameth->priv_decode(pkey, p8)) {
+ EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_PRIVATE_KEY_DECODE_ERROR);
+ goto error;
+ }
+ } else {
+ EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED);
+ goto error;
+ }
+
+ return pkey;
+
+ error:
+ EVP_PKEY_free(pkey);
+ return NULL;
+}
+
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
+{
+ return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK);
+}
+
+/* Turn a private key into a PKCS8 structure */
+
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
+{
+ PKCS8_PRIV_KEY_INFO *p8;
+
+ if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
+ EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ p8->broken = broken;
+
+ if (pkey->ameth) {
+ if (pkey->ameth->priv_encode) {
+ if (!pkey->ameth->priv_encode(p8, pkey)) {
+ EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
+ EVP_R_PRIVATE_KEY_ENCODE_ERROR);
+ goto error;
+ }
+ } else {
+ EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_METHOD_NOT_SUPPORTED);
+ goto error;
+ }
+ } else {
+ EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
+ EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+ goto error;
+ }
+ RAND_add(p8->pkey->value.octet_string->data,
+ p8->pkey->value.octet_string->length, 0.0);
+ return p8;
+ error:
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ return NULL;
+}
+
+PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
+{
+ switch (broken) {
+
+ case PKCS8_OK:
+ p8->broken = PKCS8_OK;
+ return p8;
+ break;
+
+ case PKCS8_NO_OCTET:
+ p8->broken = PKCS8_NO_OCTET;
+ p8->pkey->type = V_ASN1_SEQUENCE;
+ return p8;
+ break;
+
+ default:
+ EVPerr(EVP_F_PKCS8_SET_BROKEN, EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
+ return NULL;
+ }
+}
+
+/* EVP_PKEY attribute functions */
+
+int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
+{
+ return X509at_get_attr_count(key->attributes);
+}
+
+int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos)
+{
+ return X509at_get_attr_by_NID(key->attributes, nid, lastpos);
+}
+
+int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
+ int lastpos)
+{
+ return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos);
+}
+
+X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc)
+{
+ return X509at_get_attr(key->attributes, loc);
+}
+
+X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc)
+{
+ return X509at_delete_attr(key->attributes, loc);
+}
+
+int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr)
+{
+ if (X509at_add1_attr(&key->attributes, attr))
+ return 1;
+ return 0;
+}
+
+int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
+ const ASN1_OBJECT *obj, int type,
+ const unsigned char *bytes, int len)
+{
+ if (X509at_add1_attr_by_OBJ(&key->attributes, obj, type, bytes, len))
+ return 1;
+ return 0;
+}
+
+int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
+ int nid, int type,
+ const unsigned char *bytes, int len)
+{
+ if (X509at_add1_attr_by_NID(&key->attributes, nid, type, bytes, len))
+ return 1;
+ return 0;
+}
+
+int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
+ const char *attrname, int type,
+ const unsigned char *bytes, int len)
+{
+ if (X509at_add1_attr_by_txt(&key->attributes, attrname, type, bytes, len))
+ return 1;
+ return 0;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_dss.c b/Cryptlib/OpenSSL/crypto/evp/m_dss.c
new file mode 100644
index 00000000..14784486
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_dss.c
@@ -0,0 +1,104 @@
+/* crypto/evp/m_dss.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/sha.h>
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+
+#ifndef OPENSSL_NO_SHA
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return SHA1_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return SHA1_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return SHA1_Final(md, ctx->md_data);
+}
+
+static const EVP_MD dsa_md = {
+ NID_dsaWithSHA,
+ NID_dsaWithSHA,
+ SHA_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_DIGEST,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_DSA_method,
+ SHA_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+const EVP_MD *EVP_dss(void)
+{
+ return (&dsa_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_dss1.c b/Cryptlib/OpenSSL/crypto/evp/m_dss1.c
new file mode 100644
index 00000000..e36fabff
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_dss1.c
@@ -0,0 +1,105 @@
+/* crypto/evp/m_dss1.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_SHA
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/sha.h>
+# ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+# endif
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return SHA1_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return SHA1_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return SHA1_Final(md, ctx->md_data);
+}
+
+static const EVP_MD dss1_md = {
+ NID_dsa,
+ NID_dsaWithSHA1,
+ SHA_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_DIGEST,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_DSA_method,
+ SHA_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+const EVP_MD *EVP_dss1(void)
+{
+ return (&dss1_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_ecdsa.c b/Cryptlib/OpenSSL/crypto/evp/m_ecdsa.c
new file mode 100644
index 00000000..803d3149
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_ecdsa.c
@@ -0,0 +1,154 @@
+/* crypto/evp/m_ecdsa.c */
+/* ====================================================================
+ * Copyright (c) 1998-2002 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
+ * openssl-core@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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+#ifndef OPENSSL_NO_SHA
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return SHA1_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return SHA1_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return SHA1_Final(md, ctx->md_data);
+}
+
+static const EVP_MD ecdsa_md = {
+ NID_ecdsa_with_SHA1,
+ NID_ecdsa_with_SHA1,
+ SHA_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_DIGEST,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_ECDSA_method,
+ SHA_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+const EVP_MD *EVP_ecdsa(void)
+{
+ return (&ecdsa_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_md2.c b/Cryptlib/OpenSSL/crypto/evp/m_md2.c
new file mode 100644
index 00000000..3c4cd7bf
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_md2.c
@@ -0,0 +1,106 @@
+/* crypto/evp/m_md2.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_MD2
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/md2.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return MD2_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return MD2_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return MD2_Final(md, ctx->md_data);
+}
+
+static const EVP_MD md2_md = {
+ NID_md2,
+ NID_md2WithRSAEncryption,
+ MD2_DIGEST_LENGTH,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ MD2_BLOCK,
+ sizeof(EVP_MD *) + sizeof(MD2_CTX),
+};
+
+const EVP_MD *EVP_md2(void)
+{
+ return (&md2_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_md4.c b/Cryptlib/OpenSSL/crypto/evp/m_md4.c
new file mode 100644
index 00000000..851de69f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_md4.c
@@ -0,0 +1,108 @@
+/* crypto/evp/m_md4.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_MD4
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/md4.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+
+# include "evp_locl.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return MD4_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return MD4_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return MD4_Final(md, ctx->md_data);
+}
+
+static const EVP_MD md4_md = {
+ NID_md4,
+ NID_md4WithRSAEncryption,
+ MD4_DIGEST_LENGTH,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ MD4_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(MD4_CTX),
+};
+
+const EVP_MD *EVP_md4(void)
+{
+ return (&md4_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_md5.c b/Cryptlib/OpenSSL/crypto/evp/m_md5.c
new file mode 100644
index 00000000..e5d5f71b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_md5.c
@@ -0,0 +1,107 @@
+/* crypto/evp/m_md5.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_MD5
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/md5.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+# include "evp_locl.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return MD5_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return MD5_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return MD5_Final(md, ctx->md_data);
+}
+
+static const EVP_MD md5_md = {
+ NID_md5,
+ NID_md5WithRSAEncryption,
+ MD5_DIGEST_LENGTH,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ MD5_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(MD5_CTX),
+};
+
+const EVP_MD *EVP_md5(void)
+{
+ return (&md5_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_mdc2.c b/Cryptlib/OpenSSL/crypto/evp/m_mdc2.c
new file mode 100644
index 00000000..94e12a6b
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_mdc2.c
@@ -0,0 +1,108 @@
+/* crypto/evp/m_mdc2.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_MDC2
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/mdc2.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+
+# include "evp_locl.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return MDC2_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return MDC2_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return MDC2_Final(md, ctx->md_data);
+}
+
+static const EVP_MD mdc2_md = {
+ NID_mdc2,
+ NID_mdc2WithRSA,
+ MDC2_DIGEST_LENGTH,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_ASN1_OCTET_STRING_method,
+ MDC2_BLOCK,
+ sizeof(EVP_MD *) + sizeof(MDC2_CTX),
+};
+
+const EVP_MD *EVP_mdc2(void)
+{
+ return (&mdc2_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_null.c b/Cryptlib/OpenSSL/crypto/evp/m_null.c
new file mode 100644
index 00000000..017e1feb
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_null.c
@@ -0,0 +1,98 @@
+/* crypto/evp/m_null.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return 1;
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return 1;
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return 1;
+}
+
+static const EVP_MD null_md = {
+ NID_undef,
+ NID_undef,
+ 0,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_NULL_method,
+ 0,
+ sizeof(EVP_MD *),
+};
+
+const EVP_MD *EVP_md_null(void)
+{
+ return (&null_md);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_ripemd.c b/Cryptlib/OpenSSL/crypto/evp/m_ripemd.c
new file mode 100644
index 00000000..81de0ef4
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_ripemd.c
@@ -0,0 +1,107 @@
+/* crypto/evp/m_ripemd.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RIPEMD
+
+# include <openssl/ripemd.h>
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+# include "evp_locl.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return RIPEMD160_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return RIPEMD160_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return RIPEMD160_Final(md, ctx->md_data);
+}
+
+static const EVP_MD ripemd160_md = {
+ NID_ripemd160,
+ NID_ripemd160WithRSA,
+ RIPEMD160_DIGEST_LENGTH,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ RIPEMD160_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX),
+};
+
+const EVP_MD *EVP_ripemd160(void)
+{
+ return (&ripemd160_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_sha.c b/Cryptlib/OpenSSL/crypto/evp/m_sha.c
new file mode 100644
index 00000000..e1e22e0c
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_sha.c
@@ -0,0 +1,106 @@
+/* crypto/evp/m_sha.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0)
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+# include "evp_locl.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return SHA_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return SHA_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return SHA_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha_md = {
+ NID_sha,
+ NID_shaWithRSAEncryption,
+ SHA_DIGEST_LENGTH,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ SHA_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+const EVP_MD *EVP_sha(void)
+{
+ return (&sha_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_sha1.c b/Cryptlib/OpenSSL/crypto/evp/m_sha1.c
new file mode 100644
index 00000000..a74e6b77
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_sha1.c
@@ -0,0 +1,235 @@
+/* crypto/evp/m_sha1.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_SHA
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/sha.h>
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return SHA1_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return SHA1_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return SHA1_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha1_md = {
+ NID_sha1,
+ NID_sha1WithRSAEncryption,
+ SHA_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ SHA_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA_CTX),
+};
+
+const EVP_MD *EVP_sha1(void)
+{
+ return (&sha1_md);
+}
+#endif
+
+#ifndef OPENSSL_NO_SHA256
+static int init224(EVP_MD_CTX *ctx)
+{
+ return SHA224_Init(ctx->md_data);
+}
+
+static int init256(EVP_MD_CTX *ctx)
+{
+ return SHA256_Init(ctx->md_data);
+}
+
+/*
+ * Even though there're separate SHA224_[Update|Final], we call
+ * SHA256 functions even in SHA224 context. This is what happens
+ * there anyway, so we can spare few CPU cycles:-)
+ */
+static int update256(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return SHA256_Update(ctx->md_data, data, count);
+}
+
+static int final256(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return SHA256_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha224_md = {
+ NID_sha224,
+ NID_sha224WithRSAEncryption,
+ SHA224_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+ init224,
+ update256,
+ final256,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ SHA256_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA256_CTX),
+};
+
+const EVP_MD *EVP_sha224(void)
+{
+ return (&sha224_md);
+}
+
+static const EVP_MD sha256_md = {
+ NID_sha256,
+ NID_sha256WithRSAEncryption,
+ SHA256_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+ init256,
+ update256,
+ final256,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ SHA256_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA256_CTX),
+};
+
+const EVP_MD *EVP_sha256(void)
+{
+ return (&sha256_md);
+}
+#endif /* ifndef OPENSSL_NO_SHA256 */
+
+#ifndef OPENSSL_NO_SHA512
+static int init384(EVP_MD_CTX *ctx)
+{
+ return SHA384_Init(ctx->md_data);
+}
+
+static int init512(EVP_MD_CTX *ctx)
+{
+ return SHA512_Init(ctx->md_data);
+}
+
+/* See comment in SHA224/256 section */
+static int update512(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return SHA512_Update(ctx->md_data, data, count);
+}
+
+static int final512(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return SHA512_Final(md, ctx->md_data);
+}
+
+static const EVP_MD sha384_md = {
+ NID_sha384,
+ NID_sha384WithRSAEncryption,
+ SHA384_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+ init384,
+ update512,
+ final512,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ SHA512_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA512_CTX),
+};
+
+const EVP_MD *EVP_sha384(void)
+{
+ return (&sha384_md);
+}
+
+static const EVP_MD sha512_md = {
+ NID_sha512,
+ NID_sha512WithRSAEncryption,
+ SHA512_DIGEST_LENGTH,
+ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+ init512,
+ update512,
+ final512,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_method,
+ SHA512_CBLOCK,
+ sizeof(EVP_MD *) + sizeof(SHA512_CTX),
+};
+
+const EVP_MD *EVP_sha512(void)
+{
+ return (&sha512_md);
+}
+#endif /* ifndef OPENSSL_NO_SHA512 */
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_sigver.c b/Cryptlib/OpenSSL/crypto/evp/m_sigver.c
new file mode 100644
index 00000000..4492d207
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_sigver.c
@@ -0,0 +1,203 @@
+/* m_sigver.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006,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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include "evp_locl.h"
+
+static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+ const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
+ int ver)
+{
+ if (ctx->pctx == NULL)
+ ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
+ if (ctx->pctx == NULL)
+ return 0;
+
+ if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) {
+
+ if (type == NULL) {
+ int def_nid;
+ if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
+ type = EVP_get_digestbynid(def_nid);
+ }
+
+ if (type == NULL) {
+ EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
+ return 0;
+ }
+ }
+
+ if (ver) {
+ if (ctx->pctx->pmeth->verifyctx_init) {
+ if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0)
+ return 0;
+ ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
+ } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
+ return 0;
+ } else {
+ if (ctx->pctx->pmeth->signctx_init) {
+ if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
+ return 0;
+ ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
+ } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
+ return 0;
+ }
+ if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
+ return 0;
+ if (pctx)
+ *pctx = ctx->pctx;
+ if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
+ return 1;
+ if (!EVP_DigestInit_ex(ctx, type, e))
+ return 0;
+ return 1;
+}
+
+int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+ const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
+{
+ return do_sigver_init(ctx, pctx, type, e, pkey, 0);
+}
+
+int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+ const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
+{
+ return do_sigver_init(ctx, pctx, type, e, pkey, 1);
+}
+
+int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+ size_t *siglen)
+{
+ int sctx, r = 0;
+ EVP_PKEY_CTX *pctx = ctx->pctx;
+ if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
+ EVP_PKEY_CTX *dctx;
+ if (!sigret)
+ return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
+ dctx = EVP_PKEY_CTX_dup(ctx->pctx);
+ if (!dctx)
+ return 0;
+ r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
+ EVP_PKEY_CTX_free(dctx);
+ return r;
+ }
+ if (pctx->pmeth->signctx)
+ sctx = 1;
+ else
+ sctx = 0;
+ if (sigret) {
+ EVP_MD_CTX tmp_ctx;
+ unsigned char md[EVP_MAX_MD_SIZE];
+ unsigned int mdlen;
+ EVP_MD_CTX_init(&tmp_ctx);
+ if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
+ return 0;
+ if (sctx)
+ r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx,
+ sigret, siglen, &tmp_ctx);
+ else
+ r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
+ EVP_MD_CTX_cleanup(&tmp_ctx);
+ if (sctx || !r)
+ return r;
+ if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
+ return 0;
+ } else {
+ if (sctx) {
+ if (pctx->pmeth->signctx(pctx, sigret, siglen, ctx) <= 0)
+ return 0;
+ } else {
+ int s = EVP_MD_size(ctx->digest);
+ if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0)
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
+ size_t siglen)
+{
+ EVP_MD_CTX tmp_ctx;
+ unsigned char md[EVP_MAX_MD_SIZE];
+ int r;
+ unsigned int mdlen;
+ int vctx;
+
+ if (ctx->pctx->pmeth->verifyctx)
+ vctx = 1;
+ else
+ vctx = 0;
+ EVP_MD_CTX_init(&tmp_ctx);
+ if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
+ return -1;
+ if (vctx) {
+ r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx,
+ sig, siglen, &tmp_ctx);
+ } else
+ r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
+ EVP_MD_CTX_cleanup(&tmp_ctx);
+ if (vctx || !r)
+ return r;
+ return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/m_wp.c b/Cryptlib/OpenSSL/crypto/evp/m_wp.c
new file mode 100644
index 00000000..a890939e
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/m_wp.c
@@ -0,0 +1,48 @@
+/* crypto/evp/m_wp.c */
+
+#include <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/whrlpool.h>
+# include "evp_locl.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+ return WHIRLPOOL_Init(ctx->md_data);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+ return WHIRLPOOL_Update(ctx->md_data, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ return WHIRLPOOL_Final(md, ctx->md_data);
+}
+
+static const EVP_MD whirlpool_md = {
+ NID_whirlpool,
+ 0,
+ WHIRLPOOL_DIGEST_LENGTH,
+ 0,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_NULL_method,
+ WHIRLPOOL_BBLOCK / 8,
+ sizeof(EVP_MD *) + sizeof(WHIRLPOOL_CTX),
+};
+
+const EVP_MD *EVP_whirlpool(void)
+{
+ return (&whirlpool_md);
+}
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/names.c b/Cryptlib/OpenSSL/crypto/evp/names.c
new file mode 100644
index 00000000..ff115a31
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/names.c
@@ -0,0 +1,215 @@
+/* crypto/evp/names.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_add_cipher(const EVP_CIPHER *c)
+{
+ int r;
+
+ if (c == NULL)
+ return 0;
+
+ OPENSSL_init();
+
+ r = OBJ_NAME_add(OBJ_nid2sn(c->nid), OBJ_NAME_TYPE_CIPHER_METH,
+ (const char *)c);
+ if (r == 0)
+ return (0);
+ check_defer(c->nid);
+ r = OBJ_NAME_add(OBJ_nid2ln(c->nid), OBJ_NAME_TYPE_CIPHER_METH,
+ (const char *)c);
+ return (r);
+}
+
+int EVP_add_digest(const EVP_MD *md)
+{
+ int r;
+ const char *name;
+ OPENSSL_init();
+
+ name = OBJ_nid2sn(md->type);
+ r = OBJ_NAME_add(name, OBJ_NAME_TYPE_MD_METH, (const char *)md);
+ if (r == 0)
+ return (0);
+ check_defer(md->type);
+ r = OBJ_NAME_add(OBJ_nid2ln(md->type), OBJ_NAME_TYPE_MD_METH,
+ (const char *)md);
+ if (r == 0)
+ return (0);
+
+ if (md->pkey_type && md->type != md->pkey_type) {
+ r = OBJ_NAME_add(OBJ_nid2sn(md->pkey_type),
+ OBJ_NAME_TYPE_MD_METH | OBJ_NAME_ALIAS, name);
+ if (r == 0)
+ return (0);
+ check_defer(md->pkey_type);
+ r = OBJ_NAME_add(OBJ_nid2ln(md->pkey_type),
+ OBJ_NAME_TYPE_MD_METH | OBJ_NAME_ALIAS, name);
+ }
+ return (r);
+}
+
+const EVP_CIPHER *EVP_get_cipherbyname(const char *name)
+{
+ const EVP_CIPHER *cp;
+
+ cp = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH);
+ return (cp);
+}
+
+const EVP_MD *EVP_get_digestbyname(const char *name)
+{
+ const EVP_MD *cp;
+
+ cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
+ return (cp);
+}
+
+void EVP_cleanup(void)
+{
+ OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
+ OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
+ /*
+ * The above calls will only clean out the contents of the name hash
+ * table, but not the hash table itself. The following line does that
+ * part. -- Richard Levitte
+ */
+ OBJ_NAME_cleanup(-1);
+
+ EVP_PBE_cleanup();
+ if (obj_cleanup_defer == 2) {
+ obj_cleanup_defer = 0;
+ OBJ_cleanup();
+ }
+ OBJ_sigid_free();
+}
+
+struct doall_cipher {
+ void *arg;
+ void (*fn) (const EVP_CIPHER *ciph,
+ const char *from, const char *to, void *arg);
+};
+
+static void do_all_cipher_fn(const OBJ_NAME *nm, void *arg)
+{
+ struct doall_cipher *dc = arg;
+ if (nm->alias)
+ dc->fn(NULL, nm->name, nm->data, dc->arg);
+ else
+ dc->fn((const EVP_CIPHER *)nm->data, nm->name, NULL, dc->arg);
+}
+
+void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph,
+ const char *from, const char *to, void *x),
+ void *arg)
+{
+ struct doall_cipher dc;
+ dc.fn = fn;
+ dc.arg = arg;
+ OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc);
+}
+
+void EVP_CIPHER_do_all_sorted(void (*fn) (const EVP_CIPHER *ciph,
+ const char *from, const char *to,
+ void *x), void *arg)
+{
+ struct doall_cipher dc;
+ dc.fn = fn;
+ dc.arg = arg;
+ OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc);
+}
+
+struct doall_md {
+ void *arg;
+ void (*fn) (const EVP_MD *ciph,
+ const char *from, const char *to, void *arg);
+};
+
+static void do_all_md_fn(const OBJ_NAME *nm, void *arg)
+{
+ struct doall_md *dc = arg;
+ if (nm->alias)
+ dc->fn(NULL, nm->name, nm->data, dc->arg);
+ else
+ dc->fn((const EVP_MD *)nm->data, nm->name, NULL, dc->arg);
+}
+
+void EVP_MD_do_all(void (*fn) (const EVP_MD *md,
+ const char *from, const char *to, void *x),
+ void *arg)
+{
+ struct doall_md dc;
+ dc.fn = fn;
+ dc.arg = arg;
+ OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
+}
+
+void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md,
+ const char *from, const char *to,
+ void *x), void *arg)
+{
+ struct doall_md dc;
+ dc.fn = fn;
+ dc.arg = arg;
+ OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/p5_crpt.c b/Cryptlib/OpenSSL/crypto/evp/p5_crpt.c
new file mode 100644
index 00000000..d06ab90a
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p5_crpt.c
@@ -0,0 +1,149 @@
+/* p5_crpt.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+
+/*
+ * Doesn't do anything now: Builtin PBE algorithms in static table.
+ */
+
+void PKCS5_PBE_add(void)
+{
+}
+
+int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
+ ASN1_TYPE *param, const EVP_CIPHER *cipher,
+ const EVP_MD *md, int en_de)
+{
+ EVP_MD_CTX ctx;
+ unsigned char md_tmp[EVP_MAX_MD_SIZE];
+ unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
+ int i;
+ PBEPARAM *pbe;
+ int saltlen, iter;
+ unsigned char *salt;
+ const unsigned char *pbuf;
+ int mdsize;
+ int rv = 0;
+ EVP_MD_CTX_init(&ctx);
+
+ /* Extract useful info from parameter */
+ if (param == NULL || param->type != V_ASN1_SEQUENCE ||
+ param->value.sequence == NULL) {
+ EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+ return 0;
+ }
+
+ pbuf = param->value.sequence->data;
+ if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) {
+ EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+ return 0;
+ }
+
+ if (!pbe->iter)
+ iter = 1;
+ else
+ iter = ASN1_INTEGER_get(pbe->iter);
+ salt = pbe->salt->data;
+ saltlen = pbe->salt->length;
+
+ if (!pass)
+ passlen = 0;
+ else if (passlen == -1)
+ passlen = strlen(pass);
+
+ if (!EVP_DigestInit_ex(&ctx, md, NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, pass, passlen))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, salt, saltlen))
+ goto err;
+ PBEPARAM_free(pbe);
+ if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL))
+ goto err;
+ mdsize = EVP_MD_size(md);
+ if (mdsize < 0)
+ return 0;
+ for (i = 1; i < iter; i++) {
+ if (!EVP_DigestInit_ex(&ctx, md, NULL))
+ goto err;
+ if (!EVP_DigestUpdate(&ctx, md_tmp, mdsize))
+ goto err;
+ if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL))
+ goto err;
+ }
+ OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp));
+ memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher));
+ OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16);
+ memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)),
+ EVP_CIPHER_iv_length(cipher));
+ if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de))
+ goto err;
+ OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
+ OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
+ OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
+ rv = 1;
+ err:
+ EVP_MD_CTX_cleanup(&ctx);
+ return rv;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/p5_crpt2.c b/Cryptlib/OpenSSL/crypto/evp/p5_crpt2.c
new file mode 100644
index 00000000..f2ae1e57
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p5_crpt2.c
@@ -0,0 +1,334 @@
+/* p5_crpt2.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2006 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#if !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA)
+# include <openssl/x509.h>
+# include <openssl/evp.h>
+# include <openssl/hmac.h>
+# include "evp_locl.h"
+
+/* set this to print out info about the keygen algorithm */
+/* #define DEBUG_PKCS5V2 */
+
+# ifdef DEBUG_PKCS5V2
+static void h__dump(const unsigned char *p, int len);
+# endif
+
+/*
+ * This is an implementation of PKCS#5 v2.0 password based encryption key
+ * derivation function PBKDF2. SHA1 version verified against test vectors
+ * posted by Peter Gutmann <pgut001@cs.auckland.ac.nz> to the PKCS-TNG
+ * <pkcs-tng@rsa.com> mailing list.
+ */
+
+int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
+ const unsigned char *salt, int saltlen, int iter,
+ const EVP_MD *digest, int keylen, unsigned char *out)
+{
+ unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
+ int cplen, j, k, tkeylen, mdlen;
+ unsigned long i = 1;
+ HMAC_CTX hctx_tpl, hctx;
+
+ mdlen = EVP_MD_size(digest);
+ if (mdlen < 0)
+ return 0;
+
+ HMAC_CTX_init(&hctx_tpl);
+ p = out;
+ tkeylen = keylen;
+ if (!pass)
+ passlen = 0;
+ else if (passlen == -1)
+ passlen = strlen(pass);
+ if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ return 0;
+ }
+ while (tkeylen) {
+ if (tkeylen > mdlen)
+ cplen = mdlen;
+ else
+ cplen = tkeylen;
+ /*
+ * We are unlikely to ever use more than 256 blocks (5120 bits!) but
+ * just in case...
+ */
+ itmp[0] = (unsigned char)((i >> 24) & 0xff);
+ itmp[1] = (unsigned char)((i >> 16) & 0xff);
+ itmp[2] = (unsigned char)((i >> 8) & 0xff);
+ itmp[3] = (unsigned char)(i & 0xff);
+ if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ return 0;
+ }
+ if (!HMAC_Update(&hctx, salt, saltlen)
+ || !HMAC_Update(&hctx, itmp, 4)
+ || !HMAC_Final(&hctx, digtmp, NULL)) {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ HMAC_CTX_cleanup(&hctx);
+ return 0;
+ }
+ HMAC_CTX_cleanup(&hctx);
+ memcpy(p, digtmp, cplen);
+ for (j = 1; j < iter; j++) {
+ if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ return 0;
+ }
+ if (!HMAC_Update(&hctx, digtmp, mdlen)
+ || !HMAC_Final(&hctx, digtmp, NULL)) {
+ HMAC_CTX_cleanup(&hctx_tpl);
+ HMAC_CTX_cleanup(&hctx);
+ return 0;
+ }
+ HMAC_CTX_cleanup(&hctx);
+ for (k = 0; k < cplen; k++)
+ p[k] ^= digtmp[k];
+ }
+ tkeylen -= cplen;
+ i++;
+ p += cplen;
+ }
+ HMAC_CTX_cleanup(&hctx_tpl);
+# ifdef DEBUG_PKCS5V2
+ fprintf(stderr, "Password:\n");
+ h__dump(pass, passlen);
+ fprintf(stderr, "Salt:\n");
+ h__dump(salt, saltlen);
+ fprintf(stderr, "Iteration count %d\n", iter);
+ fprintf(stderr, "Key:\n");
+ h__dump(out, keylen);
+# endif
+ return 1;
+}
+
+int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+ const unsigned char *salt, int saltlen, int iter,
+ int keylen, unsigned char *out)
+{
+ return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(),
+ keylen, out);
+}
+
+# ifdef DO_TEST
+main()
+{
+ unsigned char out[4];
+ unsigned char salt[] = { 0x12, 0x34, 0x56, 0x78 };
+ PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out);
+ fprintf(stderr, "Out %02X %02X %02X %02X\n",
+ out[0], out[1], out[2], out[3]);
+}
+
+# endif
+
+/*
+ * Now the key derivation function itself. This is a bit evil because it has
+ * to check the ASN1 parameters are valid: and there are quite a few of
+ * them...
+ */
+
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+ ASN1_TYPE *param, const EVP_CIPHER *c,
+ const EVP_MD *md, int en_de)
+{
+ const unsigned char *pbuf;
+ int plen;
+ PBE2PARAM *pbe2 = NULL;
+ const EVP_CIPHER *cipher;
+
+ int rv = 0;
+
+ if (param == NULL || param->type != V_ASN1_SEQUENCE ||
+ param->value.sequence == NULL) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+ goto err;
+ }
+
+ pbuf = param->value.sequence->data;
+ plen = param->value.sequence->length;
+ if (!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+ goto err;
+ }
+
+ /* See if we recognise the key derivation function */
+
+ if (OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+ EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
+ goto err;
+ }
+
+ /*
+ * lets see if we recognise the encryption algorithm.
+ */
+
+ cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
+
+ if (!cipher) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_CIPHER);
+ goto err;
+ }
+
+ /* Fixup cipher based on AlgorithmIdentifier */
+ if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de))
+ goto err;
+ if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
+ EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_CIPHER_PARAMETER_ERROR);
+ goto err;
+ }
+ rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen,
+ pbe2->keyfunc->parameter, c, md, en_de);
+ err:
+ PBE2PARAM_free(pbe2);
+ return rv;
+}
+
+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
+ int passlen, ASN1_TYPE *param,
+ const EVP_CIPHER *c, const EVP_MD *md, int en_de)
+{
+ unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
+ const unsigned char *pbuf;
+ int saltlen, iter, plen;
+ int rv = 0;
+ unsigned int keylen = 0;
+ int prf_nid, hmac_md_nid;
+ PBKDF2PARAM *kdf = NULL;
+ const EVP_MD *prfmd;
+
+ if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_NO_CIPHER_SET);
+ goto err;
+ }
+ keylen = EVP_CIPHER_CTX_key_length(ctx);
+ OPENSSL_assert(keylen <= sizeof key);
+
+ /* Decode parameter */
+
+ if (!param || (param->type != V_ASN1_SEQUENCE)) {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR);
+ goto err;
+ }
+
+ pbuf = param->value.sequence->data;
+ plen = param->value.sequence->length;
+
+ if (!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen))) {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR);
+ goto err;
+ }
+
+ keylen = EVP_CIPHER_CTX_key_length(ctx);
+
+ /* Now check the parameters of the kdf */
+
+ if (kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)) {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_KEYLENGTH);
+ goto err;
+ }
+
+ if (kdf->prf)
+ prf_nid = OBJ_obj2nid(kdf->prf->algorithm);
+ else
+ prf_nid = NID_hmacWithSHA1;
+
+ if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+ goto err;
+ }
+
+ prfmd = EVP_get_digestbynid(hmac_md_nid);
+ if (prfmd == NULL) {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+ goto err;
+ }
+
+ if (kdf->salt->type != V_ASN1_OCTET_STRING) {
+ EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_SALT_TYPE);
+ goto err;
+ }
+
+ /* it seems that its all OK */
+ salt = kdf->salt->value.octet_string->data;
+ saltlen = kdf->salt->value.octet_string->length;
+ iter = ASN1_INTEGER_get(kdf->iter);
+ if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
+ keylen, key))
+ goto err;
+ rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
+ err:
+ OPENSSL_cleanse(key, keylen);
+ PBKDF2PARAM_free(kdf);
+ return rv;
+}
+
+# ifdef DEBUG_PKCS5V2
+static void h__dump(const unsigned char *p, int len)
+{
+ for (; len--; p++)
+ fprintf(stderr, "%02X ", *p);
+ fprintf(stderr, "\n");
+}
+# endif
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/p_dec.c b/Cryptlib/OpenSSL/crypto/evp/p_dec.c
new file mode 100644
index 00000000..225b8b45
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_dec.c
@@ -0,0 +1,87 @@
+/* crypto/evp/p_dec.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
+ EVP_PKEY *priv)
+{
+ int ret = -1;
+
+#ifndef OPENSSL_NO_RSA
+ if (priv->type != EVP_PKEY_RSA) {
+#endif
+ EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA);
+#ifndef OPENSSL_NO_RSA
+ goto err;
+ }
+
+ ret =
+ RSA_private_decrypt(ekl, ek, key, priv->pkey.rsa, RSA_PKCS1_PADDING);
+ err:
+#endif
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/p_enc.c b/Cryptlib/OpenSSL/crypto/evp/p_enc.c
new file mode 100644
index 00000000..f565f33f
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_enc.c
@@ -0,0 +1,87 @@
+/* crypto/evp/p_enc.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key,
+ int key_len, EVP_PKEY *pubk)
+{
+ int ret = 0;
+
+#ifndef OPENSSL_NO_RSA
+ if (pubk->type != EVP_PKEY_RSA) {
+#endif
+ EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA);
+#ifndef OPENSSL_NO_RSA
+ goto err;
+ }
+ ret =
+ RSA_public_encrypt(key_len, key, ek, pubk->pkey.rsa,
+ RSA_PKCS1_PADDING);
+ err:
+#endif
+ return (ret);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/p_lib.c b/Cryptlib/OpenSSL/crypto/evp/p_lib.c
new file mode 100644
index 00000000..c0171244
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_lib.c
@@ -0,0 +1,456 @@
+/* crypto/evp/p_lib.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+# include <openssl/dh.h>
+#endif
+
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+#include "asn1_locl.h"
+
+static void EVP_PKEY_free_it(EVP_PKEY *x);
+
+int EVP_PKEY_bits(EVP_PKEY *pkey)
+{
+ if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
+ return pkey->ameth->pkey_bits(pkey);
+ return 0;
+}
+
+int EVP_PKEY_size(EVP_PKEY *pkey)
+{
+ if (pkey && pkey->ameth && pkey->ameth->pkey_size)
+ return pkey->ameth->pkey_size(pkey);
+ return 0;
+}
+
+int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
+{
+#ifndef OPENSSL_NO_DSA
+ if (pkey->type == EVP_PKEY_DSA) {
+ int ret = pkey->save_parameters;
+
+ if (mode >= 0)
+ pkey->save_parameters = mode;
+ return (ret);
+ }
+#endif
+#ifndef OPENSSL_NO_EC
+ if (pkey->type == EVP_PKEY_EC) {
+ int ret = pkey->save_parameters;
+
+ if (mode >= 0)
+ pkey->save_parameters = mode;
+ return (ret);
+ }
+#endif
+ return (0);
+}
+
+int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+{
+ if (to->type != from->type) {
+ EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES);
+ goto err;
+ }
+
+ if (EVP_PKEY_missing_parameters(from)) {
+ EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS);
+ goto err;
+ }
+ if (from->ameth && from->ameth->param_copy)
+ return from->ameth->param_copy(to, from);
+ err:
+ return 0;
+}
+
+int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
+{
+ if (pkey->ameth && pkey->ameth->param_missing)
+ return pkey->ameth->param_missing(pkey);
+ return 0;
+}
+
+int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+ if (a->type != b->type)
+ return -1;
+ if (a->ameth && a->ameth->param_cmp)
+ return a->ameth->param_cmp(a, b);
+ return -2;
+}
+
+int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+ if (a->type != b->type)
+ return -1;
+
+ if (a->ameth) {
+ int ret;
+ /* Compare parameters if the algorithm has them */
+ if (a->ameth->param_cmp) {
+ ret = a->ameth->param_cmp(a, b);
+ if (ret <= 0)
+ return ret;
+ }
+
+ if (a->ameth->pub_cmp)
+ return a->ameth->pub_cmp(a, b);
+ }
+
+ return -2;
+}
+
+EVP_PKEY *EVP_PKEY_new(void)
+{
+ EVP_PKEY *ret;
+
+ ret = (EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY));
+ if (ret == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ ret->type = EVP_PKEY_NONE;
+ ret->save_type = EVP_PKEY_NONE;
+ ret->references = 1;
+ ret->ameth = NULL;
+ ret->engine = NULL;
+ ret->pkey.ptr = NULL;
+ ret->attributes = NULL;
+ ret->save_parameters = 1;
+ return (ret);
+}
+
+/*
+ * Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey
+ * is NULL just return 1 or 0 if the algorithm exists.
+ */
+
+static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
+{
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ ENGINE *e = NULL;
+ if (pkey) {
+ if (pkey->pkey.ptr)
+ EVP_PKEY_free_it(pkey);
+ /*
+ * If key type matches and a method exists then this lookup has
+ * succeeded once so just indicate success.
+ */
+ if ((type == pkey->save_type) && pkey->ameth)
+ return 1;
+#ifndef OPENSSL_NO_ENGINE
+ /* If we have an ENGINE release it */
+ if (pkey->engine) {
+ ENGINE_finish(pkey->engine);
+ pkey->engine = NULL;
+ }
+#endif
+ }
+ if (str)
+ ameth = EVP_PKEY_asn1_find_str(&e, str, len);
+ else
+ ameth = EVP_PKEY_asn1_find(&e, type);
+#ifndef OPENSSL_NO_ENGINE
+ if (!pkey && e)
+ ENGINE_finish(e);
+#endif
+ if (!ameth) {
+ EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
+ return 0;
+ }
+ if (pkey) {
+ pkey->ameth = ameth;
+ pkey->engine = e;
+
+ pkey->type = pkey->ameth->pkey_id;
+ pkey->save_type = type;
+ }
+ return 1;
+}
+
+int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
+{
+ return pkey_set_type(pkey, type, NULL, -1);
+}
+
+int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
+{
+ return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
+}
+
+int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
+{
+ if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
+ return 0;
+ pkey->pkey.ptr = key;
+ return (key != NULL);
+}
+
+void *EVP_PKEY_get0(EVP_PKEY *pkey)
+{
+ return pkey->pkey.ptr;
+}
+
+#ifndef OPENSSL_NO_RSA
+int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
+{
+ int ret = EVP_PKEY_assign_RSA(pkey, key);
+ if (ret)
+ RSA_up_ref(key);
+ return ret;
+}
+
+RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
+{
+ if (pkey->type != EVP_PKEY_RSA) {
+ EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
+ return NULL;
+ }
+ RSA_up_ref(pkey->pkey.rsa);
+ return pkey->pkey.rsa;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
+{
+ int ret = EVP_PKEY_assign_DSA(pkey, key);
+ if (ret)
+ DSA_up_ref(key);
+ return ret;
+}
+
+DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
+{
+ if (pkey->type != EVP_PKEY_DSA) {
+ EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY);
+ return NULL;
+ }
+ DSA_up_ref(pkey->pkey.dsa);
+ return pkey->pkey.dsa;
+}
+#endif
+
+#ifndef OPENSSL_NO_EC
+
+int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
+{
+ int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
+ if (ret)
+ EC_KEY_up_ref(key);
+ return ret;
+}
+
+EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
+{
+ if (pkey->type != EVP_PKEY_EC) {
+ EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
+ return NULL;
+ }
+ EC_KEY_up_ref(pkey->pkey.ec);
+ return pkey->pkey.ec;
+}
+#endif
+
+#ifndef OPENSSL_NO_DH
+
+int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
+{
+ int ret = EVP_PKEY_assign_DH(pkey, key);
+ if (ret)
+ DH_up_ref(key);
+ return ret;
+}
+
+DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
+{
+ if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
+ EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY);
+ return NULL;
+ }
+ DH_up_ref(pkey->pkey.dh);
+ return pkey->pkey.dh;
+}
+#endif
+
+int EVP_PKEY_type(int type)
+{
+ int ret;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ ENGINE *e;
+ ameth = EVP_PKEY_asn1_find(&e, type);
+ if (ameth)
+ ret = ameth->pkey_id;
+ else
+ ret = NID_undef;
+#ifndef OPENSSL_NO_ENGINE
+ if (e)
+ ENGINE_finish(e);
+#endif
+ return ret;
+}
+
+int EVP_PKEY_id(const EVP_PKEY *pkey)
+{
+ return pkey->type;
+}
+
+int EVP_PKEY_base_id(const EVP_PKEY *pkey)
+{
+ return EVP_PKEY_type(pkey->type);
+}
+
+void EVP_PKEY_free(EVP_PKEY *x)
+{
+ int i;
+
+ if (x == NULL)
+ return;
+
+ i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY);
+#ifdef REF_PRINT
+ REF_PRINT("EVP_PKEY", x);
+#endif
+ if (i > 0)
+ return;
+#ifdef REF_CHECK
+ if (i < 0) {
+ fprintf(stderr, "EVP_PKEY_free, bad reference count\n");
+ abort();
+ }
+#endif
+ EVP_PKEY_free_it(x);
+ if (x->attributes)
+ sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
+ OPENSSL_free(x);
+}
+
+static void EVP_PKEY_free_it(EVP_PKEY *x)
+{
+ if (x->ameth && x->ameth->pkey_free) {
+ x->ameth->pkey_free(x);
+ x->pkey.ptr = NULL;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ if (x->engine) {
+ ENGINE_finish(x->engine);
+ x->engine = NULL;
+ }
+#endif
+}
+
+static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
+ const char *kstr)
+{
+ BIO_indent(out, indent, 128);
+ BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
+ kstr, OBJ_nid2ln(pkey->type));
+ return 1;
+}
+
+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
+ int indent, ASN1_PCTX *pctx)
+{
+ if (pkey->ameth && pkey->ameth->pub_print)
+ return pkey->ameth->pub_print(out, pkey, indent, pctx);
+
+ return unsup_alg(out, pkey, indent, "Public Key");
+}
+
+int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
+ int indent, ASN1_PCTX *pctx)
+{
+ if (pkey->ameth && pkey->ameth->priv_print)
+ return pkey->ameth->priv_print(out, pkey, indent, pctx);
+
+ return unsup_alg(out, pkey, indent, "Private Key");
+}
+
+int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
+ int indent, ASN1_PCTX *pctx)
+{
+ if (pkey->ameth && pkey->ameth->param_print)
+ return pkey->ameth->param_print(out, pkey, indent, pctx);
+ return unsup_alg(out, pkey, indent, "Parameters");
+}
+
+int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
+{
+ if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
+ return -2;
+ return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
+ 0, pnid);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/p_open.c b/Cryptlib/OpenSSL/crypto/evp/p_open.c
new file mode 100644
index 00000000..229eb641
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_open.c
@@ -0,0 +1,129 @@
+/* crypto/evp/p_open.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+
+#ifndef OPENSSL_NO_RSA
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/rsa.h>
+
+int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+ const unsigned char *ek, int ekl, const unsigned char *iv,
+ EVP_PKEY *priv)
+{
+ unsigned char *key = NULL;
+ int i, size = 0, ret = 0;
+
+ if (type) {
+ EVP_CIPHER_CTX_init(ctx);
+ if (!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL))
+ return 0;
+ }
+
+ if (!priv)
+ return 1;
+
+ if (priv->type != EVP_PKEY_RSA) {
+ EVPerr(EVP_F_EVP_OPENINIT, EVP_R_PUBLIC_KEY_NOT_RSA);
+ goto err;
+ }
+
+ size = RSA_size(priv->pkey.rsa);
+ key = (unsigned char *)OPENSSL_malloc(size + 2);
+ if (key == NULL) {
+ /* ERROR */
+ EVPerr(EVP_F_EVP_OPENINIT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ i = EVP_PKEY_decrypt_old(key, ek, ekl, priv);
+ if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i)) {
+ /* ERROR */
+ goto err;
+ }
+ if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
+ goto err;
+
+ ret = 1;
+ err:
+ if (key != NULL)
+ OPENSSL_cleanse(key, size);
+ OPENSSL_free(key);
+ return (ret);
+}
+
+int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ int i;
+
+ i = EVP_DecryptFinal_ex(ctx, out, outl);
+ if (i)
+ i = EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL);
+ return (i);
+}
+#else /* !OPENSSL_NO_RSA */
+
+# ifdef PEDANTIC
+static void *dummy = &dummy;
+# endif
+
+#endif
diff --git a/Cryptlib/OpenSSL/crypto/evp/p_seal.c b/Cryptlib/OpenSSL/crypto/evp/p_seal.c
new file mode 100644
index 00000000..ba9dfff2
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_seal.c
@@ -0,0 +1,121 @@
+/* crypto/evp/p_seal.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+ unsigned char **ek, int *ekl, unsigned char *iv,
+ EVP_PKEY **pubk, int npubk)
+{
+ unsigned char key[EVP_MAX_KEY_LENGTH];
+ int i;
+
+ if (type) {
+ EVP_CIPHER_CTX_init(ctx);
+ if (!EVP_EncryptInit_ex(ctx, type, NULL, NULL, NULL))
+ return 0;
+ }
+ if ((npubk <= 0) || !pubk)
+ return 1;
+ if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
+ return 0;
+ if (EVP_CIPHER_CTX_iv_length(ctx)
+ && RAND_bytes(iv, EVP_CIPHER_CTX_iv_length(ctx)) <= 0)
+ return 0;
+
+ if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
+ return 0;
+
+ for (i = 0; i < npubk; i++) {
+ ekl[i] =
+ EVP_PKEY_encrypt_old(ek[i], key, EVP_CIPHER_CTX_key_length(ctx),
+ pubk[i]);
+ if (ekl[i] <= 0)
+ return (-1);
+ }
+ return (npubk);
+}
+
+/*- MACRO
+void EVP_SealUpdate(ctx,out,outl,in,inl)
+EVP_CIPHER_CTX *ctx;
+unsigned char *out;
+int *outl;
+unsigned char *in;
+int inl;
+ {
+ EVP_EncryptUpdate(ctx,out,outl,in,inl);
+ }
+*/
+
+int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+ int i;
+ i = EVP_EncryptFinal_ex(ctx, out, outl);
+ if (i)
+ i = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, NULL);
+ return i;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/p_sign.c b/Cryptlib/OpenSSL/crypto/evp/p_sign.c
new file mode 100644
index 00000000..1b9ba060
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_sign.c
@@ -0,0 +1,133 @@
+/* crypto/evp/p_sign.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+#ifdef undef
+void EVP_SignInit(EVP_MD_CTX *ctx, EVP_MD *type)
+{
+ EVP_DigestInit_ex(ctx, type);
+}
+
+void EVP_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count)
+{
+ EVP_DigestUpdate(ctx, data, count);
+}
+#endif
+
+int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+ unsigned int *siglen, EVP_PKEY *pkey)
+{
+ unsigned char m[EVP_MAX_MD_SIZE];
+ unsigned int m_len;
+ int i = 0, ok = 0, v;
+ EVP_MD_CTX tmp_ctx;
+ EVP_PKEY_CTX *pkctx = NULL;
+
+ *siglen = 0;
+ EVP_MD_CTX_init(&tmp_ctx);
+ if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
+ goto err;
+ if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len))
+ goto err;
+ EVP_MD_CTX_cleanup(&tmp_ctx);
+
+ if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) {
+ size_t sltmp = (size_t)EVP_PKEY_size(pkey);
+ i = 0;
+ pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (!pkctx)
+ goto err;
+ if (EVP_PKEY_sign_init(pkctx) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
+ goto err;
+ if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0)
+ goto err;
+ *siglen = sltmp;
+ i = 1;
+ err:
+ EVP_PKEY_CTX_free(pkctx);
+ return i;
+ }
+
+ for (i = 0; i < 4; i++) {
+ v = ctx->digest->required_pkey_type[i];
+ if (v == 0)
+ break;
+ if (pkey->type == v) {
+ ok = 1;
+ break;
+ }
+ }
+ if (!ok) {
+ EVPerr(EVP_F_EVP_SIGNFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE);
+ return (0);
+ }
+
+ if (ctx->digest->sign == NULL) {
+ EVPerr(EVP_F_EVP_SIGNFINAL, EVP_R_NO_SIGN_FUNCTION_CONFIGURED);
+ return (0);
+ }
+ return (ctx->digest->sign(ctx->digest->type, m, m_len, sigret, siglen,
+ pkey->pkey.ptr));
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/p_verify.c b/Cryptlib/OpenSSL/crypto/evp/p_verify.c
new file mode 100644
index 00000000..65e1e216
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/p_verify.c
@@ -0,0 +1,116 @@
+/* crypto/evp/p_verify.c */
+/* 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
+ unsigned int siglen, EVP_PKEY *pkey)
+{
+ unsigned char m[EVP_MAX_MD_SIZE];
+ unsigned int m_len;
+ int i = 0, ok = 0, v;
+ EVP_MD_CTX tmp_ctx;
+ EVP_PKEY_CTX *pkctx = NULL;
+
+ EVP_MD_CTX_init(&tmp_ctx);
+ if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
+ goto err;
+ if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len))
+ goto err;
+ EVP_MD_CTX_cleanup(&tmp_ctx);
+
+ if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) {
+ i = -1;
+ pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (!pkctx)
+ goto err;
+ if (EVP_PKEY_verify_init(pkctx) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
+ goto err;
+ i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
+ err:
+ EVP_PKEY_CTX_free(pkctx);
+ return i;
+ }
+
+ for (i = 0; i < 4; i++) {
+ v = ctx->digest->required_pkey_type[i];
+ if (v == 0)
+ break;
+ if (pkey->type == v) {
+ ok = 1;
+ break;
+ }
+ }
+ if (!ok) {
+ EVPerr(EVP_F_EVP_VERIFYFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE);
+ return (-1);
+ }
+ if (ctx->digest->verify == NULL) {
+ EVPerr(EVP_F_EVP_VERIFYFINAL, EVP_R_NO_VERIFY_FUNCTION_CONFIGURED);
+ return (0);
+ }
+
+ return (ctx->digest->verify(ctx->digest->type, m, m_len,
+ sigbuf, siglen, pkey->pkey.ptr));
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/pmeth_fn.c b/Cryptlib/OpenSSL/crypto/evp/pmeth_fn.c
new file mode 100644
index 00000000..a8b7f2f6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/pmeth_fn.c
@@ -0,0 +1,346 @@
+/* pmeth_fn.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include "evp_locl.h"
+
+#define M_check_autoarg(ctx, arg, arglen, err) \
+ if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
+ { \
+ size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
+ if (!arg) \
+ { \
+ *arglen = pksize; \
+ return 1; \
+ } \
+ else if (*arglen < pksize) \
+ { \
+ EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
+ return 0; \
+ } \
+ }
+
+int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
+{
+ int ret;
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
+ EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ ctx->operation = EVP_PKEY_OP_SIGN;
+ if (!ctx->pmeth->sign_init)
+ return 1;
+ ret = ctx->pmeth->sign_init(ctx);
+ if (ret <= 0)
+ ctx->operation = EVP_PKEY_OP_UNDEFINED;
+ return ret;
+}
+
+int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
+ unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs, size_t tbslen)
+{
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
+ EVPerr(EVP_F_EVP_PKEY_SIGN,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ if (ctx->operation != EVP_PKEY_OP_SIGN) {
+ EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
+ return -1;
+ }
+ M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
+ return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
+}
+
+int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
+{
+ int ret;
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
+ EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ ctx->operation = EVP_PKEY_OP_VERIFY;
+ if (!ctx->pmeth->verify_init)
+ return 1;
+ ret = ctx->pmeth->verify_init(ctx);
+ if (ret <= 0)
+ ctx->operation = EVP_PKEY_OP_UNDEFINED;
+ return ret;
+}
+
+int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
+ const unsigned char *sig, size_t siglen,
+ const unsigned char *tbs, size_t tbslen)
+{
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
+ EVPerr(EVP_F_EVP_PKEY_VERIFY,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ if (ctx->operation != EVP_PKEY_OP_VERIFY) {
+ EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
+ return -1;
+ }
+ return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
+}
+
+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
+{
+ int ret;
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
+ EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
+ if (!ctx->pmeth->verify_recover_init)
+ return 1;
+ ret = ctx->pmeth->verify_recover_init(ctx);
+ if (ret <= 0)
+ ctx->operation = EVP_PKEY_OP_UNDEFINED;
+ return ret;
+}
+
+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
+ unsigned char *rout, size_t *routlen,
+ const unsigned char *sig, size_t siglen)
+{
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
+ EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
+ EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
+ return -1;
+ }
+ M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
+ return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
+}
+
+int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
+{
+ int ret;
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
+ EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ ctx->operation = EVP_PKEY_OP_ENCRYPT;
+ if (!ctx->pmeth->encrypt_init)
+ return 1;
+ ret = ctx->pmeth->encrypt_init(ctx);
+ if (ret <= 0)
+ ctx->operation = EVP_PKEY_OP_UNDEFINED;
+ return ret;
+}
+
+int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
+ unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen)
+{
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
+ EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
+ EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
+ return -1;
+ }
+ M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
+ return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
+}
+
+int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
+{
+ int ret;
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
+ EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ ctx->operation = EVP_PKEY_OP_DECRYPT;
+ if (!ctx->pmeth->decrypt_init)
+ return 1;
+ ret = ctx->pmeth->decrypt_init(ctx);
+ if (ret <= 0)
+ ctx->operation = EVP_PKEY_OP_UNDEFINED;
+ return ret;
+}
+
+int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
+ unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen)
+{
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
+ EVPerr(EVP_F_EVP_PKEY_DECRYPT,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
+ EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
+ return -1;
+ }
+ M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
+ return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
+}
+
+int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
+{
+ int ret;
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
+ EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ ctx->operation = EVP_PKEY_OP_DERIVE;
+ if (!ctx->pmeth->derive_init)
+ return 1;
+ ret = ctx->pmeth->derive_init(ctx);
+ if (ret <= 0)
+ ctx->operation = EVP_PKEY_OP_UNDEFINED;
+ return ret;
+}
+
+int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
+{
+ int ret;
+ if (!ctx || !ctx->pmeth
+ || !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt)
+ || !ctx->pmeth->ctrl) {
+ EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ if (ctx->operation != EVP_PKEY_OP_DERIVE
+ && ctx->operation != EVP_PKEY_OP_ENCRYPT
+ && ctx->operation != EVP_PKEY_OP_DECRYPT) {
+ EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+ EVP_R_OPERATON_NOT_INITIALIZED);
+ return -1;
+ }
+
+ ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
+
+ if (ret <= 0)
+ return ret;
+
+ if (ret == 2)
+ return 1;
+
+ if (!ctx->pkey) {
+ EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
+ return -1;
+ }
+
+ if (ctx->pkey->type != peer->type) {
+ EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES);
+ return -1;
+ }
+
+ /*
+ * ran@cryptocom.ru: For clarity. The error is if parameters in peer are
+ * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return
+ * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1
+ * (different key types) is impossible here because it is checked earlier.
+ * -2 is OK for us here, as well as 1, so we can check for 0 only.
+ */
+ if (!EVP_PKEY_missing_parameters(peer) &&
+ !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
+ EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS);
+ return -1;
+ }
+
+ if (ctx->peerkey)
+ EVP_PKEY_free(ctx->peerkey);
+ ctx->peerkey = peer;
+
+ ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
+
+ if (ret <= 0) {
+ ctx->peerkey = NULL;
+ return ret;
+ }
+
+ CRYPTO_add(&peer->references, 1, CRYPTO_LOCK_EVP_PKEY);
+ return 1;
+}
+
+int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
+{
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
+ EVPerr(EVP_F_EVP_PKEY_DERIVE,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ if (ctx->operation != EVP_PKEY_OP_DERIVE) {
+ EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
+ return -1;
+ }
+ M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
+ return ctx->pmeth->derive(ctx, key, pkeylen);
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/pmeth_gn.c b/Cryptlib/OpenSSL/crypto/evp/pmeth_gn.c
new file mode 100644
index 00000000..6435f1b6
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/pmeth_gn.c
@@ -0,0 +1,220 @@
+/* pmeth_gn.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include "evp_locl.h"
+
+int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
+{
+ int ret;
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
+ EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ ctx->operation = EVP_PKEY_OP_PARAMGEN;
+ if (!ctx->pmeth->paramgen_init)
+ return 1;
+ ret = ctx->pmeth->paramgen_init(ctx);
+ if (ret <= 0)
+ ctx->operation = EVP_PKEY_OP_UNDEFINED;
+ return ret;
+}
+
+int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
+{
+ int ret;
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
+ EVPerr(EVP_F_EVP_PKEY_PARAMGEN,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+
+ if (ctx->operation != EVP_PKEY_OP_PARAMGEN) {
+ EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED);
+ return -1;
+ }
+
+ if (ppkey == NULL)
+ return -1;
+
+ if (*ppkey == NULL)
+ *ppkey = EVP_PKEY_new();
+
+ if (*ppkey == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_PARAMGEN, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+
+ ret = ctx->pmeth->paramgen(ctx, *ppkey);
+ if (ret <= 0) {
+ EVP_PKEY_free(*ppkey);
+ *ppkey = NULL;
+ }
+ return ret;
+}
+
+int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
+{
+ int ret;
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
+ EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ ctx->operation = EVP_PKEY_OP_KEYGEN;
+ if (!ctx->pmeth->keygen_init)
+ return 1;
+ ret = ctx->pmeth->keygen_init(ctx);
+ if (ret <= 0)
+ ctx->operation = EVP_PKEY_OP_UNDEFINED;
+ return ret;
+}
+
+int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
+{
+ int ret;
+
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
+ EVPerr(EVP_F_EVP_PKEY_KEYGEN,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ if (ctx->operation != EVP_PKEY_OP_KEYGEN) {
+ EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED);
+ return -1;
+ }
+
+ if (!ppkey)
+ return -1;
+
+ if (!*ppkey)
+ *ppkey = EVP_PKEY_new();
+
+ ret = ctx->pmeth->keygen(ctx, *ppkey);
+ if (ret <= 0) {
+ EVP_PKEY_free(*ppkey);
+ *ppkey = NULL;
+ }
+ return ret;
+}
+
+void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
+{
+ ctx->pkey_gencb = cb;
+}
+
+EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx)
+{
+ return ctx->pkey_gencb;
+}
+
+/*
+ * "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB style
+ * callbacks.
+ */
+
+static int trans_cb(int a, int b, BN_GENCB *gcb)
+{
+ EVP_PKEY_CTX *ctx = gcb->arg;
+ ctx->keygen_info[0] = a;
+ ctx->keygen_info[1] = b;
+ return ctx->pkey_gencb(ctx);
+}
+
+void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
+{
+ BN_GENCB_set(cb, trans_cb, ctx)
+}
+
+int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
+{
+ if (idx == -1)
+ return ctx->keygen_info_count;
+ if (idx < 0 || idx > ctx->keygen_info_count)
+ return 0;
+ return ctx->keygen_info[idx];
+}
+
+EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
+ const unsigned char *key, int keylen)
+{
+ EVP_PKEY_CTX *mac_ctx = NULL;
+ EVP_PKEY *mac_key = NULL;
+ mac_ctx = EVP_PKEY_CTX_new_id(type, e);
+ if (!mac_ctx)
+ return NULL;
+ if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
+ goto merr;
+ if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
+ EVP_PKEY_CTRL_SET_MAC_KEY,
+ keylen, (void *)key) <= 0)
+ goto merr;
+ if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
+ goto merr;
+ merr:
+ if (mac_ctx)
+ EVP_PKEY_CTX_free(mac_ctx);
+ return mac_key;
+}
diff --git a/Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c b/Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c
new file mode 100644
index 00000000..9f81d100
--- /dev/null
+++ b/Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c
@@ -0,0 +1,613 @@
+/* pmeth_lib.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+#include "asn1_locl.h"
+#include "evp_locl.h"
+
+typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
+
+DECLARE_STACK_OF(EVP_PKEY_METHOD)
+STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
+
+extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
+extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth;
+extern const EVP_PKEY_METHOD dhx_pkey_meth;
+
+static const EVP_PKEY_METHOD *standard_methods[] = {
+#ifndef OPENSSL_NO_RSA
+ &rsa_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_DH
+ &dh_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_DSA
+ &dsa_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_EC
+ &ec_pkey_meth,
+#endif
+ &hmac_pkey_meth,
+ &cmac_pkey_meth,
+#ifndef OPENSSL_NO_DH
+ &dhx_pkey_meth
+#endif
+};
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
+ pmeth);
+
+static int pmeth_cmp(const EVP_PKEY_METHOD *const *a,
+ const EVP_PKEY_METHOD *const *b)
+{
+ return ((*a)->pkey_id - (*b)->pkey_id);
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
+ pmeth);
+
+const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
+{
+ EVP_PKEY_METHOD tmp;
+ const EVP_PKEY_METHOD *t = &tmp, **ret;
+ tmp.pkey_id = type;
+ if (app_pkey_methods) {
+ int idx;
+ idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
+ if (idx >= 0)
+ return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
+ }
+ ret = OBJ_bsearch_pmeth(&t, standard_methods,
+ sizeof(standard_methods) /
+ sizeof(EVP_PKEY_METHOD *));
+ if (!ret || !*ret)
+ return NULL;
+ return *ret;
+}
+
+static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
+{
+ EVP_PKEY_CTX *ret;
+ const EVP_PKEY_METHOD *pmeth;
+ if (id == -1) {
+ if (!pkey || !pkey->ameth)
+ return NULL;
+ id = pkey->ameth->pkey_id;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ if (pkey && pkey->engine)
+ e = pkey->engine;
+ /* Try to find an ENGINE which implements this method */
+ if (e) {
+ if (!ENGINE_init(e)) {
+ EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB);
+ return NULL;
+ }
+ } else
+ e = ENGINE_get_pkey_meth_engine(id);
+
+ /*
+ * If an ENGINE handled this method look it up. Othewise use internal
+ * tables.
+ */
+
+ if (e)
+ pmeth = ENGINE_get_pkey_meth(e, id);
+ else
+#endif
+ pmeth = EVP_PKEY_meth_find(id);
+
+ if (pmeth == NULL) {
+ EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
+ return NULL;
+ }
+
+ ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
+ if (!ret) {
+#ifndef OPENSSL_NO_ENGINE
+ if (e)
+ ENGINE_finish(e);
+#endif
+ EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ ret->engine = e;
+ ret->pmeth = pmeth;
+ ret->operation = EVP_PKEY_OP_UNDEFINED;
+ ret->pkey = pkey;
+ ret->peerkey = NULL;
+ ret->pkey_gencb = 0;
+ if (pkey)
+ CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+ ret->data = NULL;
+
+ if (pmeth->init) {
+ if (pmeth->init(ret) <= 0) {
+ EVP_PKEY_CTX_free(ret);
+ return NULL;
+ }
+ }
+
+ return ret;
+}
+
+EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
+{
+ EVP_PKEY_METHOD *pmeth;
+ pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD));
+ if (!pmeth)
+ return NULL;
+
+ memset(pmeth, 0, sizeof(EVP_PKEY_METHOD));
+
+ pmeth->pkey_id = id;
+ pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
+
+ pmeth->init = 0;
+ pmeth->copy = 0;
+ pmeth->cleanup = 0;
+ pmeth->paramgen_init = 0;
+ pmeth->paramgen = 0;
+ pmeth->keygen_init = 0;
+ pmeth->keygen = 0;
+ pmeth->sign_init = 0;
+ pmeth->sign = 0;
+ pmeth->verify_init = 0;
+ pmeth->verify = 0;
+ pmeth->verify_recover_init = 0;
+ pmeth->verify_recover = 0;
+ pmeth->signctx_init = 0;
+ pmeth->signctx = 0;
+ pmeth->verifyctx_init = 0;
+ pmeth->verifyctx = 0;
+ pmeth->encrypt_init = 0;
+ pmeth->encrypt = 0;
+ pmeth->decrypt_init = 0;
+ pmeth->decrypt = 0;
+ pmeth->derive_init = 0;
+ pmeth->derive = 0;
+ pmeth->ctrl = 0;
+ pmeth->ctrl_str = 0;
+
+ return pmeth;
+}
+
+void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
+ const EVP_PKEY_METHOD *meth)
+{
+ if (ppkey_id)
+ *ppkey_id = meth->pkey_id;
+ if (pflags)
+ *pflags = meth->flags;
+}
+
+void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
+{
+
+ dst->init = src->init;
+ dst->copy = src->copy;
+ dst->cleanup = src->cleanup;
+
+ dst->paramgen_init = src->paramgen_init;
+ dst->paramgen = src->paramgen;
+
+ dst->keygen_init = src->keygen_init;
+ dst->keygen = src->keygen;
+
+ dst->sign_init = src->sign_init;
+ dst->sign = src->sign;
+
+ dst->verify_init = src->verify_init;
+ dst->verify = src->verify;
+
+ dst->verify_recover_init = src->verify_recover_init;
+ dst->verify_recover = src->verify_recover;
+
+ dst->signctx_init = src->signctx_init;
+ dst->signctx = src->signctx;
+
+ dst->verifyctx_init = src->verifyctx_init;
+ dst->verifyctx = src->verifyctx;
+
+ dst->encrypt_init = src->encrypt_init;
+ dst->encrypt = src->encrypt;
+
+ dst->decrypt_init = src->decrypt_init;
+ dst->decrypt = src->decrypt;
+
+ dst->derive_init = src->derive_init;
+ dst->derive = src->derive;
+
+ dst->ctrl = src->ctrl;
+ dst->ctrl_str = src->ctrl_str;
+}
+
+void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
+{
+ if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
+ OPENSSL_free(pmeth);
+}
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
+{
+ return int_ctx_new(pkey, e, -1);
+}
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
+{
+ return int_ctx_new(NULL, e, id);
+}
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
+{
+ EVP_PKEY_CTX *rctx;
+ if (!pctx->pmeth || !pctx->pmeth->copy)
+ return NULL;
+#ifndef OPENSSL_NO_ENGINE
+ /* Make sure it's safe to copy a pkey context using an ENGINE */
+ if (pctx->engine && !ENGINE_init(pctx->engine)) {
+ EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB);
+ return 0;
+ }
+#endif
+ rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
+ if (!rctx)
+ return NULL;
+
+ rctx->pmeth = pctx->pmeth;
+#ifndef OPENSSL_NO_ENGINE
+ rctx->engine = pctx->engine;
+#endif
+
+ if (pctx->pkey)
+ CRYPTO_add(&pctx->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+
+ rctx->pkey = pctx->pkey;
+
+ if (pctx->peerkey)
+ CRYPTO_add(&pctx->peerkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+
+ rctx->peerkey = pctx->peerkey;
+
+ rctx->data = NULL;
+ rctx->app_data = NULL;
+ rctx->operation = pctx->operation;
+
+ if (pctx->pmeth->copy(rctx, pctx) > 0)
+ return rctx;
+
+ EVP_PKEY_CTX_free(rctx);
+ return NULL;
+
+}
+
+int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
+{
+ if (app_pkey_methods == NULL) {
+ app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
+ if (!app_pkey_methods)
+ return 0;
+ }
+ if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth))
+ return 0;
+ sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
+ return 1;
+}
+
+void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
+{
+ if (ctx == NULL)
+ return;
+ if (ctx->pmeth && ctx->pmeth->cleanup)
+ ctx->pmeth->cleanup(ctx);
+ if (ctx->pkey)
+ EVP_PKEY_free(ctx->pkey);
+ if (ctx->peerkey)
+ EVP_PKEY_free(ctx->peerkey);
+#ifndef OPENSSL_NO_ENGINE
+ if (ctx->engine)
+ /*
+ * The EVP_PKEY_CTX we used belongs to an ENGINE, release the
+ * functional reference we held for this reason.
+ */
+ ENGINE_finish(ctx->engine);
+#endif
+ OPENSSL_free(ctx);
+}
+
+int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
+ int cmd, int p1, void *p2)
+{
+ int ret;
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
+ EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
+ return -2;
+ }
+ if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
+ return -1;
+
+ if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
+ EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
+ return -1;
+ }
+
+ if ((optype != -1) && !(ctx->operation & optype)) {
+ EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION);
+ return -1;
+ }
+
+ ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
+
+ if (ret == -2)
+ EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
+
+ return ret;
+
+}
+
+int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
+ const char *name, const char *value)
+{
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
+ EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
+ return -2;
+ }
+ if (!strcmp(name, "digest")) {
+ const EVP_MD *md;
+ if (!value || !(md = EVP_get_digestbyname(value))) {
+ EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_INVALID_DIGEST);
+ return 0;
+ }
+ return EVP_PKEY_CTX_set_signature_md(ctx, md);
+ }
+ return ctx->pmeth->ctrl_str(ctx, name, value);
+}
+
+int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
+{
+ return ctx->operation;
+}
+
+void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
+{
+ ctx->keygen_info = dat;
+ ctx->keygen_info_count = datlen;
+}
+
+void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
+{
+ ctx->data = data;
+}
+
+void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
+{
+ return ctx->data;
+}
+
+EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
+{
+ return ctx->pkey;
+}
+
+EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
+{
+ return ctx->peerkey;
+}
+
+void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
+{
+ ctx->app_data = data;
+}
+
+void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
+{
+ return ctx->app_data;
+}
+
+void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
+ int (*init) (EVP_PKEY_CTX *ctx))
+{
+ pmeth->init = init;
+}
+
+void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
+ int (*copy) (EVP_PKEY_CTX *dst,
+ EVP_PKEY_CTX *src))
+{
+ pmeth->copy = copy;
+}
+
+void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
+ void (*cleanup) (EVP_PKEY_CTX *ctx))
+{
+ pmeth->cleanup = cleanup;
+}
+
+void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
+ int (*paramgen_init) (EVP_PKEY_CTX *ctx),
+ int (*paramgen) (EVP_PKEY_CTX *ctx,
+ EVP_PKEY *pkey))
+{
+ pmeth->paramgen_init = paramgen_init;
+ pmeth->paramgen = paramgen;
+}
+
+void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
+ int (*keygen_init) (EVP_PKEY_CTX *ctx),
+ int (*keygen) (EVP_PKEY_CTX *ctx,
+ EVP_PKEY *pkey))
+{
+ pmeth->keygen_init = keygen_init;
+ pmeth->keygen = keygen;
+}
+
+void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
+ int (*sign_init) (EVP_PKEY_CTX *ctx),
+ int (*sign) (EVP_PKEY_CTX *ctx,
+ unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs,
+ size_t tbslen))
+{
+ pmeth->sign_init = sign_init;
+ pmeth->sign = sign;
+}
+
+void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
+ int (*verify_init) (EVP_PKEY_CTX *ctx),
+ int (*verify) (EVP_PKEY_CTX *ctx,
+ const unsigned char *sig,
+ size_t siglen,
+ const unsigned char *tbs,
+ size_t tbslen))
+{
+ pmeth->verify_init = verify_init;
+ pmeth->verify = verify;
+}
+
+void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
+ int (*verify_recover_init) (EVP_PKEY_CTX
+ *ctx),
+ int (*verify_recover) (EVP_PKEY_CTX
+ *ctx,
+ unsigned char
+ *sig,
+ size_t *siglen,
+ const unsigned
+ char *tbs,
+ size_t tbslen))
+{
+ pmeth->verify_recover_init = verify_recover_init;
+ pmeth->verify_recover = verify_recover;
+}
+
+void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
+ int (*signctx_init) (EVP_PKEY_CTX *ctx,
+ EVP_MD_CTX *mctx),
+ int (*signctx) (EVP_PKEY_CTX *ctx,
+ unsigned char *sig,
+ size_t *siglen,
+ EVP_MD_CTX *mctx))
+{
+ pmeth->signctx_init = signctx_init;
+ pmeth->signctx = signctx;
+}
+
+void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
+ int (*verifyctx_init) (EVP_PKEY_CTX *ctx,
+ EVP_MD_CTX *mctx),
+ int (*verifyctx) (EVP_PKEY_CTX *ctx,
+ const unsigned char *sig,
+ int siglen,
+ EVP_MD_CTX *mctx))
+{
+ pmeth->verifyctx_init = verifyctx_init;
+ pmeth->verifyctx = verifyctx;
+}
+
+void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
+ int (*encrypt_init) (EVP_PKEY_CTX *ctx),
+ int (*encryptfn) (EVP_PKEY_CTX *ctx,
+ unsigned char *out,
+ size_t *outlen,
+ const unsigned char *in,
+ size_t inlen))
+{
+ pmeth->encrypt_init = encrypt_init;
+ pmeth->encrypt = encryptfn;
+}
+
+void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
+ int (*decrypt_init) (EVP_PKEY_CTX *ctx),
+ int (*decrypt) (EVP_PKEY_CTX *ctx,
+ unsigned char *out,
+ size_t *outlen,
+ const unsigned char *in,
+ size_t inlen))
+{
+ pmeth->decrypt_init = decrypt_init;
+ pmeth->decrypt = decrypt;
+}
+
+void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
+ int (*derive_init) (EVP_PKEY_CTX *ctx),
+ int (*derive) (EVP_PKEY_CTX *ctx,
+ unsigned char *key,
+ size_t *keylen))
+{
+ pmeth->derive_init = derive_init;
+ pmeth->derive = derive;
+}
+
+void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
+ int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
+ void *p2),
+ int (*ctrl_str) (EVP_PKEY_CTX *ctx,
+ const char *type,
+ const char *value))
+{
+ pmeth->ctrl = ctrl;
+ pmeth->ctrl_str = ctrl_str;
+}