mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Upgrade openssl from 1.1.0e to 1.1.1b, with source code. 4.0.78
This commit is contained in:
parent
8f1c992379
commit
96dbd7bced
1476 changed files with 616554 additions and 4 deletions
553
trunk/3rdparty/openssl-1.1-fit/crypto/evp/bio_b64.c
vendored
Normal file
553
trunk/3rdparty/openssl-1.1-fit/crypto/evp/bio_b64.c
vendored
Normal file
|
@ -0,0 +1,553 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/bio.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 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 const BIO_METHOD methods_b64 = {
|
||||
BIO_TYPE_BASE64,
|
||||
"base64 encoding",
|
||||
/* TODO: Convert to new style write function */
|
||||
bwrite_conv,
|
||||
b64_write,
|
||||
/* TODO: Convert to new style read function */
|
||||
bread_conv,
|
||||
b64_read,
|
||||
b64_puts,
|
||||
NULL, /* b64_gets, */
|
||||
b64_ctrl,
|
||||
b64_new,
|
||||
b64_free,
|
||||
b64_callback_ctrl,
|
||||
};
|
||||
|
||||
|
||||
const BIO_METHOD *BIO_f_base64(void)
|
||||
{
|
||||
return &methods_b64;
|
||||
}
|
||||
|
||||
static int b64_new(BIO *bi)
|
||||
{
|
||||
BIO_B64_CTX *ctx;
|
||||
|
||||
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
|
||||
EVPerr(EVP_F_B64_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->cont = 1;
|
||||
ctx->start = 1;
|
||||
ctx->base64 = EVP_ENCODE_CTX_new();
|
||||
if (ctx->base64 == NULL) {
|
||||
OPENSSL_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIO_set_data(bi, ctx);
|
||||
BIO_set_init(bi, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int b64_free(BIO *a)
|
||||
{
|
||||
BIO_B64_CTX *ctx;
|
||||
if (a == NULL)
|
||||
return 0;
|
||||
|
||||
ctx = BIO_get_data(a);
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
EVP_ENCODE_CTX_free(ctx->base64);
|
||||
OPENSSL_free(ctx);
|
||||
BIO_set_data(a, NULL);
|
||||
BIO_set_init(a, 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;
|
||||
BIO *next;
|
||||
|
||||
if (out == NULL)
|
||||
return 0;
|
||||
ctx = (BIO_B64_CTX *)BIO_get_data(b);
|
||||
|
||||
next = BIO_next(b);
|
||||
if ((ctx == NULL) || (next == 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(next, &(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(next)) {
|
||||
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;
|
||||
|
||||
jj = i & ~3; /* process per 4 */
|
||||
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;
|
||||
}
|
||||
/*
|
||||
* If eof or an error was signalled, then the condition
|
||||
* 'ctx->cont <= 0' will prevent b64_read() from reading
|
||||
* more data on subsequent calls. This assignment was
|
||||
* deleted accidentally in commit 5562cfaca4f3.
|
||||
*/
|
||||
ctx->cont = i;
|
||||
|
||||
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;
|
||||
BIO *next;
|
||||
|
||||
ctx = (BIO_B64_CTX *)BIO_get_data(b);
|
||||
next = BIO_next(b);
|
||||
if ((ctx == NULL) || (next == NULL))
|
||||
return 0;
|
||||
|
||||
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(next, &(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 {
|
||||
if (!EVP_EncodeUpdate(ctx->base64,
|
||||
(unsigned char *)ctx->buf, &ctx->buf_len,
|
||||
(unsigned char *)in, n))
|
||||
return ((ret == 0) ? -1 : ret);
|
||||
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(next, &(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;
|
||||
BIO *next;
|
||||
|
||||
ctx = (BIO_B64_CTX *)BIO_get_data(b);
|
||||
next = BIO_next(b);
|
||||
if ((ctx == NULL) || (next == NULL))
|
||||
return 0;
|
||||
|
||||
switch (cmd) {
|
||||
case BIO_CTRL_RESET:
|
||||
ctx->cont = 1;
|
||||
ctx->start = 1;
|
||||
ctx->encode = B64_NONE;
|
||||
ret = BIO_ctrl(next, cmd, num, ptr);
|
||||
break;
|
||||
case BIO_CTRL_EOF: /* More to read */
|
||||
if (ctx->cont <= 0)
|
||||
ret = 1;
|
||||
else
|
||||
ret = BIO_ctrl(next, 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)
|
||||
&& (EVP_ENCODE_CTX_num(ctx->base64) != 0))
|
||||
ret = 1;
|
||||
else if (ret <= 0)
|
||||
ret = BIO_ctrl(next, 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(next, 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
|
||||
&& EVP_ENCODE_CTX_num(ctx->base64) != 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(next, cmd, num, ptr);
|
||||
break;
|
||||
|
||||
case BIO_C_DO_STATE_MACHINE:
|
||||
BIO_clear_retry_flags(b);
|
||||
ret = BIO_ctrl(next, 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(next, cmd, num, ptr);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long b64_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
|
||||
{
|
||||
long ret = 1;
|
||||
BIO *next = BIO_next(b);
|
||||
|
||||
if (next == NULL)
|
||||
return 0;
|
||||
switch (cmd) {
|
||||
default:
|
||||
ret = BIO_callback_ctrl(next, cmd, fp);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int b64_puts(BIO *b, const char *str)
|
||||
{
|
||||
return b64_write(b, str, strlen(str));
|
||||
}
|
429
trunk/3rdparty/openssl-1.1-fit/crypto/evp/bio_enc.c
vendored
Normal file
429
trunk/3rdparty/openssl-1.1-fit/crypto/evp/bio_enc.c
vendored
Normal file
|
@ -0,0 +1,429 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/bio.h"
|
||||
|
||||
static int enc_write(BIO *h, const char *buf, int num);
|
||||
static int enc_read(BIO *h, char *buf, 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 ENC_MIN_CHUNK (256)
|
||||
#define BUF_OFFSET (ENC_MIN_CHUNK + EVP_MAX_BLOCK_LENGTH)
|
||||
|
||||
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;
|
||||
unsigned char *read_start, *read_end;
|
||||
/*
|
||||
* buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return
|
||||
* up to a block more data than is presented to it
|
||||
*/
|
||||
unsigned char buf[BUF_OFFSET + ENC_BLOCK_SIZE];
|
||||
} BIO_ENC_CTX;
|
||||
|
||||
static const BIO_METHOD methods_enc = {
|
||||
BIO_TYPE_CIPHER,
|
||||
"cipher",
|
||||
/* TODO: Convert to new style write function */
|
||||
bwrite_conv,
|
||||
enc_write,
|
||||
/* TODO: Convert to new style read function */
|
||||
bread_conv,
|
||||
enc_read,
|
||||
NULL, /* enc_puts, */
|
||||
NULL, /* enc_gets, */
|
||||
enc_ctrl,
|
||||
enc_new,
|
||||
enc_free,
|
||||
enc_callback_ctrl,
|
||||
};
|
||||
|
||||
const BIO_METHOD *BIO_f_cipher(void)
|
||||
{
|
||||
return &methods_enc;
|
||||
}
|
||||
|
||||
static int enc_new(BIO *bi)
|
||||
{
|
||||
BIO_ENC_CTX *ctx;
|
||||
|
||||
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
|
||||
EVPerr(EVP_F_ENC_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->cipher = EVP_CIPHER_CTX_new();
|
||||
if (ctx->cipher == NULL) {
|
||||
OPENSSL_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
ctx->cont = 1;
|
||||
ctx->ok = 1;
|
||||
ctx->read_end = ctx->read_start = &(ctx->buf[BUF_OFFSET]);
|
||||
BIO_set_data(bi, ctx);
|
||||
BIO_set_init(bi, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int enc_free(BIO *a)
|
||||
{
|
||||
BIO_ENC_CTX *b;
|
||||
|
||||
if (a == NULL)
|
||||
return 0;
|
||||
|
||||
b = BIO_get_data(a);
|
||||
if (b == NULL)
|
||||
return 0;
|
||||
|
||||
EVP_CIPHER_CTX_free(b->cipher);
|
||||
OPENSSL_clear_free(b, sizeof(BIO_ENC_CTX));
|
||||
BIO_set_data(a, NULL);
|
||||
BIO_set_init(a, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int enc_read(BIO *b, char *out, int outl)
|
||||
{
|
||||
int ret = 0, i, blocksize;
|
||||
BIO_ENC_CTX *ctx;
|
||||
BIO *next;
|
||||
|
||||
if (out == NULL)
|
||||
return 0;
|
||||
ctx = BIO_get_data(b);
|
||||
|
||||
next = BIO_next(b);
|
||||
if ((ctx == NULL) || (next == 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;
|
||||
}
|
||||
}
|
||||
|
||||
blocksize = EVP_CIPHER_CTX_block_size(ctx->cipher);
|
||||
if (blocksize == 1)
|
||||
blocksize = 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;
|
||||
|
||||
if (ctx->read_start == ctx->read_end) { /* time to read more data */
|
||||
ctx->read_end = ctx->read_start = &(ctx->buf[BUF_OFFSET]);
|
||||
i = BIO_read(next, ctx->read_start, ENC_BLOCK_SIZE);
|
||||
if (i > 0)
|
||||
ctx->read_end += i;
|
||||
} else {
|
||||
i = ctx->read_end - ctx->read_start;
|
||||
}
|
||||
|
||||
if (i <= 0) {
|
||||
/* Should be continue next time we are called? */
|
||||
if (!BIO_should_retry(next)) {
|
||||
ctx->cont = i;
|
||||
i = EVP_CipherFinal_ex(ctx->cipher,
|
||||
ctx->buf, &(ctx->buf_len));
|
||||
ctx->ok = i;
|
||||
ctx->buf_off = 0;
|
||||
} else {
|
||||
ret = (ret == 0) ? i : ret;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (outl > ENC_MIN_CHUNK) {
|
||||
/*
|
||||
* Depending on flags block cipher decrypt can write
|
||||
* one extra block and then back off, i.e. output buffer
|
||||
* has to accommodate extra block...
|
||||
*/
|
||||
int j = outl - blocksize, buf_len;
|
||||
|
||||
if (!EVP_CipherUpdate(ctx->cipher,
|
||||
(unsigned char *)out, &buf_len,
|
||||
ctx->read_start, i > j ? j : i)) {
|
||||
BIO_clear_retry_flags(b);
|
||||
return 0;
|
||||
}
|
||||
ret += buf_len;
|
||||
out += buf_len;
|
||||
outl -= buf_len;
|
||||
|
||||
if ((i -= j) <= 0) {
|
||||
ctx->read_start = ctx->read_end;
|
||||
continue;
|
||||
}
|
||||
ctx->read_start += j;
|
||||
}
|
||||
if (i > ENC_MIN_CHUNK)
|
||||
i = ENC_MIN_CHUNK;
|
||||
if (!EVP_CipherUpdate(ctx->cipher,
|
||||
ctx->buf, &ctx->buf_len,
|
||||
ctx->read_start, i)) {
|
||||
BIO_clear_retry_flags(b);
|
||||
ctx->ok = 0;
|
||||
return 0;
|
||||
}
|
||||
ctx->read_start += 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;
|
||||
BIO *next;
|
||||
|
||||
ctx = BIO_get_data(b);
|
||||
next = BIO_next(b);
|
||||
if ((ctx == NULL) || (next == NULL))
|
||||
return 0;
|
||||
|
||||
ret = inl;
|
||||
|
||||
BIO_clear_retry_flags(b);
|
||||
n = ctx->buf_len - ctx->buf_off;
|
||||
while (n > 0) {
|
||||
i = BIO_write(next, &(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;
|
||||
if (!EVP_CipherUpdate(ctx->cipher,
|
||||
ctx->buf, &ctx->buf_len,
|
||||
(const unsigned char *)in, n)) {
|
||||
BIO_clear_retry_flags(b);
|
||||
ctx->ok = 0;
|
||||
return 0;
|
||||
}
|
||||
inl -= n;
|
||||
in += n;
|
||||
|
||||
ctx->buf_off = 0;
|
||||
n = ctx->buf_len;
|
||||
while (n > 0) {
|
||||
i = BIO_write(next, &(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;
|
||||
BIO *next;
|
||||
|
||||
ctx = BIO_get_data(b);
|
||||
next = BIO_next(b);
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
switch (cmd) {
|
||||
case BIO_CTRL_RESET:
|
||||
ctx->ok = 1;
|
||||
ctx->finished = 0;
|
||||
if (!EVP_CipherInit_ex(ctx->cipher, NULL, NULL, NULL, NULL,
|
||||
EVP_CIPHER_CTX_encrypting(ctx->cipher)))
|
||||
return 0;
|
||||
ret = BIO_ctrl(next, cmd, num, ptr);
|
||||
break;
|
||||
case BIO_CTRL_EOF: /* More to read */
|
||||
if (ctx->cont <= 0)
|
||||
ret = 1;
|
||||
else
|
||||
ret = BIO_ctrl(next, cmd, num, ptr);
|
||||
break;
|
||||
case BIO_CTRL_WPENDING:
|
||||
ret = ctx->buf_len - ctx->buf_off;
|
||||
if (ret <= 0)
|
||||
ret = BIO_ctrl(next, 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(next, 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(next, 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(next, 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;
|
||||
BIO_set_init(b, 1);
|
||||
break;
|
||||
case BIO_CTRL_DUP:
|
||||
dbio = (BIO *)ptr;
|
||||
dctx = BIO_get_data(dbio);
|
||||
dctx->cipher = EVP_CIPHER_CTX_new();
|
||||
if (dctx->cipher == NULL)
|
||||
return 0;
|
||||
ret = EVP_CIPHER_CTX_copy(dctx->cipher, ctx->cipher);
|
||||
if (ret)
|
||||
BIO_set_init(dbio, 1);
|
||||
break;
|
||||
default:
|
||||
ret = BIO_ctrl(next, cmd, num, ptr);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long enc_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
|
||||
{
|
||||
long ret = 1;
|
||||
BIO *next = BIO_next(b);
|
||||
|
||||
if (next == NULL)
|
||||
return 0;
|
||||
switch (cmd) {
|
||||
default:
|
||||
ret = BIO_callback_ctrl(next, cmd, fp);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
|
||||
const unsigned char *i, int e)
|
||||
{
|
||||
BIO_ENC_CTX *ctx;
|
||||
long (*callback) (struct bio_st *, int, const char *, int, long, long);
|
||||
|
||||
ctx = BIO_get_data(b);
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
callback = BIO_get_callback(b);
|
||||
|
||||
if ((callback != NULL) &&
|
||||
(callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e,
|
||||
0L) <= 0))
|
||||
return 0;
|
||||
|
||||
BIO_set_init(b, 1);
|
||||
|
||||
if (!EVP_CipherInit_ex(ctx->cipher, c, NULL, k, i, e))
|
||||
return 0;
|
||||
|
||||
if (callback != NULL)
|
||||
return callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L);
|
||||
return 1;
|
||||
}
|
233
trunk/3rdparty/openssl-1.1-fit/crypto/evp/bio_md.c
vendored
Normal file
233
trunk/3rdparty/openssl-1.1-fit/crypto/evp/bio_md.c
vendored
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "evp_locl.h"
|
||||
#include "internal/bio.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_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 const BIO_METHOD methods_md = {
|
||||
BIO_TYPE_MD,
|
||||
"message digest",
|
||||
/* TODO: Convert to new style write function */
|
||||
bwrite_conv,
|
||||
md_write,
|
||||
/* TODO: Convert to new style read function */
|
||||
bread_conv,
|
||||
md_read,
|
||||
NULL, /* md_puts, */
|
||||
md_gets,
|
||||
md_ctrl,
|
||||
md_new,
|
||||
md_free,
|
||||
md_callback_ctrl,
|
||||
};
|
||||
|
||||
const BIO_METHOD *BIO_f_md(void)
|
||||
{
|
||||
return &methods_md;
|
||||
}
|
||||
|
||||
static int md_new(BIO *bi)
|
||||
{
|
||||
EVP_MD_CTX *ctx;
|
||||
|
||||
ctx = EVP_MD_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
BIO_set_init(bi, 1);
|
||||
BIO_set_data(bi, ctx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int md_free(BIO *a)
|
||||
{
|
||||
if (a == NULL)
|
||||
return 0;
|
||||
EVP_MD_CTX_free(BIO_get_data(a));
|
||||
BIO_set_data(a, NULL);
|
||||
BIO_set_init(a, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int md_read(BIO *b, char *out, int outl)
|
||||
{
|
||||
int ret = 0;
|
||||
EVP_MD_CTX *ctx;
|
||||
BIO *next;
|
||||
|
||||
if (out == NULL)
|
||||
return 0;
|
||||
|
||||
ctx = BIO_get_data(b);
|
||||
next = BIO_next(b);
|
||||
|
||||
if ((ctx == NULL) || (next == NULL))
|
||||
return 0;
|
||||
|
||||
ret = BIO_read(next, out, outl);
|
||||
if (BIO_get_init(b)) {
|
||||
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;
|
||||
BIO *next;
|
||||
|
||||
if ((in == NULL) || (inl <= 0))
|
||||
return 0;
|
||||
|
||||
ctx = BIO_get_data(b);
|
||||
next = BIO_next(b);
|
||||
if ((ctx != NULL) && (next != NULL))
|
||||
ret = BIO_write(next, in, inl);
|
||||
|
||||
if (BIO_get_init(b)) {
|
||||
if (ret > 0) {
|
||||
if (!EVP_DigestUpdate(ctx, (const unsigned char *)in,
|
||||
(unsigned int)ret)) {
|
||||
BIO_clear_retry_flags(b);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (next != 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, *next;
|
||||
|
||||
|
||||
ctx = BIO_get_data(b);
|
||||
next = BIO_next(b);
|
||||
|
||||
switch (cmd) {
|
||||
case BIO_CTRL_RESET:
|
||||
if (BIO_get_init(b))
|
||||
ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL);
|
||||
else
|
||||
ret = 0;
|
||||
if (ret > 0)
|
||||
ret = BIO_ctrl(next, cmd, num, ptr);
|
||||
break;
|
||||
case BIO_C_GET_MD:
|
||||
if (BIO_get_init(b)) {
|
||||
ppmd = ptr;
|
||||
*ppmd = ctx->digest;
|
||||
} else
|
||||
ret = 0;
|
||||
break;
|
||||
case BIO_C_GET_MD_CTX:
|
||||
pctx = ptr;
|
||||
*pctx = ctx;
|
||||
BIO_set_init(b, 1);
|
||||
break;
|
||||
case BIO_C_SET_MD_CTX:
|
||||
if (BIO_get_init(b))
|
||||
BIO_set_data(b, ptr);
|
||||
else
|
||||
ret = 0;
|
||||
break;
|
||||
case BIO_C_DO_STATE_MACHINE:
|
||||
BIO_clear_retry_flags(b);
|
||||
ret = BIO_ctrl(next, 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)
|
||||
BIO_set_init(b, 1);
|
||||
break;
|
||||
case BIO_CTRL_DUP:
|
||||
dbio = ptr;
|
||||
dctx = BIO_get_data(dbio);
|
||||
if (!EVP_MD_CTX_copy_ex(dctx, ctx))
|
||||
return 0;
|
||||
BIO_set_init(b, 1);
|
||||
break;
|
||||
default:
|
||||
ret = BIO_ctrl(next, cmd, num, ptr);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long md_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
|
||||
{
|
||||
long ret = 1;
|
||||
BIO *next;
|
||||
|
||||
next = BIO_next(b);
|
||||
|
||||
if (next == NULL)
|
||||
return 0;
|
||||
|
||||
switch (cmd) {
|
||||
default:
|
||||
ret = BIO_callback_ctrl(next, cmd, fp);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int md_gets(BIO *bp, char *buf, int size)
|
||||
{
|
||||
EVP_MD_CTX *ctx;
|
||||
unsigned int ret;
|
||||
|
||||
ctx = BIO_get_data(bp);
|
||||
|
||||
if (size < ctx->digest->md_size)
|
||||
return 0;
|
||||
|
||||
if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0)
|
||||
return -1;
|
||||
|
||||
return (int)ret;
|
||||
}
|
610
trunk/3rdparty/openssl-1.1-fit/crypto/evp/bio_ok.c
vendored
Normal file
610
trunk/3rdparty/openssl-1.1-fit/crypto/evp/bio_ok.c
vendored
Normal file
|
@ -0,0 +1,610 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*-
|
||||
From: Arne Ansper
|
||||
|
||||
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 "internal/cryptlib.h"
|
||||
#include <openssl/buffer.h>
|
||||
#include "internal/bio.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "internal/evp_int.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 __owur int sig_out(BIO *b);
|
||||
static __owur int sig_in(BIO *b);
|
||||
static __owur int block_out(BIO *b);
|
||||
static __owur 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 const BIO_METHOD methods_ok = {
|
||||
BIO_TYPE_CIPHER,
|
||||
"reliable",
|
||||
/* TODO: Convert to new style write function */
|
||||
bwrite_conv,
|
||||
ok_write,
|
||||
/* TODO: Convert to new style read function */
|
||||
bread_conv,
|
||||
ok_read,
|
||||
NULL, /* ok_puts, */
|
||||
NULL, /* ok_gets, */
|
||||
ok_ctrl,
|
||||
ok_new,
|
||||
ok_free,
|
||||
ok_callback_ctrl,
|
||||
};
|
||||
|
||||
const BIO_METHOD *BIO_f_reliable(void)
|
||||
{
|
||||
return &methods_ok;
|
||||
}
|
||||
|
||||
static int ok_new(BIO *bi)
|
||||
{
|
||||
BIO_OK_CTX *ctx;
|
||||
|
||||
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
|
||||
EVPerr(EVP_F_OK_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->cont = 1;
|
||||
ctx->sigio = 1;
|
||||
ctx->md = EVP_MD_CTX_new();
|
||||
if (ctx->md == NULL) {
|
||||
OPENSSL_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
BIO_set_init(bi, 0);
|
||||
BIO_set_data(bi, ctx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ok_free(BIO *a)
|
||||
{
|
||||
BIO_OK_CTX *ctx;
|
||||
|
||||
if (a == NULL)
|
||||
return 0;
|
||||
|
||||
ctx = BIO_get_data(a);
|
||||
|
||||
EVP_MD_CTX_free(ctx->md);
|
||||
OPENSSL_clear_free(ctx, sizeof(BIO_OK_CTX));
|
||||
BIO_set_data(a, NULL);
|
||||
BIO_set_init(a, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ok_read(BIO *b, char *out, int outl)
|
||||
{
|
||||
int ret = 0, i, n;
|
||||
BIO_OK_CTX *ctx;
|
||||
BIO *next;
|
||||
|
||||
if (out == NULL)
|
||||
return 0;
|
||||
|
||||
ctx = BIO_get_data(b);
|
||||
next = BIO_next(b);
|
||||
|
||||
if ((ctx == NULL) || (next == NULL) || (BIO_get_init(b) == 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(next, &(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;
|
||||
BIO *next;
|
||||
|
||||
if (inl <= 0)
|
||||
return inl;
|
||||
|
||||
ctx = BIO_get_data(b);
|
||||
next = BIO_next(b);
|
||||
ret = inl;
|
||||
|
||||
if ((ctx == NULL) || (next == NULL) || (BIO_get_init(b) == 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(next, &(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(&ctx->buf[ctx->buf_len], 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;
|
||||
BIO *next;
|
||||
|
||||
ctx = BIO_get_data(b);
|
||||
next = BIO_next(b);
|
||||
|
||||
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(next, cmd, num, ptr);
|
||||
break;
|
||||
case BIO_CTRL_EOF: /* More to read */
|
||||
if (ctx->cont <= 0)
|
||||
ret = 1;
|
||||
else
|
||||
ret = BIO_ctrl(next, 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(next, 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(next, cmd, num, ptr);
|
||||
break;
|
||||
case BIO_C_DO_STATE_MACHINE:
|
||||
BIO_clear_retry_flags(b);
|
||||
ret = BIO_ctrl(next, 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;
|
||||
BIO_set_init(b, 1);
|
||||
break;
|
||||
case BIO_C_GET_MD:
|
||||
if (BIO_get_init(b)) {
|
||||
ppmd = ptr;
|
||||
*ppmd = EVP_MD_CTX_md(ctx->md);
|
||||
} else
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
ret = BIO_ctrl(next, cmd, num, ptr);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long ok_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
|
||||
{
|
||||
long ret = 1;
|
||||
BIO *next;
|
||||
|
||||
next = BIO_next(b);
|
||||
|
||||
if (next == NULL)
|
||||
return 0;
|
||||
|
||||
switch (cmd) {
|
||||
default:
|
||||
ret = BIO_callback_ctrl(next, 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;
|
||||
const EVP_MD *digest;
|
||||
int md_size;
|
||||
void *md_data;
|
||||
|
||||
ctx = BIO_get_data(b);
|
||||
md = ctx->md;
|
||||
digest = EVP_MD_CTX_md(md);
|
||||
md_size = EVP_MD_size(digest);
|
||||
md_data = EVP_MD_CTX_md_data(md);
|
||||
|
||||
if (ctx->buf_len + 2 * md_size > OK_BLOCK_SIZE)
|
||||
return 1;
|
||||
|
||||
if (!EVP_DigestInit_ex(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_bytes(md_data, md_size) <= 0)
|
||||
goto berr;
|
||||
memcpy(&(ctx->buf[ctx->buf_len]), md_data, md_size);
|
||||
longswap(&(ctx->buf[ctx->buf_len]), md_size);
|
||||
ctx->buf_len += 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_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;
|
||||
const EVP_MD *digest;
|
||||
int md_size;
|
||||
void *md_data;
|
||||
|
||||
ctx = BIO_get_data(b);
|
||||
md = ctx->md;
|
||||
digest = EVP_MD_CTX_md(md);
|
||||
md_size = EVP_MD_size(digest);
|
||||
md_data = EVP_MD_CTX_md_data(md);
|
||||
|
||||
if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md_size)
|
||||
return 1;
|
||||
|
||||
if (!EVP_DigestInit_ex(md, digest, NULL))
|
||||
goto berr;
|
||||
memcpy(md_data, &(ctx->buf[ctx->buf_off]), md_size);
|
||||
longswap(md_data, md_size);
|
||||
ctx->buf_off += 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_size) == 0;
|
||||
ctx->buf_off += 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;
|
||||
const EVP_MD *digest;
|
||||
int md_size;
|
||||
|
||||
ctx = BIO_get_data(b);
|
||||
md = ctx->md;
|
||||
digest = EVP_MD_CTX_md(md);
|
||||
md_size = EVP_MD_size(digest);
|
||||
|
||||
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_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];
|
||||
int md_size;
|
||||
|
||||
ctx = BIO_get_data(b);
|
||||
md = ctx->md;
|
||||
md_size = EVP_MD_size(EVP_MD_CTX_md(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_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_size) == 0) {
|
||||
/* there might be parts from next block lurking around ! */
|
||||
ctx->buf_off_save = tl + OK_BLOCK_BLOCK + 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;
|
||||
}
|
25
trunk/3rdparty/openssl-1.1-fit/crypto/evp/build.info
vendored
Normal file
25
trunk/3rdparty/openssl-1.1-fit/crypto/evp/build.info
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
encode.c digest.c evp_enc.c evp_key.c evp_cnf.c \
|
||||
e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
|
||||
e_rc4.c e_aes.c names.c e_seed.c e_aria.c e_sm4.c \
|
||||
e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \
|
||||
m_null.c m_md2.c m_md4.c m_md5.c m_sha1.c m_wp.c \
|
||||
m_md5_sha1.c m_mdc2.c m_ripemd.c m_sha3.c \
|
||||
p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
|
||||
bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
|
||||
c_allc.c c_alld.c evp_lib.c bio_ok.c \
|
||||
evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \
|
||||
e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \
|
||||
e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
|
||||
e_chacha20_poly1305.c cmeth_lib.c
|
||||
|
||||
INCLUDE[e_aes.o]=.. ../modes
|
||||
INCLUDE[e_aes_cbc_hmac_sha1.o]=../modes
|
||||
INCLUDE[e_aes_cbc_hmac_sha256.o]=../modes
|
||||
INCLUDE[e_aria.o]=.. ../modes
|
||||
INCLUDE[e_camellia.o]=.. ../modes
|
||||
INCLUDE[e_sm4.o]=.. ../modes
|
||||
INCLUDE[e_des.o]=..
|
||||
INCLUDE[e_des3.o]=..
|
||||
INCLUDE[m_sha3.o]=..
|
266
trunk/3rdparty/openssl-1.1-fit/crypto/evp/c_allc.c
vendored
Normal file
266
trunk/3rdparty/openssl-1.1-fit/crypto/evp/c_allc.c
vendored
Normal file
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/objects.h>
|
||||
|
||||
void openssl_add_all_ciphers_int(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_alias(SN_des_ede_ecb, "DES-EDE-ECB");
|
||||
EVP_add_cipher_alias(SN_des_ede_ecb, "des-ede-ecb");
|
||||
EVP_add_cipher(EVP_des_ede3());
|
||||
EVP_add_cipher_alias(SN_des_ede3_ecb, "DES-EDE3-ECB");
|
||||
EVP_add_cipher_alias(SN_des_ede3_ecb, "des-ede3-ecb");
|
||||
EVP_add_cipher(EVP_des_ede3_wrap());
|
||||
EVP_add_cipher_alias(SN_id_smime_alg_CMS3DESwrap, "des3-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_SM4
|
||||
EVP_add_cipher(EVP_sm4_ecb());
|
||||
EVP_add_cipher(EVP_sm4_cbc());
|
||||
EVP_add_cipher(EVP_sm4_cfb());
|
||||
EVP_add_cipher(EVP_sm4_ofb());
|
||||
EVP_add_cipher(EVP_sm4_ctr());
|
||||
EVP_add_cipher_alias(SN_sm4_cbc, "SM4");
|
||||
EVP_add_cipher_alias(SN_sm4_cbc, "sm4");
|
||||
#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");
|
||||
EVP_add_cipher_alias(SN_rc2_cbc, "rc2-128");
|
||||
EVP_add_cipher_alias(SN_rc2_64_cbc, "rc2-64");
|
||||
EVP_add_cipher_alias(SN_rc2_40_cbc, "rc2-40");
|
||||
#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
|
||||
|
||||
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());
|
||||
#ifndef OPENSSL_NO_OCB
|
||||
EVP_add_cipher(EVP_aes_128_ocb());
|
||||
#endif
|
||||
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_id_aes128_wrap, "aes128-wrap");
|
||||
EVP_add_cipher(EVP_aes_128_wrap_pad());
|
||||
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());
|
||||
#ifndef OPENSSL_NO_OCB
|
||||
EVP_add_cipher(EVP_aes_192_ocb());
|
||||
#endif
|
||||
EVP_add_cipher(EVP_aes_192_ccm());
|
||||
EVP_add_cipher(EVP_aes_192_wrap());
|
||||
EVP_add_cipher_alias(SN_id_aes192_wrap, "aes192-wrap");
|
||||
EVP_add_cipher(EVP_aes_192_wrap_pad());
|
||||
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());
|
||||
#ifndef OPENSSL_NO_OCB
|
||||
EVP_add_cipher(EVP_aes_256_ocb());
|
||||
#endif
|
||||
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_id_aes256_wrap, "aes256-wrap");
|
||||
EVP_add_cipher(EVP_aes_256_wrap_pad());
|
||||
EVP_add_cipher_alias(SN_aes_256_cbc, "AES256");
|
||||
EVP_add_cipher_alias(SN_aes_256_cbc, "aes256");
|
||||
EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
|
||||
EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
|
||||
EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256());
|
||||
EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256());
|
||||
|
||||
#ifndef OPENSSL_NO_ARIA
|
||||
EVP_add_cipher(EVP_aria_128_ecb());
|
||||
EVP_add_cipher(EVP_aria_128_cbc());
|
||||
EVP_add_cipher(EVP_aria_128_cfb());
|
||||
EVP_add_cipher(EVP_aria_128_cfb1());
|
||||
EVP_add_cipher(EVP_aria_128_cfb8());
|
||||
EVP_add_cipher(EVP_aria_128_ctr());
|
||||
EVP_add_cipher(EVP_aria_128_ofb());
|
||||
EVP_add_cipher(EVP_aria_128_gcm());
|
||||
EVP_add_cipher(EVP_aria_128_ccm());
|
||||
EVP_add_cipher_alias(SN_aria_128_cbc, "ARIA128");
|
||||
EVP_add_cipher_alias(SN_aria_128_cbc, "aria128");
|
||||
EVP_add_cipher(EVP_aria_192_ecb());
|
||||
EVP_add_cipher(EVP_aria_192_cbc());
|
||||
EVP_add_cipher(EVP_aria_192_cfb());
|
||||
EVP_add_cipher(EVP_aria_192_cfb1());
|
||||
EVP_add_cipher(EVP_aria_192_cfb8());
|
||||
EVP_add_cipher(EVP_aria_192_ctr());
|
||||
EVP_add_cipher(EVP_aria_192_ofb());
|
||||
EVP_add_cipher(EVP_aria_192_gcm());
|
||||
EVP_add_cipher(EVP_aria_192_ccm());
|
||||
EVP_add_cipher_alias(SN_aria_192_cbc, "ARIA192");
|
||||
EVP_add_cipher_alias(SN_aria_192_cbc, "aria192");
|
||||
EVP_add_cipher(EVP_aria_256_ecb());
|
||||
EVP_add_cipher(EVP_aria_256_cbc());
|
||||
EVP_add_cipher(EVP_aria_256_cfb());
|
||||
EVP_add_cipher(EVP_aria_256_cfb1());
|
||||
EVP_add_cipher(EVP_aria_256_cfb8());
|
||||
EVP_add_cipher(EVP_aria_256_ctr());
|
||||
EVP_add_cipher(EVP_aria_256_ofb());
|
||||
EVP_add_cipher(EVP_aria_256_gcm());
|
||||
EVP_add_cipher(EVP_aria_256_ccm());
|
||||
EVP_add_cipher_alias(SN_aria_256_cbc, "ARIA256");
|
||||
EVP_add_cipher_alias(SN_aria_256_cbc, "aria256");
|
||||
#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");
|
||||
EVP_add_cipher(EVP_camellia_128_ctr());
|
||||
EVP_add_cipher(EVP_camellia_192_ctr());
|
||||
EVP_add_cipher(EVP_camellia_256_ctr());
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_CHACHA
|
||||
EVP_add_cipher(EVP_chacha20());
|
||||
# ifndef OPENSSL_NO_POLY1305
|
||||
EVP_add_cipher(EVP_chacha20_poly1305());
|
||||
# endif
|
||||
#endif
|
||||
}
|
60
trunk/3rdparty/openssl-1.1-fit/crypto/evp/c_alld.c
vendored
Normal file
60
trunk/3rdparty/openssl-1.1-fit/crypto/evp/c_alld.c
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/objects.h>
|
||||
|
||||
void openssl_add_all_digests_int(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, "ssl3-md5");
|
||||
EVP_add_digest(EVP_md5_sha1());
|
||||
#endif
|
||||
EVP_add_digest(EVP_sha1());
|
||||
EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
|
||||
EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
|
||||
#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
|
||||
EVP_add_digest(EVP_mdc2());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_RMD160
|
||||
EVP_add_digest(EVP_ripemd160());
|
||||
EVP_add_digest_alias(SN_ripemd160, "ripemd");
|
||||
EVP_add_digest_alias(SN_ripemd160, "rmd160");
|
||||
#endif
|
||||
EVP_add_digest(EVP_sha224());
|
||||
EVP_add_digest(EVP_sha256());
|
||||
EVP_add_digest(EVP_sha384());
|
||||
EVP_add_digest(EVP_sha512());
|
||||
EVP_add_digest(EVP_sha512_224());
|
||||
EVP_add_digest(EVP_sha512_256());
|
||||
#ifndef OPENSSL_NO_WHIRLPOOL
|
||||
EVP_add_digest(EVP_whirlpool());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SM3
|
||||
EVP_add_digest(EVP_sm3());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_BLAKE2
|
||||
EVP_add_digest(EVP_blake2b512());
|
||||
EVP_add_digest(EVP_blake2s256());
|
||||
#endif
|
||||
EVP_add_digest(EVP_sha3_224());
|
||||
EVP_add_digest(EVP_sha3_256());
|
||||
EVP_add_digest(EVP_sha3_384());
|
||||
EVP_add_digest(EVP_sha3_512());
|
||||
EVP_add_digest(EVP_shake128());
|
||||
EVP_add_digest(EVP_shake256());
|
||||
}
|
151
trunk/3rdparty/openssl-1.1-fit/crypto/evp/cmeth_lib.c
vendored
Normal file
151
trunk/3rdparty/openssl-1.1-fit/crypto/evp/cmeth_lib.c
vendored
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len)
|
||||
{
|
||||
EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER));
|
||||
|
||||
if (cipher != NULL) {
|
||||
cipher->nid = cipher_type;
|
||||
cipher->block_size = block_size;
|
||||
cipher->key_len = key_len;
|
||||
}
|
||||
return cipher;
|
||||
}
|
||||
|
||||
EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher)
|
||||
{
|
||||
EVP_CIPHER *to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size,
|
||||
cipher->key_len);
|
||||
|
||||
if (to != NULL)
|
||||
memcpy(to, cipher, sizeof(*to));
|
||||
return to;
|
||||
}
|
||||
|
||||
void EVP_CIPHER_meth_free(EVP_CIPHER *cipher)
|
||||
{
|
||||
OPENSSL_free(cipher);
|
||||
}
|
||||
|
||||
int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len)
|
||||
{
|
||||
cipher->iv_len = iv_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags)
|
||||
{
|
||||
cipher->flags = flags;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size)
|
||||
{
|
||||
cipher->ctx_size = ctx_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher,
|
||||
int (*init) (EVP_CIPHER_CTX *ctx,
|
||||
const unsigned char *key,
|
||||
const unsigned char *iv,
|
||||
int enc))
|
||||
{
|
||||
cipher->init = init;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher,
|
||||
int (*do_cipher) (EVP_CIPHER_CTX *ctx,
|
||||
unsigned char *out,
|
||||
const unsigned char *in,
|
||||
size_t inl))
|
||||
{
|
||||
cipher->do_cipher = do_cipher;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher,
|
||||
int (*cleanup) (EVP_CIPHER_CTX *))
|
||||
{
|
||||
cipher->cleanup = cleanup;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher,
|
||||
int (*set_asn1_parameters) (EVP_CIPHER_CTX *,
|
||||
ASN1_TYPE *))
|
||||
{
|
||||
cipher->set_asn1_parameters = set_asn1_parameters;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher,
|
||||
int (*get_asn1_parameters) (EVP_CIPHER_CTX *,
|
||||
ASN1_TYPE *))
|
||||
{
|
||||
cipher->get_asn1_parameters = get_asn1_parameters;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher,
|
||||
int (*ctrl) (EVP_CIPHER_CTX *, int type,
|
||||
int arg, void *ptr))
|
||||
{
|
||||
cipher->ctrl = ctrl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
|
||||
const unsigned char *key,
|
||||
const unsigned char *iv,
|
||||
int enc)
|
||||
{
|
||||
return cipher->init;
|
||||
}
|
||||
int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
|
||||
unsigned char *out,
|
||||
const unsigned char *in,
|
||||
size_t inl)
|
||||
{
|
||||
return cipher->do_cipher;
|
||||
}
|
||||
|
||||
int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *)
|
||||
{
|
||||
return cipher->cleanup;
|
||||
}
|
||||
|
||||
int (*EVP_CIPHER_meth_get_set_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
|
||||
ASN1_TYPE *)
|
||||
{
|
||||
return cipher->set_asn1_parameters;
|
||||
}
|
||||
|
||||
int (*EVP_CIPHER_meth_get_get_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
|
||||
ASN1_TYPE *)
|
||||
{
|
||||
return cipher->get_asn1_parameters;
|
||||
}
|
||||
|
||||
int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
|
||||
int type, int arg,
|
||||
void *ptr)
|
||||
{
|
||||
return cipher->ctrl;
|
||||
}
|
||||
|
298
trunk/3rdparty/openssl-1.1-fit/crypto/evp/digest.c
vendored
Normal file
298
trunk/3rdparty/openssl-1.1-fit/crypto/evp/digest.c
vendored
Normal file
|
@ -0,0 +1,298 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/engine.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
/* This call frees resources associated with the context */
|
||||
int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* 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_clear_free(ctx->md_data, ctx->digest->ctx_size);
|
||||
}
|
||||
/*
|
||||
* pctx should be freed by the user of EVP_MD_CTX
|
||||
* if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set
|
||||
*/
|
||||
if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX))
|
||||
EVP_PKEY_CTX_free(ctx->pctx);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(ctx->engine);
|
||||
#endif
|
||||
OPENSSL_cleanse(ctx, sizeof(*ctx));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
EVP_MD_CTX *EVP_MD_CTX_new(void)
|
||||
{
|
||||
return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
|
||||
}
|
||||
|
||||
void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
|
||||
{
|
||||
EVP_MD_CTX_reset(ctx);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
|
||||
{
|
||||
EVP_MD_CTX_reset(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);
|
||||
#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 unnecessary.
|
||||
*/
|
||||
if (ctx->engine && ctx->digest &&
|
||||
(type == NULL || (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).
|
||||
*/
|
||||
ENGINE_finish(ctx->engine);
|
||||
if (impl != NULL) {
|
||||
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 != NULL) {
|
||||
/* There's an ENGINE for this job ... (apparently) */
|
||||
const EVP_MD *d = ENGINE_get_digest(impl, type->type);
|
||||
|
||||
if (d == NULL) {
|
||||
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_clear_free(ctx->md_data, ctx->digest->ctx_size);
|
||||
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_zalloc(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;
|
||||
return ctx->digest->init(ctx);
|
||||
}
|
||||
|
||||
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
return ctx->update(ctx, data, count);
|
||||
}
|
||||
|
||||
/* 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_reset(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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (ctx->digest->flags & EVP_MD_FLAG_XOF
|
||||
&& size <= INT_MAX
|
||||
&& ctx->digest->md_ctrl(ctx, EVP_MD_CTRL_XOF_LEN, (int)size, NULL)) {
|
||||
ret = ctx->digest->final(ctx, md);
|
||||
|
||||
if (ctx->digest->cleanup != NULL) {
|
||||
ctx->digest->cleanup(ctx);
|
||||
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
|
||||
}
|
||||
OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
|
||||
} else {
|
||||
EVPerr(EVP_F_EVP_DIGESTFINALXOF, EVP_R_NOT_XOF_OR_INVALID_LENGTH);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
|
||||
{
|
||||
EVP_MD_CTX_reset(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_reset(out);
|
||||
memcpy(out, in, sizeof(*out));
|
||||
|
||||
/* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */
|
||||
EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
|
||||
|
||||
/* Null these variables, since they are getting fixed up
|
||||
* properly below. Anything else may cause a memleak and/or
|
||||
* double free if any of the memory allocations below fail
|
||||
*/
|
||||
out->md_data = NULL;
|
||||
out->pctx = NULL;
|
||||
|
||||
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 == NULL) {
|
||||
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_reset(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 = EVP_MD_CTX_new();
|
||||
int ret;
|
||||
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
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_free(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
|
||||
{
|
||||
if (ctx->digest && ctx->digest->md_ctrl) {
|
||||
int ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
4210
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_aes.c
vendored
Normal file
4210
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_aes.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
964
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_aes_cbc_hmac_sha1.c
vendored
Normal file
964
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_aes_cbc_hmac_sha1.c
vendored
Normal file
|
@ -0,0 +1,964 @@
|
|||
/*
|
||||
* Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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 "internal/evp_int.h"
|
||||
#include "internal/constant_time_locl.h"
|
||||
|
||||
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) )
|
||||
|
||||
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 *)EVP_CIPHER_CTX_get_cipher_data(ctx))
|
||||
|
||||
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,
|
||||
EVP_CIPHER_CTX_key_length(ctx) * 8,
|
||||
&key->ks);
|
||||
else
|
||||
ret = aesni_set_decrypt_key(inkey,
|
||||
EVP_CIPHER_CTX_key_length(ctx) * 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)
|
||||
|
||||
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 (EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
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,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
&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, EVP_CIPHER_CTX_iv_noconst(ctx), 1);
|
||||
} else {
|
||||
aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off,
|
||||
&key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 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(EVP_CIPHER_CTX_iv_noconst(ctx), 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,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx), 0);
|
||||
|
||||
/* figure out payload length */
|
||||
pad = out[len - 1];
|
||||
maxpad = len - (SHA_DIGEST_LENGTH + 1);
|
||||
maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
|
||||
maxpad &= 255;
|
||||
|
||||
mask = constant_time_ge(maxpad, pad);
|
||||
ret &= mask;
|
||||
/*
|
||||
* If pad is invalid then we will fail the above test but we must
|
||||
* continue anyway because we are in constant time code. However,
|
||||
* we'll use the maxpad value instead of the supplied pad to make
|
||||
* sure we perform well defined pointer arithmetic.
|
||||
*/
|
||||
pad = constant_time_select(mask, pad, maxpad);
|
||||
|
||||
inp_len = len - (SHA_DIGEST_LENGTH + pad + 1);
|
||||
|
||||
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 /* see original reference version in #else */
|
||||
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 /* pre-lucky-13 reference version of above */
|
||||
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 /* see original reference version in #else */
|
||||
{
|
||||
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 /* pre-lucky-13 reference version of above */
|
||||
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,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx), 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 (EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
key->payload_length = len;
|
||||
if ((key->aux.tls_ver =
|
||||
p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
|
||||
if (len < AES_BLOCK_SIZE)
|
||||
return 0;
|
||||
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)
|
||||
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 (EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
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
|
||||
AES_BLOCK_SIZE, 16, AES_BLOCK_SIZE,
|
||||
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
|
||||
AES_BLOCK_SIZE, 32, AES_BLOCK_SIZE,
|
||||
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
|
950
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_aes_cbc_hmac_sha256.c
vendored
Normal file
950
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_aes_cbc_hmac_sha256.c
vendored
Normal file
|
@ -0,0 +1,950 @@
|
|||
/*
|
||||
* Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#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 "internal/constant_time_locl.h"
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
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) )
|
||||
|
||||
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 *)EVP_CIPHER_CTX_get_cipher_data(ctx))
|
||||
|
||||
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)
|
||||
ret = aesni_set_encrypt_key(inkey,
|
||||
EVP_CIPHER_CTX_key_length(ctx) * 8,
|
||||
&key->ks);
|
||||
else
|
||||
ret = aesni_set_decrypt_key(inkey,
|
||||
EVP_CIPHER_CTX_key_length(ctx) * 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)
|
||||
|
||||
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 (EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
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.
|
||||
* But SHAEXT-capable go ahead...
|
||||
*/
|
||||
if (((OPENSSL_ia32cap_P[2] & (1 << 29)) || /* SHAEXT? */
|
||||
((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,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
&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, EVP_CIPHER_CTX_iv_noconst(ctx), 1);
|
||||
} else {
|
||||
aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off,
|
||||
&key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 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,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx), 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;
|
||||
|
||||
mask = constant_time_ge(maxpad, pad);
|
||||
ret &= mask;
|
||||
/*
|
||||
* If pad is invalid then we will fail the above test but we must
|
||||
* continue anyway because we are in constant time code. However,
|
||||
* we'll use the maxpad value instead of the supplied pad to make
|
||||
* sure we perform well defined pointer arithmetic.
|
||||
*/
|
||||
pad = constant_time_select(mask, pad, maxpad);
|
||||
|
||||
inp_len = len - (SHA256_DIGEST_LENGTH + pad + 1);
|
||||
|
||||
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 /* see original reference version in #else */
|
||||
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 /* pre-lucky-13 reference version of above */
|
||||
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 /* see original reference version in #else */
|
||||
{
|
||||
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 /* pre-lucky-13 reference version of above */
|
||||
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);
|
||||
unsigned int u_arg = (unsigned int)arg;
|
||||
|
||||
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 < 0)
|
||||
return -1;
|
||||
|
||||
if (u_arg > 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;
|
||||
|
||||
if (arg != EVP_AEAD_TLS1_AAD_LEN)
|
||||
return -1;
|
||||
|
||||
len = p[arg - 2] << 8 | p[arg - 1];
|
||||
|
||||
if (EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
key->payload_length = len;
|
||||
if ((key->aux.tls_ver =
|
||||
p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
|
||||
if (len < AES_BLOCK_SIZE)
|
||||
return 0;
|
||||
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)
|
||||
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 < 0)
|
||||
return -1;
|
||||
|
||||
if (u_arg < sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM))
|
||||
return -1;
|
||||
|
||||
inp_len = param->inp[11] << 8 | param->inp[12];
|
||||
|
||||
if (EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
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
|
||||
AES_BLOCK_SIZE, 16, AES_BLOCK_SIZE,
|
||||
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
|
||||
AES_BLOCK_SIZE, 32, AES_BLOCK_SIZE,
|
||||
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
|
756
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_aria.c
vendored
Normal file
756
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_aria.c
vendored
Normal file
|
@ -0,0 +1,756 @@
|
|||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
#ifndef OPENSSL_NO_ARIA
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/modes.h>
|
||||
# include <openssl/rand.h>
|
||||
# include <openssl/rand_drbg.h>
|
||||
# include "internal/aria.h"
|
||||
# include "internal/evp_int.h"
|
||||
# include "modes_lcl.h"
|
||||
# include "evp_locl.h"
|
||||
|
||||
/* ARIA subkey Structure */
|
||||
typedef struct {
|
||||
ARIA_KEY ks;
|
||||
} EVP_ARIA_KEY;
|
||||
|
||||
/* ARIA GCM context */
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
ARIA_KEY ks;
|
||||
} ks; /* ARIA subkey 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 */
|
||||
} EVP_ARIA_GCM_CTX;
|
||||
|
||||
/* ARIA CCM context */
|
||||
typedef struct {
|
||||
union {
|
||||
double align;
|
||||
ARIA_KEY ks;
|
||||
} ks; /* ARIA 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 */
|
||||
int tls_aad_len; /* TLS AAD length */
|
||||
CCM128_CONTEXT ccm;
|
||||
ccm128_f str;
|
||||
} EVP_ARIA_CCM_CTX;
|
||||
|
||||
/* The subkey for ARIA is generated. */
|
||||
static int aria_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
int ret;
|
||||
int mode = EVP_CIPHER_CTX_mode(ctx);
|
||||
|
||||
if (enc || (mode != EVP_CIPH_ECB_MODE && mode != EVP_CIPH_CBC_MODE))
|
||||
ret = aria_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
|
||||
EVP_CIPHER_CTX_get_cipher_data(ctx));
|
||||
else
|
||||
ret = aria_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
|
||||
EVP_CIPHER_CTX_get_cipher_data(ctx));
|
||||
if (ret < 0) {
|
||||
EVPerr(EVP_F_ARIA_INIT_KEY,EVP_R_ARIA_KEY_SETUP_FAILED);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void aria_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const ARIA_KEY *key,
|
||||
unsigned char *ivec, const int enc)
|
||||
{
|
||||
|
||||
if (enc)
|
||||
CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
|
||||
(block128_f) aria_encrypt);
|
||||
else
|
||||
CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
|
||||
(block128_f) aria_encrypt);
|
||||
}
|
||||
|
||||
static void aria_cfb128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const ARIA_KEY *key,
|
||||
unsigned char *ivec, int *num, const int enc)
|
||||
{
|
||||
|
||||
CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
|
||||
(block128_f) aria_encrypt);
|
||||
}
|
||||
|
||||
static void aria_cfb1_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const ARIA_KEY *key,
|
||||
unsigned char *ivec, int *num, const int enc)
|
||||
{
|
||||
CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc,
|
||||
(block128_f) aria_encrypt);
|
||||
}
|
||||
|
||||
static void aria_cfb8_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const ARIA_KEY *key,
|
||||
unsigned char *ivec, int *num, const int enc)
|
||||
{
|
||||
CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc,
|
||||
(block128_f) aria_encrypt);
|
||||
}
|
||||
|
||||
static void aria_ecb_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const ARIA_KEY *key, const int enc)
|
||||
{
|
||||
aria_encrypt(in, out, key);
|
||||
}
|
||||
|
||||
static void aria_ofb128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const ARIA_KEY *key,
|
||||
unsigned char *ivec, int *num)
|
||||
{
|
||||
CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
|
||||
(block128_f) aria_encrypt);
|
||||
}
|
||||
|
||||
IMPLEMENT_BLOCK_CIPHER(aria_128, ks, aria, EVP_ARIA_KEY,
|
||||
NID_aria_128, 16, 16, 16, 128,
|
||||
0, aria_init_key, NULL,
|
||||
EVP_CIPHER_set_asn1_iv,
|
||||
EVP_CIPHER_get_asn1_iv,
|
||||
NULL)
|
||||
IMPLEMENT_BLOCK_CIPHER(aria_192, ks, aria, EVP_ARIA_KEY,
|
||||
NID_aria_192, 16, 24, 16, 128,
|
||||
0, aria_init_key, NULL,
|
||||
EVP_CIPHER_set_asn1_iv,
|
||||
EVP_CIPHER_get_asn1_iv,
|
||||
NULL)
|
||||
IMPLEMENT_BLOCK_CIPHER(aria_256, ks, aria, EVP_ARIA_KEY,
|
||||
NID_aria_256, 16, 32, 16, 128,
|
||||
0, aria_init_key, NULL,
|
||||
EVP_CIPHER_set_asn1_iv,
|
||||
EVP_CIPHER_get_asn1_iv,
|
||||
NULL)
|
||||
|
||||
# define IMPLEMENT_ARIA_CFBR(ksize,cbits) \
|
||||
IMPLEMENT_CFBR(aria,aria,EVP_ARIA_KEY,ks,ksize,cbits,16,0)
|
||||
IMPLEMENT_ARIA_CFBR(128,1)
|
||||
IMPLEMENT_ARIA_CFBR(192,1)
|
||||
IMPLEMENT_ARIA_CFBR(256,1)
|
||||
IMPLEMENT_ARIA_CFBR(128,8)
|
||||
IMPLEMENT_ARIA_CFBR(192,8)
|
||||
IMPLEMENT_ARIA_CFBR(256,8)
|
||||
|
||||
# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
|
||||
static const EVP_CIPHER aria_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
|
||||
flags|EVP_CIPH_##MODE##_MODE, \
|
||||
aria_init_key, \
|
||||
aria_##mode##_cipher, \
|
||||
NULL, \
|
||||
sizeof(EVP_ARIA_KEY), \
|
||||
NULL,NULL,NULL,NULL }; \
|
||||
const EVP_CIPHER *EVP_aria_##keylen##_##mode(void) \
|
||||
{ return &aria_##keylen##_##mode; }
|
||||
|
||||
static int aria_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
unsigned int num = EVP_CIPHER_CTX_num(ctx);
|
||||
EVP_ARIA_KEY *dat = EVP_C_DATA(EVP_ARIA_KEY,ctx);
|
||||
|
||||
CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_buf_noconst(ctx), &num,
|
||||
(block128_f) aria_encrypt);
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
return 1;
|
||||
}
|
||||
|
||||
BLOCK_CIPHER_generic(NID_aria, 128, 1, 16, ctr, ctr, CTR, 0)
|
||||
BLOCK_CIPHER_generic(NID_aria, 192, 1, 16, ctr, ctr, CTR, 0)
|
||||
BLOCK_CIPHER_generic(NID_aria, 256, 1, 16, ctr, ctr, CTR, 0)
|
||||
|
||||
/* Authenticated cipher modes (GCM/CCM) */
|
||||
|
||||
/* 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 aria_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
int ret;
|
||||
EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx);
|
||||
|
||||
if (!iv && !key)
|
||||
return 1;
|
||||
if (key) {
|
||||
ret = aria_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
|
||||
&gctx->ks.ks);
|
||||
CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
|
||||
(block128_f) aria_encrypt);
|
||||
if (ret < 0) {
|
||||
EVPerr(EVP_F_ARIA_GCM_INIT_KEY,EVP_R_ARIA_KEY_SETUP_FAILED);
|
||||
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;
|
||||
}
|
||||
|
||||
static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||
{
|
||||
EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,c);
|
||||
|
||||
switch (type) {
|
||||
case EVP_CTRL_INIT:
|
||||
gctx->key_set = 0;
|
||||
gctx->iv_set = 0;
|
||||
gctx->ivlen = EVP_CIPHER_CTX_iv_length(c);
|
||||
gctx->iv = EVP_CIPHER_CTX_iv_noconst(c);
|
||||
gctx->taglen = -1;
|
||||
gctx->iv_gen = 0;
|
||||
gctx->tls_aad_len = -1;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_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 != EVP_CIPHER_CTX_iv_noconst(c))
|
||||
OPENSSL_free(gctx->iv);
|
||||
if ((gctx->iv = OPENSSL_malloc(arg)) == NULL) {
|
||||
EVPerr(EVP_F_ARIA_GCM_CTRL, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
gctx->ivlen = arg;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_SET_TAG:
|
||||
if (arg <= 0 || arg > 16 || EVP_CIPHER_CTX_encrypting(c))
|
||||
return 0;
|
||||
memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
|
||||
gctx->taglen = arg;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_GET_TAG:
|
||||
if (arg <= 0 || arg > 16 || !EVP_CIPHER_CTX_encrypting(c)
|
||||
|| gctx->taglen < 0)
|
||||
return 0;
|
||||
memcpy(ptr, EVP_CIPHER_CTX_buf_noconst(c), 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 (EVP_CIPHER_CTX_encrypting(c)
|
||||
&& 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
|
||||
|| EVP_CIPHER_CTX_encrypting(c))
|
||||
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(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
|
||||
gctx->tls_aad_len = arg;
|
||||
{
|
||||
unsigned int len =
|
||||
EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8
|
||||
| EVP_CIPHER_CTX_buf_noconst(c)[arg - 1];
|
||||
/* Correct length for explicit IV */
|
||||
if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN)
|
||||
return 0;
|
||||
len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
|
||||
/* If decrypting correct for tag too */
|
||||
if (!EVP_CIPHER_CTX_encrypting(c)) {
|
||||
if (len < EVP_GCM_TLS_TAG_LEN)
|
||||
return 0;
|
||||
len -= EVP_GCM_TLS_TAG_LEN;
|
||||
}
|
||||
EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8;
|
||||
EVP_CIPHER_CTX_buf_noconst(c)[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_ARIA_GCM_CTX *gctx_out = EVP_C_DATA(EVP_ARIA_GCM_CTX,out);
|
||||
if (gctx->gcm.key) {
|
||||
if (gctx->gcm.key != &gctx->ks)
|
||||
return 0;
|
||||
gctx_out->gcm.key = &gctx_out->ks;
|
||||
}
|
||||
if (gctx->iv == EVP_CIPHER_CTX_iv_noconst(c))
|
||||
gctx_out->iv = EVP_CIPHER_CTX_iv_noconst(out);
|
||||
else {
|
||||
if ((gctx_out->iv = OPENSSL_malloc(gctx->ivlen)) == NULL) {
|
||||
EVPerr(EVP_F_ARIA_GCM_CTRL, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
default:
|
||||
return -1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int aria_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx);
|
||||
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, EVP_CIPHER_CTX_encrypting(ctx) ?
|
||||
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, EVP_CIPHER_CTX_buf_noconst(ctx),
|
||||
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 (EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
/* Encrypt payload */
|
||||
if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
|
||||
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 (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
|
||||
goto err;
|
||||
/* Retrieve tag */
|
||||
CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx),
|
||||
EVP_GCM_TLS_TAG_LEN);
|
||||
/* If tag mismatch wipe buffer */
|
||||
if (CRYPTO_memcmp(EVP_CIPHER_CTX_buf_noconst(ctx), 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 aria_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx);
|
||||
|
||||
/* If not set up, return error */
|
||||
if (!gctx->key_set)
|
||||
return -1;
|
||||
|
||||
if (gctx->tls_aad_len >= 0)
|
||||
return aria_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 (EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
|
||||
return -1;
|
||||
} else {
|
||||
if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
|
||||
return -1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
if (!EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
if (gctx->taglen < 0)
|
||||
return -1;
|
||||
if (CRYPTO_gcm128_finish(&gctx->gcm,
|
||||
EVP_CIPHER_CTX_buf_noconst(ctx),
|
||||
gctx->taglen) != 0)
|
||||
return -1;
|
||||
gctx->iv_set = 0;
|
||||
return 0;
|
||||
}
|
||||
CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), 16);
|
||||
gctx->taglen = 16;
|
||||
/* Don't reuse the IV */
|
||||
gctx->iv_set = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aria_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
int ret;
|
||||
EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,ctx);
|
||||
|
||||
if (!iv && !key)
|
||||
return 1;
|
||||
|
||||
if (key) {
|
||||
ret = aria_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
|
||||
&cctx->ks.ks);
|
||||
CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
|
||||
&cctx->ks, (block128_f) aria_encrypt);
|
||||
if (ret < 0) {
|
||||
EVPerr(EVP_F_ARIA_CCM_INIT_KEY,EVP_R_ARIA_KEY_SETUP_FAILED);
|
||||
return 0;
|
||||
}
|
||||
cctx->str = NULL;
|
||||
cctx->key_set = 1;
|
||||
}
|
||||
if (iv) {
|
||||
memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L);
|
||||
cctx->iv_set = 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||
{
|
||||
EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,c);
|
||||
|
||||
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;
|
||||
cctx->tls_aad_len = -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(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
|
||||
cctx->tls_aad_len = arg;
|
||||
{
|
||||
uint16_t len =
|
||||
EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8
|
||||
| EVP_CIPHER_CTX_buf_noconst(c)[arg - 1];
|
||||
/* Correct length for explicit IV */
|
||||
if (len < EVP_CCM_TLS_EXPLICIT_IV_LEN)
|
||||
return 0;
|
||||
len -= EVP_CCM_TLS_EXPLICIT_IV_LEN;
|
||||
/* If decrypting correct for tag too */
|
||||
if (!EVP_CIPHER_CTX_encrypting(c)) {
|
||||
if (len < cctx->M)
|
||||
return 0;
|
||||
len -= cctx->M;
|
||||
}
|
||||
EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8;
|
||||
EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff;
|
||||
}
|
||||
/* Extra padding: tag appended to record */
|
||||
return cctx->M;
|
||||
|
||||
case EVP_CTRL_CCM_SET_IV_FIXED:
|
||||
/* Sanity check length */
|
||||
if (arg != EVP_CCM_TLS_FIXED_IV_LEN)
|
||||
return 0;
|
||||
/* Just copy to first part of IV */
|
||||
memcpy(EVP_CIPHER_CTX_iv_noconst(c), ptr, arg);
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_SET_IVLEN:
|
||||
arg = 15 - arg;
|
||||
/* fall thru */
|
||||
case EVP_CTRL_CCM_SET_L:
|
||||
if (arg < 2 || arg > 8)
|
||||
return 0;
|
||||
cctx->L = arg;
|
||||
return 1;
|
||||
case EVP_CTRL_AEAD_SET_TAG:
|
||||
if ((arg & 1) || arg < 4 || arg > 16)
|
||||
return 0;
|
||||
if (EVP_CIPHER_CTX_encrypting(c) && ptr)
|
||||
return 0;
|
||||
if (ptr) {
|
||||
cctx->tag_set = 1;
|
||||
memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
|
||||
}
|
||||
cctx->M = arg;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_GET_TAG:
|
||||
if (!EVP_CIPHER_CTX_encrypting(c) || !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_ARIA_CCM_CTX *cctx_out = EVP_C_DATA(EVP_ARIA_CCM_CTX,out);
|
||||
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 aria_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,ctx);
|
||||
CCM128_CONTEXT *ccm = &cctx->ccm;
|
||||
|
||||
/* Encrypt/decrypt must be performed in place */
|
||||
if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->M))
|
||||
return -1;
|
||||
/* If encrypting set explicit IV from sequence number (start of AAD) */
|
||||
if (EVP_CIPHER_CTX_encrypting(ctx))
|
||||
memcpy(out, EVP_CIPHER_CTX_buf_noconst(ctx),
|
||||
EVP_CCM_TLS_EXPLICIT_IV_LEN);
|
||||
/* Get rest of IV from explicit IV */
|
||||
memcpy(EVP_CIPHER_CTX_iv_noconst(ctx) + EVP_CCM_TLS_FIXED_IV_LEN, in,
|
||||
EVP_CCM_TLS_EXPLICIT_IV_LEN);
|
||||
/* Correct length value */
|
||||
len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M;
|
||||
if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), 15 - cctx->L,
|
||||
len))
|
||||
return -1;
|
||||
/* Use saved AAD */
|
||||
CRYPTO_ccm128_aad(ccm, EVP_CIPHER_CTX_buf_noconst(ctx), cctx->tls_aad_len);
|
||||
/* Fix buffer to point to payload */
|
||||
in += EVP_CCM_TLS_EXPLICIT_IV_LEN;
|
||||
out += EVP_CCM_TLS_EXPLICIT_IV_LEN;
|
||||
if (EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str)
|
||||
: CRYPTO_ccm128_encrypt(ccm, in, out, len))
|
||||
return -1;
|
||||
if (!CRYPTO_ccm128_tag(ccm, out + len, cctx->M))
|
||||
return -1;
|
||||
return len + EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M;
|
||||
} else {
|
||||
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, in + len, cctx->M))
|
||||
return len;
|
||||
}
|
||||
}
|
||||
OPENSSL_cleanse(out, len);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,ctx);
|
||||
CCM128_CONTEXT *ccm = &cctx->ccm;
|
||||
|
||||
/* If not set up, return error */
|
||||
if (!cctx->key_set)
|
||||
return -1;
|
||||
|
||||
if (cctx->tls_aad_len >= 0)
|
||||
return aria_ccm_tls_cipher(ctx, out, in, len);
|
||||
|
||||
/* EVP_*Final() doesn't return any data */
|
||||
if (in == NULL && out != NULL)
|
||||
return 0;
|
||||
|
||||
if (!cctx->iv_set)
|
||||
return -1;
|
||||
|
||||
if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set)
|
||||
return -1;
|
||||
if (!out) {
|
||||
if (!in) {
|
||||
if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
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;
|
||||
}
|
||||
/* If not set length yet do it */
|
||||
if (!cctx->len_set) {
|
||||
if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
15 - cctx->L, len))
|
||||
return -1;
|
||||
cctx->len_set = 1;
|
||||
}
|
||||
if (EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
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, EVP_CIPHER_CTX_buf_noconst(ctx),
|
||||
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 ARIA_AUTH_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 | EVP_CIPH_FLAG_AEAD_CIPHER)
|
||||
|
||||
#define BLOCK_CIPHER_aead(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
|
||||
static const EVP_CIPHER aria_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##nmode, \
|
||||
blocksize, keylen/8, ivlen, \
|
||||
ARIA_AUTH_FLAGS|EVP_CIPH_##MODE##_MODE, \
|
||||
aria_##mode##_init_key, \
|
||||
aria_##mode##_cipher, \
|
||||
NULL, \
|
||||
sizeof(EVP_ARIA_##MODE##_CTX), \
|
||||
NULL,NULL,aria_##mode##_ctrl,NULL }; \
|
||||
const EVP_CIPHER *EVP_aria_##keylen##_##mode(void) \
|
||||
{ return (EVP_CIPHER*)&aria_##keylen##_##mode; }
|
||||
|
||||
BLOCK_CIPHER_aead(NID_aria, 128, 1, 12, gcm, gcm, GCM, 0)
|
||||
BLOCK_CIPHER_aead(NID_aria, 192, 1, 12, gcm, gcm, GCM, 0)
|
||||
BLOCK_CIPHER_aead(NID_aria, 256, 1, 12, gcm, gcm, GCM, 0)
|
||||
|
||||
BLOCK_CIPHER_aead(NID_aria, 128, 1, 12, ccm, ccm, CCM, 0)
|
||||
BLOCK_CIPHER_aead(NID_aria, 192, 1, 12, ccm, ccm, CCM, 0)
|
||||
BLOCK_CIPHER_aead(NID_aria, 256, 1, 12, ccm, ccm, CCM, 0)
|
||||
|
||||
#endif
|
38
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_bf.c
vendored
Normal file
38
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_bf.c
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#ifndef OPENSSL_NO_BF
|
||||
# include <openssl/evp.h>
|
||||
# include "internal/evp_int.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
|
366
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_camellia.c
vendored
Normal file
366
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_camellia.c
vendored
Normal file
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_CAMELLIA
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/err.h>
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
# include <openssl/camellia.h>
|
||||
# include "internal/evp_int.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 *)EVP_CIPHER_CTX_get_cipher_data(ctx);
|
||||
|
||||
mode = EVP_CIPHER_CTX_mode(ctx);
|
||||
bits = EVP_CIPHER_CTX_key_length(ctx) * 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) \
|
||||
BLOCK_CIPHER_generic(nid, keylen, 1, 16, ctr, ctr, CTR, flags)
|
||||
|
||||
/* 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_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
||||
|
||||
ret = Camellia_set_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, &dat->ks);
|
||||
if (ret < 0) {
|
||||
EVPerr(EVP_F_CAMELLIA_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mode = EVP_CIPHER_CTX_mode(ctx);
|
||||
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_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
||||
|
||||
if (dat->stream.cbc)
|
||||
(*dat->stream.cbc) (in, out, len, &dat->ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
else if (EVP_CIPHER_CTX_encrypting(ctx))
|
||||
CRYPTO_cbc128_encrypt(in, out, len, &dat->ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx), dat->block);
|
||||
else
|
||||
CRYPTO_cbc128_decrypt(in, out, len, &dat->ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx), 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 = EVP_CIPHER_CTX_block_size(ctx);
|
||||
size_t i;
|
||||
EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
||||
|
||||
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_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
||||
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
CRYPTO_ofb128_encrypt(in, out, len, &dat->ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx), &num, dat->block);
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
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_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
||||
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
CRYPTO_cfb128_encrypt(in, out, len, &dat->ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
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_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
||||
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
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_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
||||
|
||||
if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) {
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (len >= MAXBITCHUNK) {
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
len -= MAXBITCHUNK;
|
||||
out += MAXBITCHUNK;
|
||||
in += MAXBITCHUNK;
|
||||
}
|
||||
if (len) {
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
unsigned int num = EVP_CIPHER_CTX_num(ctx);
|
||||
EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
|
||||
|
||||
if (dat->stream.ctr)
|
||||
CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_buf_noconst(ctx), &num,
|
||||
dat->stream.ctr);
|
||||
else
|
||||
CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_buf_noconst(ctx), &num,
|
||||
dat->block);
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
return 1;
|
||||
}
|
||||
|
||||
BLOCK_CIPHER_generic_pack(NID_camellia, 128, 0)
|
||||
BLOCK_CIPHER_generic_pack(NID_camellia, 192, 0)
|
||||
BLOCK_CIPHER_generic_pack(NID_camellia, 256, 0)
|
||||
#endif
|
40
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_cast.c
vendored
Normal file
40
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_cast.c
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#ifndef OPENSSL_NO_CAST
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include "internal/evp_int.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
|
630
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_chacha20_poly1305.c
vendored
Normal file
630
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_chacha20_poly1305.c
vendored
Normal file
|
@ -0,0 +1,630 @@
|
|||
/*
|
||||
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#ifndef OPENSSL_NO_CHACHA
|
||||
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include "evp_locl.h"
|
||||
# include "internal/evp_int.h"
|
||||
# include "internal/chacha.h"
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double align; /* this ensures even sizeof(EVP_CHACHA_KEY)%8==0 */
|
||||
unsigned int d[CHACHA_KEY_SIZE / 4];
|
||||
} key;
|
||||
unsigned int counter[CHACHA_CTR_SIZE / 4];
|
||||
unsigned char buf[CHACHA_BLK_SIZE];
|
||||
unsigned int partial_len;
|
||||
} EVP_CHACHA_KEY;
|
||||
|
||||
#define data(ctx) ((EVP_CHACHA_KEY *)(ctx)->cipher_data)
|
||||
|
||||
static int chacha_init_key(EVP_CIPHER_CTX *ctx,
|
||||
const unsigned char user_key[CHACHA_KEY_SIZE],
|
||||
const unsigned char iv[CHACHA_CTR_SIZE], int enc)
|
||||
{
|
||||
EVP_CHACHA_KEY *key = data(ctx);
|
||||
unsigned int i;
|
||||
|
||||
if (user_key)
|
||||
for (i = 0; i < CHACHA_KEY_SIZE; i+=4) {
|
||||
key->key.d[i/4] = CHACHA_U8TOU32(user_key+i);
|
||||
}
|
||||
|
||||
if (iv)
|
||||
for (i = 0; i < CHACHA_CTR_SIZE; i+=4) {
|
||||
key->counter[i/4] = CHACHA_U8TOU32(iv+i);
|
||||
}
|
||||
|
||||
key->partial_len = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int chacha_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out,
|
||||
const unsigned char *inp, size_t len)
|
||||
{
|
||||
EVP_CHACHA_KEY *key = data(ctx);
|
||||
unsigned int n, rem, ctr32;
|
||||
|
||||
if ((n = key->partial_len)) {
|
||||
while (len && n < CHACHA_BLK_SIZE) {
|
||||
*out++ = *inp++ ^ key->buf[n++];
|
||||
len--;
|
||||
}
|
||||
key->partial_len = n;
|
||||
|
||||
if (len == 0)
|
||||
return 1;
|
||||
|
||||
if (n == CHACHA_BLK_SIZE) {
|
||||
key->partial_len = 0;
|
||||
key->counter[0]++;
|
||||
if (key->counter[0] == 0)
|
||||
key->counter[1]++;
|
||||
}
|
||||
}
|
||||
|
||||
rem = (unsigned int)(len % CHACHA_BLK_SIZE);
|
||||
len -= rem;
|
||||
ctr32 = key->counter[0];
|
||||
while (len >= CHACHA_BLK_SIZE) {
|
||||
size_t blocks = len / CHACHA_BLK_SIZE;
|
||||
/*
|
||||
* 1<<28 is just a not-so-small yet not-so-large number...
|
||||
* Below condition is practically never met, but it has to
|
||||
* be checked for code correctness.
|
||||
*/
|
||||
if (sizeof(size_t)>sizeof(unsigned int) && blocks>(1U<<28))
|
||||
blocks = (1U<<28);
|
||||
|
||||
/*
|
||||
* As ChaCha20_ctr32 operates on 32-bit counter, caller
|
||||
* has to handle overflow. 'if' below detects the
|
||||
* overflow, which is then handled by limiting the
|
||||
* amount of blocks to the exact overflow point...
|
||||
*/
|
||||
ctr32 += (unsigned int)blocks;
|
||||
if (ctr32 < blocks) {
|
||||
blocks -= ctr32;
|
||||
ctr32 = 0;
|
||||
}
|
||||
blocks *= CHACHA_BLK_SIZE;
|
||||
ChaCha20_ctr32(out, inp, blocks, key->key.d, key->counter);
|
||||
len -= blocks;
|
||||
inp += blocks;
|
||||
out += blocks;
|
||||
|
||||
key->counter[0] = ctr32;
|
||||
if (ctr32 == 0) key->counter[1]++;
|
||||
}
|
||||
|
||||
if (rem) {
|
||||
memset(key->buf, 0, sizeof(key->buf));
|
||||
ChaCha20_ctr32(key->buf, key->buf, CHACHA_BLK_SIZE,
|
||||
key->key.d, key->counter);
|
||||
for (n = 0; n < rem; n++)
|
||||
out[n] = inp[n] ^ key->buf[n];
|
||||
key->partial_len = rem;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const EVP_CIPHER chacha20 = {
|
||||
NID_chacha20,
|
||||
1, /* block_size */
|
||||
CHACHA_KEY_SIZE, /* key_len */
|
||||
CHACHA_CTR_SIZE, /* iv_len, 128-bit counter in the context */
|
||||
EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT,
|
||||
chacha_init_key,
|
||||
chacha_cipher,
|
||||
NULL,
|
||||
sizeof(EVP_CHACHA_KEY),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const EVP_CIPHER *EVP_chacha20(void)
|
||||
{
|
||||
return &chacha20;
|
||||
}
|
||||
|
||||
# ifndef OPENSSL_NO_POLY1305
|
||||
# include "internal/poly1305.h"
|
||||
|
||||
typedef struct {
|
||||
EVP_CHACHA_KEY key;
|
||||
unsigned int nonce[12/4];
|
||||
unsigned char tag[POLY1305_BLOCK_SIZE];
|
||||
unsigned char tls_aad[POLY1305_BLOCK_SIZE];
|
||||
struct { uint64_t aad, text; } len;
|
||||
int aad, mac_inited, tag_len, nonce_len;
|
||||
size_t tls_payload_length;
|
||||
} EVP_CHACHA_AEAD_CTX;
|
||||
|
||||
# define NO_TLS_PAYLOAD_LENGTH ((size_t)-1)
|
||||
# define aead_data(ctx) ((EVP_CHACHA_AEAD_CTX *)(ctx)->cipher_data)
|
||||
# define POLY1305_ctx(actx) ((POLY1305 *)(actx + 1))
|
||||
|
||||
static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx,
|
||||
const unsigned char *inkey,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
|
||||
|
||||
if (!inkey && !iv)
|
||||
return 1;
|
||||
|
||||
actx->len.aad = 0;
|
||||
actx->len.text = 0;
|
||||
actx->aad = 0;
|
||||
actx->mac_inited = 0;
|
||||
actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
|
||||
|
||||
if (iv != NULL) {
|
||||
unsigned char temp[CHACHA_CTR_SIZE] = { 0 };
|
||||
|
||||
/* pad on the left */
|
||||
if (actx->nonce_len <= CHACHA_CTR_SIZE)
|
||||
memcpy(temp + CHACHA_CTR_SIZE - actx->nonce_len, iv,
|
||||
actx->nonce_len);
|
||||
|
||||
chacha_init_key(ctx, inkey, temp, enc);
|
||||
|
||||
actx->nonce[0] = actx->key.counter[1];
|
||||
actx->nonce[1] = actx->key.counter[2];
|
||||
actx->nonce[2] = actx->key.counter[3];
|
||||
} else {
|
||||
chacha_init_key(ctx, inkey, NULL, enc);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# if !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
|
||||
# if defined(POLY1305_ASM) && (defined(__x86_64) || defined(__x86_64__) || \
|
||||
defined(_M_AMD64) || defined(_M_X64))
|
||||
# define XOR128_HELPERS
|
||||
void *xor128_encrypt_n_pad(void *out, const void *inp, void *otp, size_t len);
|
||||
void *xor128_decrypt_n_pad(void *out, const void *inp, void *otp, size_t len);
|
||||
static const unsigned char zero[4 * CHACHA_BLK_SIZE] = { 0 };
|
||||
# else
|
||||
static const unsigned char zero[2 * CHACHA_BLK_SIZE] = { 0 };
|
||||
# endif
|
||||
|
||||
static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
|
||||
size_t tail, tohash_len, buf_len, plen = actx->tls_payload_length;
|
||||
unsigned char *buf, *tohash, *ctr, storage[sizeof(zero) + 32];
|
||||
|
||||
if (len != plen + POLY1305_BLOCK_SIZE)
|
||||
return -1;
|
||||
|
||||
buf = storage + ((0 - (size_t)storage) & 15); /* align */
|
||||
ctr = buf + CHACHA_BLK_SIZE;
|
||||
tohash = buf + CHACHA_BLK_SIZE - POLY1305_BLOCK_SIZE;
|
||||
|
||||
# ifdef XOR128_HELPERS
|
||||
if (plen <= 3 * CHACHA_BLK_SIZE) {
|
||||
actx->key.counter[0] = 0;
|
||||
buf_len = (plen + 2 * CHACHA_BLK_SIZE - 1) & (0 - CHACHA_BLK_SIZE);
|
||||
ChaCha20_ctr32(buf, zero, buf_len, actx->key.key.d,
|
||||
actx->key.counter);
|
||||
Poly1305_Init(POLY1305_ctx(actx), buf);
|
||||
actx->key.partial_len = 0;
|
||||
memcpy(tohash, actx->tls_aad, POLY1305_BLOCK_SIZE);
|
||||
tohash_len = POLY1305_BLOCK_SIZE;
|
||||
actx->len.aad = EVP_AEAD_TLS1_AAD_LEN;
|
||||
actx->len.text = plen;
|
||||
|
||||
if (plen) {
|
||||
if (ctx->encrypt)
|
||||
ctr = xor128_encrypt_n_pad(out, in, ctr, plen);
|
||||
else
|
||||
ctr = xor128_decrypt_n_pad(out, in, ctr, plen);
|
||||
|
||||
in += plen;
|
||||
out += plen;
|
||||
tohash_len = (size_t)(ctr - tohash);
|
||||
}
|
||||
}
|
||||
# else
|
||||
if (plen <= CHACHA_BLK_SIZE) {
|
||||
size_t i;
|
||||
|
||||
actx->key.counter[0] = 0;
|
||||
ChaCha20_ctr32(buf, zero, (buf_len = 2 * CHACHA_BLK_SIZE),
|
||||
actx->key.key.d, actx->key.counter);
|
||||
Poly1305_Init(POLY1305_ctx(actx), buf);
|
||||
actx->key.partial_len = 0;
|
||||
memcpy(tohash, actx->tls_aad, POLY1305_BLOCK_SIZE);
|
||||
tohash_len = POLY1305_BLOCK_SIZE;
|
||||
actx->len.aad = EVP_AEAD_TLS1_AAD_LEN;
|
||||
actx->len.text = plen;
|
||||
|
||||
if (ctx->encrypt) {
|
||||
for (i = 0; i < plen; i++) {
|
||||
out[i] = ctr[i] ^= in[i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < plen; i++) {
|
||||
unsigned char c = in[i];
|
||||
out[i] = ctr[i] ^ c;
|
||||
ctr[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
in += i;
|
||||
out += i;
|
||||
|
||||
tail = (0 - i) & (POLY1305_BLOCK_SIZE - 1);
|
||||
memset(ctr + i, 0, tail);
|
||||
ctr += i + tail;
|
||||
tohash_len += i + tail;
|
||||
}
|
||||
# endif
|
||||
else {
|
||||
actx->key.counter[0] = 0;
|
||||
ChaCha20_ctr32(buf, zero, (buf_len = CHACHA_BLK_SIZE),
|
||||
actx->key.key.d, actx->key.counter);
|
||||
Poly1305_Init(POLY1305_ctx(actx), buf);
|
||||
actx->key.counter[0] = 1;
|
||||
actx->key.partial_len = 0;
|
||||
Poly1305_Update(POLY1305_ctx(actx), actx->tls_aad, POLY1305_BLOCK_SIZE);
|
||||
tohash = ctr;
|
||||
tohash_len = 0;
|
||||
actx->len.aad = EVP_AEAD_TLS1_AAD_LEN;
|
||||
actx->len.text = plen;
|
||||
|
||||
if (ctx->encrypt) {
|
||||
ChaCha20_ctr32(out, in, plen, actx->key.key.d, actx->key.counter);
|
||||
Poly1305_Update(POLY1305_ctx(actx), out, plen);
|
||||
} else {
|
||||
Poly1305_Update(POLY1305_ctx(actx), in, plen);
|
||||
ChaCha20_ctr32(out, in, plen, actx->key.key.d, actx->key.counter);
|
||||
}
|
||||
|
||||
in += plen;
|
||||
out += plen;
|
||||
tail = (0 - plen) & (POLY1305_BLOCK_SIZE - 1);
|
||||
Poly1305_Update(POLY1305_ctx(actx), zero, tail);
|
||||
}
|
||||
|
||||
{
|
||||
const union {
|
||||
long one;
|
||||
char little;
|
||||
} is_endian = { 1 };
|
||||
|
||||
if (is_endian.little) {
|
||||
memcpy(ctr, (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE);
|
||||
} else {
|
||||
ctr[0] = (unsigned char)(actx->len.aad);
|
||||
ctr[1] = (unsigned char)(actx->len.aad>>8);
|
||||
ctr[2] = (unsigned char)(actx->len.aad>>16);
|
||||
ctr[3] = (unsigned char)(actx->len.aad>>24);
|
||||
ctr[4] = (unsigned char)(actx->len.aad>>32);
|
||||
ctr[5] = (unsigned char)(actx->len.aad>>40);
|
||||
ctr[6] = (unsigned char)(actx->len.aad>>48);
|
||||
ctr[7] = (unsigned char)(actx->len.aad>>56);
|
||||
|
||||
ctr[8] = (unsigned char)(actx->len.text);
|
||||
ctr[9] = (unsigned char)(actx->len.text>>8);
|
||||
ctr[10] = (unsigned char)(actx->len.text>>16);
|
||||
ctr[11] = (unsigned char)(actx->len.text>>24);
|
||||
ctr[12] = (unsigned char)(actx->len.text>>32);
|
||||
ctr[13] = (unsigned char)(actx->len.text>>40);
|
||||
ctr[14] = (unsigned char)(actx->len.text>>48);
|
||||
ctr[15] = (unsigned char)(actx->len.text>>56);
|
||||
}
|
||||
tohash_len += POLY1305_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
Poly1305_Update(POLY1305_ctx(actx), tohash, tohash_len);
|
||||
OPENSSL_cleanse(buf, buf_len);
|
||||
Poly1305_Final(POLY1305_ctx(actx), ctx->encrypt ? actx->tag
|
||||
: tohash);
|
||||
|
||||
actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
|
||||
|
||||
if (ctx->encrypt) {
|
||||
memcpy(out, actx->tag, POLY1305_BLOCK_SIZE);
|
||||
} else {
|
||||
if (CRYPTO_memcmp(tohash, in, POLY1305_BLOCK_SIZE)) {
|
||||
memset(out - (len - POLY1305_BLOCK_SIZE), 0,
|
||||
len - POLY1305_BLOCK_SIZE);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
# else
|
||||
static const unsigned char zero[CHACHA_BLK_SIZE] = { 0 };
|
||||
# endif
|
||||
|
||||
static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
|
||||
size_t rem, plen = actx->tls_payload_length;
|
||||
|
||||
if (!actx->mac_inited) {
|
||||
# if !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
if (plen != NO_TLS_PAYLOAD_LENGTH && out != NULL)
|
||||
return chacha20_poly1305_tls_cipher(ctx, out, in, len);
|
||||
# endif
|
||||
actx->key.counter[0] = 0;
|
||||
ChaCha20_ctr32(actx->key.buf, zero, CHACHA_BLK_SIZE,
|
||||
actx->key.key.d, actx->key.counter);
|
||||
Poly1305_Init(POLY1305_ctx(actx), actx->key.buf);
|
||||
actx->key.counter[0] = 1;
|
||||
actx->key.partial_len = 0;
|
||||
actx->len.aad = actx->len.text = 0;
|
||||
actx->mac_inited = 1;
|
||||
if (plen != NO_TLS_PAYLOAD_LENGTH) {
|
||||
Poly1305_Update(POLY1305_ctx(actx), actx->tls_aad,
|
||||
EVP_AEAD_TLS1_AAD_LEN);
|
||||
actx->len.aad = EVP_AEAD_TLS1_AAD_LEN;
|
||||
actx->aad = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (in) { /* aad or text */
|
||||
if (out == NULL) { /* aad */
|
||||
Poly1305_Update(POLY1305_ctx(actx), in, len);
|
||||
actx->len.aad += len;
|
||||
actx->aad = 1;
|
||||
return len;
|
||||
} else { /* plain- or ciphertext */
|
||||
if (actx->aad) { /* wrap up aad */
|
||||
if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE))
|
||||
Poly1305_Update(POLY1305_ctx(actx), zero,
|
||||
POLY1305_BLOCK_SIZE - rem);
|
||||
actx->aad = 0;
|
||||
}
|
||||
|
||||
actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
|
||||
if (plen == NO_TLS_PAYLOAD_LENGTH)
|
||||
plen = len;
|
||||
else if (len != plen + POLY1305_BLOCK_SIZE)
|
||||
return -1;
|
||||
|
||||
if (ctx->encrypt) { /* plaintext */
|
||||
chacha_cipher(ctx, out, in, plen);
|
||||
Poly1305_Update(POLY1305_ctx(actx), out, plen);
|
||||
in += plen;
|
||||
out += plen;
|
||||
actx->len.text += plen;
|
||||
} else { /* ciphertext */
|
||||
Poly1305_Update(POLY1305_ctx(actx), in, plen);
|
||||
chacha_cipher(ctx, out, in, plen);
|
||||
in += plen;
|
||||
out += plen;
|
||||
actx->len.text += plen;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (in == NULL /* explicit final */
|
||||
|| plen != len) { /* or tls mode */
|
||||
const union {
|
||||
long one;
|
||||
char little;
|
||||
} is_endian = { 1 };
|
||||
unsigned char temp[POLY1305_BLOCK_SIZE];
|
||||
|
||||
if (actx->aad) { /* wrap up aad */
|
||||
if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE))
|
||||
Poly1305_Update(POLY1305_ctx(actx), zero,
|
||||
POLY1305_BLOCK_SIZE - rem);
|
||||
actx->aad = 0;
|
||||
}
|
||||
|
||||
if ((rem = (size_t)actx->len.text % POLY1305_BLOCK_SIZE))
|
||||
Poly1305_Update(POLY1305_ctx(actx), zero,
|
||||
POLY1305_BLOCK_SIZE - rem);
|
||||
|
||||
if (is_endian.little) {
|
||||
Poly1305_Update(POLY1305_ctx(actx),
|
||||
(unsigned char *)&actx->len, POLY1305_BLOCK_SIZE);
|
||||
} else {
|
||||
temp[0] = (unsigned char)(actx->len.aad);
|
||||
temp[1] = (unsigned char)(actx->len.aad>>8);
|
||||
temp[2] = (unsigned char)(actx->len.aad>>16);
|
||||
temp[3] = (unsigned char)(actx->len.aad>>24);
|
||||
temp[4] = (unsigned char)(actx->len.aad>>32);
|
||||
temp[5] = (unsigned char)(actx->len.aad>>40);
|
||||
temp[6] = (unsigned char)(actx->len.aad>>48);
|
||||
temp[7] = (unsigned char)(actx->len.aad>>56);
|
||||
|
||||
temp[8] = (unsigned char)(actx->len.text);
|
||||
temp[9] = (unsigned char)(actx->len.text>>8);
|
||||
temp[10] = (unsigned char)(actx->len.text>>16);
|
||||
temp[11] = (unsigned char)(actx->len.text>>24);
|
||||
temp[12] = (unsigned char)(actx->len.text>>32);
|
||||
temp[13] = (unsigned char)(actx->len.text>>40);
|
||||
temp[14] = (unsigned char)(actx->len.text>>48);
|
||||
temp[15] = (unsigned char)(actx->len.text>>56);
|
||||
|
||||
Poly1305_Update(POLY1305_ctx(actx), temp, POLY1305_BLOCK_SIZE);
|
||||
}
|
||||
Poly1305_Final(POLY1305_ctx(actx), ctx->encrypt ? actx->tag
|
||||
: temp);
|
||||
actx->mac_inited = 0;
|
||||
|
||||
if (in != NULL && len != plen) { /* tls mode */
|
||||
if (ctx->encrypt) {
|
||||
memcpy(out, actx->tag, POLY1305_BLOCK_SIZE);
|
||||
} else {
|
||||
if (CRYPTO_memcmp(temp, in, POLY1305_BLOCK_SIZE)) {
|
||||
memset(out - plen, 0, plen);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!ctx->encrypt) {
|
||||
if (CRYPTO_memcmp(temp, actx->tag, actx->tag_len))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static int chacha20_poly1305_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
|
||||
if (actx)
|
||||
OPENSSL_cleanse(ctx->cipher_data, sizeof(*actx) + Poly1305_ctx_size());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
|
||||
void *ptr)
|
||||
{
|
||||
EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
|
||||
|
||||
switch(type) {
|
||||
case EVP_CTRL_INIT:
|
||||
if (actx == NULL)
|
||||
actx = ctx->cipher_data
|
||||
= OPENSSL_zalloc(sizeof(*actx) + Poly1305_ctx_size());
|
||||
if (actx == NULL) {
|
||||
EVPerr(EVP_F_CHACHA20_POLY1305_CTRL, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
actx->len.aad = 0;
|
||||
actx->len.text = 0;
|
||||
actx->aad = 0;
|
||||
actx->mac_inited = 0;
|
||||
actx->tag_len = 0;
|
||||
actx->nonce_len = 12;
|
||||
actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
|
||||
memset(actx->tls_aad, 0, POLY1305_BLOCK_SIZE);
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_COPY:
|
||||
if (actx) {
|
||||
EVP_CIPHER_CTX *dst = (EVP_CIPHER_CTX *)ptr;
|
||||
|
||||
dst->cipher_data =
|
||||
OPENSSL_memdup(actx, sizeof(*actx) + Poly1305_ctx_size());
|
||||
if (dst->cipher_data == NULL) {
|
||||
EVPerr(EVP_F_CHACHA20_POLY1305_CTRL, EVP_R_COPY_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_SET_IVLEN:
|
||||
if (arg <= 0 || arg > CHACHA_CTR_SIZE)
|
||||
return 0;
|
||||
actx->nonce_len = arg;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_SET_IV_FIXED:
|
||||
if (arg != 12)
|
||||
return 0;
|
||||
actx->nonce[0] = actx->key.counter[1]
|
||||
= CHACHA_U8TOU32((unsigned char *)ptr);
|
||||
actx->nonce[1] = actx->key.counter[2]
|
||||
= CHACHA_U8TOU32((unsigned char *)ptr+4);
|
||||
actx->nonce[2] = actx->key.counter[3]
|
||||
= CHACHA_U8TOU32((unsigned char *)ptr+8);
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_SET_TAG:
|
||||
if (arg <= 0 || arg > POLY1305_BLOCK_SIZE)
|
||||
return 0;
|
||||
if (ptr != NULL) {
|
||||
memcpy(actx->tag, ptr, arg);
|
||||
actx->tag_len = arg;
|
||||
}
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_GET_TAG:
|
||||
if (arg <= 0 || arg > POLY1305_BLOCK_SIZE || !ctx->encrypt)
|
||||
return 0;
|
||||
memcpy(ptr, actx->tag, arg);
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_TLS1_AAD:
|
||||
if (arg != EVP_AEAD_TLS1_AAD_LEN)
|
||||
return 0;
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned char *aad = ptr;
|
||||
|
||||
memcpy(actx->tls_aad, ptr, EVP_AEAD_TLS1_AAD_LEN);
|
||||
len = aad[EVP_AEAD_TLS1_AAD_LEN - 2] << 8 |
|
||||
aad[EVP_AEAD_TLS1_AAD_LEN - 1];
|
||||
aad = actx->tls_aad;
|
||||
if (!ctx->encrypt) {
|
||||
if (len < POLY1305_BLOCK_SIZE)
|
||||
return 0;
|
||||
len -= POLY1305_BLOCK_SIZE; /* discount attached tag */
|
||||
aad[EVP_AEAD_TLS1_AAD_LEN - 2] = (unsigned char)(len >> 8);
|
||||
aad[EVP_AEAD_TLS1_AAD_LEN - 1] = (unsigned char)len;
|
||||
}
|
||||
actx->tls_payload_length = len;
|
||||
|
||||
/*
|
||||
* merge record sequence number as per RFC7905
|
||||
*/
|
||||
actx->key.counter[1] = actx->nonce[0];
|
||||
actx->key.counter[2] = actx->nonce[1] ^ CHACHA_U8TOU32(aad);
|
||||
actx->key.counter[3] = actx->nonce[2] ^ CHACHA_U8TOU32(aad+4);
|
||||
actx->mac_inited = 0;
|
||||
|
||||
return POLY1305_BLOCK_SIZE; /* tag length */
|
||||
}
|
||||
|
||||
case EVP_CTRL_AEAD_SET_MAC_KEY:
|
||||
/* no-op */
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static EVP_CIPHER chacha20_poly1305 = {
|
||||
NID_chacha20_poly1305,
|
||||
1, /* block_size */
|
||||
CHACHA_KEY_SIZE, /* key_len */
|
||||
12, /* iv_len, 96-bit nonce in the context */
|
||||
EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CUSTOM_IV |
|
||||
EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
|
||||
EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER,
|
||||
chacha20_poly1305_init_key,
|
||||
chacha20_poly1305_cipher,
|
||||
chacha20_poly1305_cleanup,
|
||||
0, /* 0 moves context-specific structure allocation to ctrl */
|
||||
NULL, /* set_asn1_parameters */
|
||||
NULL, /* get_asn1_parameters */
|
||||
chacha20_poly1305_ctrl,
|
||||
NULL /* app_data */
|
||||
};
|
||||
|
||||
const EVP_CIPHER *EVP_chacha20_poly1305(void)
|
||||
{
|
||||
return(&chacha20_poly1305);
|
||||
}
|
||||
# endif
|
||||
#endif
|
242
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_des.c
vendored
Normal file
242
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_des.c
vendored
Normal file
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#ifndef OPENSSL_NO_DES
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include "internal/evp_int.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),
|
||||
EVP_CIPHER_CTX_get_cipher_data(ctx),
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
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) {
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
|
||||
EVP_CIPHER_CTX_get_cipher_data(ctx),
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num);
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
inl -= EVP_MAXCHUNK;
|
||||
in += EVP_MAXCHUNK;
|
||||
out += EVP_MAXCHUNK;
|
||||
}
|
||||
if (inl) {
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
DES_ofb64_encrypt(in, out, (long)inl,
|
||||
EVP_CIPHER_CTX_get_cipher_data(ctx),
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num);
|
||||
EVP_CIPHER_CTX_set_num(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 *) EVP_CIPHER_CTX_get_cipher_data(ctx);
|
||||
|
||||
if (dat->stream.cbc != NULL) {
|
||||
(*dat->stream.cbc) (in, out, inl, &dat->ks.ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx));
|
||||
return 1;
|
||||
}
|
||||
while (inl >= EVP_MAXCHUNK) {
|
||||
DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK,
|
||||
EVP_CIPHER_CTX_get_cipher_data(ctx),
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
inl -= EVP_MAXCHUNK;
|
||||
in += EVP_MAXCHUNK;
|
||||
out += EVP_MAXCHUNK;
|
||||
}
|
||||
if (inl)
|
||||
DES_ncbc_encrypt(in, out, (long)inl,
|
||||
EVP_CIPHER_CTX_get_cipher_data(ctx),
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
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) {
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK,
|
||||
EVP_CIPHER_CTX_get_cipher_data(ctx),
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num,
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
inl -= EVP_MAXCHUNK;
|
||||
in += EVP_MAXCHUNK;
|
||||
out += EVP_MAXCHUNK;
|
||||
}
|
||||
if (inl) {
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
DES_cfb64_encrypt(in, out, (long)inl,
|
||||
EVP_CIPHER_CTX_get_cipher_data(ctx),
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num,
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
}
|
||||
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, EVP_CIPHER_CTX_get_cipher_data(ctx),
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
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,
|
||||
EVP_CIPHER_CTX_get_cipher_data(ctx),
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
inl -= EVP_MAXCHUNK;
|
||||
in += EVP_MAXCHUNK;
|
||||
out += EVP_MAXCHUNK;
|
||||
}
|
||||
if (inl)
|
||||
DES_cfb_encrypt(in, out, 8, (long)inl,
|
||||
EVP_CIPHER_CTX_get_cipher_data(ctx),
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
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 *) EVP_CIPHER_CTX_get_cipher_data(ctx);
|
||||
|
||||
dat->stream.cbc = NULL;
|
||||
# if defined(SPARC_DES_CAPABLE)
|
||||
if (SPARC_DES_CAPABLE) {
|
||||
int mode = EVP_CIPHER_CTX_mode(ctx);
|
||||
|
||||
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
|
||||
DES_set_key_unchecked(deskey, EVP_CIPHER_CTX_get_cipher_data(ctx));
|
||||
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_priv_bytes(ptr, 8) <= 0)
|
||||
return 0;
|
||||
DES_set_odd_parity((DES_cblock *)ptr);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
424
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_des3.c
vendored
Normal file
424
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_des3.c
vendored
Normal file
|
@ -0,0 +1,424 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#ifndef OPENSSL_NO_DES
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include "internal/evp_int.h"
|
||||
# include <openssl/des.h>
|
||||
# include <openssl/rand.h>
|
||||
# include "evp_locl.h"
|
||||
|
||||
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) EVP_C_DATA(DES_EDE_KEY,ctx)
|
||||
|
||||
/*
|
||||
* 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, EVP_CIPHER_CTX_encrypting(ctx));
|
||||
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) {
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
|
||||
&data(ctx)->ks1, &data(ctx)->ks2,
|
||||
&data(ctx)->ks3,
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
&num);
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
inl -= EVP_MAXCHUNK;
|
||||
in += EVP_MAXCHUNK;
|
||||
out += EVP_MAXCHUNK;
|
||||
}
|
||||
if (inl) {
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
DES_ede3_ofb64_encrypt(in, out, (long)inl,
|
||||
&data(ctx)->ks1, &data(ctx)->ks2,
|
||||
&data(ctx)->ks3,
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
&num);
|
||||
EVP_CIPHER_CTX_set_num(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);
|
||||
|
||||
if (dat->stream.cbc != NULL) {
|
||||
(*dat->stream.cbc) (in, out, inl, dat->ks.ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx));
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (inl >= EVP_MAXCHUNK) {
|
||||
DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
|
||||
&dat->ks1, &dat->ks2, &dat->ks3,
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
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 *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
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) {
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK,
|
||||
&data(ctx)->ks1, &data(ctx)->ks2,
|
||||
&data(ctx)->ks3,
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
&num, EVP_CIPHER_CTX_encrypting(ctx));
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
inl -= EVP_MAXCHUNK;
|
||||
in += EVP_MAXCHUNK;
|
||||
out += EVP_MAXCHUNK;
|
||||
}
|
||||
if (inl) {
|
||||
int num = EVP_CIPHER_CTX_num(ctx);
|
||||
DES_ede3_cfb64_encrypt(in, out, (long)inl,
|
||||
&data(ctx)->ks1, &data(ctx)->ks2,
|
||||
&data(ctx)->ks3,
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
&num, EVP_CIPHER_CTX_encrypting(ctx));
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
}
|
||||
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];
|
||||
|
||||
if (!EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
|
||||
inl *= 8;
|
||||
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 *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
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 *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
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 *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
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_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_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_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 = EVP_CIPHER_CTX_mode(ctx);
|
||||
|
||||
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
|
||||
DES_set_key_unchecked(&deskey[0], &dat->ks1);
|
||||
DES_set_key_unchecked(&deskey[1], &dat->ks2);
|
||||
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);
|
||||
|
||||
dat->stream.cbc = NULL;
|
||||
# if defined(SPARC_DES_CAPABLE)
|
||||
if (SPARC_DES_CAPABLE) {
|
||||
int mode = EVP_CIPHER_CTX_mode(ctx);
|
||||
|
||||
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
|
||||
DES_set_key_unchecked(&deskey[0], &dat->ks1);
|
||||
DES_set_key_unchecked(&deskey[1], &dat->ks2);
|
||||
DES_set_key_unchecked(&deskey[2], &dat->ks3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int des3_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
|
||||
{
|
||||
|
||||
DES_cblock *deskey = ptr;
|
||||
|
||||
switch (type) {
|
||||
case EVP_CTRL_RAND_KEY:
|
||||
if (RAND_priv_bytes(ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0)
|
||||
return 0;
|
||||
DES_set_odd_parity(deskey);
|
||||
if (EVP_CIPHER_CTX_key_length(ctx) >= 16)
|
||||
DES_set_odd_parity(deskey + 1);
|
||||
if (EVP_CIPHER_CTX_key_length(ctx) >= 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;
|
||||
}
|
||||
|
||||
|
||||
# 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(EVP_CIPHER_CTX_iv_noconst(ctx), 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(EVP_CIPHER_CTX_iv_noconst(ctx), 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(EVP_CIPHER_CTX_iv_noconst(ctx), 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(EVP_CIPHER_CTX_iv_noconst(ctx), 8) <= 0)
|
||||
return -1;
|
||||
memcpy(out, EVP_CIPHER_CTX_iv_noconst(ctx), 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(EVP_CIPHER_CTX_iv_noconst(ctx), 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 (is_partially_overlapping(out, in, inl)) {
|
||||
EVPerr(EVP_F_DES_EDE3_WRAP_CIPHER, EVP_R_PARTIALLY_OVERLAPPING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (EVP_CIPHER_CTX_encrypting(ctx))
|
||||
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
|
70
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_idea.c
vendored
Normal file
70
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_idea.c
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#ifndef OPENSSL_NO_IDEA
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include "internal/evp_int.h"
|
||||
# include <openssl/idea.h>
|
||||
|
||||
/* Can't use IMPLEMENT_BLOCK_CIPHER because IDEA_ecb_encrypt is different */
|
||||
|
||||
typedef struct {
|
||||
IDEA_KEY_SCHEDULE ks;
|
||||
} EVP_IDEA_KEY;
|
||||
|
||||
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, &EVP_C_DATA(EVP_IDEA_KEY,ctx)->ks);
|
||||
return 1;
|
||||
}
|
||||
|
||||
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, &EVP_C_DATA(EVP_IDEA_KEY,ctx)->ks);
|
||||
else {
|
||||
IDEA_KEY_SCHEDULE tmp;
|
||||
|
||||
IDEA_set_encrypt_key(key, &tmp);
|
||||
IDEA_set_decrypt_key(&tmp, &EVP_C_DATA(EVP_IDEA_KEY,ctx)->ks);
|
||||
OPENSSL_cleanse((unsigned char *)&tmp, sizeof(IDEA_KEY_SCHEDULE));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
50
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_null.c
vendored
Normal file
50
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_null.c
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include "internal/evp_int.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)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t inl)
|
||||
{
|
||||
if (in != out)
|
||||
memcpy(out, in, inl);
|
||||
return 1;
|
||||
}
|
113
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_old.c
vendored
Normal file
113
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_old.c
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#if OPENSSL_API_COMPAT >= 0x00908000L
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#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
|
||||
|
||||
# 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
|
191
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_rc2.c
vendored
Normal file
191
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_rc2.c
vendored
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#ifndef OPENSSL_NO_RC2
|
||||
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include "internal/evp_int.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_C_DATA(EVP_RC2_KEY,ctx)
|
||||
|
||||
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;
|
||||
|
||||
if (EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i) <= 0)
|
||||
return 0;
|
||||
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;
|
||||
if (EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits,
|
||||
NULL) <= 0
|
||||
|| EVP_CIPHER_CTX_set_key_length(c, key_bits / 8) <= 0)
|
||||
return -1;
|
||||
}
|
||||
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,
|
||||
(unsigned char *)EVP_CIPHER_CTX_original_iv(c),
|
||||
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
|
82
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_rc4.c
vendored
Normal file
82
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_rc4.c
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#ifndef OPENSSL_NO_RC4
|
||||
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include <openssl/rc4.h>
|
||||
|
||||
# include "internal/evp_int.h"
|
||||
|
||||
typedef struct {
|
||||
RC4_KEY ks; /* working key */
|
||||
} EVP_RC4_KEY;
|
||||
|
||||
# define data(ctx) ((EVP_RC4_KEY *)EVP_CIPHER_CTX_get_cipher_data(ctx))
|
||||
|
||||
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
|
262
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_rc4_hmac_md5.c
vendored
Normal file
262
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_rc4_hmac_md5.c
vendored
Normal file
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#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>
|
||||
# include "internal/evp_int.h"
|
||||
|
||||
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 *)EVP_CIPHER_CTX_get_cipher_data(ctx))
|
||||
|
||||
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(RC4_ASM) && defined(MD5_ASM) && ( \
|
||||
defined(__x86_64) || defined(__x86_64__) || \
|
||||
defined(_M_AMD64) || defined(_M_X64) )
|
||||
# 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 (EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
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));
|
||||
|
||||
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 (!EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
if (len < MD5_DIGEST_LENGTH)
|
||||
return -1;
|
||||
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
|
74
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_rc5.c
vendored
Normal file
74
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_rc5.c
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#ifndef OPENSSL_NO_RC5
|
||||
|
||||
# include <openssl/evp.h>
|
||||
# include "internal/evp_int.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_UNSUPPORTED_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
|
39
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_seed.c
vendored
Normal file
39
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_seed.c
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_SEED
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/err.h>
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
# include <openssl/seed.h>
|
||||
# include "internal/evp_int.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, EVP_CIPH_FLAG_DEFAULT_ASN1,
|
||||
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, &EVP_C_DATA(EVP_SEED_KEY,ctx)->ks);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
100
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_sm4.c
vendored
Normal file
100
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_sm4.c
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2017 Ribose Inc. All Rights Reserved.
|
||||
* Ported from Ribose contributions from Botan.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
#ifndef OPENSSL_NO_SM4
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/modes.h>
|
||||
# include "internal/sm4.h"
|
||||
# include "internal/evp_int.h"
|
||||
|
||||
typedef struct {
|
||||
SM4_KEY ks;
|
||||
} EVP_SM4_KEY;
|
||||
|
||||
static int sm4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
SM4_set_key(key, EVP_CIPHER_CTX_get_cipher_data(ctx));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void sm4_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const SM4_KEY *key,
|
||||
unsigned char *ivec, const int enc)
|
||||
{
|
||||
if (enc)
|
||||
CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
|
||||
(block128_f)SM4_encrypt);
|
||||
else
|
||||
CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
|
||||
(block128_f)SM4_decrypt);
|
||||
}
|
||||
|
||||
static void sm4_cfb128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const SM4_KEY *key,
|
||||
unsigned char *ivec, int *num, const int enc)
|
||||
{
|
||||
CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
|
||||
(block128_f)SM4_encrypt);
|
||||
}
|
||||
|
||||
static void sm4_ecb_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const SM4_KEY *key, const int enc)
|
||||
{
|
||||
if (enc)
|
||||
SM4_encrypt(in, out, key);
|
||||
else
|
||||
SM4_decrypt(in, out, key);
|
||||
}
|
||||
|
||||
static void sm4_ofb128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const SM4_KEY *key,
|
||||
unsigned char *ivec, int *num)
|
||||
{
|
||||
CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
|
||||
(block128_f)SM4_encrypt);
|
||||
}
|
||||
|
||||
IMPLEMENT_BLOCK_CIPHER(sm4, ks, sm4, EVP_SM4_KEY, NID_sm4,
|
||||
16, 16, 16, 128, EVP_CIPH_FLAG_DEFAULT_ASN1,
|
||||
sm4_init_key, 0, 0, 0, 0)
|
||||
|
||||
static int sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
unsigned int num = EVP_CIPHER_CTX_num(ctx);
|
||||
EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY, ctx);
|
||||
|
||||
CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
|
||||
EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
EVP_CIPHER_CTX_buf_noconst(ctx), &num,
|
||||
(block128_f)SM4_encrypt);
|
||||
EVP_CIPHER_CTX_set_num(ctx, num);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const EVP_CIPHER sm4_ctr_mode = {
|
||||
NID_sm4_ctr, 1, 16, 16,
|
||||
EVP_CIPH_CTR_MODE,
|
||||
sm4_init_key,
|
||||
sm4_ctr_cipher,
|
||||
NULL,
|
||||
sizeof(EVP_SM4_KEY),
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
const EVP_CIPHER *EVP_sm4_ctr(void)
|
||||
{
|
||||
return &sm4_ctr_mode;
|
||||
}
|
||||
|
||||
#endif
|
83
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_xcbc_d.c
vendored
Normal file
83
trunk/3rdparty/openssl-1.1-fit/crypto/evp/e_xcbc_d.c
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#ifndef OPENSSL_NO_DES
|
||||
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include "internal/evp_int.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) EVP_C_DATA(DESX_CBC_KEY,ctx)
|
||||
|
||||
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 *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
&data(ctx)->inw, &data(ctx)->outw,
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
inl -= EVP_MAXCHUNK;
|
||||
in += EVP_MAXCHUNK;
|
||||
out += EVP_MAXCHUNK;
|
||||
}
|
||||
if (inl)
|
||||
DES_xcbc_encrypt(in, out, (long)inl, &data(ctx)->ks,
|
||||
(DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
|
||||
&data(ctx)->inw, &data(ctx)->outw,
|
||||
EVP_CIPHER_CTX_encrypting(ctx));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
478
trunk/3rdparty/openssl-1.1-fit/crypto/evp/encode.c
vendored
Normal file
478
trunk/3rdparty/openssl-1.1-fit/crypto/evp/encode.c
vendored
Normal file
|
@ -0,0 +1,478 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include "evp_locl.h"
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
static unsigned char conv_ascii2bin(unsigned char a,
|
||||
const unsigned char *table);
|
||||
static int evp_encodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
|
||||
const unsigned char *f, int dlen);
|
||||
static int evp_decodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
|
||||
const unsigned char *f, int n);
|
||||
|
||||
#ifndef CHARSET_EBCDIC
|
||||
# define conv_bin2ascii(a, table) ((table)[(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, table) ((table)[(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] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/* SRP uses a different base64 alphabet */
|
||||
static const unsigned char srpdata_bin2ascii[65] =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
|
||||
|
||||
|
||||
/*-
|
||||
* 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,
|
||||
};
|
||||
|
||||
static const unsigned char srpdata_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, 0xFF, 0xFF, 0xF2, 0x3E, 0x3F,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
|
||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||
0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
|
||||
0x21, 0x22, 0x23, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,
|
||||
0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
|
||||
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
|
||||
0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
|
||||
#ifndef CHARSET_EBCDIC
|
||||
static unsigned char conv_ascii2bin(unsigned char a, const unsigned char *table)
|
||||
{
|
||||
if (a & 0x80)
|
||||
return B64_ERROR;
|
||||
return table[a];
|
||||
}
|
||||
#else
|
||||
static unsigned char conv_ascii2bin(unsigned char a, const unsigned char *table)
|
||||
{
|
||||
a = os_toascii[a];
|
||||
if (a & 0x80)
|
||||
return B64_ERROR;
|
||||
return table[a];
|
||||
}
|
||||
#endif
|
||||
|
||||
EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void)
|
||||
{
|
||||
return OPENSSL_zalloc(sizeof(EVP_ENCODE_CTX));
|
||||
}
|
||||
|
||||
void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx)
|
||||
{
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, EVP_ENCODE_CTX *sctx)
|
||||
{
|
||||
memcpy(dctx, sctx, sizeof(EVP_ENCODE_CTX));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx)
|
||||
{
|
||||
return ctx->num;
|
||||
}
|
||||
|
||||
void evp_encode_ctx_set_flags(EVP_ENCODE_CTX *ctx, unsigned int flags)
|
||||
{
|
||||
ctx->flags = flags;
|
||||
}
|
||||
|
||||
void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
|
||||
{
|
||||
ctx->length = 48;
|
||||
ctx->num = 0;
|
||||
ctx->line_num = 0;
|
||||
ctx->flags = 0;
|
||||
}
|
||||
|
||||
int 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 0;
|
||||
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 1;
|
||||
}
|
||||
if (ctx->num != 0) {
|
||||
i = ctx->length - ctx->num;
|
||||
memcpy(&(ctx->enc_data[ctx->num]), in, i);
|
||||
in += i;
|
||||
inl -= i;
|
||||
j = evp_encodeblock_int(ctx, out, ctx->enc_data, ctx->length);
|
||||
ctx->num = 0;
|
||||
out += j;
|
||||
total = j;
|
||||
if ((ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) == 0) {
|
||||
*(out++) = '\n';
|
||||
total++;
|
||||
}
|
||||
*out = '\0';
|
||||
}
|
||||
while (inl >= ctx->length && total <= INT_MAX) {
|
||||
j = evp_encodeblock_int(ctx, out, in, ctx->length);
|
||||
in += ctx->length;
|
||||
inl -= ctx->length;
|
||||
out += j;
|
||||
total += j;
|
||||
if ((ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) == 0) {
|
||||
*(out++) = '\n';
|
||||
total++;
|
||||
}
|
||||
*out = '\0';
|
||||
}
|
||||
if (total > INT_MAX) {
|
||||
/* Too much output data! */
|
||||
*outl = 0;
|
||||
return 0;
|
||||
}
|
||||
if (inl != 0)
|
||||
memcpy(&(ctx->enc_data[0]), in, inl);
|
||||
ctx->num = inl;
|
||||
*outl = total;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
|
||||
if (ctx->num != 0) {
|
||||
ret = evp_encodeblock_int(ctx, out, ctx->enc_data, ctx->num);
|
||||
if ((ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) == 0)
|
||||
out[ret++] = '\n';
|
||||
out[ret] = '\0';
|
||||
ctx->num = 0;
|
||||
}
|
||||
*outl = ret;
|
||||
}
|
||||
|
||||
static int evp_encodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
|
||||
const unsigned char *f, int dlen)
|
||||
{
|
||||
int i, ret = 0;
|
||||
unsigned long l;
|
||||
const unsigned char *table;
|
||||
|
||||
if (ctx != NULL && (ctx->flags & EVP_ENCODE_CTX_USE_SRP_ALPHABET) != 0)
|
||||
table = srpdata_bin2ascii;
|
||||
else
|
||||
table = data_bin2ascii;
|
||||
|
||||
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, table);
|
||||
*(t++) = conv_bin2ascii(l >> 12L, table);
|
||||
*(t++) = conv_bin2ascii(l >> 6L, table);
|
||||
*(t++) = conv_bin2ascii(l, table);
|
||||
} else {
|
||||
l = ((unsigned long)f[0]) << 16L;
|
||||
if (i == 2)
|
||||
l |= ((unsigned long)f[1] << 8L);
|
||||
|
||||
*(t++) = conv_bin2ascii(l >> 18L, table);
|
||||
*(t++) = conv_bin2ascii(l >> 12L, table);
|
||||
*(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L, table);
|
||||
*(t++) = '=';
|
||||
}
|
||||
ret += 4;
|
||||
f += 3;
|
||||
}
|
||||
|
||||
*t = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
|
||||
{
|
||||
return evp_encodeblock_int(NULL, t, f, dlen);
|
||||
}
|
||||
|
||||
void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
|
||||
{
|
||||
/* Only ctx->num and ctx->flags are used during decoding. */
|
||||
ctx->num = 0;
|
||||
ctx->length = 0;
|
||||
ctx->line_num = 0;
|
||||
ctx->flags = 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;
|
||||
const unsigned char *table;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if ((ctx->flags & EVP_ENCODE_CTX_USE_SRP_ALPHABET) != 0)
|
||||
table = srpdata_ascii2bin;
|
||||
else
|
||||
table = data_ascii2bin;
|
||||
|
||||
for (i = 0; i < inl; i++) {
|
||||
tmp = *(in++);
|
||||
v = conv_ascii2bin(tmp, table);
|
||||
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_int(ctx, 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_int(ctx, 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;
|
||||
}
|
||||
|
||||
static int evp_decodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
|
||||
const unsigned char *f, int n)
|
||||
{
|
||||
int i, ret = 0, a, b, c, d;
|
||||
unsigned long l;
|
||||
const unsigned char *table;
|
||||
|
||||
if (ctx != NULL && (ctx->flags & EVP_ENCODE_CTX_USE_SRP_ALPHABET) != 0)
|
||||
table = srpdata_ascii2bin;
|
||||
else
|
||||
table = data_ascii2bin;
|
||||
|
||||
/* trim white space from the start of the line. */
|
||||
while ((conv_ascii2bin(*f, table) == 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], table))))
|
||||
n--;
|
||||
|
||||
if (n % 4 != 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < n; i += 4) {
|
||||
a = conv_ascii2bin(*(f++), table);
|
||||
b = conv_ascii2bin(*(f++), table);
|
||||
c = conv_ascii2bin(*(f++), table);
|
||||
d = conv_ascii2bin(*(f++), table);
|
||||
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_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
|
||||
{
|
||||
return evp_decodeblock_int(NULL, t, f, n);
|
||||
}
|
||||
|
||||
int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
|
||||
{
|
||||
int i;
|
||||
|
||||
*outl = 0;
|
||||
if (ctx->num != 0) {
|
||||
i = evp_decodeblock_int(ctx, out, ctx->enc_data, ctx->num);
|
||||
if (i < 0)
|
||||
return -1;
|
||||
ctx->num = 0;
|
||||
*outl = i;
|
||||
return 1;
|
||||
} else
|
||||
return 1;
|
||||
}
|
56
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_cnf.c
vendored
Normal file
56
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_cnf.c
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 2012-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
/* 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)) == NULL) {
|
||||
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") == 0) {
|
||||
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) {
|
||||
EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
} 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);
|
||||
}
|
677
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_enc.c
vendored
Normal file
677
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_enc.c
vendored
Normal file
|
@ -0,0 +1,677 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/rand_drbg.h>
|
||||
#include <openssl/engine.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c)
|
||||
{
|
||||
if (c == NULL)
|
||||
return 1;
|
||||
if (c->cipher != NULL) {
|
||||
if (c->cipher->cleanup && !c->cipher->cleanup(c))
|
||||
return 0;
|
||||
/* Cleanse cipher context data */
|
||||
if (c->cipher_data && c->cipher->ctx_size)
|
||||
OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
|
||||
}
|
||||
OPENSSL_free(c->cipher_data);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(c->engine);
|
||||
#endif
|
||||
memset(c, 0, sizeof(*c));
|
||||
return 1;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
|
||||
{
|
||||
return OPENSSL_zalloc(sizeof(EVP_CIPHER_CTX));
|
||||
}
|
||||
|
||||
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
EVP_CIPHER_CTX_reset(ctx);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
||||
const unsigned char *key, const unsigned char *iv, int enc)
|
||||
{
|
||||
if (cipher != NULL)
|
||||
EVP_CIPHER_CTX_reset(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 unnecessary.
|
||||
*/
|
||||
if (ctx->engine && ctx->cipher
|
||||
&& (cipher == NULL || 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_reset(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
|
||||
* misspellings 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
|
||||
|
||||
ctx->cipher = cipher;
|
||||
if (ctx->cipher->ctx_size) {
|
||||
ctx->cipher_data = OPENSSL_zalloc(ctx->cipher->ctx_size);
|
||||
if (ctx->cipher_data == NULL) {
|
||||
ctx->cipher = NULL;
|
||||
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)) {
|
||||
ctx->cipher = 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
|
||||
/* 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_flags(EVP_CIPHER_CTX_cipher(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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* According to the letter of standard difference between pointers
|
||||
* is specified to be valid only within same object. This makes
|
||||
* it formally challenging to determine if input and output buffers
|
||||
* are not partially overlapping with standard pointer arithmetic.
|
||||
*/
|
||||
#ifdef PTRDIFF_T
|
||||
# undef PTRDIFF_T
|
||||
#endif
|
||||
#if defined(OPENSSL_SYS_VMS) && __INITIAL_POINTER_SIZE==64
|
||||
/*
|
||||
* Then we have VMS that distinguishes itself by adhering to
|
||||
* sizeof(size_t)==4 even in 64-bit builds, which means that
|
||||
* difference between two pointers might be truncated to 32 bits.
|
||||
* In the context one can even wonder how comparison for
|
||||
* equality is implemented. To be on the safe side we adhere to
|
||||
* PTRDIFF_T even for comparison for equality.
|
||||
*/
|
||||
# define PTRDIFF_T uint64_t
|
||||
#else
|
||||
# define PTRDIFF_T size_t
|
||||
#endif
|
||||
|
||||
int is_partially_overlapping(const void *ptr1, const void *ptr2, int len)
|
||||
{
|
||||
PTRDIFF_T diff = (PTRDIFF_T)ptr1-(PTRDIFF_T)ptr2;
|
||||
/*
|
||||
* Check for partially overlapping buffers. [Binary logical
|
||||
* operations are used instead of boolean to minimize number
|
||||
* of conditional branches.]
|
||||
*/
|
||||
int overlapped = (len > 0) & (diff != 0) & ((diff < (PTRDIFF_T)len) |
|
||||
(diff > (0 - (PTRDIFF_T)len)));
|
||||
|
||||
return overlapped;
|
||||
}
|
||||
|
||||
static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
|
||||
unsigned char *out, int *outl,
|
||||
const unsigned char *in, int inl)
|
||||
{
|
||||
int i, j, bl, cmpl = inl;
|
||||
|
||||
if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
|
||||
cmpl = (cmpl + 7) / 8;
|
||||
|
||||
bl = ctx->cipher->block_size;
|
||||
|
||||
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
||||
/* If block size > 1 then the cipher will have to do this check */
|
||||
if (bl == 1 && is_partially_overlapping(out, in, cmpl)) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
i = ctx->cipher->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 (is_partially_overlapping(out + ctx->buf_len, in, cmpl)) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->buf_len == 0 && (inl & (ctx->block_mask)) == 0) {
|
||||
if (ctx->cipher->do_cipher(ctx, out, in, inl)) {
|
||||
*outl = inl;
|
||||
return 1;
|
||||
} else {
|
||||
*outl = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
i = ctx->buf_len;
|
||||
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);
|
||||
inl -= j;
|
||||
in += j;
|
||||
if (!ctx->cipher->do_cipher(ctx, out, ctx->buf, bl))
|
||||
return 0;
|
||||
out += bl;
|
||||
*outl = bl;
|
||||
}
|
||||
} else
|
||||
*outl = 0;
|
||||
i = inl & (bl - 1);
|
||||
inl -= i;
|
||||
if (inl > 0) {
|
||||
if (!ctx->cipher->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_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
const unsigned char *in, int inl)
|
||||
{
|
||||
/* Prevent accidental use of decryption context when encrypting */
|
||||
if (!ctx->encrypt) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_INVALID_OPERATION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* Prevent accidental use of decryption context when encrypting */
|
||||
if (!ctx->encrypt) {
|
||||
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_INVALID_OPERATION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
||||
ret = ctx->cipher->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 = ctx->cipher->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, cmpl = inl;
|
||||
unsigned int b;
|
||||
|
||||
/* Prevent accidental use of encryption context when decrypting */
|
||||
if (ctx->encrypt) {
|
||||
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_INVALID_OPERATION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
b = ctx->cipher->block_size;
|
||||
|
||||
if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
|
||||
cmpl = (cmpl + 7) / 8;
|
||||
|
||||
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
||||
if (b == 1 && is_partially_overlapping(out, in, cmpl)) {
|
||||
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fix_len = ctx->cipher->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_EncryptDecryptUpdate(ctx, out, outl, in, inl);
|
||||
|
||||
OPENSSL_assert(b <= sizeof(ctx->final));
|
||||
|
||||
if (ctx->final_used) {
|
||||
/* see comment about PTRDIFF_T comparison above */
|
||||
if (((PTRDIFF_T)out == (PTRDIFF_T)in)
|
||||
|| is_partially_overlapping(out, in, b)) {
|
||||
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
|
||||
return 0;
|
||||
}
|
||||
memcpy(out, ctx->final, b);
|
||||
out += b;
|
||||
fix_len = 1;
|
||||
} else
|
||||
fix_len = 0;
|
||||
|
||||
if (!evp_EncryptDecryptUpdate(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;
|
||||
|
||||
/* Prevent accidental use of encryption context when decrypting */
|
||||
if (ctx->encrypt) {
|
||||
EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_INVALID_OPERATION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*outl = 0;
|
||||
|
||||
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
||||
i = ctx->cipher->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;
|
||||
}
|
||||
|
||||
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_priv_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_reset(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 == NULL) {
|
||||
out->cipher = NULL;
|
||||
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)
|
||||
if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out)) {
|
||||
out->cipher = NULL;
|
||||
EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
283
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_err.c
vendored
Normal file
283
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_err.c
vendored
Normal file
|
@ -0,0 +1,283 @@
|
|||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evperr.h>
|
||||
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
static const ERR_STRING_DATA EVP_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AESNI_INIT_KEY, 0), "aesni_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_GCM_CTRL, 0), "aes_gcm_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_INIT_KEY, 0), "aes_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_OCB_CIPHER, 0), "aes_ocb_cipher"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_T4_INIT_KEY, 0), "aes_t4_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_WRAP_CIPHER, 0), "aes_wrap_cipher"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_ALG_MODULE_INIT, 0), "alg_module_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_CCM_INIT_KEY, 0), "aria_ccm_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_GCM_CTRL, 0), "aria_gcm_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_GCM_INIT_KEY, 0), "aria_gcm_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_INIT_KEY, 0), "aria_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_B64_NEW, 0), "b64_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_CAMELLIA_INIT_KEY, 0), "camellia_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_CHACHA20_POLY1305_CTRL, 0),
|
||||
"chacha20_poly1305_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_CMLL_T4_INIT_KEY, 0), "cmll_t4_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_DES_EDE3_WRAP_CIPHER, 0),
|
||||
"des_ede3_wrap_cipher"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_DO_SIGVER_INIT, 0), "do_sigver_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_ENC_NEW, 0), "enc_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHERINIT_EX, 0), "EVP_CipherInit_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_ASN1_TO_PARAM, 0),
|
||||
"EVP_CIPHER_asn1_to_param"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_COPY, 0),
|
||||
"EVP_CIPHER_CTX_copy"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_CTRL, 0),
|
||||
"EVP_CIPHER_CTX_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, 0),
|
||||
"EVP_CIPHER_CTX_set_key_length"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_PARAM_TO_ASN1, 0),
|
||||
"EVP_CIPHER_param_to_asn1"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, 0),
|
||||
"EVP_DecryptFinal_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTUPDATE, 0), "EVP_DecryptUpdate"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTFINALXOF, 0), "EVP_DigestFinalXOF"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTINIT_EX, 0), "EVP_DigestInit_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTDECRYPTUPDATE, 0),
|
||||
"evp_EncryptDecryptUpdate"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0),
|
||||
"EVP_EncryptFinal_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTUPDATE, 0), "EVP_EncryptUpdate"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_CTX_COPY_EX, 0), "EVP_MD_CTX_copy_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_SIZE, 0), "EVP_MD_size"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_OPENINIT, 0), "EVP_OpenInit"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_ALG_ADD, 0), "EVP_PBE_alg_add"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_ALG_ADD_TYPE, 0),
|
||||
"EVP_PBE_alg_add_type"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_CIPHERINIT, 0), "EVP_PBE_CipherInit"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_SCRYPT, 0), "EVP_PBE_scrypt"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKCS82PKEY, 0), "EVP_PKCS82PKEY"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY2PKCS8, 0), "EVP_PKEY2PKCS8"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ASN1_ADD0, 0), "EVP_PKEY_asn1_add0"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CHECK, 0), "EVP_PKEY_check"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_COPY_PARAMETERS, 0),
|
||||
"EVP_PKEY_copy_parameters"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, 0), "EVP_PKEY_CTX_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL_STR, 0),
|
||||
"EVP_PKEY_CTX_ctrl_str"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_DUP, 0), "EVP_PKEY_CTX_dup"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_MD, 0), "EVP_PKEY_CTX_md"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DECRYPT, 0), "EVP_PKEY_decrypt"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DECRYPT_INIT, 0),
|
||||
"EVP_PKEY_decrypt_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DECRYPT_OLD, 0),
|
||||
"EVP_PKEY_decrypt_old"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE, 0), "EVP_PKEY_derive"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE_INIT, 0),
|
||||
"EVP_PKEY_derive_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE_SET_PEER, 0),
|
||||
"EVP_PKEY_derive_set_peer"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ENCRYPT, 0), "EVP_PKEY_encrypt"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ENCRYPT_INIT, 0),
|
||||
"EVP_PKEY_encrypt_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ENCRYPT_OLD, 0),
|
||||
"EVP_PKEY_encrypt_old"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_DH, 0), "EVP_PKEY_get0_DH"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_DSA, 0), "EVP_PKEY_get0_DSA"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_EC_KEY, 0),
|
||||
"EVP_PKEY_get0_EC_KEY"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_HMAC, 0), "EVP_PKEY_get0_hmac"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_POLY1305, 0),
|
||||
"EVP_PKEY_get0_poly1305"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_RSA, 0), "EVP_PKEY_get0_RSA"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_SIPHASH, 0),
|
||||
"EVP_PKEY_get0_siphash"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, 0),
|
||||
"EVP_PKEY_get_raw_private_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, 0),
|
||||
"EVP_PKEY_get_raw_public_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_KEYGEN, 0), "EVP_PKEY_keygen"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_KEYGEN_INIT, 0),
|
||||
"EVP_PKEY_keygen_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_METH_ADD0, 0), "EVP_PKEY_meth_add0"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_METH_NEW, 0), "EVP_PKEY_meth_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW, 0), "EVP_PKEY_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_CMAC_KEY, 0),
|
||||
"EVP_PKEY_new_CMAC_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY, 0),
|
||||
"EVP_PKEY_new_raw_private_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY, 0),
|
||||
"EVP_PKEY_new_raw_public_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN, 0), "EVP_PKEY_paramgen"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN_INIT, 0),
|
||||
"EVP_PKEY_paramgen_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAM_CHECK, 0),
|
||||
"EVP_PKEY_param_check"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PUBLIC_CHECK, 0),
|
||||
"EVP_PKEY_public_check"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET1_ENGINE, 0),
|
||||
"EVP_PKEY_set1_engine"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET_ALIAS_TYPE, 0),
|
||||
"EVP_PKEY_set_alias_type"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN, 0), "EVP_PKEY_sign"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN_INIT, 0), "EVP_PKEY_sign_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, 0), "EVP_PKEY_verify"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY_INIT, 0),
|
||||
"EVP_PKEY_verify_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY_RECOVER, 0),
|
||||
"EVP_PKEY_verify_recover"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT, 0),
|
||||
"EVP_PKEY_verify_recover_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_SIGNFINAL, 0), "EVP_SignFinal"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, 0), "EVP_VerifyFinal"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_INT_CTX_NEW, 0), "int_ctx_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_OK_NEW, 0), "ok_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_PBE_KEYIVGEN, 0), "PKCS5_PBE_keyivgen"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_PBE_KEYIVGEN, 0),
|
||||
"PKCS5_v2_PBE_keyivgen"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, 0),
|
||||
"PKCS5_v2_PBKDF2_keyivgen"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, 0),
|
||||
"PKCS5_v2_scrypt_keyivgen"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_SET_TYPE, 0), "pkey_set_type"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_RC2_MAGIC_TO_METH, 0), "rc2_magic_to_meth"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_RC5_CTRL, 0), "rc5_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_CTRL, 0), "s390x_aes_gcm_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_UPDATE, 0), "update"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_AES_KEY_SETUP_FAILED),
|
||||
"aes key setup failed"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ARIA_KEY_SETUP_FAILED),
|
||||
"aria key setup failed"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_DECRYPT), "bad decrypt"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BUFFER_TOO_SMALL), "buffer too small"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CAMELLIA_KEY_SETUP_FAILED),
|
||||
"camellia key setup failed"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_PARAMETER_ERROR),
|
||||
"cipher parameter error"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_COMMAND_NOT_SUPPORTED),
|
||||
"command not supported"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_COPY_ERROR), "copy error"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CTRL_NOT_IMPLEMENTED),
|
||||
"ctrl not implemented"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED),
|
||||
"ctrl operation not implemented"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),
|
||||
"data not multiple of block length"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DECODE_ERROR), "decode error"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_KEY_TYPES),
|
||||
"different key types"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_PARAMETERS),
|
||||
"different parameters"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ERROR_LOADING_SECTION),
|
||||
"error loading section"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ERROR_SETTING_FIPS_MODE),
|
||||
"error setting fips mode"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_HMAC_KEY),
|
||||
"expecting an hmac key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_RSA_KEY),
|
||||
"expecting an rsa key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DH_KEY), "expecting a dh key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DSA_KEY),
|
||||
"expecting a dsa key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_EC_KEY), "expecting a ec key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_POLY1305_KEY),
|
||||
"expecting a poly1305 key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_SIPHASH_KEY),
|
||||
"expecting a siphash key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FIPS_MODE_NOT_SUPPORTED),
|
||||
"fips mode not supported"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GET_RAW_KEY_FAILED), "get raw key failed"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ILLEGAL_SCRYPT_PARAMETERS),
|
||||
"illegal scrypt parameters"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INITIALIZATION_ERROR),
|
||||
"initialization error"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INPUT_NOT_INITIALIZED),
|
||||
"input not initialized"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_DIGEST), "invalid digest"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_FIPS_MODE), "invalid fips mode"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY), "invalid key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY_LENGTH), "invalid key length"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "invalid operation"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYGEN_FAILURE), "keygen failure"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEY_SETUP_FAILED), "key setup failed"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MEMORY_LIMIT_EXCEEDED),
|
||||
"memory limit exceeded"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MESSAGE_DIGEST_IS_NULL),
|
||||
"message digest is null"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_METHOD_NOT_SUPPORTED),
|
||||
"method not supported"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MISSING_PARAMETERS), "missing parameters"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NOT_XOF_OR_INVALID_LENGTH),
|
||||
"not XOF or invalid length"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_CIPHER_SET), "no cipher set"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DEFAULT_DIGEST), "no default digest"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DIGEST_SET), "no digest set"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEY_SET), "no key set"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_OPERATION_SET), "no operation set"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ONLY_ONESHOT_SUPPORTED),
|
||||
"only oneshot supported"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),
|
||||
"operation not supported for this keytype"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATON_NOT_INITIALIZED),
|
||||
"operaton not initialized"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARTIALLY_OVERLAPPING),
|
||||
"partially overlapping buffers"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PBKDF2_ERROR), "pbkdf2 error"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED),
|
||||
"pkey application asn1 method already registered"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PRIVATE_KEY_DECODE_ERROR),
|
||||
"private key decode error"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PRIVATE_KEY_ENCODE_ERROR),
|
||||
"private key encode error"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_CIPHER), "unknown cipher"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_DIGEST), "unknown digest"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_OPTION), "unknown option"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_PBE_ALGORITHM),
|
||||
"unknown pbe algorithm"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_ALGORITHM),
|
||||
"unsupported algorithm"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_CIPHER), "unsupported cipher"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEYLENGTH),
|
||||
"unsupported keylength"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),
|
||||
"unsupported key derivation function"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEY_SIZE),
|
||||
"unsupported key size"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS),
|
||||
"unsupported number of rounds"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_PRF), "unsupported prf"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM),
|
||||
"unsupported private key algorithm"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_SALT_TYPE),
|
||||
"unsupported salt type"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRAP_MODE_NOT_ALLOWED),
|
||||
"wrap mode not allowed"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRONG_FINAL_BLOCK_LENGTH),
|
||||
"wrong final block length"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
int ERR_load_EVP_strings(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) {
|
||||
ERR_load_strings_const(EVP_str_functs);
|
||||
ERR_load_strings_const(EVP_str_reasons);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
150
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_key.c
vendored
Normal file
150
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_key.c
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ui.h>
|
||||
|
||||
/* 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 = -1;
|
||||
char buff[BUFSIZ];
|
||||
UI *ui;
|
||||
|
||||
if ((prompt == NULL) && (prompt_string[0] != '\0'))
|
||||
prompt = prompt_string;
|
||||
ui = UI_new();
|
||||
if (ui == NULL)
|
||||
return ret;
|
||||
if (UI_add_input_string(ui, prompt, 0, buf, min,
|
||||
(len >= BUFSIZ) ? BUFSIZ - 1 : len) < 0
|
||||
|| (verify
|
||||
&& UI_add_verify_string(ui, prompt, 0, buff, min,
|
||||
(len >= BUFSIZ) ? BUFSIZ - 1 : len,
|
||||
buf) < 0))
|
||||
goto end;
|
||||
ret = UI_process(ui);
|
||||
OPENSSL_cleanse(buff, BUFSIZ);
|
||||
end:
|
||||
UI_free(ui);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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 = EVP_CIPHER_key_length(type);
|
||||
niv = EVP_CIPHER_iv_length(type);
|
||||
OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
|
||||
OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH);
|
||||
|
||||
if (data == NULL)
|
||||
return nkey;
|
||||
|
||||
c = EVP_MD_CTX_new();
|
||||
if (c == NULL)
|
||||
goto err;
|
||||
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 = EVP_CIPHER_key_length(type);
|
||||
err:
|
||||
EVP_MD_CTX_free(c);
|
||||
OPENSSL_cleanse(md_buf, sizeof(md_buf));
|
||||
return rv;
|
||||
}
|
528
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_lib.c
vendored
Normal file
528
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_lib.c
vendored
Normal file
|
@ -0,0 +1,528 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
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:
|
||||
case EVP_CIPH_OCB_MODE:
|
||||
ret = -2;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = EVP_CIPHER_set_asn1_iv(c, type);
|
||||
}
|
||||
} else
|
||||
ret = -1;
|
||||
if (ret <= 0)
|
||||
EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, ret == -2 ?
|
||||
ASN1_R_UNSUPPORTED_CIPHER :
|
||||
EVP_R_CIPHER_PARAMETER_ERROR);
|
||||
if (ret < -1)
|
||||
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:
|
||||
case EVP_CIPH_OCB_MODE:
|
||||
ret = -2;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = EVP_CIPHER_get_asn1_iv(c, type);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
ret = -1;
|
||||
if (ret <= 0)
|
||||
EVPerr(EVP_F_EVP_CIPHER_ASN1_TO_PARAM, ret == -2 ?
|
||||
EVP_R_UNSUPPORTED_CIPHER :
|
||||
EVP_R_CIPHER_PARAMETER_ERROR);
|
||||
if (ret < -1)
|
||||
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 (OBJ_get0_data(otmp) == NULL)
|
||||
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_impl_ctx_size(const EVP_CIPHER *e)
|
||||
{
|
||||
return e->ctx_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;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return ctx->encrypt;
|
||||
}
|
||||
|
||||
unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
|
||||
{
|
||||
return cipher->flags;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void *EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return ctx->cipher_data;
|
||||
}
|
||||
|
||||
void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data)
|
||||
{
|
||||
void *old_cipher_data;
|
||||
|
||||
old_cipher_data = ctx->cipher_data;
|
||||
ctx->cipher_data = cipher_data;
|
||||
|
||||
return old_cipher_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;
|
||||
}
|
||||
|
||||
const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return ctx->oiv;
|
||||
}
|
||||
|
||||
const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return ctx->iv;
|
||||
}
|
||||
|
||||
unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return ctx->iv;
|
||||
}
|
||||
|
||||
unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return ctx->buf;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return ctx->num;
|
||||
}
|
||||
|
||||
void EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num)
|
||||
{
|
||||
ctx->num = num;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
unsigned long EVP_MD_flags(const EVP_MD *md)
|
||||
{
|
||||
return md->flags;
|
||||
}
|
||||
|
||||
EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type)
|
||||
{
|
||||
EVP_MD *md = OPENSSL_zalloc(sizeof(*md));
|
||||
|
||||
if (md != NULL) {
|
||||
md->type = md_type;
|
||||
md->pkey_type = pkey_type;
|
||||
}
|
||||
return md;
|
||||
}
|
||||
EVP_MD *EVP_MD_meth_dup(const EVP_MD *md)
|
||||
{
|
||||
EVP_MD *to = EVP_MD_meth_new(md->type, md->pkey_type);
|
||||
|
||||
if (to != NULL)
|
||||
memcpy(to, md, sizeof(*to));
|
||||
return to;
|
||||
}
|
||||
void EVP_MD_meth_free(EVP_MD *md)
|
||||
{
|
||||
OPENSSL_free(md);
|
||||
}
|
||||
int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize)
|
||||
{
|
||||
md->block_size = blocksize;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize)
|
||||
{
|
||||
md->md_size = resultsize;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize)
|
||||
{
|
||||
md->ctx_size = datasize;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags)
|
||||
{
|
||||
md->flags = flags;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx))
|
||||
{
|
||||
md->init = init;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx,
|
||||
const void *data,
|
||||
size_t count))
|
||||
{
|
||||
md->update = update;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx,
|
||||
unsigned char *md))
|
||||
{
|
||||
md->final = final;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to,
|
||||
const EVP_MD_CTX *from))
|
||||
{
|
||||
md->copy = copy;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx))
|
||||
{
|
||||
md->cleanup = cleanup;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd,
|
||||
int p1, void *p2))
|
||||
{
|
||||
md->md_ctrl = ctrl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_MD_meth_get_input_blocksize(const EVP_MD *md)
|
||||
{
|
||||
return md->block_size;
|
||||
}
|
||||
int EVP_MD_meth_get_result_size(const EVP_MD *md)
|
||||
{
|
||||
return md->md_size;
|
||||
}
|
||||
int EVP_MD_meth_get_app_datasize(const EVP_MD *md)
|
||||
{
|
||||
return md->ctx_size;
|
||||
}
|
||||
unsigned long EVP_MD_meth_get_flags(const EVP_MD *md)
|
||||
{
|
||||
return md->flags;
|
||||
}
|
||||
int (*EVP_MD_meth_get_init(const EVP_MD *md))(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return md->init;
|
||||
}
|
||||
int (*EVP_MD_meth_get_update(const EVP_MD *md))(EVP_MD_CTX *ctx,
|
||||
const void *data,
|
||||
size_t count)
|
||||
{
|
||||
return md->update;
|
||||
}
|
||||
int (*EVP_MD_meth_get_final(const EVP_MD *md))(EVP_MD_CTX *ctx,
|
||||
unsigned char *md)
|
||||
{
|
||||
return md->final;
|
||||
}
|
||||
int (*EVP_MD_meth_get_copy(const EVP_MD *md))(EVP_MD_CTX *to,
|
||||
const EVP_MD_CTX *from)
|
||||
{
|
||||
return md->copy;
|
||||
}
|
||||
int (*EVP_MD_meth_get_cleanup(const EVP_MD *md))(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return md->cleanup;
|
||||
}
|
||||
int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
|
||||
int p1, void *p2)
|
||||
{
|
||||
return md->md_ctrl;
|
||||
}
|
||||
|
||||
const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
|
||||
{
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
return ctx->digest;
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx)
|
||||
{
|
||||
return ctx->pctx;
|
||||
}
|
||||
|
||||
void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx)
|
||||
{
|
||||
/*
|
||||
* it's reasonable to set NULL pctx (a.k.a clear the ctx->pctx), so
|
||||
* we have to deal with the cleanup job here.
|
||||
*/
|
||||
if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX))
|
||||
EVP_PKEY_CTX_free(ctx->pctx);
|
||||
|
||||
ctx->pctx = pctx;
|
||||
|
||||
if (pctx != NULL) {
|
||||
/* make sure pctx is not freed when destroying EVP_MD_CTX */
|
||||
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
|
||||
} else {
|
||||
EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
|
||||
}
|
||||
}
|
||||
|
||||
void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx)
|
||||
{
|
||||
return ctx->md_data;
|
||||
}
|
||||
|
||||
int (*EVP_MD_CTX_update_fn(EVP_MD_CTX *ctx))(EVP_MD_CTX *ctx,
|
||||
const void *data, size_t count)
|
||||
{
|
||||
return ctx->update;
|
||||
}
|
||||
|
||||
void EVP_MD_CTX_set_update_fn(EVP_MD_CTX *ctx,
|
||||
int (*update) (EVP_MD_CTX *ctx,
|
||||
const void *data, size_t count))
|
||||
{
|
||||
ctx->update = update;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
68
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_locl.h
vendored
Normal file
68
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_locl.h
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* EVP_MD_CTX related stuff */
|
||||
|
||||
struct evp_md_ctx_st {
|
||||
const EVP_MD *digest;
|
||||
ENGINE *engine; /* functional reference if 'digest' is
|
||||
* ENGINE-provided */
|
||||
unsigned long flags;
|
||||
void *md_data;
|
||||
/* Public key context for sign/verify */
|
||||
EVP_PKEY_CTX *pctx;
|
||||
/* Update function: usually copied from EVP_MD */
|
||||
int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
|
||||
} /* EVP_MD_CTX */ ;
|
||||
|
||||
struct evp_cipher_ctx_st {
|
||||
const EVP_CIPHER *cipher;
|
||||
ENGINE *engine; /* functional reference if 'cipher' is
|
||||
* ENGINE-provided */
|
||||
int encrypt; /* encrypt or decrypt */
|
||||
int buf_len; /* number we have left */
|
||||
unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */
|
||||
unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */
|
||||
unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */
|
||||
int num; /* used by cfb/ofb/ctr mode */
|
||||
/* FIXME: Should this even exist? It appears unused */
|
||||
void *app_data; /* application stuff */
|
||||
int key_len; /* May change for variable length cipher */
|
||||
unsigned long flags; /* Various flags */
|
||||
void *cipher_data; /* per EVP data */
|
||||
int final_used;
|
||||
int block_mask;
|
||||
unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */
|
||||
} /* EVP_CIPHER_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);
|
||||
|
||||
struct evp_Encode_Ctx_st {
|
||||
/* number saved in a partial encode/decode */
|
||||
int num;
|
||||
/*
|
||||
* The length is either the output line length (in input bytes) or the
|
||||
* shortest input line length that is ok. Once decoding begins, the
|
||||
* length is adjusted up each time a longer line is decoded
|
||||
*/
|
||||
int length;
|
||||
/* data to encode */
|
||||
unsigned char enc_data[80];
|
||||
/* number read on current line */
|
||||
int line_num;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
typedef struct evp_pbe_st EVP_PBE_CTL;
|
||||
DEFINE_STACK_OF(EVP_PBE_CTL)
|
||||
|
||||
int is_partially_overlapping(const void *ptr1, const void *ptr2, int len);
|
262
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_pbe.c
vendored
Normal file
262
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_pbe.c
vendored
Normal file
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/x509.h>
|
||||
#include "evp_locl.h"
|
||||
|
||||
/* Password based encryption (PBE) functions */
|
||||
|
||||
/* Setup a cipher context from a PBE algorithm */
|
||||
|
||||
struct evp_pbe_st {
|
||||
int pbe_type;
|
||||
int pbe_nid;
|
||||
int cipher_nid;
|
||||
int md_nid;
|
||||
EVP_PBE_KEYGEN *keygen;
|
||||
};
|
||||
|
||||
static STACK_OF(EVP_PBE_CTL) *pbe_algs;
|
||||
|
||||
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},
|
||||
|
||||
{EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
|
||||
|
||||
{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},
|
||||
|
||||
{EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
|
||||
|
||||
{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_hmac_md5, -1, NID_md5, 0},
|
||||
{EVP_PBE_TYPE_PRF, NID_hmac_sha1, -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},
|
||||
{EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_2012_256, -1,
|
||||
NID_id_GostR3411_2012_256, 0},
|
||||
{EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_2012_512, -1,
|
||||
NID_id_GostR3411_2012_512, 0},
|
||||
{EVP_PBE_TYPE_PRF, NID_hmacWithSHA512_224, -1, NID_sha512_224, 0},
|
||||
{EVP_PBE_TYPE_PRF, NID_hmacWithSHA512_256, -1, NID_sha512_256, 0},
|
||||
{EVP_PBE_TYPE_KDF, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
|
||||
#ifndef OPENSSL_NO_SCRYPT
|
||||
{EVP_PBE_TYPE_KDF, NID_id_scrypt, -1, -1, PKCS5_v2_scrypt_keyivgen}
|
||||
#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)
|
||||
OPENSSL_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;
|
||||
|
||||
if (!sk_EVP_PBE_CTL_push(pbe_algs, pbe_tmp)) {
|
||||
OPENSSL_free(pbe_tmp);
|
||||
goto err;
|
||||
}
|
||||
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 != NULL) {
|
||||
i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
|
||||
pbetmp = sk_EVP_PBE_CTL_value(pbe_algs, i);
|
||||
}
|
||||
if (pbetmp == NULL) {
|
||||
pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe, OSSL_NELEM(builtin_pbe));
|
||||
}
|
||||
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_free(pbe);
|
||||
}
|
||||
|
||||
void EVP_PBE_cleanup(void)
|
||||
{
|
||||
sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
|
||||
pbe_algs = NULL;
|
||||
}
|
||||
|
||||
int EVP_PBE_get(int *ptype, int *ppbe_nid, size_t num)
|
||||
{
|
||||
const EVP_PBE_CTL *tpbe;
|
||||
|
||||
if (num >= OSSL_NELEM(builtin_pbe))
|
||||
return 0;
|
||||
|
||||
tpbe = builtin_pbe + num;
|
||||
if (ptype)
|
||||
*ptype = tpbe->pbe_type;
|
||||
if (ppbe_nid)
|
||||
*ppbe_nid = tpbe->pbe_nid;
|
||||
return 1;
|
||||
}
|
149
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_pkey.c
vendored
Normal file
149
trunk/3rdparty/openssl-1.1-fit/crypto/evp/evp_pkey.c
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/x509_int.h"
|
||||
|
||||
/* Extract a private key from a PKCS8 structure */
|
||||
|
||||
EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8)
|
||||
{
|
||||
EVP_PKEY *pkey = NULL;
|
||||
const ASN1_OBJECT *algoid;
|
||||
char obj_tmp[80];
|
||||
|
||||
if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
|
||||
return NULL;
|
||||
|
||||
if ((pkey = EVP_PKEY_new()) == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* Turn a private key into a PKCS8 structure */
|
||||
|
||||
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
|
||||
{
|
||||
PKCS8_PRIV_KEY_INFO *p8 = PKCS8_PRIV_KEY_INFO_new();
|
||||
if (p8 == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pkey->ameth) {
|
||||
if (pkey->ameth->priv_encode) {
|
||||
if (!pkey->ameth->priv_encode(p8, pkey)) {
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_PRIVATE_KEY_ENCODE_ERROR);
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_METHOD_NOT_SUPPORTED);
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
|
||||
goto error;
|
||||
}
|
||||
return p8;
|
||||
error:
|
||||
PKCS8_PRIV_KEY_INFO_free(p8);
|
||||
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, const 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;
|
||||
}
|
56
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_md2.c
vendored
Normal file
56
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_md2.c
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#ifndef OPENSSL_NO_MD2
|
||||
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/md2.h>
|
||||
# include <openssl/rsa.h>
|
||||
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
static int init(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return MD2_Init(EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
return MD2_Update(EVP_MD_CTX_md_data(ctx), data, count);
|
||||
}
|
||||
|
||||
static int final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
return MD2_Final(md, EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static const EVP_MD md2_md = {
|
||||
NID_md2,
|
||||
NID_md2WithRSAEncryption,
|
||||
MD2_DIGEST_LENGTH,
|
||||
0,
|
||||
init,
|
||||
update,
|
||||
final,
|
||||
NULL,
|
||||
NULL,
|
||||
MD2_BLOCK,
|
||||
sizeof(EVP_MD *) + sizeof(MD2_CTX),
|
||||
};
|
||||
|
||||
const EVP_MD *EVP_md2(void)
|
||||
{
|
||||
return &md2_md;
|
||||
}
|
||||
#endif
|
55
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_md4.c
vendored
Normal file
55
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_md4.c
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#ifndef OPENSSL_NO_MD4
|
||||
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/md4.h>
|
||||
# include <openssl/rsa.h>
|
||||
# include "internal/evp_int.h"
|
||||
|
||||
static int init(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return MD4_Init(EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
return MD4_Update(EVP_MD_CTX_md_data(ctx), data, count);
|
||||
}
|
||||
|
||||
static int final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
return MD4_Final(md, EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static const EVP_MD md4_md = {
|
||||
NID_md4,
|
||||
NID_md4WithRSAEncryption,
|
||||
MD4_DIGEST_LENGTH,
|
||||
0,
|
||||
init,
|
||||
update,
|
||||
final,
|
||||
NULL,
|
||||
NULL,
|
||||
MD4_CBLOCK,
|
||||
sizeof(EVP_MD *) + sizeof(MD4_CTX),
|
||||
};
|
||||
|
||||
const EVP_MD *EVP_md4(void)
|
||||
{
|
||||
return &md4_md;
|
||||
}
|
||||
#endif
|
55
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_md5.c
vendored
Normal file
55
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_md5.c
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#ifndef OPENSSL_NO_MD5
|
||||
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/md5.h>
|
||||
# include <openssl/rsa.h>
|
||||
# include "internal/evp_int.h"
|
||||
|
||||
static int init(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return MD5_Init(EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
return MD5_Update(EVP_MD_CTX_md_data(ctx), data, count);
|
||||
}
|
||||
|
||||
static int final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
return MD5_Final(md, EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static const EVP_MD md5_md = {
|
||||
NID_md5,
|
||||
NID_md5WithRSAEncryption,
|
||||
MD5_DIGEST_LENGTH,
|
||||
0,
|
||||
init,
|
||||
update,
|
||||
final,
|
||||
NULL,
|
||||
NULL,
|
||||
MD5_CBLOCK,
|
||||
sizeof(EVP_MD *) + sizeof(MD5_CTX),
|
||||
};
|
||||
|
||||
const EVP_MD *EVP_md5(void)
|
||||
{
|
||||
return &md5_md;
|
||||
}
|
||||
#endif
|
142
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_md5_sha1.c
vendored
Normal file
142
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_md5_sha1.c
vendored
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#if !defined(OPENSSL_NO_MD5)
|
||||
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/md5.h>
|
||||
# include <openssl/sha.h>
|
||||
# include "internal/cryptlib.h"
|
||||
# include "internal/evp_int.h"
|
||||
# include <openssl/rsa.h>
|
||||
|
||||
struct md5_sha1_ctx {
|
||||
MD5_CTX md5;
|
||||
SHA_CTX sha1;
|
||||
};
|
||||
|
||||
static int init(EVP_MD_CTX *ctx)
|
||||
{
|
||||
struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
|
||||
if (!MD5_Init(&mctx->md5))
|
||||
return 0;
|
||||
return SHA1_Init(&mctx->sha1);
|
||||
}
|
||||
|
||||
static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
|
||||
if (!MD5_Update(&mctx->md5, data, count))
|
||||
return 0;
|
||||
return SHA1_Update(&mctx->sha1, data, count);
|
||||
}
|
||||
|
||||
static int final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
|
||||
if (!MD5_Final(md, &mctx->md5))
|
||||
return 0;
|
||||
return SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1);
|
||||
}
|
||||
|
||||
static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms)
|
||||
{
|
||||
unsigned char padtmp[48];
|
||||
unsigned char md5tmp[MD5_DIGEST_LENGTH];
|
||||
unsigned char sha1tmp[SHA_DIGEST_LENGTH];
|
||||
struct md5_sha1_ctx *mctx;
|
||||
|
||||
if (cmd != EVP_CTRL_SSL3_MASTER_SECRET)
|
||||
return -2;
|
||||
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
mctx = EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
/* SSLv3 client auth handling: see RFC-6101 5.6.8 */
|
||||
if (mslen != 48)
|
||||
return 0;
|
||||
|
||||
/* At this point hash contains all handshake messages, update
|
||||
* with master secret and pad_1.
|
||||
*/
|
||||
|
||||
if (update(ctx, ms, mslen) <= 0)
|
||||
return 0;
|
||||
|
||||
/* Set padtmp to pad_1 value */
|
||||
memset(padtmp, 0x36, sizeof(padtmp));
|
||||
|
||||
if (!MD5_Update(&mctx->md5, padtmp, sizeof(padtmp)))
|
||||
return 0;
|
||||
|
||||
if (!MD5_Final(md5tmp, &mctx->md5))
|
||||
return 0;
|
||||
|
||||
if (!SHA1_Update(&mctx->sha1, padtmp, 40))
|
||||
return 0;
|
||||
|
||||
if (!SHA1_Final(sha1tmp, &mctx->sha1))
|
||||
return 0;
|
||||
|
||||
/* Reinitialise context */
|
||||
|
||||
if (!init(ctx))
|
||||
return 0;
|
||||
|
||||
if (update(ctx, ms, mslen) <= 0)
|
||||
return 0;
|
||||
|
||||
/* Set padtmp to pad_2 value */
|
||||
memset(padtmp, 0x5c, sizeof(padtmp));
|
||||
|
||||
if (!MD5_Update(&mctx->md5, padtmp, sizeof(padtmp)))
|
||||
return 0;
|
||||
|
||||
if (!MD5_Update(&mctx->md5, md5tmp, sizeof(md5tmp)))
|
||||
return 0;
|
||||
|
||||
if (!SHA1_Update(&mctx->sha1, padtmp, 40))
|
||||
return 0;
|
||||
|
||||
if (!SHA1_Update(&mctx->sha1, sha1tmp, sizeof(sha1tmp)))
|
||||
return 0;
|
||||
|
||||
/* Now when ctx is finalised it will return the SSL v3 hash value */
|
||||
|
||||
OPENSSL_cleanse(md5tmp, sizeof(md5tmp));
|
||||
OPENSSL_cleanse(sha1tmp, sizeof(sha1tmp));
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
static const EVP_MD md5_sha1_md = {
|
||||
NID_md5_sha1,
|
||||
NID_md5_sha1,
|
||||
MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
|
||||
0,
|
||||
init,
|
||||
update,
|
||||
final,
|
||||
NULL,
|
||||
NULL,
|
||||
MD5_CBLOCK,
|
||||
sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx),
|
||||
ctrl
|
||||
};
|
||||
|
||||
const EVP_MD *EVP_md5_sha1(void)
|
||||
{
|
||||
return &md5_sha1_md;
|
||||
}
|
||||
#endif
|
55
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_mdc2.c
vendored
Normal file
55
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_mdc2.c
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#ifndef OPENSSL_NO_MDC2
|
||||
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/mdc2.h>
|
||||
# include <openssl/rsa.h>
|
||||
# include "internal/evp_int.h"
|
||||
|
||||
static int init(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return MDC2_Init(EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
return MDC2_Update(EVP_MD_CTX_md_data(ctx), data, count);
|
||||
}
|
||||
|
||||
static int final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
return MDC2_Final(md, EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static const EVP_MD mdc2_md = {
|
||||
NID_mdc2,
|
||||
NID_mdc2WithRSA,
|
||||
MDC2_DIGEST_LENGTH,
|
||||
0,
|
||||
init,
|
||||
update,
|
||||
final,
|
||||
NULL,
|
||||
NULL,
|
||||
MDC2_BLOCK,
|
||||
sizeof(EVP_MD *) + sizeof(MDC2_CTX),
|
||||
};
|
||||
|
||||
const EVP_MD *EVP_mdc2(void)
|
||||
{
|
||||
return &mdc2_md;
|
||||
}
|
||||
#endif
|
49
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_null.c
vendored
Normal file
49
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_null.c
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
#include "internal/evp_int.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,
|
||||
0,
|
||||
sizeof(EVP_MD *),
|
||||
};
|
||||
|
||||
const EVP_MD *EVP_md_null(void)
|
||||
{
|
||||
return &null_md;
|
||||
}
|
55
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_ripemd.c
vendored
Normal file
55
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_ripemd.c
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#ifndef OPENSSL_NO_RMD160
|
||||
|
||||
# include <openssl/ripemd.h>
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/rsa.h>
|
||||
# include "internal/evp_int.h"
|
||||
|
||||
static int init(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return RIPEMD160_Init(EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
return RIPEMD160_Update(EVP_MD_CTX_md_data(ctx), data, count);
|
||||
}
|
||||
|
||||
static int final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
return RIPEMD160_Final(md, EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static const EVP_MD ripemd160_md = {
|
||||
NID_ripemd160,
|
||||
NID_ripemd160WithRSA,
|
||||
RIPEMD160_DIGEST_LENGTH,
|
||||
0,
|
||||
init,
|
||||
update,
|
||||
final,
|
||||
NULL,
|
||||
NULL,
|
||||
RIPEMD160_CBLOCK,
|
||||
sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX),
|
||||
};
|
||||
|
||||
const EVP_MD *EVP_ripemd160(void)
|
||||
{
|
||||
return &ripemd160_md;
|
||||
}
|
||||
#endif
|
297
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_sha1.c
vendored
Normal file
297
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_sha1.c
vendored
Normal file
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/sha.h"
|
||||
|
||||
static int init(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return SHA1_Init(EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
return SHA1_Update(EVP_MD_CTX_md_data(ctx), data, count);
|
||||
}
|
||||
|
||||
static int final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
return SHA1_Final(md, EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms)
|
||||
{
|
||||
unsigned char padtmp[40];
|
||||
unsigned char sha1tmp[SHA_DIGEST_LENGTH];
|
||||
|
||||
SHA_CTX *sha1;
|
||||
|
||||
if (cmd != EVP_CTRL_SSL3_MASTER_SECRET)
|
||||
return -2;
|
||||
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
sha1 = EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
/* SSLv3 client auth handling: see RFC-6101 5.6.8 */
|
||||
if (mslen != 48)
|
||||
return 0;
|
||||
|
||||
/* At this point hash contains all handshake messages, update
|
||||
* with master secret and pad_1.
|
||||
*/
|
||||
|
||||
if (SHA1_Update(sha1, ms, mslen) <= 0)
|
||||
return 0;
|
||||
|
||||
/* Set padtmp to pad_1 value */
|
||||
memset(padtmp, 0x36, sizeof(padtmp));
|
||||
|
||||
if (!SHA1_Update(sha1, padtmp, sizeof(padtmp)))
|
||||
return 0;
|
||||
|
||||
if (!SHA1_Final(sha1tmp, sha1))
|
||||
return 0;
|
||||
|
||||
/* Reinitialise context */
|
||||
|
||||
if (!SHA1_Init(sha1))
|
||||
return 0;
|
||||
|
||||
if (SHA1_Update(sha1, ms, mslen) <= 0)
|
||||
return 0;
|
||||
|
||||
/* Set padtmp to pad_2 value */
|
||||
memset(padtmp, 0x5c, sizeof(padtmp));
|
||||
|
||||
if (!SHA1_Update(sha1, padtmp, sizeof(padtmp)))
|
||||
return 0;
|
||||
|
||||
if (!SHA1_Update(sha1, sha1tmp, sizeof(sha1tmp)))
|
||||
return 0;
|
||||
|
||||
/* Now when ctx is finalised it will return the SSL v3 hash value */
|
||||
OPENSSL_cleanse(sha1tmp, sizeof(sha1tmp));
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
static const EVP_MD sha1_md = {
|
||||
NID_sha1,
|
||||
NID_sha1WithRSAEncryption,
|
||||
SHA_DIGEST_LENGTH,
|
||||
EVP_MD_FLAG_DIGALGID_ABSENT,
|
||||
init,
|
||||
update,
|
||||
final,
|
||||
NULL,
|
||||
NULL,
|
||||
SHA_CBLOCK,
|
||||
sizeof(EVP_MD *) + sizeof(SHA_CTX),
|
||||
ctrl
|
||||
};
|
||||
|
||||
const EVP_MD *EVP_sha1(void)
|
||||
{
|
||||
return &sha1_md;
|
||||
}
|
||||
|
||||
static int init224(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return SHA224_Init(EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int update224(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
return SHA224_Update(EVP_MD_CTX_md_data(ctx), data, count);
|
||||
}
|
||||
|
||||
static int final224(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
return SHA224_Final(md, EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int init256(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return SHA256_Init(EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int update256(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
return SHA256_Update(EVP_MD_CTX_md_data(ctx), data, count);
|
||||
}
|
||||
|
||||
static int final256(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
return SHA256_Final(md, EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static const EVP_MD sha224_md = {
|
||||
NID_sha224,
|
||||
NID_sha224WithRSAEncryption,
|
||||
SHA224_DIGEST_LENGTH,
|
||||
EVP_MD_FLAG_DIGALGID_ABSENT,
|
||||
init224,
|
||||
update224,
|
||||
final224,
|
||||
NULL,
|
||||
NULL,
|
||||
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_DIGALGID_ABSENT,
|
||||
init256,
|
||||
update256,
|
||||
final256,
|
||||
NULL,
|
||||
NULL,
|
||||
SHA256_CBLOCK,
|
||||
sizeof(EVP_MD *) + sizeof(SHA256_CTX),
|
||||
};
|
||||
|
||||
const EVP_MD *EVP_sha256(void)
|
||||
{
|
||||
return &sha256_md;
|
||||
}
|
||||
|
||||
static int init512_224(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return sha512_224_init(EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int init512_256(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return sha512_256_init(EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int init384(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return SHA384_Init(EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int update384(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
return SHA384_Update(EVP_MD_CTX_md_data(ctx), data, count);
|
||||
}
|
||||
|
||||
static int final384(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
return SHA384_Final(md, EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int init512(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return SHA512_Init(EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
/* See comment in SHA224/256 section */
|
||||
static int update512(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
return SHA512_Update(EVP_MD_CTX_md_data(ctx), data, count);
|
||||
}
|
||||
|
||||
static int final512(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
return SHA512_Final(md, EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static const EVP_MD sha512_224_md = {
|
||||
NID_sha512_224,
|
||||
NID_sha512_224WithRSAEncryption,
|
||||
SHA224_DIGEST_LENGTH,
|
||||
EVP_MD_FLAG_DIGALGID_ABSENT,
|
||||
init512_224,
|
||||
update512,
|
||||
final512,
|
||||
NULL,
|
||||
NULL,
|
||||
SHA512_CBLOCK,
|
||||
sizeof(EVP_MD *) + sizeof(SHA512_CTX),
|
||||
};
|
||||
|
||||
const EVP_MD *EVP_sha512_224(void)
|
||||
{
|
||||
return &sha512_224_md;
|
||||
}
|
||||
|
||||
static const EVP_MD sha512_256_md = {
|
||||
NID_sha512_256,
|
||||
NID_sha512_256WithRSAEncryption,
|
||||
SHA256_DIGEST_LENGTH,
|
||||
EVP_MD_FLAG_DIGALGID_ABSENT,
|
||||
init512_256,
|
||||
update512,
|
||||
final512,
|
||||
NULL,
|
||||
NULL,
|
||||
SHA512_CBLOCK,
|
||||
sizeof(EVP_MD *) + sizeof(SHA512_CTX),
|
||||
};
|
||||
|
||||
const EVP_MD *EVP_sha512_256(void)
|
||||
{
|
||||
return &sha512_256_md;
|
||||
}
|
||||
|
||||
static const EVP_MD sha384_md = {
|
||||
NID_sha384,
|
||||
NID_sha384WithRSAEncryption,
|
||||
SHA384_DIGEST_LENGTH,
|
||||
EVP_MD_FLAG_DIGALGID_ABSENT,
|
||||
init384,
|
||||
update384,
|
||||
final384,
|
||||
NULL,
|
||||
NULL,
|
||||
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_DIGALGID_ABSENT,
|
||||
init512,
|
||||
update512,
|
||||
final512,
|
||||
NULL,
|
||||
NULL,
|
||||
SHA512_CBLOCK,
|
||||
sizeof(EVP_MD *) + sizeof(SHA512_CTX),
|
||||
};
|
||||
|
||||
const EVP_MD *EVP_sha512(void)
|
||||
{
|
||||
return &sha512_md;
|
||||
}
|
406
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_sha3.c
vendored
Normal file
406
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_sha3.c
vendored
Normal file
|
@ -0,0 +1,406 @@
|
|||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t len,
|
||||
size_t r);
|
||||
void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r);
|
||||
|
||||
#define KECCAK1600_WIDTH 1600
|
||||
|
||||
typedef struct {
|
||||
uint64_t A[5][5];
|
||||
size_t block_size; /* cached ctx->digest->block_size */
|
||||
size_t md_size; /* output length, variable in XOF */
|
||||
size_t num; /* used bytes in below buffer */
|
||||
unsigned char buf[KECCAK1600_WIDTH / 8 - 32];
|
||||
unsigned char pad;
|
||||
} KECCAK1600_CTX;
|
||||
|
||||
static int init(EVP_MD_CTX *evp_ctx, unsigned char pad)
|
||||
{
|
||||
KECCAK1600_CTX *ctx = evp_ctx->md_data;
|
||||
size_t bsz = evp_ctx->digest->block_size;
|
||||
|
||||
if (bsz <= sizeof(ctx->buf)) {
|
||||
memset(ctx->A, 0, sizeof(ctx->A));
|
||||
|
||||
ctx->num = 0;
|
||||
ctx->block_size = bsz;
|
||||
ctx->md_size = evp_ctx->digest->md_size;
|
||||
ctx->pad = pad;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha3_init(EVP_MD_CTX *evp_ctx)
|
||||
{
|
||||
return init(evp_ctx, '\x06');
|
||||
}
|
||||
|
||||
static int shake_init(EVP_MD_CTX *evp_ctx)
|
||||
{
|
||||
return init(evp_ctx, '\x1f');
|
||||
}
|
||||
|
||||
static int sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len)
|
||||
{
|
||||
KECCAK1600_CTX *ctx = evp_ctx->md_data;
|
||||
const unsigned char *inp = _inp;
|
||||
size_t bsz = ctx->block_size;
|
||||
size_t num, rem;
|
||||
|
||||
if (len == 0)
|
||||
return 1;
|
||||
|
||||
if ((num = ctx->num) != 0) { /* process intermediate buffer? */
|
||||
rem = bsz - num;
|
||||
|
||||
if (len < rem) {
|
||||
memcpy(ctx->buf + num, inp, len);
|
||||
ctx->num += len;
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* We have enough data to fill or overflow the intermediate
|
||||
* buffer. So we append |rem| bytes and process the block,
|
||||
* leaving the rest for later processing...
|
||||
*/
|
||||
memcpy(ctx->buf + num, inp, rem);
|
||||
inp += rem, len -= rem;
|
||||
(void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
|
||||
ctx->num = 0;
|
||||
/* ctx->buf is processed, ctx->num is guaranteed to be zero */
|
||||
}
|
||||
|
||||
if (len >= bsz)
|
||||
rem = SHA3_absorb(ctx->A, inp, len, bsz);
|
||||
else
|
||||
rem = len;
|
||||
|
||||
if (rem) {
|
||||
memcpy(ctx->buf, inp + len - rem, rem);
|
||||
ctx->num = rem;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int sha3_final(EVP_MD_CTX *evp_ctx, unsigned char *md)
|
||||
{
|
||||
KECCAK1600_CTX *ctx = evp_ctx->md_data;
|
||||
size_t bsz = ctx->block_size;
|
||||
size_t num = ctx->num;
|
||||
|
||||
/*
|
||||
* Pad the data with 10*1. Note that |num| can be |bsz - 1|
|
||||
* in which case both byte operations below are performed on
|
||||
* same byte...
|
||||
*/
|
||||
memset(ctx->buf + num, 0, bsz - num);
|
||||
ctx->buf[num] = ctx->pad;
|
||||
ctx->buf[bsz - 1] |= 0x80;
|
||||
|
||||
(void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
|
||||
|
||||
SHA3_squeeze(ctx->A, md, ctx->md_size, bsz);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int shake_ctrl(EVP_MD_CTX *evp_ctx, int cmd, int p1, void *p2)
|
||||
{
|
||||
KECCAK1600_CTX *ctx = evp_ctx->md_data;
|
||||
|
||||
switch (cmd) {
|
||||
case EVP_MD_CTRL_XOF_LEN:
|
||||
ctx->md_size = p1;
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM)
|
||||
/*
|
||||
* IBM S390X support
|
||||
*/
|
||||
# include "s390x_arch.h"
|
||||
|
||||
# define S390X_SHA3_FC(ctx) ((ctx)->pad)
|
||||
|
||||
# define S390X_sha3_224_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \
|
||||
S390X_CAPBIT(S390X_SHA3_224)) && \
|
||||
(OPENSSL_s390xcap_P.klmd[0] & \
|
||||
S390X_CAPBIT(S390X_SHA3_224)))
|
||||
# define S390X_sha3_256_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \
|
||||
S390X_CAPBIT(S390X_SHA3_256)) && \
|
||||
(OPENSSL_s390xcap_P.klmd[0] & \
|
||||
S390X_CAPBIT(S390X_SHA3_256)))
|
||||
# define S390X_sha3_384_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \
|
||||
S390X_CAPBIT(S390X_SHA3_384)) && \
|
||||
(OPENSSL_s390xcap_P.klmd[0] & \
|
||||
S390X_CAPBIT(S390X_SHA3_384)))
|
||||
# define S390X_sha3_512_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \
|
||||
S390X_CAPBIT(S390X_SHA3_512)) && \
|
||||
(OPENSSL_s390xcap_P.klmd[0] & \
|
||||
S390X_CAPBIT(S390X_SHA3_512)))
|
||||
# define S390X_shake128_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \
|
||||
S390X_CAPBIT(S390X_SHAKE_128)) && \
|
||||
(OPENSSL_s390xcap_P.klmd[0] & \
|
||||
S390X_CAPBIT(S390X_SHAKE_128)))
|
||||
# define S390X_shake256_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \
|
||||
S390X_CAPBIT(S390X_SHAKE_256)) && \
|
||||
(OPENSSL_s390xcap_P.klmd[0] & \
|
||||
S390X_CAPBIT(S390X_SHAKE_256)))
|
||||
|
||||
/* Convert md-size to block-size. */
|
||||
# define S390X_KECCAK1600_BSZ(n) ((KECCAK1600_WIDTH - ((n) << 1)) >> 3)
|
||||
|
||||
static int s390x_sha3_init(EVP_MD_CTX *evp_ctx)
|
||||
{
|
||||
KECCAK1600_CTX *ctx = evp_ctx->md_data;
|
||||
const size_t bsz = evp_ctx->digest->block_size;
|
||||
|
||||
/*-
|
||||
* KECCAK1600_CTX structure's pad field is used to store the KIMD/KLMD
|
||||
* function code.
|
||||
*/
|
||||
switch (bsz) {
|
||||
case S390X_KECCAK1600_BSZ(224):
|
||||
ctx->pad = S390X_SHA3_224;
|
||||
break;
|
||||
case S390X_KECCAK1600_BSZ(256):
|
||||
ctx->pad = S390X_SHA3_256;
|
||||
break;
|
||||
case S390X_KECCAK1600_BSZ(384):
|
||||
ctx->pad = S390X_SHA3_384;
|
||||
break;
|
||||
case S390X_KECCAK1600_BSZ(512):
|
||||
ctx->pad = S390X_SHA3_512;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(ctx->A, 0, sizeof(ctx->A));
|
||||
ctx->num = 0;
|
||||
ctx->block_size = bsz;
|
||||
ctx->md_size = evp_ctx->digest->md_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_shake_init(EVP_MD_CTX *evp_ctx)
|
||||
{
|
||||
KECCAK1600_CTX *ctx = evp_ctx->md_data;
|
||||
const size_t bsz = evp_ctx->digest->block_size;
|
||||
|
||||
/*-
|
||||
* KECCAK1600_CTX structure's pad field is used to store the KIMD/KLMD
|
||||
* function code.
|
||||
*/
|
||||
switch (bsz) {
|
||||
case S390X_KECCAK1600_BSZ(128):
|
||||
ctx->pad = S390X_SHAKE_128;
|
||||
break;
|
||||
case S390X_KECCAK1600_BSZ(256):
|
||||
ctx->pad = S390X_SHAKE_256;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(ctx->A, 0, sizeof(ctx->A));
|
||||
ctx->num = 0;
|
||||
ctx->block_size = bsz;
|
||||
ctx->md_size = evp_ctx->digest->md_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len)
|
||||
{
|
||||
KECCAK1600_CTX *ctx = evp_ctx->md_data;
|
||||
const unsigned char *inp = _inp;
|
||||
const size_t bsz = ctx->block_size;
|
||||
size_t num, rem;
|
||||
|
||||
if (len == 0)
|
||||
return 1;
|
||||
|
||||
if ((num = ctx->num) != 0) {
|
||||
rem = bsz - num;
|
||||
|
||||
if (len < rem) {
|
||||
memcpy(ctx->buf + num, inp, len);
|
||||
ctx->num += len;
|
||||
return 1;
|
||||
}
|
||||
memcpy(ctx->buf + num, inp, rem);
|
||||
inp += rem;
|
||||
len -= rem;
|
||||
s390x_kimd(ctx->buf, bsz, ctx->pad, ctx->A);
|
||||
ctx->num = 0;
|
||||
}
|
||||
rem = len % bsz;
|
||||
|
||||
s390x_kimd(inp, len - rem, ctx->pad, ctx->A);
|
||||
|
||||
if (rem) {
|
||||
memcpy(ctx->buf, inp + len - rem, rem);
|
||||
ctx->num = rem;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_sha3_final(EVP_MD_CTX *evp_ctx, unsigned char *md)
|
||||
{
|
||||
KECCAK1600_CTX *ctx = evp_ctx->md_data;
|
||||
|
||||
s390x_klmd(ctx->buf, ctx->num, NULL, 0, ctx->pad, ctx->A);
|
||||
memcpy(md, ctx->A, ctx->md_size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_shake_final(EVP_MD_CTX *evp_ctx, unsigned char *md)
|
||||
{
|
||||
KECCAK1600_CTX *ctx = evp_ctx->md_data;
|
||||
|
||||
s390x_klmd(ctx->buf, ctx->num, md, ctx->md_size, ctx->pad, ctx->A);
|
||||
return 1;
|
||||
}
|
||||
|
||||
# define EVP_MD_SHA3(bitlen) \
|
||||
const EVP_MD *EVP_sha3_##bitlen(void) \
|
||||
{ \
|
||||
static const EVP_MD s390x_sha3_##bitlen##_md = { \
|
||||
NID_sha3_##bitlen, \
|
||||
NID_RSA_SHA3_##bitlen, \
|
||||
bitlen / 8, \
|
||||
EVP_MD_FLAG_DIGALGID_ABSENT, \
|
||||
s390x_sha3_init, \
|
||||
s390x_sha3_update, \
|
||||
s390x_sha3_final, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
|
||||
sizeof(KECCAK1600_CTX), \
|
||||
}; \
|
||||
static const EVP_MD sha3_##bitlen##_md = { \
|
||||
NID_sha3_##bitlen, \
|
||||
NID_RSA_SHA3_##bitlen, \
|
||||
bitlen / 8, \
|
||||
EVP_MD_FLAG_DIGALGID_ABSENT, \
|
||||
sha3_init, \
|
||||
sha3_update, \
|
||||
sha3_final, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
|
||||
sizeof(KECCAK1600_CTX), \
|
||||
}; \
|
||||
return S390X_sha3_##bitlen##_CAPABLE ? \
|
||||
&s390x_sha3_##bitlen##_md : \
|
||||
&sha3_##bitlen##_md; \
|
||||
}
|
||||
|
||||
# define EVP_MD_SHAKE(bitlen) \
|
||||
const EVP_MD *EVP_shake##bitlen(void) \
|
||||
{ \
|
||||
static const EVP_MD s390x_shake##bitlen##_md = { \
|
||||
NID_shake##bitlen, \
|
||||
0, \
|
||||
bitlen / 8, \
|
||||
EVP_MD_FLAG_XOF, \
|
||||
s390x_shake_init, \
|
||||
s390x_sha3_update, \
|
||||
s390x_shake_final, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
|
||||
sizeof(KECCAK1600_CTX), \
|
||||
shake_ctrl \
|
||||
}; \
|
||||
static const EVP_MD shake##bitlen##_md = { \
|
||||
NID_shake##bitlen, \
|
||||
0, \
|
||||
bitlen / 8, \
|
||||
EVP_MD_FLAG_XOF, \
|
||||
shake_init, \
|
||||
sha3_update, \
|
||||
sha3_final, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
|
||||
sizeof(KECCAK1600_CTX), \
|
||||
shake_ctrl \
|
||||
}; \
|
||||
return S390X_shake##bitlen##_CAPABLE ? \
|
||||
&s390x_shake##bitlen##_md : \
|
||||
&shake##bitlen##_md; \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# define EVP_MD_SHA3(bitlen) \
|
||||
const EVP_MD *EVP_sha3_##bitlen(void) \
|
||||
{ \
|
||||
static const EVP_MD sha3_##bitlen##_md = { \
|
||||
NID_sha3_##bitlen, \
|
||||
NID_RSA_SHA3_##bitlen, \
|
||||
bitlen / 8, \
|
||||
EVP_MD_FLAG_DIGALGID_ABSENT, \
|
||||
sha3_init, \
|
||||
sha3_update, \
|
||||
sha3_final, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
|
||||
sizeof(KECCAK1600_CTX), \
|
||||
}; \
|
||||
return &sha3_##bitlen##_md; \
|
||||
}
|
||||
|
||||
# define EVP_MD_SHAKE(bitlen) \
|
||||
const EVP_MD *EVP_shake##bitlen(void) \
|
||||
{ \
|
||||
static const EVP_MD shake##bitlen##_md = { \
|
||||
NID_shake##bitlen, \
|
||||
0, \
|
||||
bitlen / 8, \
|
||||
EVP_MD_FLAG_XOF, \
|
||||
shake_init, \
|
||||
sha3_update, \
|
||||
sha3_final, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
|
||||
sizeof(KECCAK1600_CTX), \
|
||||
shake_ctrl \
|
||||
}; \
|
||||
return &shake##bitlen##_md; \
|
||||
}
|
||||
#endif
|
||||
|
||||
EVP_MD_SHA3(224)
|
||||
EVP_MD_SHA3(256)
|
||||
EVP_MD_SHA3(384)
|
||||
EVP_MD_SHA3(512)
|
||||
|
||||
EVP_MD_SHAKE(128)
|
||||
EVP_MD_SHAKE(256)
|
218
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_sigver.c
vendored
Normal file
218
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_sigver.c
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen)
|
||||
{
|
||||
EVPerr(EVP_F_UPDATE, EVP_R_ONLY_ONESHOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (ctx->pctx->pmeth->digestverify != 0) {
|
||||
ctx->pctx->operation = EVP_PKEY_OP_VERIFY;
|
||||
ctx->update = update;
|
||||
} 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 (ctx->pctx->pmeth->digestsign != 0) {
|
||||
ctx->pctx->operation = EVP_PKEY_OP_SIGN;
|
||||
ctx->update = update;
|
||||
} 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;
|
||||
/*
|
||||
* This indicates the current algorithm requires
|
||||
* special treatment before hashing the tbs-message.
|
||||
*/
|
||||
if (ctx->pctx->pmeth->digest_custom != NULL)
|
||||
return ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx);
|
||||
|
||||
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 = 0, r = 0;
|
||||
EVP_PKEY_CTX *pctx = ctx->pctx;
|
||||
if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
|
||||
if (!sigret)
|
||||
return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
|
||||
if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
|
||||
r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
|
||||
else {
|
||||
EVP_PKEY_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) {
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
unsigned int mdlen = 0;
|
||||
if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
|
||||
if (sctx)
|
||||
r = ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx);
|
||||
else
|
||||
r = EVP_DigestFinal_ex(ctx, md, &mdlen);
|
||||
} else {
|
||||
EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
|
||||
if (tmp_ctx == NULL)
|
||||
return 0;
|
||||
if (!EVP_MD_CTX_copy_ex(tmp_ctx, ctx)) {
|
||||
EVP_MD_CTX_free(tmp_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_free(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_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen)
|
||||
{
|
||||
if (ctx->pctx->pmeth->digestsign != NULL)
|
||||
return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen);
|
||||
if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0)
|
||||
return 0;
|
||||
return EVP_DigestSignFinal(ctx, sigret, siglen);
|
||||
}
|
||||
|
||||
int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
size_t siglen)
|
||||
{
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
int r = 0;
|
||||
unsigned int mdlen = 0;
|
||||
int vctx = 0;
|
||||
|
||||
if (ctx->pctx->pmeth->verifyctx)
|
||||
vctx = 1;
|
||||
else
|
||||
vctx = 0;
|
||||
if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
|
||||
if (vctx)
|
||||
r = ctx->pctx->pmeth->verifyctx(ctx->pctx, sig, siglen, ctx);
|
||||
else
|
||||
r = EVP_DigestFinal_ex(ctx, md, &mdlen);
|
||||
} else {
|
||||
EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
|
||||
if (tmp_ctx == NULL)
|
||||
return -1;
|
||||
if (!EVP_MD_CTX_copy_ex(tmp_ctx, ctx)) {
|
||||
EVP_MD_CTX_free(tmp_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_free(tmp_ctx);
|
||||
}
|
||||
if (vctx || !r)
|
||||
return r;
|
||||
return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
|
||||
}
|
||||
|
||||
int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
|
||||
size_t siglen, const unsigned char *tbs, size_t tbslen)
|
||||
{
|
||||
if (ctx->pctx->pmeth->digestverify != NULL)
|
||||
return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen);
|
||||
if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0)
|
||||
return -1;
|
||||
return EVP_DigestVerifyFinal(ctx, sigret, siglen);
|
||||
}
|
54
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_wp.c
vendored
Normal file
54
trunk/3rdparty/openssl-1.1-fit/crypto/evp/m_wp.c
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#ifndef OPENSSL_NO_WHIRLPOOL
|
||||
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/objects.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/whrlpool.h>
|
||||
# include "internal/evp_int.h"
|
||||
|
||||
static int init(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return WHIRLPOOL_Init(EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
return WHIRLPOOL_Update(EVP_MD_CTX_md_data(ctx), data, count);
|
||||
}
|
||||
|
||||
static int final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
return WHIRLPOOL_Final(md, EVP_MD_CTX_md_data(ctx));
|
||||
}
|
||||
|
||||
static const EVP_MD whirlpool_md = {
|
||||
NID_whirlpool,
|
||||
0,
|
||||
WHIRLPOOL_DIGEST_LENGTH,
|
||||
0,
|
||||
init,
|
||||
update,
|
||||
final,
|
||||
NULL,
|
||||
NULL,
|
||||
WHIRLPOOL_BBLOCK / 8,
|
||||
sizeof(EVP_MD *) + sizeof(WHIRLPOOL_CTX),
|
||||
};
|
||||
|
||||
const EVP_MD *EVP_whirlpool(void)
|
||||
{
|
||||
return &whirlpool_md;
|
||||
}
|
||||
#endif
|
180
trunk/3rdparty/openssl-1.1-fit/crypto/evp/names.c
vendored
Normal file
180
trunk/3rdparty/openssl-1.1-fit/crypto/evp/names.c
vendored
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/objects.h"
|
||||
#include <openssl/x509.h>
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
int EVP_add_cipher(const EVP_CIPHER *c)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (c == NULL)
|
||||
return 0;
|
||||
|
||||
r = OBJ_NAME_add(OBJ_nid2sn(c->nid), OBJ_NAME_TYPE_CIPHER_METH,
|
||||
(const char *)c);
|
||||
if (r == 0)
|
||||
return 0;
|
||||
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;
|
||||
|
||||
name = OBJ_nid2sn(md->type);
|
||||
r = OBJ_NAME_add(name, OBJ_NAME_TYPE_MD_METH, (const char *)md);
|
||||
if (r == 0)
|
||||
return 0;
|
||||
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;
|
||||
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;
|
||||
|
||||
if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL))
|
||||
return NULL;
|
||||
|
||||
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;
|
||||
|
||||
if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL))
|
||||
return NULL;
|
||||
|
||||
cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
|
||||
return cp;
|
||||
}
|
||||
|
||||
void evp_cleanup_int(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();
|
||||
OBJ_sigid_free();
|
||||
|
||||
evp_app_cleanup_int();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* Ignore errors */
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL);
|
||||
|
||||
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;
|
||||
|
||||
/* Ignore errors */
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL);
|
||||
|
||||
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;
|
||||
|
||||
/* Ignore errors */
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
|
||||
|
||||
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;
|
||||
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
|
||||
|
||||
dc.fn = fn;
|
||||
dc.arg = arg;
|
||||
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
|
||||
}
|
103
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p5_crpt.c
vendored
Normal file
103
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p5_crpt.c
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "internal/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;
|
||||
int mdsize;
|
||||
int rv = 0;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), param);
|
||||
if (pbe == NULL) {
|
||||
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);
|
||||
|
||||
ctx = EVP_MD_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
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_free(ctx);
|
||||
return rv;
|
||||
}
|
265
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p5_crpt2.c
vendored
Normal file
265
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p5_crpt2.c
vendored
Normal file
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "internal/cryptlib.h"
|
||||
# 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 OPENSSL_DEBUG_PKCS5V2 */
|
||||
|
||||
# ifdef OPENSSL_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 to the PKCS-TNG 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)
|
||||
{
|
||||
const char *empty = "";
|
||||
unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
|
||||
int cplen, j, k, tkeylen, mdlen;
|
||||
unsigned long i = 1;
|
||||
HMAC_CTX *hctx_tpl = NULL, *hctx = NULL;
|
||||
|
||||
mdlen = EVP_MD_size(digest);
|
||||
if (mdlen < 0)
|
||||
return 0;
|
||||
|
||||
hctx_tpl = HMAC_CTX_new();
|
||||
if (hctx_tpl == NULL)
|
||||
return 0;
|
||||
p = out;
|
||||
tkeylen = keylen;
|
||||
if (pass == NULL) {
|
||||
pass = empty;
|
||||
passlen = 0;
|
||||
} else if (passlen == -1) {
|
||||
passlen = strlen(pass);
|
||||
}
|
||||
if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) {
|
||||
HMAC_CTX_free(hctx_tpl);
|
||||
return 0;
|
||||
}
|
||||
hctx = HMAC_CTX_new();
|
||||
if (hctx == NULL) {
|
||||
HMAC_CTX_free(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_free(hctx);
|
||||
HMAC_CTX_free(hctx_tpl);
|
||||
return 0;
|
||||
}
|
||||
if (!HMAC_Update(hctx, salt, saltlen)
|
||||
|| !HMAC_Update(hctx, itmp, 4)
|
||||
|| !HMAC_Final(hctx, digtmp, NULL)) {
|
||||
HMAC_CTX_free(hctx);
|
||||
HMAC_CTX_free(hctx_tpl);
|
||||
return 0;
|
||||
}
|
||||
memcpy(p, digtmp, cplen);
|
||||
for (j = 1; j < iter; j++) {
|
||||
if (!HMAC_CTX_copy(hctx, hctx_tpl)) {
|
||||
HMAC_CTX_free(hctx);
|
||||
HMAC_CTX_free(hctx_tpl);
|
||||
return 0;
|
||||
}
|
||||
if (!HMAC_Update(hctx, digtmp, mdlen)
|
||||
|| !HMAC_Final(hctx, digtmp, NULL)) {
|
||||
HMAC_CTX_free(hctx);
|
||||
HMAC_CTX_free(hctx_tpl);
|
||||
return 0;
|
||||
}
|
||||
for (k = 0; k < cplen; k++)
|
||||
p[k] ^= digtmp[k];
|
||||
}
|
||||
tkeylen -= cplen;
|
||||
i++;
|
||||
p += cplen;
|
||||
}
|
||||
HMAC_CTX_free(hctx);
|
||||
HMAC_CTX_free(hctx_tpl);
|
||||
# ifdef OPENSSL_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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
PBE2PARAM *pbe2 = NULL;
|
||||
const EVP_CIPHER *cipher;
|
||||
EVP_PBE_KEYGEN *kdf;
|
||||
|
||||
int rv = 0;
|
||||
|
||||
pbe2 = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBE2PARAM), param);
|
||||
if (pbe2 == NULL) {
|
||||
EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* See if we recognise the key derivation function */
|
||||
if (!EVP_PBE_find(EVP_PBE_TYPE_KDF, OBJ_obj2nid(pbe2->keyfunc->algorithm),
|
||||
NULL, NULL, &kdf)) {
|
||||
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 = kdf(ctx, pass, passlen, pbe2->keyfunc->parameter, NULL, NULL, 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];
|
||||
int saltlen, iter;
|
||||
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 */
|
||||
|
||||
kdf = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), param);
|
||||
|
||||
if (kdf == NULL) {
|
||||
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 OPENSSL_DEBUG_PKCS5V2
|
||||
static void h__dump(const unsigned char *p, int len)
|
||||
{
|
||||
for (; len--; p++)
|
||||
fprintf(stderr, "%02X ", *p);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
# endif
|
36
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_dec.c
vendored
Normal file
36
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_dec.c
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/rsa.h>
|
||||
#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 (EVP_PKEY_id(priv) != 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, EVP_PKEY_get0_RSA(priv),
|
||||
RSA_PKCS1_PADDING);
|
||||
err:
|
||||
#endif
|
||||
return ret;
|
||||
}
|
35
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_enc.c
vendored
Normal file
35
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_enc.c
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/rsa.h>
|
||||
#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 (EVP_PKEY_id(pubk) != 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, EVP_PKEY_get0_RSA(pubk),
|
||||
RSA_PKCS1_PADDING);
|
||||
err:
|
||||
#endif
|
||||
return ret;
|
||||
}
|
686
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_lib.c
vendored
Normal file
686
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_lib.c
vendored
Normal file
|
@ -0,0 +1,686 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/refcount.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/cmac.h>
|
||||
#include <openssl/engine.h>
|
||||
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
static void EVP_PKEY_free_it(EVP_PKEY *x);
|
||||
|
||||
int EVP_PKEY_bits(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
|
||||
return pkey->ameth->pkey_bits(pkey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVP_PKEY_security_bits(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey == NULL)
|
||||
return 0;
|
||||
if (!pkey->ameth || !pkey->ameth->pkey_security_bits)
|
||||
return -2;
|
||||
return pkey->ameth->pkey_security_bits(pkey);
|
||||
}
|
||||
|
||||
int EVP_PKEY_size(const 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 == EVP_PKEY_NONE) {
|
||||
if (EVP_PKEY_set_type(to, from->type) == 0)
|
||||
return 0;
|
||||
} else 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 (!EVP_PKEY_missing_parameters(to)) {
|
||||
if (EVP_PKEY_cmp_parameters(to, from) == 1)
|
||||
return 1;
|
||||
EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_PARAMETERS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
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->save_parameters = 1;
|
||||
ret->lock = CRYPTO_THREAD_lock_new();
|
||||
if (ret->lock == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_up_ref(EVP_PKEY *pkey)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0)
|
||||
return 0;
|
||||
|
||||
REF_PRINT_COUNT("EVP_PKEY", pkey);
|
||||
REF_ASSERT_ISNT(i < 2);
|
||||
return ((i > 1) ? 1 : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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, ENGINE *e, int type, const char *str,
|
||||
int len)
|
||||
{
|
||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||
ENGINE **eptr = (e == NULL) ? &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 ENGINEs release them */
|
||||
ENGINE_finish(pkey->engine);
|
||||
pkey->engine = NULL;
|
||||
ENGINE_finish(pkey->pmeth_engine);
|
||||
pkey->pmeth_engine = NULL;
|
||||
#endif
|
||||
}
|
||||
if (str)
|
||||
ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
|
||||
else
|
||||
ameth = EVP_PKEY_asn1_find(eptr, type);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (pkey == NULL && eptr != NULL)
|
||||
ENGINE_finish(e);
|
||||
#endif
|
||||
if (ameth == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
|
||||
const unsigned char *priv,
|
||||
size_t len)
|
||||
{
|
||||
EVP_PKEY *ret = EVP_PKEY_new();
|
||||
|
||||
if (ret == NULL
|
||||
|| !pkey_set_type(ret, e, type, NULL, -1)) {
|
||||
/* EVPerr already called */
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ret->ameth->set_priv_key == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ret->ameth->set_priv_key(ret, priv, len)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY, EVP_R_KEY_SETUP_FAILED);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
EVP_PKEY_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
|
||||
const unsigned char *pub,
|
||||
size_t len)
|
||||
{
|
||||
EVP_PKEY *ret = EVP_PKEY_new();
|
||||
|
||||
if (ret == NULL
|
||||
|| !pkey_set_type(ret, e, type, NULL, -1)) {
|
||||
/* EVPerr already called */
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ret->ameth->set_pub_key == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ret->ameth->set_pub_key(ret, pub, len)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY, EVP_R_KEY_SETUP_FAILED);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
EVP_PKEY_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
|
||||
size_t *len)
|
||||
{
|
||||
if (pkey->ameth->get_priv_key == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pkey->ameth->get_priv_key(pkey, priv, len)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, EVP_R_GET_RAW_KEY_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
|
||||
size_t *len)
|
||||
{
|
||||
if (pkey->ameth->get_pub_key == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pkey->ameth->get_pub_key(pkey, pub, len)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, EVP_R_GET_RAW_KEY_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
size_t len, const EVP_CIPHER *cipher)
|
||||
{
|
||||
#ifndef OPENSSL_NO_CMAC
|
||||
EVP_PKEY *ret = EVP_PKEY_new();
|
||||
CMAC_CTX *cmctx = CMAC_CTX_new();
|
||||
|
||||
if (ret == NULL
|
||||
|| cmctx == NULL
|
||||
|| !pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1)) {
|
||||
/* EVPerr already called */
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!CMAC_Init(cmctx, priv, len, cipher, e)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret->pkey.ptr = cmctx;
|
||||
return ret;
|
||||
|
||||
err:
|
||||
EVP_PKEY_free(ret);
|
||||
CMAC_CTX_free(cmctx);
|
||||
return NULL;
|
||||
#else
|
||||
EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
|
||||
{
|
||||
return pkey_set_type(pkey, NULL, type, NULL, -1);
|
||||
}
|
||||
|
||||
int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
|
||||
{
|
||||
return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len);
|
||||
}
|
||||
|
||||
int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type)
|
||||
{
|
||||
if (pkey->type == type) {
|
||||
return 1; /* it already is that type */
|
||||
}
|
||||
|
||||
/*
|
||||
* The application is requesting to alias this to a different pkey type,
|
||||
* but not one that resolves to the base type.
|
||||
*/
|
||||
if (EVP_PKEY_type(type) != EVP_PKEY_base_id(pkey)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_SET_ALIAS_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkey->type = type;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
|
||||
{
|
||||
if (e != NULL) {
|
||||
if (!ENGINE_init(e)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, ERR_R_ENGINE_LIB);
|
||||
return 0;
|
||||
}
|
||||
if (ENGINE_get_pkey_meth(e, pkey->type) == NULL) {
|
||||
ENGINE_finish(e);
|
||||
EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, EVP_R_UNSUPPORTED_ALGORITHM);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ENGINE_finish(pkey->pmeth_engine);
|
||||
pkey->pmeth_engine = e;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
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(const EVP_PKEY *pkey)
|
||||
{
|
||||
return pkey->pkey.ptr;
|
||||
}
|
||||
|
||||
const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
|
||||
{
|
||||
ASN1_OCTET_STRING *os = NULL;
|
||||
if (pkey->type != EVP_PKEY_HMAC) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET0_HMAC, EVP_R_EXPECTING_AN_HMAC_KEY);
|
||||
return NULL;
|
||||
}
|
||||
os = EVP_PKEY_get0(pkey);
|
||||
*len = os->length;
|
||||
return os->data;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_POLY1305
|
||||
const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len)
|
||||
{
|
||||
ASN1_OCTET_STRING *os = NULL;
|
||||
if (pkey->type != EVP_PKEY_POLY1305) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET0_POLY1305, EVP_R_EXPECTING_A_POLY1305_KEY);
|
||||
return NULL;
|
||||
}
|
||||
os = EVP_PKEY_get0(pkey);
|
||||
*len = os->length;
|
||||
return os->data;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SIPHASH
|
||||
const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len)
|
||||
{
|
||||
ASN1_OCTET_STRING *os = NULL;
|
||||
|
||||
if (pkey->type != EVP_PKEY_SIPHASH) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET0_SIPHASH, EVP_R_EXPECTING_A_SIPHASH_KEY);
|
||||
return NULL;
|
||||
}
|
||||
os = EVP_PKEY_get0(pkey);
|
||||
*len = os->length;
|
||||
return os->data;
|
||||
}
|
||||
#endif
|
||||
|
||||
#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_get0_RSA(EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey->type != EVP_PKEY_RSA) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
|
||||
return NULL;
|
||||
}
|
||||
return pkey->pkey.rsa;
|
||||
}
|
||||
|
||||
RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
|
||||
{
|
||||
RSA *ret = EVP_PKEY_get0_RSA(pkey);
|
||||
if (ret != NULL)
|
||||
RSA_up_ref(ret);
|
||||
return ret;
|
||||
}
|
||||
#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_get0_DSA(EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey->type != EVP_PKEY_DSA) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET0_DSA, EVP_R_EXPECTING_A_DSA_KEY);
|
||||
return NULL;
|
||||
}
|
||||
return pkey->pkey.dsa;
|
||||
}
|
||||
|
||||
DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
|
||||
{
|
||||
DSA *ret = EVP_PKEY_get0_DSA(pkey);
|
||||
if (ret != NULL)
|
||||
DSA_up_ref(ret);
|
||||
return ret;
|
||||
}
|
||||
#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_get0_EC_KEY(EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey->type != EVP_PKEY_EC) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
|
||||
return NULL;
|
||||
}
|
||||
return pkey->pkey.ec;
|
||||
}
|
||||
|
||||
EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
|
||||
{
|
||||
EC_KEY *ret = EVP_PKEY_get0_EC_KEY(pkey);
|
||||
if (ret != NULL)
|
||||
EC_KEY_up_ref(ret);
|
||||
return ret;
|
||||
}
|
||||
#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_get0_DH(EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET0_DH, EVP_R_EXPECTING_A_DH_KEY);
|
||||
return NULL;
|
||||
}
|
||||
return pkey->pkey.dh;
|
||||
}
|
||||
|
||||
DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
|
||||
{
|
||||
DH *ret = EVP_PKEY_get0_DH(pkey);
|
||||
if (ret != NULL)
|
||||
DH_up_ref(ret);
|
||||
return ret;
|
||||
}
|
||||
#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
|
||||
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;
|
||||
|
||||
CRYPTO_DOWN_REF(&x->references, &i, x->lock);
|
||||
REF_PRINT_COUNT("EVP_PKEY", x);
|
||||
if (i > 0)
|
||||
return;
|
||||
REF_ASSERT_ISNT(i < 0);
|
||||
EVP_PKEY_free_it(x);
|
||||
CRYPTO_THREAD_lock_free(x->lock);
|
||||
sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
|
||||
OPENSSL_free(x);
|
||||
}
|
||||
|
||||
static void EVP_PKEY_free_it(EVP_PKEY *x)
|
||||
{
|
||||
/* internal function; x is never NULL */
|
||||
if (x->ameth && x->ameth->pkey_free) {
|
||||
x->ameth->pkey_free(x);
|
||||
x->pkey.ptr = NULL;
|
||||
}
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(x->engine);
|
||||
x->engine = NULL;
|
||||
ENGINE_finish(x->pmeth_engine);
|
||||
x->pmeth_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");
|
||||
}
|
||||
|
||||
static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
|
||||
{
|
||||
if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
|
||||
return -2;
|
||||
return pkey->ameth->pkey_ctrl(pkey, op, arg1, arg2);
|
||||
}
|
||||
|
||||
int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
|
||||
{
|
||||
return evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid);
|
||||
}
|
||||
|
||||
int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
|
||||
const unsigned char *pt, size_t ptlen)
|
||||
{
|
||||
if (ptlen > INT_MAX)
|
||||
return 0;
|
||||
if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, ptlen,
|
||||
(void *)pt) <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt)
|
||||
{
|
||||
int rv;
|
||||
rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppt);
|
||||
if (rv <= 0)
|
||||
return 0;
|
||||
return rv;
|
||||
}
|
73
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_open.c
vendored
Normal file
73
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_open.c
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
#ifdef OPENSSL_NO_RSA
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include <stdio.h>
|
||||
# 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_reset(ctx);
|
||||
if (!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!priv)
|
||||
return 1;
|
||||
|
||||
if (EVP_PKEY_id(priv) != EVP_PKEY_RSA) {
|
||||
EVPerr(EVP_F_EVP_OPENINIT, EVP_R_PUBLIC_KEY_NOT_RSA);
|
||||
goto err;
|
||||
}
|
||||
|
||||
size = EVP_PKEY_size(priv);
|
||||
key = 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:
|
||||
OPENSSL_clear_free(key, size);
|
||||
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;
|
||||
}
|
||||
#endif
|
65
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_seal.c
vendored
Normal file
65
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_seal.c
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/rsa.h>
|
||||
#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;
|
||||
int rv = 0;
|
||||
|
||||
if (type) {
|
||||
EVP_CIPHER_CTX_reset(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)
|
||||
goto err;
|
||||
|
||||
if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
|
||||
goto err;
|
||||
|
||||
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) {
|
||||
rv = -1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
rv = npubk;
|
||||
err:
|
||||
OPENSSL_cleanse(key, sizeof(key));
|
||||
return rv;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
61
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_sign.c
vendored
Normal file
61
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_sign.c
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
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 = 0;
|
||||
int i = 0;
|
||||
size_t sltmp;
|
||||
EVP_PKEY_CTX *pkctx = NULL;
|
||||
|
||||
*siglen = 0;
|
||||
if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_FINALISE)) {
|
||||
if (!EVP_DigestFinal_ex(ctx, m, &m_len))
|
||||
goto err;
|
||||
} else {
|
||||
int rv = 0;
|
||||
EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
|
||||
if (tmp_ctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_SIGNFINAL, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx);
|
||||
if (rv)
|
||||
rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len);
|
||||
EVP_MD_CTX_free(tmp_ctx);
|
||||
if (!rv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
sltmp = (size_t)EVP_PKEY_size(pkey);
|
||||
i = 0;
|
||||
pkctx = EVP_PKEY_CTX_new(pkey, NULL);
|
||||
if (pkctx == NULL)
|
||||
goto err;
|
||||
if (EVP_PKEY_sign_init(pkctx) <= 0)
|
||||
goto err;
|
||||
if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(ctx)) <= 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;
|
||||
}
|
55
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_verify.c
vendored
Normal file
55
trunk/3rdparty/openssl-1.1-fit/crypto/evp/p_verify.c
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
#include "internal/evp_int.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 = 0;
|
||||
int i = 0;
|
||||
EVP_PKEY_CTX *pkctx = NULL;
|
||||
|
||||
if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_FINALISE)) {
|
||||
if (!EVP_DigestFinal_ex(ctx, m, &m_len))
|
||||
goto err;
|
||||
} else {
|
||||
int rv = 0;
|
||||
EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
|
||||
if (tmp_ctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_VERIFYFINAL, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx);
|
||||
if (rv)
|
||||
rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len);
|
||||
EVP_MD_CTX_free(tmp_ctx);
|
||||
if (!rv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
i = -1;
|
||||
pkctx = EVP_PKEY_CTX_new(pkey, NULL);
|
||||
if (pkctx == NULL)
|
||||
goto err;
|
||||
if (EVP_PKEY_verify_init(pkctx) <= 0)
|
||||
goto err;
|
||||
if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(ctx)) <= 0)
|
||||
goto err;
|
||||
i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
|
||||
err:
|
||||
EVP_PKEY_CTX_free(pkctx);
|
||||
return i;
|
||||
}
|
266
trunk/3rdparty/openssl-1.1-fit/crypto/evp/pbe_scrypt.c
vendored
Normal file
266
trunk/3rdparty/openssl-1.1-fit/crypto/evp/pbe_scrypt.c
vendored
Normal file
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include "internal/numbers.h"
|
||||
|
||||
#ifndef OPENSSL_NO_SCRYPT
|
||||
|
||||
#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
|
||||
static void salsa208_word_specification(uint32_t inout[16])
|
||||
{
|
||||
int i;
|
||||
uint32_t x[16];
|
||||
memcpy(x, inout, sizeof(x));
|
||||
for (i = 8; i > 0; i -= 2) {
|
||||
x[4] ^= R(x[0] + x[12], 7);
|
||||
x[8] ^= R(x[4] + x[0], 9);
|
||||
x[12] ^= R(x[8] + x[4], 13);
|
||||
x[0] ^= R(x[12] + x[8], 18);
|
||||
x[9] ^= R(x[5] + x[1], 7);
|
||||
x[13] ^= R(x[9] + x[5], 9);
|
||||
x[1] ^= R(x[13] + x[9], 13);
|
||||
x[5] ^= R(x[1] + x[13], 18);
|
||||
x[14] ^= R(x[10] + x[6], 7);
|
||||
x[2] ^= R(x[14] + x[10], 9);
|
||||
x[6] ^= R(x[2] + x[14], 13);
|
||||
x[10] ^= R(x[6] + x[2], 18);
|
||||
x[3] ^= R(x[15] + x[11], 7);
|
||||
x[7] ^= R(x[3] + x[15], 9);
|
||||
x[11] ^= R(x[7] + x[3], 13);
|
||||
x[15] ^= R(x[11] + x[7], 18);
|
||||
x[1] ^= R(x[0] + x[3], 7);
|
||||
x[2] ^= R(x[1] + x[0], 9);
|
||||
x[3] ^= R(x[2] + x[1], 13);
|
||||
x[0] ^= R(x[3] + x[2], 18);
|
||||
x[6] ^= R(x[5] + x[4], 7);
|
||||
x[7] ^= R(x[6] + x[5], 9);
|
||||
x[4] ^= R(x[7] + x[6], 13);
|
||||
x[5] ^= R(x[4] + x[7], 18);
|
||||
x[11] ^= R(x[10] + x[9], 7);
|
||||
x[8] ^= R(x[11] + x[10], 9);
|
||||
x[9] ^= R(x[8] + x[11], 13);
|
||||
x[10] ^= R(x[9] + x[8], 18);
|
||||
x[12] ^= R(x[15] + x[14], 7);
|
||||
x[13] ^= R(x[12] + x[15], 9);
|
||||
x[14] ^= R(x[13] + x[12], 13);
|
||||
x[15] ^= R(x[14] + x[13], 18);
|
||||
}
|
||||
for (i = 0; i < 16; ++i)
|
||||
inout[i] += x[i];
|
||||
OPENSSL_cleanse(x, sizeof(x));
|
||||
}
|
||||
|
||||
static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r)
|
||||
{
|
||||
uint64_t i, j;
|
||||
uint32_t X[16], *pB;
|
||||
|
||||
memcpy(X, B + (r * 2 - 1) * 16, sizeof(X));
|
||||
pB = B;
|
||||
for (i = 0; i < r * 2; i++) {
|
||||
for (j = 0; j < 16; j++)
|
||||
X[j] ^= *pB++;
|
||||
salsa208_word_specification(X);
|
||||
memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X));
|
||||
}
|
||||
OPENSSL_cleanse(X, sizeof(X));
|
||||
}
|
||||
|
||||
static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N,
|
||||
uint32_t *X, uint32_t *T, uint32_t *V)
|
||||
{
|
||||
unsigned char *pB;
|
||||
uint32_t *pV;
|
||||
uint64_t i, k;
|
||||
|
||||
/* Convert from little endian input */
|
||||
for (pV = V, i = 0, pB = B; i < 32 * r; i++, pV++) {
|
||||
*pV = *pB++;
|
||||
*pV |= *pB++ << 8;
|
||||
*pV |= *pB++ << 16;
|
||||
*pV |= (uint32_t)*pB++ << 24;
|
||||
}
|
||||
|
||||
for (i = 1; i < N; i++, pV += 32 * r)
|
||||
scryptBlockMix(pV, pV - 32 * r, r);
|
||||
|
||||
scryptBlockMix(X, V + (N - 1) * 32 * r, r);
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
uint32_t j;
|
||||
j = X[16 * (2 * r - 1)] % N;
|
||||
pV = V + 32 * r * j;
|
||||
for (k = 0; k < 32 * r; k++)
|
||||
T[k] = X[k] ^ *pV++;
|
||||
scryptBlockMix(X, T, r);
|
||||
}
|
||||
/* Convert output to little endian */
|
||||
for (i = 0, pB = B; i < 32 * r; i++) {
|
||||
uint32_t xtmp = X[i];
|
||||
*pB++ = xtmp & 0xff;
|
||||
*pB++ = (xtmp >> 8) & 0xff;
|
||||
*pB++ = (xtmp >> 16) & 0xff;
|
||||
*pB++ = (xtmp >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX ((size_t)-1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Maximum power of two that will fit in uint64_t: this should work on
|
||||
* most (all?) platforms.
|
||||
*/
|
||||
|
||||
#define LOG2_UINT64_MAX (sizeof(uint64_t) * 8 - 1)
|
||||
|
||||
/*
|
||||
* Maximum value of p * r:
|
||||
* p <= ((2^32-1) * hLen) / MFLen =>
|
||||
* p <= ((2^32-1) * 32) / (128 * r) =>
|
||||
* p * r <= (2^30-1)
|
||||
*
|
||||
*/
|
||||
|
||||
#define SCRYPT_PR_MAX ((1 << 30) - 1)
|
||||
|
||||
/*
|
||||
* Maximum permitted memory allow this to be overridden with Configuration
|
||||
* option: e.g. -DSCRYPT_MAX_MEM=0 for maximum possible.
|
||||
*/
|
||||
|
||||
#ifdef SCRYPT_MAX_MEM
|
||||
# if SCRYPT_MAX_MEM == 0
|
||||
# undef SCRYPT_MAX_MEM
|
||||
/*
|
||||
* Although we could theoretically allocate SIZE_MAX memory that would leave
|
||||
* no memory available for anything else so set limit as half that.
|
||||
*/
|
||||
# define SCRYPT_MAX_MEM (SIZE_MAX/2)
|
||||
# endif
|
||||
#else
|
||||
/* Default memory limit: 32 MB */
|
||||
# define SCRYPT_MAX_MEM (1024 * 1024 * 32)
|
||||
#endif
|
||||
|
||||
int EVP_PBE_scrypt(const char *pass, size_t passlen,
|
||||
const unsigned char *salt, size_t saltlen,
|
||||
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
|
||||
unsigned char *key, size_t keylen)
|
||||
{
|
||||
int rv = 0;
|
||||
unsigned char *B;
|
||||
uint32_t *X, *V, *T;
|
||||
uint64_t i, Blen, Vlen;
|
||||
|
||||
/* Sanity check parameters */
|
||||
/* initial check, r,p must be non zero, N >= 2 and a power of 2 */
|
||||
if (r == 0 || p == 0 || N < 2 || (N & (N - 1)))
|
||||
return 0;
|
||||
/* Check p * r < SCRYPT_PR_MAX avoiding overflow */
|
||||
if (p > SCRYPT_PR_MAX / r) {
|
||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to check N: if 2^(128 * r / 8) overflows limit this is
|
||||
* automatically satisfied since N <= UINT64_MAX.
|
||||
*/
|
||||
|
||||
if (16 * r <= LOG2_UINT64_MAX) {
|
||||
if (N >= (((uint64_t)1) << (16 * r))) {
|
||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Memory checks: check total allocated buffer size fits in uint64_t */
|
||||
|
||||
/*
|
||||
* B size in section 5 step 1.S
|
||||
* Note: we know p * 128 * r < UINT64_MAX because we already checked
|
||||
* p * r < SCRYPT_PR_MAX
|
||||
*/
|
||||
Blen = p * 128 * r;
|
||||
/*
|
||||
* Yet we pass it as integer to PKCS5_PBKDF2_HMAC... [This would
|
||||
* have to be revised when/if PKCS5_PBKDF2_HMAC accepts size_t.]
|
||||
*/
|
||||
if (Blen > INT_MAX) {
|
||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check 32 * r * (N + 2) * sizeof(uint32_t) fits in uint64_t
|
||||
* This is combined size V, X and T (section 4)
|
||||
*/
|
||||
i = UINT64_MAX / (32 * sizeof(uint32_t));
|
||||
if (N + 2 > i / r) {
|
||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
||||
return 0;
|
||||
}
|
||||
Vlen = 32 * r * (N + 2) * sizeof(uint32_t);
|
||||
|
||||
/* check total allocated size fits in uint64_t */
|
||||
if (Blen > UINT64_MAX - Vlen) {
|
||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (maxmem == 0)
|
||||
maxmem = SCRYPT_MAX_MEM;
|
||||
|
||||
/* Check that the maximum memory doesn't exceed a size_t limits */
|
||||
if (maxmem > SIZE_MAX)
|
||||
maxmem = SIZE_MAX;
|
||||
|
||||
if (Blen + Vlen > maxmem) {
|
||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If no key return to indicate parameters are OK */
|
||||
if (key == NULL)
|
||||
return 1;
|
||||
|
||||
B = OPENSSL_malloc((size_t)(Blen + Vlen));
|
||||
if (B == NULL) {
|
||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
X = (uint32_t *)(B + Blen);
|
||||
T = X + 32 * r;
|
||||
V = T + 32 * r;
|
||||
if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(),
|
||||
(int)Blen, B) == 0)
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < p; i++)
|
||||
scryptROMix(B + 128 * r * i, r, N, X, T, V);
|
||||
|
||||
if (PKCS5_PBKDF2_HMAC(pass, passlen, B, (int)Blen, 1, EVP_sha256(),
|
||||
keylen, key) == 0)
|
||||
goto err;
|
||||
rv = 1;
|
||||
err:
|
||||
if (rv == 0)
|
||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PBKDF2_ERROR);
|
||||
|
||||
OPENSSL_clear_free(B, (size_t)(Blen + Vlen));
|
||||
return rv;
|
||||
}
|
||||
#endif
|
297
trunk/3rdparty/openssl-1.1-fit/crypto/evp/pmeth_fn.c
vendored
Normal file
297
trunk/3rdparty/openssl-1.1-fit/crypto/evp/pmeth_fn.c
vendored
Normal file
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
* Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/evp_int.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 (pksize == 0) { \
|
||||
EVPerr(err, EVP_R_INVALID_KEY); /*ckerr_ignore*/ \
|
||||
return 0; \
|
||||
} \
|
||||
if (!arg) { \
|
||||
*arglen = pksize; \
|
||||
return 1; \
|
||||
} \
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
EVP_PKEY_up_ref(peer);
|
||||
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);
|
||||
}
|
239
trunk/3rdparty/openssl-1.1-fit/crypto/evp/pmeth_gn.c
vendored
Normal file
239
trunk/3rdparty/openssl-1.1-fit/crypto/evp/pmeth_gn.c
vendored
Normal file
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/bn_int.h"
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/evp_int.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 == NULL)
|
||||
return -1;
|
||||
|
||||
if (*ppkey == NULL)
|
||||
*ppkey = EVP_PKEY_new();
|
||||
if (*ppkey == NULL)
|
||||
return -1;
|
||||
|
||||
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 = BN_GENCB_get_arg(gcb);
|
||||
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_set_mac_key(mac_ctx, key, keylen) <= 0)
|
||||
goto merr;
|
||||
if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
|
||||
goto merr;
|
||||
merr:
|
||||
EVP_PKEY_CTX_free(mac_ctx);
|
||||
return mac_key;
|
||||
}
|
||||
|
||||
int EVP_PKEY_check(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
EVP_PKEY *pkey = ctx->pkey;
|
||||
|
||||
if (pkey == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_CHECK, EVP_R_NO_KEY_SET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* call customized check function first */
|
||||
if (ctx->pmeth->check != NULL)
|
||||
return ctx->pmeth->check(pkey);
|
||||
|
||||
/* use default check function in ameth */
|
||||
if (pkey->ameth == NULL || pkey->ameth->pkey_check == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_CHECK,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
return pkey->ameth->pkey_check(pkey);
|
||||
}
|
||||
|
||||
int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
EVP_PKEY *pkey = ctx->pkey;
|
||||
|
||||
if (pkey == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK, EVP_R_NO_KEY_SET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* call customized public key check function first */
|
||||
if (ctx->pmeth->public_check != NULL)
|
||||
return ctx->pmeth->public_check(pkey);
|
||||
|
||||
/* use default public key check function in ameth */
|
||||
if (pkey->ameth == NULL || pkey->ameth->pkey_public_check == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
return pkey->ameth->pkey_public_check(pkey);
|
||||
}
|
||||
|
||||
int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
EVP_PKEY *pkey = ctx->pkey;
|
||||
|
||||
if (pkey == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK, EVP_R_NO_KEY_SET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* call customized param check function first */
|
||||
if (ctx->pmeth->param_check != NULL)
|
||||
return ctx->pmeth->param_check(pkey);
|
||||
|
||||
/* use default param check function in ameth */
|
||||
if (pkey->ameth == NULL || pkey->ameth->pkey_param_check == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
return pkey->ameth->pkey_param_check(pkey);
|
||||
}
|
864
trunk/3rdparty/openssl-1.1-fit/crypto/evp/pmeth_lib.c
vendored
Normal file
864
trunk/3rdparty/openssl-1.1-fit/crypto/evp/pmeth_lib.c
vendored
Normal file
|
@ -0,0 +1,864 @@
|
|||
/*
|
||||
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/numbers.h"
|
||||
|
||||
typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
|
||||
|
||||
static STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
|
||||
|
||||
/* This array needs to be in order of NIDs */
|
||||
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,
|
||||
#ifndef OPENSSL_NO_CMAC
|
||||
&cmac_pkey_meth,
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
&rsa_pss_pkey_meth,
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DH
|
||||
&dhx_pkey_meth,
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SCRYPT
|
||||
&scrypt_pkey_meth,
|
||||
#endif
|
||||
&tls1_prf_pkey_meth,
|
||||
#ifndef OPENSSL_NO_EC
|
||||
&ecx25519_pkey_meth,
|
||||
&ecx448_pkey_meth,
|
||||
#endif
|
||||
&hkdf_pkey_meth,
|
||||
#ifndef OPENSSL_NO_POLY1305
|
||||
&poly1305_pkey_meth,
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SIPHASH
|
||||
&siphash_pkey_meth,
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
&ed25519_pkey_meth,
|
||||
&ed448_pkey_meth,
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
&sm2_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 == NULL)
|
||||
return 0;
|
||||
id = pkey->type;
|
||||
}
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (e == NULL && pkey != NULL)
|
||||
e = pkey->pmeth_engine != NULL ? pkey->pmeth_engine : 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. Otherwise use internal
|
||||
* tables.
|
||||
*/
|
||||
if (e)
|
||||
pmeth = ENGINE_get_pkey_meth(e, id);
|
||||
else
|
||||
#endif
|
||||
pmeth = EVP_PKEY_meth_find(id);
|
||||
|
||||
if (pmeth == NULL) {
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(e);
|
||||
#endif
|
||||
EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
if (ret == NULL) {
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
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;
|
||||
if (pkey != NULL)
|
||||
EVP_PKEY_up_ref(pkey);
|
||||
|
||||
if (pmeth->init) {
|
||||
if (pmeth->init(ret) <= 0) {
|
||||
ret->pmeth = NULL;
|
||||
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_zalloc(sizeof(*pmeth));
|
||||
if (pmeth == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_METH_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pmeth->pkey_id = id;
|
||||
pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
|
||||
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;
|
||||
|
||||
dst->check = src->check;
|
||||
}
|
||||
|
||||
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(*rctx));
|
||||
if (rctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rctx->pmeth = pctx->pmeth;
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
rctx->engine = pctx->engine;
|
||||
#endif
|
||||
|
||||
if (pctx->pkey)
|
||||
EVP_PKEY_up_ref(pctx->pkey);
|
||||
|
||||
rctx->pkey = pctx->pkey;
|
||||
|
||||
if (pctx->peerkey)
|
||||
EVP_PKEY_up_ref(pctx->peerkey);
|
||||
|
||||
rctx->peerkey = pctx->peerkey;
|
||||
|
||||
rctx->data = NULL;
|
||||
rctx->app_data = NULL;
|
||||
rctx->operation = pctx->operation;
|
||||
|
||||
if (pctx->pmeth->copy(rctx, pctx) > 0)
|
||||
return rctx;
|
||||
|
||||
rctx->pmeth = NULL;
|
||||
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 == NULL){
|
||||
EVPerr(EVP_F_EVP_PKEY_METH_ADD0, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_METH_ADD0, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void evp_app_cleanup_int(void)
|
||||
{
|
||||
if (app_pkey_methods != NULL)
|
||||
sk_EVP_PKEY_METHOD_pop_free(app_pkey_methods, EVP_PKEY_meth_free);
|
||||
}
|
||||
|
||||
int EVP_PKEY_meth_remove(const EVP_PKEY_METHOD *pmeth)
|
||||
{
|
||||
const EVP_PKEY_METHOD *ret;
|
||||
|
||||
ret = sk_EVP_PKEY_METHOD_delete_ptr(app_pkey_methods, pmeth);
|
||||
|
||||
return ret == NULL ? 0 : 1;
|
||||
}
|
||||
|
||||
size_t EVP_PKEY_meth_get_count(void)
|
||||
{
|
||||
size_t rv = OSSL_NELEM(standard_methods);
|
||||
|
||||
if (app_pkey_methods)
|
||||
rv += sk_EVP_PKEY_METHOD_num(app_pkey_methods);
|
||||
return rv;
|
||||
}
|
||||
|
||||
const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx)
|
||||
{
|
||||
if (idx < OSSL_NELEM(standard_methods))
|
||||
return standard_methods[idx];
|
||||
if (app_pkey_methods == NULL)
|
||||
return NULL;
|
||||
idx -= OSSL_NELEM(standard_methods);
|
||||
if (idx >= (size_t)sk_EVP_PKEY_METHOD_num(app_pkey_methods))
|
||||
return NULL;
|
||||
return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
|
||||
}
|
||||
|
||||
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
if (ctx->pmeth && ctx->pmeth->cleanup)
|
||||
ctx->pmeth->cleanup(ctx);
|
||||
EVP_PKEY_free(ctx->pkey);
|
||||
EVP_PKEY_free(ctx->peerkey);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
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;
|
||||
|
||||
/* Skip the operation checks since this is called in a very early stage */
|
||||
if (ctx->pmeth->digest_custom != NULL)
|
||||
goto doit;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
doit:
|
||||
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_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
int cmd, uint64_t value)
|
||||
{
|
||||
return EVP_PKEY_CTX_ctrl(ctx, keytype, optype, cmd, 0, &value);
|
||||
}
|
||||
|
||||
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") == 0)
|
||||
return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD,
|
||||
value);
|
||||
return ctx->pmeth->ctrl_str(ctx, name, value);
|
||||
}
|
||||
|
||||
/* Utility functions to send a string of hex string to a ctrl */
|
||||
|
||||
int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = strlen(str);
|
||||
if (len > INT_MAX)
|
||||
return -1;
|
||||
return ctx->pmeth->ctrl(ctx, cmd, len, (void *)str);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex)
|
||||
{
|
||||
unsigned char *bin;
|
||||
long binlen;
|
||||
int rv = -1;
|
||||
|
||||
bin = OPENSSL_hexstr2buf(hex, &binlen);
|
||||
if (bin == NULL)
|
||||
return 0;
|
||||
if (binlen <= INT_MAX)
|
||||
rv = ctx->pmeth->ctrl(ctx, cmd, binlen, bin);
|
||||
OPENSSL_free(bin);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Pass a message digest to a ctrl */
|
||||
int EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md)
|
||||
{
|
||||
const EVP_MD *m;
|
||||
|
||||
if (md == NULL || (m = EVP_get_digestbyname(md)) == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_CTX_MD, EVP_R_INVALID_DIGEST);
|
||||
return 0;
|
||||
}
|
||||
return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, 0, (void *)m);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth,
|
||||
int (*check) (EVP_PKEY *pkey))
|
||||
{
|
||||
pmeth->check = check;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_set_public_check(EVP_PKEY_METHOD *pmeth,
|
||||
int (*check) (EVP_PKEY *pkey))
|
||||
{
|
||||
pmeth->public_check = check;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth,
|
||||
int (*check) (EVP_PKEY *pkey))
|
||||
{
|
||||
pmeth->param_check = check;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_set_digest_custom(EVP_PKEY_METHOD *pmeth,
|
||||
int (*digest_custom) (EVP_PKEY_CTX *ctx,
|
||||
EVP_MD_CTX *mctx))
|
||||
{
|
||||
pmeth->digest_custom = digest_custom;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_init(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pinit) (EVP_PKEY_CTX *ctx))
|
||||
{
|
||||
*pinit = pmeth->init;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_copy(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pcopy) (EVP_PKEY_CTX *dst,
|
||||
EVP_PKEY_CTX *src))
|
||||
{
|
||||
*pcopy = pmeth->copy;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_cleanup(const EVP_PKEY_METHOD *pmeth,
|
||||
void (**pcleanup) (EVP_PKEY_CTX *ctx))
|
||||
{
|
||||
*pcleanup = pmeth->cleanup;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_paramgen(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pparamgen_init) (EVP_PKEY_CTX *ctx),
|
||||
int (**pparamgen) (EVP_PKEY_CTX *ctx,
|
||||
EVP_PKEY *pkey))
|
||||
{
|
||||
if (pparamgen_init)
|
||||
*pparamgen_init = pmeth->paramgen_init;
|
||||
if (pparamgen)
|
||||
*pparamgen = pmeth->paramgen;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_keygen(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pkeygen_init) (EVP_PKEY_CTX *ctx),
|
||||
int (**pkeygen) (EVP_PKEY_CTX *ctx,
|
||||
EVP_PKEY *pkey))
|
||||
{
|
||||
if (pkeygen_init)
|
||||
*pkeygen_init = pmeth->keygen_init;
|
||||
if (pkeygen)
|
||||
*pkeygen = pmeth->keygen;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_sign(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**psign_init) (EVP_PKEY_CTX *ctx),
|
||||
int (**psign) (EVP_PKEY_CTX *ctx,
|
||||
unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs,
|
||||
size_t tbslen))
|
||||
{
|
||||
if (psign_init)
|
||||
*psign_init = pmeth->sign_init;
|
||||
if (psign)
|
||||
*psign = pmeth->sign;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_verify(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pverify_init) (EVP_PKEY_CTX *ctx),
|
||||
int (**pverify) (EVP_PKEY_CTX *ctx,
|
||||
const unsigned char *sig,
|
||||
size_t siglen,
|
||||
const unsigned char *tbs,
|
||||
size_t tbslen))
|
||||
{
|
||||
if (pverify_init)
|
||||
*pverify_init = pmeth->verify_init;
|
||||
if (pverify)
|
||||
*pverify = pmeth->verify;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_verify_recover(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pverify_recover_init) (EVP_PKEY_CTX
|
||||
*ctx),
|
||||
int (**pverify_recover) (EVP_PKEY_CTX
|
||||
*ctx,
|
||||
unsigned char
|
||||
*sig,
|
||||
size_t *siglen,
|
||||
const unsigned
|
||||
char *tbs,
|
||||
size_t tbslen))
|
||||
{
|
||||
if (pverify_recover_init)
|
||||
*pverify_recover_init = pmeth->verify_recover_init;
|
||||
if (pverify_recover)
|
||||
*pverify_recover = pmeth->verify_recover;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_signctx(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**psignctx_init) (EVP_PKEY_CTX *ctx,
|
||||
EVP_MD_CTX *mctx),
|
||||
int (**psignctx) (EVP_PKEY_CTX *ctx,
|
||||
unsigned char *sig,
|
||||
size_t *siglen,
|
||||
EVP_MD_CTX *mctx))
|
||||
{
|
||||
if (psignctx_init)
|
||||
*psignctx_init = pmeth->signctx_init;
|
||||
if (psignctx)
|
||||
*psignctx = pmeth->signctx;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_verifyctx(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pverifyctx_init) (EVP_PKEY_CTX *ctx,
|
||||
EVP_MD_CTX *mctx),
|
||||
int (**pverifyctx) (EVP_PKEY_CTX *ctx,
|
||||
const unsigned char *sig,
|
||||
int siglen,
|
||||
EVP_MD_CTX *mctx))
|
||||
{
|
||||
if (pverifyctx_init)
|
||||
*pverifyctx_init = pmeth->verifyctx_init;
|
||||
if (pverifyctx)
|
||||
*pverifyctx = pmeth->verifyctx;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_encrypt(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pencrypt_init) (EVP_PKEY_CTX *ctx),
|
||||
int (**pencryptfn) (EVP_PKEY_CTX *ctx,
|
||||
unsigned char *out,
|
||||
size_t *outlen,
|
||||
const unsigned char *in,
|
||||
size_t inlen))
|
||||
{
|
||||
if (pencrypt_init)
|
||||
*pencrypt_init = pmeth->encrypt_init;
|
||||
if (pencryptfn)
|
||||
*pencryptfn = pmeth->encrypt;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_decrypt(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pdecrypt_init) (EVP_PKEY_CTX *ctx),
|
||||
int (**pdecrypt) (EVP_PKEY_CTX *ctx,
|
||||
unsigned char *out,
|
||||
size_t *outlen,
|
||||
const unsigned char *in,
|
||||
size_t inlen))
|
||||
{
|
||||
if (pdecrypt_init)
|
||||
*pdecrypt_init = pmeth->decrypt_init;
|
||||
if (pdecrypt)
|
||||
*pdecrypt = pmeth->decrypt;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_derive(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pderive_init) (EVP_PKEY_CTX *ctx),
|
||||
int (**pderive) (EVP_PKEY_CTX *ctx,
|
||||
unsigned char *key,
|
||||
size_t *keylen))
|
||||
{
|
||||
if (pderive_init)
|
||||
*pderive_init = pmeth->derive_init;
|
||||
if (pderive)
|
||||
*pderive = pmeth->derive;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_ctrl(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
|
||||
void *p2),
|
||||
int (**pctrl_str) (EVP_PKEY_CTX *ctx,
|
||||
const char *type,
|
||||
const char *value))
|
||||
{
|
||||
if (pctrl)
|
||||
*pctrl = pmeth->ctrl;
|
||||
if (pctrl_str)
|
||||
*pctrl_str = pmeth->ctrl_str;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_check(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pcheck) (EVP_PKEY *pkey))
|
||||
{
|
||||
if (pcheck != NULL)
|
||||
*pcheck = pmeth->check;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_public_check(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pcheck) (EVP_PKEY *pkey))
|
||||
{
|
||||
if (pcheck != NULL)
|
||||
*pcheck = pmeth->public_check;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_param_check(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pcheck) (EVP_PKEY *pkey))
|
||||
{
|
||||
if (pcheck != NULL)
|
||||
*pcheck = pmeth->param_check;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth,
|
||||
int (**pdigest_custom) (EVP_PKEY_CTX *ctx,
|
||||
EVP_MD_CTX *mctx))
|
||||
{
|
||||
if (pdigest_custom != NULL)
|
||||
*pdigest_custom = pmeth->digest_custom;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue