check in v3.8.2 source

This commit is contained in:
2023-11-06 23:46:37 -08:00
parent e2db88c634
commit 2b68369a2b
1216 changed files with 563118 additions and 0 deletions

571
crypto/evp/bio_b64.c Normal file
View File

@@ -0,0 +1,571 @@
/* $OpenBSD: bio_b64.c,v 1.28 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <openssl/buffer.h>
#include <openssl/evp.h>
#include "bio_local.h"
#include "evp_local.h"
static int b64_write(BIO *h, const char *buf, int num);
static int b64_read(BIO *h, char *buf, int size);
static int b64_puts(BIO *h, const char *str);
/*static int b64_gets(BIO *h, char *str, int size); */
static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int b64_new(BIO *h);
static int b64_free(BIO *data);
static long b64_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
#define B64_BLOCK_SIZE 1024
#define B64_BLOCK_SIZE2 768
#define B64_NONE 0
#define B64_ENCODE 1
#define B64_DECODE 2
typedef struct b64_struct {
/*BIO *bio; moved to the BIO structure */
int buf_len;
int buf_off;
int tmp_len; /* used to find the start when decoding */
int tmp_nl; /* If true, scan until '\n' */
int encode;
int start; /* have we started decoding yet? */
int cont; /* <= 0 when finished */
EVP_ENCODE_CTX base64;
char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10];
char tmp[B64_BLOCK_SIZE];
} BIO_B64_CTX;
static const BIO_METHOD methods_b64 = {
.type = BIO_TYPE_BASE64,
.name = "base64 encoding",
.bwrite = b64_write,
.bread = b64_read,
.bputs = b64_puts,
.ctrl = b64_ctrl,
.create = b64_new,
.destroy = b64_free,
.callback_ctrl = b64_callback_ctrl
};
const BIO_METHOD *
BIO_f_base64(void)
{
return (&methods_b64);
}
static int
b64_new(BIO *bi)
{
BIO_B64_CTX *ctx;
ctx = malloc(sizeof(BIO_B64_CTX));
if (ctx == NULL)
return (0);
ctx->buf_len = 0;
ctx->tmp_len = 0;
ctx->tmp_nl = 0;
ctx->buf_off = 0;
ctx->cont = 1;
ctx->start = 1;
ctx->encode = 0;
bi->init = 1;
bi->ptr = (char *)ctx;
bi->flags = 0;
bi->num = 0;
return (1);
}
static int
b64_free(BIO *a)
{
if (a == NULL)
return (0);
free(a->ptr);
a->ptr = NULL;
a->init = 0;
a->flags = 0;
return (1);
}
static int
b64_read(BIO *b, char *out, int outl)
{
int ret = 0, i, ii, j, k, x, n, num, ret_code = 0;
BIO_B64_CTX *ctx;
unsigned char *p, *q;
if (out == NULL)
return (0);
ctx = (BIO_B64_CTX *)b->ptr;
if ((ctx == NULL) || (b->next_bio == NULL))
return (0);
BIO_clear_retry_flags(b);
if (ctx->encode != B64_DECODE) {
ctx->encode = B64_DECODE;
ctx->buf_len = 0;
ctx->buf_off = 0;
ctx->tmp_len = 0;
EVP_DecodeInit(&(ctx->base64));
}
/* First check if there are bytes decoded/encoded */
if (ctx->buf_len > 0) {
OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
i = ctx->buf_len - ctx->buf_off;
if (i > outl)
i = outl;
OPENSSL_assert(ctx->buf_off + i < (int)sizeof(ctx->buf));
memcpy(out, &(ctx->buf[ctx->buf_off]), i);
ret = i;
out += i;
outl -= i;
ctx->buf_off += i;
if (ctx->buf_len == ctx->buf_off) {
ctx->buf_len = 0;
ctx->buf_off = 0;
}
}
/* At this point, we have room of outl bytes and an empty
* buffer, so we should read in some more. */
ret_code = 0;
while (outl > 0) {
if (ctx->cont <= 0)
break;
i = BIO_read(b->next_bio, &(ctx->tmp[ctx->tmp_len]),
B64_BLOCK_SIZE - ctx->tmp_len);
if (i <= 0) {
ret_code = i;
/* Should we continue next time we are called? */
if (!BIO_should_retry(b->next_bio)) {
ctx->cont = i;
/* If buffer empty break */
if (ctx->tmp_len == 0)
break;
/* Fall through and process what we have */
else
i = 0;
}
/* else we retry and add more data to buffer */
else
break;
}
i += ctx->tmp_len;
ctx->tmp_len = i;
/* We need to scan, a line at a time until we
* have a valid line if we are starting. */
if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) {
/* ctx->start=1; */
ctx->tmp_len = 0;
} else if (ctx->start) {
q = p =(unsigned char *)ctx->tmp;
num = 0;
for (j = 0; j < i; j++) {
if (*(q++) != '\n')
continue;
/* due to a previous very long line,
* we need to keep on scanning for a '\n'
* before we even start looking for
* base64 encoded stuff. */
if (ctx->tmp_nl) {
p = q;
ctx->tmp_nl = 0;
continue;
}
k = EVP_DecodeUpdate(&(ctx->base64),
(unsigned char *)ctx->buf,
&num, p, q - p);
if ((k <= 0) && (num == 0) && (ctx->start))
EVP_DecodeInit(&ctx->base64);
else {
if (p != (unsigned char *)
&(ctx->tmp[0])) {
i -= (p - (unsigned char *)
&(ctx->tmp[0]));
for (x = 0; x < i; x++)
ctx->tmp[x] = p[x];
}
EVP_DecodeInit(&ctx->base64);
ctx->start = 0;
break;
}
p = q;
}
/* we fell off the end without starting */
if ((j == i) && (num == 0)) {
/* Is this is one long chunk?, if so, keep on
* reading until a new line. */
if (p == (unsigned char *)&(ctx->tmp[0])) {
/* Check buffer full */
if (i == B64_BLOCK_SIZE) {
ctx->tmp_nl = 1;
ctx->tmp_len = 0;
}
}
else if (p != q) /* finished on a '\n' */
{
n = q - p;
for (ii = 0; ii < n; ii++)
ctx->tmp[ii] = p[ii];
ctx->tmp_len = n;
}
/* else finished on a '\n' */
continue;
} else {
ctx->tmp_len = 0;
}
} else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) {
/* If buffer isn't full and we can retry then
* restart to read in more data.
*/
continue;
}
if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
int z, jj;
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;
}
ctx->buf_off = 0;
if (i < 0) {
ret_code = 0;
ctx->buf_len = 0;
break;
}
if (ctx->buf_len <= outl)
i = ctx->buf_len;
else
i = outl;
memcpy(out, ctx->buf, i);
ret += i;
ctx->buf_off = i;
if (ctx->buf_off == ctx->buf_len) {
ctx->buf_len = 0;
ctx->buf_off = 0;
}
outl -= i;
out += i;
}
/* BIO_clear_retry_flags(b); */
BIO_copy_next_retry(b);
return ((ret == 0) ? ret_code : ret);
}
static int
b64_write(BIO *b, const char *in, int inl)
{
int ret = 0;
int n;
int i;
BIO_B64_CTX *ctx;
ctx = (BIO_B64_CTX *)b->ptr;
BIO_clear_retry_flags(b);
if (ctx->encode != B64_ENCODE) {
ctx->encode = B64_ENCODE;
ctx->buf_len = 0;
ctx->buf_off = 0;
ctx->tmp_len = 0;
EVP_EncodeInit(&(ctx->base64));
}
OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf));
OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
n = ctx->buf_len - ctx->buf_off;
while (n > 0) {
i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
if (i <= 0) {
BIO_copy_next_retry(b);
return (i);
}
OPENSSL_assert(i <= n);
ctx->buf_off += i;
OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
n -= i;
}
/* at this point all pending data has been written */
ctx->buf_off = 0;
ctx->buf_len = 0;
if ((in == NULL) || (inl <= 0))
return (0);
while (inl > 0) {
n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl;
if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
if (ctx->tmp_len > 0) {
OPENSSL_assert(ctx->tmp_len <= 3);
n = 3 - ctx->tmp_len;
/* There's a theoretical possibility for this */
if (n > inl)
n = inl;
memcpy(&(ctx->tmp[ctx->tmp_len]), in, n);
ctx->tmp_len += n;
ret += n;
if (ctx->tmp_len < 3)
break;
ctx->buf_len = EVP_EncodeBlock(
(unsigned char *)ctx->buf,
(unsigned char *)ctx->tmp, ctx->tmp_len);
OPENSSL_assert(ctx->buf_len <=
(int)sizeof(ctx->buf));
OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
/* Since we're now done using the temporary
buffer, the length should be 0'd */
ctx->tmp_len = 0;
} else {
if (n < 3) {
memcpy(ctx->tmp, in, n);
ctx->tmp_len = n;
ret += n;
break;
}
n -= n % 3;
ctx->buf_len = EVP_EncodeBlock(
(unsigned char *)ctx->buf,
(const unsigned char *)in, n);
OPENSSL_assert(ctx->buf_len <=
(int)sizeof(ctx->buf));
OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
ret += n;
}
} else {
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(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
if (i <= 0) {
BIO_copy_next_retry(b);
return ((ret == 0) ? i : ret);
}
OPENSSL_assert(i <= n);
n -= i;
ctx->buf_off += i;
OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
}
ctx->buf_len = 0;
ctx->buf_off = 0;
}
return (ret);
}
static long
b64_ctrl(BIO *b, int cmd, long num, void *ptr)
{
BIO_B64_CTX *ctx;
long ret = 1;
int i;
ctx = (BIO_B64_CTX *)b->ptr;
switch (cmd) {
case BIO_CTRL_RESET:
ctx->cont = 1;
ctx->start = 1;
ctx->encode = B64_NONE;
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_CTRL_EOF: /* More to read */
if (ctx->cont <= 0)
ret = 1;
else
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_CTRL_WPENDING: /* More to write in buffer */
OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
ret = ctx->buf_len - ctx->buf_off;
if ((ret == 0) && (ctx->encode != B64_NONE) &&
(ctx->base64.num != 0))
ret = 1;
else if (ret <= 0)
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_CTRL_PENDING: /* More to read in buffer */
OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
ret = ctx->buf_len - ctx->buf_off;
if (ret <= 0)
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_CTRL_FLUSH:
/* do a final write */
again:
while (ctx->buf_len != ctx->buf_off) {
i = b64_write(b, NULL, 0);
if (i < 0)
return i;
}
if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
if (ctx->tmp_len != 0) {
ctx->buf_len = EVP_EncodeBlock(
(unsigned char *)ctx->buf,
(unsigned char *)ctx->tmp,
ctx->tmp_len);
ctx->buf_off = 0;
ctx->tmp_len = 0;
goto again;
}
} else if (ctx->encode != B64_NONE && ctx->base64.num != 0) {
ctx->buf_off = 0;
EVP_EncodeFinal(&(ctx->base64),
(unsigned char *)ctx->buf,
&(ctx->buf_len));
/* push out the bytes */
goto again;
}
/* Finally flush the underlying BIO */
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_C_DO_STATE_MACHINE:
BIO_clear_retry_flags(b);
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
BIO_copy_next_retry(b);
break;
case BIO_CTRL_DUP:
break;
case BIO_CTRL_INFO:
case BIO_CTRL_GET:
case BIO_CTRL_SET:
default:
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
}
return (ret);
}
static long
b64_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
long ret = 1;
if (b->next_bio == NULL)
return (0);
switch (cmd) {
default:
ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
break;
}
return (ret);
}
static int
b64_puts(BIO *b, const char *str)
{
return b64_write(b, str, strlen(str));
}

418
crypto/evp/bio_enc.c Normal file
View File

@@ -0,0 +1,418 @@
/* $OpenBSD: bio_enc.c,v 1.29 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <openssl/buffer.h>
#include <openssl/evp.h>
#include "bio_local.h"
#include "evp_local.h"
static int enc_write(BIO *h, const char *buf, int num);
static int enc_read(BIO *h, char *buf, int size);
/*static int enc_puts(BIO *h, const char *str); */
/*static int enc_gets(BIO *h, char *str, int size); */
static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int enc_new(BIO *h);
static int enc_free(BIO *data);
static long enc_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fps);
#define ENC_BLOCK_SIZE (1024*4)
#define BUF_OFFSET (EVP_MAX_BLOCK_LENGTH*2)
typedef struct enc_struct {
int buf_len;
int buf_off;
int cont; /* <= 0 when finished */
int finished;
int ok; /* bad decrypt */
EVP_CIPHER_CTX cipher;
/* buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate
* can return up to a block more data than is presented to it
*/
char buf[ENC_BLOCK_SIZE + BUF_OFFSET + 2];
} BIO_ENC_CTX;
static const BIO_METHOD methods_enc = {
.type = BIO_TYPE_CIPHER,
.name = "cipher",
.bwrite = enc_write,
.bread = enc_read,
.ctrl = enc_ctrl,
.create = enc_new,
.destroy = enc_free,
.callback_ctrl = enc_callback_ctrl
};
const BIO_METHOD *
BIO_f_cipher(void)
{
return (&methods_enc);
}
static int
enc_new(BIO *bi)
{
BIO_ENC_CTX *ctx;
ctx = malloc(sizeof(BIO_ENC_CTX));
if (ctx == NULL)
return (0);
EVP_CIPHER_CTX_init(&ctx->cipher);
ctx->buf_len = 0;
ctx->buf_off = 0;
ctx->cont = 1;
ctx->finished = 0;
ctx->ok = 1;
bi->init = 0;
bi->ptr = (char *)ctx;
bi->flags = 0;
return (1);
}
static int
enc_free(BIO *a)
{
BIO_ENC_CTX *b;
if (a == NULL)
return (0);
b = (BIO_ENC_CTX *)a->ptr;
EVP_CIPHER_CTX_cleanup(&(b->cipher));
freezero(a->ptr, sizeof(BIO_ENC_CTX));
a->ptr = NULL;
a->init = 0;
a->flags = 0;
return (1);
}
static int
enc_read(BIO *b, char *out, int outl)
{
int ret = 0, i;
BIO_ENC_CTX *ctx;
if (out == NULL)
return (0);
ctx = (BIO_ENC_CTX *)b->ptr;
if ((ctx == NULL) || (b->next_bio == NULL))
return (0);
/* First check if there are bytes decoded/encoded */
if (ctx->buf_len > 0) {
i = ctx->buf_len - ctx->buf_off;
if (i > outl)
i = outl;
memcpy(out, &(ctx->buf[ctx->buf_off]), i);
ret = i;
out += i;
outl -= i;
ctx->buf_off += i;
if (ctx->buf_len == ctx->buf_off) {
ctx->buf_len = 0;
ctx->buf_off = 0;
}
}
/* At this point, we have room of outl bytes and an empty
* buffer, so we should read in some more. */
while (outl > 0) {
if (ctx->cont <= 0)
break;
/* read in at IV offset, read the EVP_Cipher
* documentation about why */
i = BIO_read(b->next_bio, &(ctx->buf[BUF_OFFSET]), ENC_BLOCK_SIZE);
if (i <= 0) {
/* Should be continue next time we are called? */
if (!BIO_should_retry(b->next_bio)) {
ctx->cont = i;
i = EVP_CipherFinal_ex(&(ctx->cipher),
(unsigned char *)ctx->buf,
&(ctx->buf_len));
ctx->ok = i;
ctx->buf_off = 0;
} else {
ret = (ret == 0) ? i : ret;
break;
}
} else {
EVP_CipherUpdate(&(ctx->cipher),
(unsigned char *)ctx->buf, &ctx->buf_len,
(unsigned char *)&(ctx->buf[BUF_OFFSET]), i);
ctx->cont = 1;
/* Note: it is possible for EVP_CipherUpdate to
* decrypt zero bytes because this is or looks like
* the final block: if this happens we should retry
* and either read more data or decrypt the final
* block
*/
if (ctx->buf_len == 0)
continue;
}
if (ctx->buf_len <= outl)
i = ctx->buf_len;
else
i = outl;
if (i <= 0)
break;
memcpy(out, ctx->buf, i);
ret += i;
ctx->buf_off = i;
outl -= i;
out += i;
}
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
return ((ret == 0) ? ctx->cont : ret);
}
static int
enc_write(BIO *b, const char *in, int inl)
{
int ret = 0, n, i;
BIO_ENC_CTX *ctx;
ctx = (BIO_ENC_CTX *)b->ptr;
ret = inl;
BIO_clear_retry_flags(b);
n = ctx->buf_len - ctx->buf_off;
while (n > 0) {
i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
if (i <= 0) {
BIO_copy_next_retry(b);
return (i);
}
ctx->buf_off += i;
n -= i;
}
/* at this point all pending data has been written */
if ((in == NULL) || (inl <= 0))
return (0);
ctx->buf_off = 0;
while (inl > 0) {
n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl;
EVP_CipherUpdate(&(ctx->cipher),
(unsigned char *)ctx->buf, &ctx->buf_len,
(unsigned char *)in, n);
inl -= n;
in += n;
ctx->buf_off = 0;
n = ctx->buf_len;
while (n > 0) {
i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
if (i <= 0) {
BIO_copy_next_retry(b);
return (ret == inl) ? i : ret - inl;
}
n -= i;
ctx->buf_off += i;
}
ctx->buf_len = 0;
ctx->buf_off = 0;
}
BIO_copy_next_retry(b);
return (ret);
}
static long
enc_ctrl(BIO *b, int cmd, long num, void *ptr)
{
BIO *dbio;
BIO_ENC_CTX *ctx, *dctx;
long ret = 1;
int i;
EVP_CIPHER_CTX **c_ctx;
ctx = (BIO_ENC_CTX *)b->ptr;
switch (cmd) {
case BIO_CTRL_RESET:
ctx->ok = 1;
ctx->finished = 0;
EVP_CipherInit_ex(&(ctx->cipher), NULL, NULL, NULL, NULL,
ctx->cipher.encrypt);
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_CTRL_EOF: /* More to read */
if (ctx->cont <= 0)
ret = 1;
else
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_CTRL_WPENDING:
ret = ctx->buf_len - ctx->buf_off;
if (ret <= 0)
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_CTRL_PENDING: /* More to read in buffer */
ret = ctx->buf_len - ctx->buf_off;
if (ret <= 0)
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_CTRL_FLUSH:
/* do a final write */
again:
while (ctx->buf_len != ctx->buf_off) {
i = enc_write(b, NULL, 0);
if (i < 0)
return i;
}
if (!ctx->finished) {
ctx->finished = 1;
ctx->buf_off = 0;
ret = EVP_CipherFinal_ex(&(ctx->cipher),
(unsigned char *)ctx->buf,
&(ctx->buf_len));
ctx->ok = (int)ret;
if (ret <= 0)
break;
/* push out the bytes */
goto again;
}
/* Finally flush the underlying BIO */
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_C_GET_CIPHER_STATUS:
ret = (long)ctx->ok;
break;
case BIO_C_DO_STATE_MACHINE:
BIO_clear_retry_flags(b);
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
BIO_copy_next_retry(b);
break;
case BIO_C_GET_CIPHER_CTX:
c_ctx = (EVP_CIPHER_CTX **)ptr;
(*c_ctx) = &(ctx->cipher);
b->init = 1;
break;
case BIO_CTRL_DUP:
dbio = (BIO *)ptr;
dctx = (BIO_ENC_CTX *)dbio->ptr;
EVP_CIPHER_CTX_init(&dctx->cipher);
ret = EVP_CIPHER_CTX_copy(&dctx->cipher, &ctx->cipher);
if (ret)
dbio->init = 1;
break;
default:
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
}
return (ret);
}
static long
enc_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
long ret = 1;
if (b->next_bio == NULL)
return (0);
switch (cmd) {
default:
ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
break;
}
return (ret);
}
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 (*cb)(BIO *, int, const char *, int, long, long);
if (b == NULL)
return 0;
if ((ctx = BIO_get_data(b)) == NULL)
return 0;
if ((cb = BIO_get_callback(b)) != NULL) {
if (cb(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 (cb != NULL)
return cb(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L);
return 1;
}

280
crypto/evp/bio_md.c Normal file
View File

@@ -0,0 +1,280 @@
/* $OpenBSD: bio_md.c,v 1.21 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <errno.h>
#include <openssl/buffer.h>
#include <openssl/evp.h>
#include "bio_local.h"
#include "evp_local.h"
/* BIO_put and BIO_get both add to the digest,
* BIO_gets returns the digest */
static int md_write(BIO *h, char const *buf, int num);
static int md_read(BIO *h, char *buf, int size);
/*static int md_puts(BIO *h, const char *str); */
static int md_gets(BIO *h, char *str, int size);
static long md_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int md_new(BIO *h);
static int md_free(BIO *data);
static long md_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
static const BIO_METHOD methods_md = {
.type = BIO_TYPE_MD,
.name = "message digest",
.bwrite = md_write,
.bread = md_read,
.bgets = md_gets,
.ctrl = md_ctrl,
.create = md_new,
.destroy = md_free,
.callback_ctrl = 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_create();
if (ctx == NULL)
return (0);
bi->init = 0;
bi->ptr = (char *)ctx;
bi->flags = 0;
return (1);
}
static int
md_free(BIO *a)
{
if (a == NULL)
return (0);
EVP_MD_CTX_destroy(a->ptr);
a->ptr = NULL;
a->init = 0;
a->flags = 0;
return (1);
}
static int
md_read(BIO *b, char *out, int outl)
{
int ret = 0;
EVP_MD_CTX *ctx;
if (out == NULL)
return (0);
ctx = b->ptr;
if ((ctx == NULL) || (b->next_bio == NULL))
return (0);
ret = BIO_read(b->next_bio, out, outl);
if (b->init) {
if (ret > 0) {
if (EVP_DigestUpdate(ctx, (unsigned char *)out,
(unsigned int)ret) <= 0)
return (-1);
}
}
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
return (ret);
}
static int
md_write(BIO *b, const char *in, int inl)
{
int ret = 0;
EVP_MD_CTX *ctx;
if ((in == NULL) || (inl <= 0))
return (0);
ctx = b->ptr;
if ((ctx != NULL) && (b->next_bio != NULL))
ret = BIO_write(b->next_bio, in, inl);
if (b->init) {
if (ret > 0) {
if (!EVP_DigestUpdate(ctx, (const unsigned char *)in,
(unsigned int)ret)) {
BIO_clear_retry_flags(b);
return 0;
}
}
}
if (b->next_bio != NULL) {
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
}
return (ret);
}
static long
md_ctrl(BIO *b, int cmd, long num, void *ptr)
{
EVP_MD_CTX *ctx, *dctx, **pctx;
const EVP_MD **ppmd;
EVP_MD *md;
long ret = 1;
BIO *dbio;
ctx = b->ptr;
switch (cmd) {
case BIO_CTRL_RESET:
if (b->init)
ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL);
else
ret = 0;
if (ret > 0)
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
case BIO_C_GET_MD:
if (b->init) {
ppmd = ptr;
*ppmd = ctx->digest;
} else
ret = 0;
break;
case BIO_C_GET_MD_CTX:
pctx = ptr;
*pctx = ctx;
b->init = 1;
break;
case BIO_C_SET_MD_CTX:
if (b->init)
b->ptr = ptr;
else
ret = 0;
break;
case BIO_C_DO_STATE_MACHINE:
BIO_clear_retry_flags(b);
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
BIO_copy_next_retry(b);
break;
case BIO_C_SET_MD:
md = ptr;
ret = EVP_DigestInit_ex(ctx, md, NULL);
if (ret > 0)
b->init = 1;
break;
case BIO_CTRL_DUP:
dbio = ptr;
dctx = dbio->ptr;
if (!EVP_MD_CTX_copy_ex(dctx, ctx))
return 0;
b->init = 1;
break;
default:
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
break;
}
return (ret);
}
static long
md_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
long ret = 1;
if (b->next_bio == NULL)
return (0);
switch (cmd) {
default:
ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
break;
}
return (ret);
}
static int
md_gets(BIO *bp, char *buf, int size)
{
EVP_MD_CTX *ctx;
unsigned int ret;
ctx = bp->ptr;
if (size < ctx->digest->md_size)
return (0);
if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0)
return -1;
return ((int)ret);
}
/*
static int md_puts(bp,str)
BIO *bp;
char *str;
{
return(-1);
}
*/

329
crypto/evp/c_all.c Normal file
View File

@@ -0,0 +1,329 @@
/* $OpenBSD: c_all.c,v 1.32 2023/07/24 10:24:58 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <pthread.h>
#include <openssl/opensslconf.h>
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include "cryptlib.h"
static void
OpenSSL_add_all_ciphers_internal(void)
{
#ifndef OPENSSL_NO_DES
EVP_add_cipher(EVP_des_cfb());
EVP_add_cipher(EVP_des_cfb1());
EVP_add_cipher(EVP_des_cfb8());
EVP_add_cipher(EVP_des_ede_cfb());
EVP_add_cipher(EVP_des_ede3_cfb());
EVP_add_cipher(EVP_des_ede3_cfb1());
EVP_add_cipher(EVP_des_ede3_cfb8());
EVP_add_cipher(EVP_des_ofb());
EVP_add_cipher(EVP_des_ede_ofb());
EVP_add_cipher(EVP_des_ede3_ofb());
EVP_add_cipher(EVP_desx_cbc());
EVP_add_cipher_alias(SN_desx_cbc, "DESX");
EVP_add_cipher_alias(SN_desx_cbc, "desx");
EVP_add_cipher(EVP_des_cbc());
EVP_add_cipher_alias(SN_des_cbc, "DES");
EVP_add_cipher_alias(SN_des_cbc, "des");
EVP_add_cipher(EVP_des_ede_cbc());
EVP_add_cipher(EVP_des_ede3_cbc());
EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3");
EVP_add_cipher_alias(SN_des_ede3_cbc, "des3");
EVP_add_cipher(EVP_des_ecb());
EVP_add_cipher(EVP_des_ede());
EVP_add_cipher(EVP_des_ede3());
#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_RC2
EVP_add_cipher(EVP_rc2_ecb());
EVP_add_cipher(EVP_rc2_cfb());
EVP_add_cipher(EVP_rc2_ofb());
EVP_add_cipher(EVP_rc2_cbc());
EVP_add_cipher(EVP_rc2_40_cbc());
EVP_add_cipher(EVP_rc2_64_cbc());
EVP_add_cipher_alias(SN_rc2_cbc, "RC2");
EVP_add_cipher_alias(SN_rc2_cbc, "rc2");
#endif
#ifndef OPENSSL_NO_BF
EVP_add_cipher(EVP_bf_ecb());
EVP_add_cipher(EVP_bf_cfb());
EVP_add_cipher(EVP_bf_ofb());
EVP_add_cipher(EVP_bf_cbc());
EVP_add_cipher_alias(SN_bf_cbc, "BF");
EVP_add_cipher_alias(SN_bf_cbc, "bf");
EVP_add_cipher_alias(SN_bf_cbc, "blowfish");
#endif
#ifndef OPENSSL_NO_CAST
EVP_add_cipher(EVP_cast5_ecb());
EVP_add_cipher(EVP_cast5_cfb());
EVP_add_cipher(EVP_cast5_ofb());
EVP_add_cipher(EVP_cast5_cbc());
EVP_add_cipher_alias(SN_cast5_cbc, "CAST");
EVP_add_cipher_alias(SN_cast5_cbc, "cast");
EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc");
EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc");
#endif
#ifndef OPENSSL_NO_AES
EVP_add_cipher(EVP_aes_128_ecb());
EVP_add_cipher(EVP_aes_128_cbc());
EVP_add_cipher(EVP_aes_128_ccm());
EVP_add_cipher(EVP_aes_128_cfb());
EVP_add_cipher(EVP_aes_128_cfb1());
EVP_add_cipher(EVP_aes_128_cfb8());
EVP_add_cipher(EVP_aes_128_ofb());
EVP_add_cipher(EVP_aes_128_ctr());
EVP_add_cipher(EVP_aes_128_gcm());
EVP_add_cipher(EVP_aes_128_wrap());
EVP_add_cipher(EVP_aes_128_xts());
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_ccm());
EVP_add_cipher(EVP_aes_192_cfb());
EVP_add_cipher(EVP_aes_192_cfb1());
EVP_add_cipher(EVP_aes_192_cfb8());
EVP_add_cipher(EVP_aes_192_ofb());
EVP_add_cipher(EVP_aes_192_ctr());
EVP_add_cipher(EVP_aes_192_gcm());
EVP_add_cipher(EVP_aes_192_wrap());
EVP_add_cipher_alias(SN_aes_192_cbc, "AES192");
EVP_add_cipher_alias(SN_aes_192_cbc, "aes192");
EVP_add_cipher(EVP_aes_256_ecb());
EVP_add_cipher(EVP_aes_256_cbc());
EVP_add_cipher(EVP_aes_256_ccm());
EVP_add_cipher(EVP_aes_256_cfb());
EVP_add_cipher(EVP_aes_256_cfb1());
EVP_add_cipher(EVP_aes_256_cfb8());
EVP_add_cipher(EVP_aes_256_ofb());
EVP_add_cipher(EVP_aes_256_ctr());
EVP_add_cipher(EVP_aes_256_gcm());
EVP_add_cipher(EVP_aes_256_wrap());
EVP_add_cipher(EVP_aes_256_xts());
EVP_add_cipher_alias(SN_aes_256_cbc, "AES256");
EVP_add_cipher_alias(SN_aes_256_cbc, "aes256");
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
#endif
#endif
#ifndef OPENSSL_NO_CAMELLIA
EVP_add_cipher(EVP_camellia_128_ecb());
EVP_add_cipher(EVP_camellia_128_cbc());
EVP_add_cipher(EVP_camellia_128_cfb());
EVP_add_cipher(EVP_camellia_128_cfb1());
EVP_add_cipher(EVP_camellia_128_cfb8());
EVP_add_cipher(EVP_camellia_128_ofb());
EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128");
EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128");
EVP_add_cipher(EVP_camellia_192_ecb());
EVP_add_cipher(EVP_camellia_192_cbc());
EVP_add_cipher(EVP_camellia_192_cfb());
EVP_add_cipher(EVP_camellia_192_cfb1());
EVP_add_cipher(EVP_camellia_192_cfb8());
EVP_add_cipher(EVP_camellia_192_ofb());
EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192");
EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192");
EVP_add_cipher(EVP_camellia_256_ecb());
EVP_add_cipher(EVP_camellia_256_cbc());
EVP_add_cipher(EVP_camellia_256_cfb());
EVP_add_cipher(EVP_camellia_256_cfb1());
EVP_add_cipher(EVP_camellia_256_cfb8());
EVP_add_cipher(EVP_camellia_256_ofb());
EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256");
EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256");
#endif
#ifndef OPENSSL_NO_CHACHA
EVP_add_cipher(EVP_chacha20());
#endif
#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
EVP_add_cipher(EVP_chacha20_poly1305());
#endif
#ifndef OPENSSL_NO_GOST
EVP_add_cipher(EVP_gost2814789_ecb());
EVP_add_cipher(EVP_gost2814789_cfb64());
EVP_add_cipher(EVP_gost2814789_cnt());
#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
}
void
OpenSSL_add_all_ciphers(void)
{
static pthread_once_t add_all_ciphers_once = PTHREAD_ONCE_INIT;
(void) pthread_once(&add_all_ciphers_once, OpenSSL_add_all_ciphers_internal);
}
static void
OpenSSL_add_all_digests_internal(void)
{
#ifndef OPENSSL_NO_MD4
EVP_add_digest(EVP_md4());
#endif
#ifndef OPENSSL_NO_MD5
EVP_add_digest(EVP_md5());
EVP_add_digest(EVP_md5_sha1());
EVP_add_digest_alias(SN_md5, "ssl2-md5");
EVP_add_digest_alias(SN_md5, "ssl3-md5");
#endif
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
EVP_add_digest(EVP_sha1());
EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
#endif
#ifndef OPENSSL_NO_GOST
EVP_add_digest(EVP_gostr341194());
EVP_add_digest(EVP_gost2814789imit());
EVP_add_digest(EVP_streebog256());
EVP_add_digest(EVP_streebog512());
#endif
#ifndef OPENSSL_NO_RIPEMD
EVP_add_digest(EVP_ripemd160());
EVP_add_digest_alias(SN_ripemd160, "ripemd");
EVP_add_digest_alias(SN_ripemd160, "rmd160");
#endif
#ifndef OPENSSL_NO_SHA256
EVP_add_digest(EVP_sha224());
EVP_add_digest(EVP_sha256());
#endif
#ifndef OPENSSL_NO_SHA512
EVP_add_digest(EVP_sha384());
EVP_add_digest(EVP_sha512());
EVP_add_digest(EVP_sha512_224());
EVP_add_digest(EVP_sha512_256());
#endif
#ifndef OPENSSL_NO_SHA3
EVP_add_digest(EVP_sha3_224());
EVP_add_digest(EVP_sha3_256());
EVP_add_digest(EVP_sha3_384());
EVP_add_digest(EVP_sha3_512());
#endif
#ifndef OPENSSL_NO_SM3
EVP_add_digest(EVP_sm3());
#endif
#ifndef OPENSSL_NO_WHIRLPOOL
EVP_add_digest(EVP_whirlpool());
#endif
}
void
OpenSSL_add_all_digests(void)
{
static pthread_once_t add_all_digests_once = PTHREAD_ONCE_INIT;
(void) pthread_once(&add_all_digests_once, OpenSSL_add_all_digests_internal);
}
void
OPENSSL_add_all_algorithms_noconf(void)
{
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();
}
void
OPENSSL_add_all_algorithms_conf(void)
{
OPENSSL_add_all_algorithms_noconf();
OPENSSL_config(NULL);
}

View File

@@ -0,0 +1,178 @@
/* $OpenBSD: cipher_method_lib.c,v 1.10 2023/07/07 19:37:53 beck Exp $ */
/*
* Written by Richard Levitte (levitte@openssl.org) for the OpenSSL project
* 2015.
*/
/* ====================================================================
* Copyright (c) 2015 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdlib.h>
#include <openssl/evp.h>
#include "evp_local.h"
EVP_CIPHER *
EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len)
{
EVP_CIPHER *cipher;
if ((cipher = calloc(1, sizeof(*cipher))) == NULL)
return 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 *copy;
if ((copy = calloc(1, sizeof(*copy))) == NULL)
return NULL;
*copy = *cipher;
return copy;
}
void
EVP_CIPHER_meth_free(EVP_CIPHER *cipher)
{
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;
}

429
crypto/evp/digest.c Normal file
View File

@@ -0,0 +1,429 @@
/* $OpenBSD: digest.c,v 1.38 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#include "evp_local.h"
int
EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
{
EVP_MD_CTX_init(ctx);
return EVP_DigestInit_ex(ctx, type, NULL);
}
int
EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
{
EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
#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 ||
(type && (type->type == ctx->digest->type))))
goto skip_to_init;
if (type) {
/* Ensure an ENGINE left lying around from last time is cleared
* (the previous check attempted to avoid this if the same
* ENGINE and EVP_MD could be used). */
ENGINE_finish(ctx->engine);
if (impl != NULL) {
if (!ENGINE_init(impl)) {
EVPerror(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) {
/* Same comment from evp_enc.c */
EVPerror(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) {
EVPerror(EVP_R_NO_DIGEST_SET);
return 0;
}
#endif
if (ctx->digest != type) {
if (ctx->digest && ctx->digest->ctx_size && ctx->md_data &&
!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
freezero(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 = calloc(1, type->ctx_size);
if (ctx->md_data == NULL) {
EVP_PKEY_CTX_free(ctx->pctx);
ctx->pctx = NULL;
EVPerror(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_cleanup(ctx);
return ret;
}
/* The caller can assume that this removes any secret data from the context */
int
EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
{
int ret;
if ((size_t)ctx->digest->md_size > EVP_MAX_MD_SIZE) {
EVPerror(EVP_R_TOO_LARGE);
return 0;
}
ret = ctx->digest->final(ctx, md);
if (size != NULL)
*size = ctx->digest->md_size;
if (ctx->digest->cleanup) {
ctx->digest->cleanup(ctx);
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
}
memset(ctx->md_data, 0, ctx->digest->ctx_size);
return ret;
}
int
EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
{
EVP_MD_CTX_init(out);
return EVP_MD_CTX_copy_ex(out, in);
}
int
EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
{
unsigned char *tmp_buf;
if ((in == NULL) || (in->digest == NULL)) {
EVPerror(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)) {
EVPerror(ERR_R_ENGINE_LIB);
return 0;
}
#endif
if (out->digest == in->digest) {
tmp_buf = out->md_data;
EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE);
} else
tmp_buf = NULL;
EVP_MD_CTX_cleanup(out);
memcpy(out, in, sizeof *out);
out->md_data = NULL;
out->pctx = NULL;
/*
* Because of the EVP_PKEY_CTX_dup() below, EVP_MD_CTX_cleanup() needs
* to free out->pctx in all cases (even if this flag is set on in).
*/
EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
if (in->md_data && out->digest->ctx_size) {
if (tmp_buf) {
out->md_data = tmp_buf;
} else {
out->md_data = calloc(1, out->digest->ctx_size);
if (out->md_data == NULL) {
EVPerror(ERR_R_MALLOC_FAILURE);
return 0;
}
}
memcpy(out->md_data, in->md_data, out->digest->ctx_size);
}
out->update = in->update;
if (in->pctx) {
out->pctx = EVP_PKEY_CTX_dup(in->pctx);
if (!out->pctx) {
EVP_MD_CTX_cleanup(out);
return 0;
}
}
if (out->digest->copy)
return out->digest->copy(out, in);
return 1;
}
int
EVP_Digest(const void *data, size_t count,
unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl)
{
EVP_MD_CTX ctx;
int ret;
EVP_MD_CTX_init(&ctx);
EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT);
ret = EVP_DigestInit_ex(&ctx, type, impl) &&
EVP_DigestUpdate(&ctx, data, count) &&
EVP_DigestFinal_ex(&ctx, md, size);
EVP_MD_CTX_cleanup(&ctx);
return ret;
}
EVP_MD_CTX *
EVP_MD_CTX_new(void)
{
return calloc(1, sizeof(EVP_MD_CTX));
}
void
EVP_MD_CTX_free(EVP_MD_CTX *ctx)
{
if (ctx == NULL)
return;
EVP_MD_CTX_cleanup(ctx);
free(ctx);
}
void
EVP_MD_CTX_init(EVP_MD_CTX *ctx)
{
memset(ctx, 0, sizeof(*ctx));
}
int
EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
{
return EVP_MD_CTX_cleanup(ctx);
}
EVP_MD_CTX *
EVP_MD_CTX_create(void)
{
return EVP_MD_CTX_new();
}
void
EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
{
EVP_MD_CTX_free(ctx);
}
/* This call frees resources associated with the context */
int
EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
{
/*
* 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))
freezero(ctx->md_data, ctx->digest->ctx_size);
/*
* If EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set, EVP_MD_CTX_set_pkey() was
* called and its strange API contract implies we don't own ctx->pctx.
*/
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
memset(ctx, 0, sizeof(*ctx));
return 1;
}
int
EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
{
int ret;
if (!ctx->digest) {
EVPerror(EVP_R_NO_CIPHER_SET);
return 0;
}
if (!ctx->digest->md_ctrl) {
EVPerror(EVP_R_CTRL_NOT_IMPLEMENTED);
return 0;
}
ret = ctx->digest->md_ctrl(ctx, type, arg, ptr);
if (ret == -1) {
EVPerror(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
return 0;
}
return ret;
}

2602
crypto/evp/e_aes.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,604 @@
/* $OpenBSD: e_aes_cbc_hmac_sha1.c,v 1.19 2023/07/07 19:37:53 beck Exp $ */
/* ====================================================================
* Copyright (c) 2011-2013 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
#include <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1)
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/aes.h>
#include <openssl/sha.h>
#include "constant_time.h"
#include "evp_local.h"
#define TLS1_1_VERSION 0x0302
typedef struct {
AES_KEY ks;
SHA_CTX head, tail, md;
size_t payload_length; /* AAD length in decrypt case */
union {
unsigned int tls_ver;
unsigned char tls_aad[16]; /* 13 used */
} aux;
} EVP_AES_HMAC_SHA1;
#define NO_PAYLOAD_LENGTH ((size_t)-1)
#if defined(AES_ASM) && ( \
defined(__x86_64) || defined(__x86_64__) || \
defined(_M_AMD64) || defined(_M_X64) || \
defined(__INTEL__) )
#include "x86_arch.h"
#if defined(__GNUC__) && __GNUC__>=2
# define BSWAP(x) ({ unsigned int r=(x); asm ("bswapl %0":"=r"(r):"0"(r)); r; })
#endif
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);
#define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data)
static int
aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *inkey,
const unsigned char *iv, int enc)
{
EVP_AES_HMAC_SHA1 *key = data(ctx);
int ret;
if (enc)
ret = aesni_set_encrypt_key(inkey, ctx->key_len * 8, &key->ks);
else
ret = aesni_set_decrypt_key(inkey, ctx->key_len * 8, &key->ks);
SHA1_Init(&key->head); /* handy when benchmarking */
key->tail = key->head;
key->md = key->head;
key->payload_length = NO_PAYLOAD_LENGTH;
return ret < 0 ? 0 : 1;
}
#define STITCHED_CALL
#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
static int
aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t len)
{
EVP_AES_HMAC_SHA1 *key = data(ctx);
unsigned int l;
size_t plen = key->payload_length,
iv = 0, /* explicit IV in TLS 1.1 and later */
sha_off = 0;
#if defined(STITCHED_CALL)
size_t aes_off = 0, blocks;
sha_off = SHA_CBLOCK - key->md.num;
#endif
key->payload_length = NO_PAYLOAD_LENGTH;
if (len % AES_BLOCK_SIZE)
return 0;
if (ctx->encrypt) {
if (plen == NO_PAYLOAD_LENGTH)
plen = len;
else if (len != ((plen + SHA_DIGEST_LENGTH + AES_BLOCK_SIZE) &
-AES_BLOCK_SIZE))
return 0;
else if (key->aux.tls_ver >= TLS1_1_VERSION)
iv = AES_BLOCK_SIZE;
#if defined(STITCHED_CALL)
if (plen > (sha_off + iv) &&
(blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) {
SHA1_Update(&key->md, in + iv, sha_off);
aesni_cbc_sha1_enc(in, out, blocks, &key->ks,
ctx->iv, &key->md, in + iv + sha_off);
blocks *= SHA_CBLOCK;
aes_off += blocks;
sha_off += blocks;
key->md.Nh += blocks >> 29;
key->md.Nl += blocks <<= 3;
if (key->md.Nl < (unsigned int)blocks)
key->md.Nh++;
} else {
sha_off = 0;
}
#endif
sha_off += iv;
SHA1_Update(&key->md, in + sha_off, plen - sha_off);
if (plen != len) { /* "TLS" mode of operation */
if (in != out)
memcpy(out + aes_off, in + aes_off,
plen - aes_off);
/* calculate HMAC and append it to payload */
SHA1_Final(out + plen, &key->md);
key->md = key->tail;
SHA1_Update(&key->md, out + plen, SHA_DIGEST_LENGTH);
SHA1_Final(out + plen, &key->md);
/* pad the payload|hmac */
plen += SHA_DIGEST_LENGTH;
for (l = len - plen - 1; plen < len; plen++)
out[plen] = l;
/* encrypt HMAC|padding at once */
aesni_cbc_encrypt(out + aes_off, out + aes_off,
len - aes_off, &key->ks, ctx->iv, 1);
} else {
aesni_cbc_encrypt(in + aes_off, out + aes_off,
len - aes_off, &key->ks, ctx->iv, 1);
}
} else {
union {
unsigned int u[SHA_DIGEST_LENGTH/sizeof(unsigned int)];
unsigned char c[32 + SHA_DIGEST_LENGTH];
} mac, *pmac;
/* arrange cache line alignment */
pmac = (void *)(((size_t)mac.c + 31) & ((size_t)0 - 32));
/* decrypt HMAC|padding at once */
aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0);
if (plen == 0 || plen == NO_PAYLOAD_LENGTH) {
SHA1_Update(&key->md, out, len);
} else if (plen < 4) {
return 0;
} else { /* "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 ((key->aux.tls_aad[plen - 4] << 8 |
key->aux.tls_aad[plen - 3]) >= TLS1_1_VERSION)
iv = AES_BLOCK_SIZE;
if (len < (iv + SHA_DIGEST_LENGTH + 1))
return 0;
/* omit explicit iv */
out += iv;
len -= iv;
/* figure out payload length */
pad = out[len - 1];
maxpad = len - (SHA_DIGEST_LENGTH + 1);
maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
maxpad &= 255;
ret &= constant_time_ge(maxpad, pad);
inp_len = len - (SHA_DIGEST_LENGTH + pad + 1);
mask = (0 - ((inp_len - len) >>
(sizeof(inp_len) * 8 - 1)));
inp_len &= mask;
ret &= (int)mask;
key->aux.tls_aad[plen - 2] = inp_len >> 8;
key->aux.tls_aad[plen - 1] = inp_len;
/* calculate HMAC */
key->md = key->head;
SHA1_Update(&key->md, key->aux.tls_aad, plen);
#if 1
len -= SHA_DIGEST_LENGTH; /* amend mac */
if (len >= (256 + SHA_CBLOCK)) {
j = (len - (256 + SHA_CBLOCK)) &
(0 - SHA_CBLOCK);
j += SHA_CBLOCK - key->md.num;
SHA1_Update(&key->md, out, j);
out += j;
len -= j;
inp_len -= j;
}
/* but pretend as if we hashed padded payload */
bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */
#ifdef BSWAP
bitlen = BSWAP(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 BSWAP
pmac->u[0] = BSWAP(pmac->u[0]);
pmac->u[1] = BSWAP(pmac->u[1]);
pmac->u[2] = BSWAP(pmac->u[2]);
pmac->u[3] = BSWAP(pmac->u[3]);
pmac->u[4] = BSWAP(pmac->u[4]);
#else
for (i = 0; i < 5; i++) {
res = pmac->u[i];
pmac->c[4 * i + 0] = (unsigned char)(res >> 24);
pmac->c[4 * i + 1] = (unsigned char)(res >> 16);
pmac->c[4 * i + 2] = (unsigned char)(res >> 8);
pmac->c[4 * i + 3] = (unsigned char)res;
}
#endif
len += SHA_DIGEST_LENGTH;
#else
SHA1_Update(&key->md, out, inp_len);
res = key->md.num;
SHA1_Final(pmac->c, &key->md);
{
unsigned int inp_blocks, pad_blocks;
/* but pretend as if we hashed padded payload */
inp_blocks = 1 + ((SHA_CBLOCK - 9 - res) >>
(sizeof(res) * 8 - 1));
res += (unsigned int)(len - inp_len);
pad_blocks = res / SHA_CBLOCK;
res %= SHA_CBLOCK;
pad_blocks += 1 + ((SHA_CBLOCK - 9 - res) >>
(sizeof(res) * 8 - 1));
for (; inp_blocks < pad_blocks; inp_blocks++)
sha1_block_data_order(&key->md,
data, 1);
}
#endif
key->md = key->tail;
SHA1_Update(&key->md, pmac->c, SHA_DIGEST_LENGTH);
SHA1_Final(pmac->c, &key->md);
/* verify HMAC */
out += inp_len;
len -= inp_len;
#if 1
{
unsigned char *p =
out + len - 1 - maxpad - SHA_DIGEST_LENGTH;
size_t off = out - p;
unsigned int c, cmask;
maxpad += SHA_DIGEST_LENGTH;
for (res = 0, i = 0, j = 0; j < maxpad; j++) {
c = p[j];
cmask = ((int)(j - off -
SHA_DIGEST_LENGTH)) >>
(sizeof(int) * 8 - 1);
res |= (c ^ pad) & ~cmask; /* ... and padding */
cmask &= ((int)(off - 1 - j)) >>
(sizeof(int) * 8 - 1);
res |= (c ^ pmac->c[i]) & cmask;
i += 1 & cmask;
}
maxpad -= SHA_DIGEST_LENGTH;
res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
ret &= (int)~res;
}
#else
for (res = 0, i = 0; i < SHA_DIGEST_LENGTH; i++)
res |= out[i] ^ pmac->c[i];
res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
ret &= (int)~res;
/* verify padding */
pad = (pad & ~res) | (maxpad & res);
out = out + len - 1 - pad;
for (res = 0, i = 0; i < pad; i++)
res |= out[i] ^ pad;
res = (0 - res) >> (sizeof(res) * 8 - 1);
ret &= (int)~res;
#endif
return ret;
}
}
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));
explicit_bzero(hmac_key, sizeof(hmac_key));
return 1;
}
case EVP_CTRL_AEAD_TLS1_AAD:
{
unsigned char *p = ptr;
unsigned int len;
/* RFC 5246, 6.2.3.3: additional data has length 13 */
if (arg != 13)
return -1;
len = p[arg - 2] << 8 | p[arg - 1];
if (ctx->encrypt) {
key->payload_length = len;
if ((key->aux.tls_ver = p[arg - 4] << 8 |
p[arg - 3]) >= TLS1_1_VERSION) {
len -= AES_BLOCK_SIZE;
p[arg - 2] = len >> 8;
p[arg - 1] = len;
}
key->md = key->head;
SHA1_Update(&key->md, p, arg);
return (int)(((len + SHA_DIGEST_LENGTH +
AES_BLOCK_SIZE) & -AES_BLOCK_SIZE) - len);
} else {
memcpy(key->aux.tls_aad, ptr, arg);
key->payload_length = arg;
return SHA_DIGEST_LENGTH;
}
}
default:
return -1;
}
}
static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher = {
#ifdef NID_aes_128_cbc_hmac_sha1
.nid = NID_aes_128_cbc_hmac_sha1,
#else
.nid = NID_undef,
#endif
.block_size = 16,
.key_len = 16,
.iv_len = 16,
.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
EVP_CIPH_FLAG_AEAD_CIPHER,
.init = aesni_cbc_hmac_sha1_init_key,
.do_cipher = aesni_cbc_hmac_sha1_cipher,
.ctx_size = sizeof(EVP_AES_HMAC_SHA1),
.ctrl = aesni_cbc_hmac_sha1_ctrl
};
static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher = {
#ifdef NID_aes_256_cbc_hmac_sha1
.nid = NID_aes_256_cbc_hmac_sha1,
#else
.nid = NID_undef,
#endif
.block_size = 16,
.key_len = 32,
.iv_len = 16,
.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
EVP_CIPH_FLAG_AEAD_CIPHER,
.init = aesni_cbc_hmac_sha1_init_key,
.do_cipher = aesni_cbc_hmac_sha1_cipher,
.ctx_size = sizeof(EVP_AES_HMAC_SHA1),
.ctrl = aesni_cbc_hmac_sha1_ctrl
};
const EVP_CIPHER *
EVP_aes_128_cbc_hmac_sha1(void)
{
return (OPENSSL_cpu_caps() & CPUCAP_MASK_AESNI) ?
&aesni_128_cbc_hmac_sha1_cipher : NULL;
}
const EVP_CIPHER *
EVP_aes_256_cbc_hmac_sha1(void)
{
return (OPENSSL_cpu_caps() & CPUCAP_MASK_AESNI) ?
&aesni_256_cbc_hmac_sha1_cipher : NULL;
}
#else
const EVP_CIPHER *
EVP_aes_128_cbc_hmac_sha1(void)
{
return NULL;
}
const EVP_CIPHER *
EVP_aes_256_cbc_hmac_sha1(void)
{
return NULL;
}
#endif
#endif

247
crypto/evp/e_bf.c Normal file
View File

@@ -0,0 +1,247 @@
/* $OpenBSD: e_bf.c,v 1.17 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <limits.h>
#include <stdio.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_BF
#include <openssl/blowfish.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include "evp_local.h"
typedef struct {
BF_KEY ks;
} EVP_BF_KEY;
#define data(ctx) ((EVP_BF_KEY *)(ctx)->cipher_data)
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;
}
static int
bf_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
BF_cbc_encrypt(in, out, (long)chunk, &((EVP_BF_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
BF_cbc_encrypt(in, out, (long)inl, &((EVP_BF_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
return 1;
}
static int
bf_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
BF_cfb64_encrypt(in, out, (long)chunk, &((EVP_BF_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static int
bf_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t i, bl;
bl = ctx->cipher->block_size;
if (inl < bl)
return 1;
inl -= bl;
for (i = 0; i <= inl; i += bl)
BF_ecb_encrypt(in + i, out + i, &((EVP_BF_KEY *)ctx->cipher_data)->ks, ctx->encrypt);
return 1;
}
static int
bf_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
BF_ofb64_encrypt(in, out, (long)chunk, &((EVP_BF_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
BF_ofb64_encrypt(in, out, (long)inl, &((EVP_BF_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
return 1;
}
static const EVP_CIPHER bf_cbc = {
.nid = NID_bf_cbc,
.block_size = 8,
.key_len = 16,
.iv_len = 8,
.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CBC_MODE,
.init = bf_init_key,
.do_cipher = bf_cbc_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_BF_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_bf_cbc(void)
{
return &bf_cbc;
}
static const EVP_CIPHER bf_cfb64 = {
.nid = NID_bf_cfb64,
.block_size = 1,
.key_len = 16,
.iv_len = 8,
.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CFB_MODE,
.init = bf_init_key,
.do_cipher = bf_cfb64_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_BF_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_bf_cfb64(void)
{
return &bf_cfb64;
}
static const EVP_CIPHER bf_ofb = {
.nid = NID_bf_ofb64,
.block_size = 1,
.key_len = 16,
.iv_len = 8,
.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_OFB_MODE,
.init = bf_init_key,
.do_cipher = bf_ofb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_BF_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_bf_ofb(void)
{
return &bf_ofb;
}
static const EVP_CIPHER bf_ecb = {
.nid = NID_bf_ecb,
.block_size = 8,
.key_len = 16,
.iv_len = 0,
.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ECB_MODE,
.init = bf_init_key,
.do_cipher = bf_ecb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_BF_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_bf_ecb(void)
{
return &bf_ecb;
}
#endif

823
crypto/evp/e_camellia.c Normal file
View File

@@ -0,0 +1,823 @@
/* $OpenBSD: e_camellia.c,v 1.18 2023/07/07 19:37:53 beck Exp $ */
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <string.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_CAMELLIA
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/camellia.h>
#include "evp_local.h"
/* Camellia subkey Structure */
typedef struct {
CAMELLIA_KEY ks;
} EVP_CAMELLIA_KEY;
/* Attribute operation for Camellia */
#define data(ctx) ((EVP_CAMELLIA_KEY *)(ctx)->cipher_data)
static int
camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
int ret;
ret = Camellia_set_key(key, ctx->key_len * 8, ctx->cipher_data);
if (ret < 0) {
EVPerror(EVP_R_CAMELLIA_KEY_SETUP_FAILED);
return 0;
}
return 1;
}
static int
camellia_128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
while (inl >= EVP_MAXCHUNK) {
Camellia_cbc_encrypt(in, out, EVP_MAXCHUNK, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
inl -= EVP_MAXCHUNK;
in += EVP_MAXCHUNK;
out += EVP_MAXCHUNK;
}
if (inl)
Camellia_cbc_encrypt(in, out, inl, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
return 1;
}
static int
camellia_128_cfb128_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = EVP_MAXCHUNK;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
Camellia_cfb128_encrypt(in, out, chunk, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static int
camellia_128_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t i, bl;
bl = ctx->cipher->block_size;
if (inl < bl)
return 1;
inl -= bl;
for (i = 0; i <= inl; i += bl)
Camellia_ecb_encrypt(in + i, out + i, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->encrypt);
return 1;
}
static int
camellia_128_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
while (inl >= EVP_MAXCHUNK) {
Camellia_ofb128_encrypt(in, out, EVP_MAXCHUNK, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
inl -= EVP_MAXCHUNK;
in += EVP_MAXCHUNK;
out += EVP_MAXCHUNK;
}
if (inl)
Camellia_ofb128_encrypt(in, out, inl, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
return 1;
}
static const EVP_CIPHER camellia_128_cbc = {
.nid = NID_camellia_128_cbc,
.block_size = 16,
.key_len = 16,
.iv_len = 16,
.flags = 0 | EVP_CIPH_CBC_MODE,
.init = camellia_init_key,
.do_cipher = camellia_128_cbc_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_128_cbc(void)
{
return &camellia_128_cbc;
}
static const EVP_CIPHER camellia_128_cfb128 = {
.nid = NID_camellia_128_cfb128,
.block_size = 1,
.key_len = 16,
.iv_len = 16,
.flags = 0 | EVP_CIPH_CFB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_128_cfb128_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_128_cfb128(void)
{
return &camellia_128_cfb128;
}
static const EVP_CIPHER camellia_128_ofb = {
.nid = NID_camellia_128_ofb128,
.block_size = 1,
.key_len = 16,
.iv_len = 16,
.flags = 0 | EVP_CIPH_OFB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_128_ofb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_128_ofb(void)
{
return &camellia_128_ofb;
}
static const EVP_CIPHER camellia_128_ecb = {
.nid = NID_camellia_128_ecb,
.block_size = 16,
.key_len = 16,
.iv_len = 0,
.flags = 0 | EVP_CIPH_ECB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_128_ecb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_128_ecb(void)
{
return &camellia_128_ecb;
}
static int
camellia_192_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
while (inl >= EVP_MAXCHUNK) {
Camellia_cbc_encrypt(in, out, EVP_MAXCHUNK, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
inl -= EVP_MAXCHUNK;
in += EVP_MAXCHUNK;
out += EVP_MAXCHUNK;
}
if (inl)
Camellia_cbc_encrypt(in, out, inl, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
return 1;
}
static int
camellia_192_cfb128_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = EVP_MAXCHUNK;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
Camellia_cfb128_encrypt(in, out, chunk, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static int
camellia_192_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t i, bl;
bl = ctx->cipher->block_size;
if (inl < bl)
return 1;
inl -= bl;
for (i = 0; i <= inl; i += bl)
Camellia_ecb_encrypt(in + i, out + i, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->encrypt);
return 1;
}
static int
camellia_192_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
while (inl >= EVP_MAXCHUNK) {
Camellia_ofb128_encrypt(in, out, EVP_MAXCHUNK, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
inl -= EVP_MAXCHUNK;
in += EVP_MAXCHUNK;
out += EVP_MAXCHUNK;
}
if (inl)
Camellia_ofb128_encrypt(in, out, inl, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
return 1;
}
static const EVP_CIPHER camellia_192_cbc = {
.nid = NID_camellia_192_cbc,
.block_size = 16,
.key_len = 24,
.iv_len = 16,
.flags = 0 | EVP_CIPH_CBC_MODE,
.init = camellia_init_key,
.do_cipher = camellia_192_cbc_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_192_cbc(void)
{
return &camellia_192_cbc;
}
static const EVP_CIPHER camellia_192_cfb128 = {
.nid = NID_camellia_192_cfb128,
.block_size = 1,
.key_len = 24,
.iv_len = 16,
.flags = 0 | EVP_CIPH_CFB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_192_cfb128_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_192_cfb128(void)
{
return &camellia_192_cfb128;
}
static const EVP_CIPHER camellia_192_ofb = {
.nid = NID_camellia_192_ofb128,
.block_size = 1,
.key_len = 24,
.iv_len = 16,
.flags = 0 | EVP_CIPH_OFB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_192_ofb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_192_ofb(void)
{
return &camellia_192_ofb;
}
static const EVP_CIPHER camellia_192_ecb = {
.nid = NID_camellia_192_ecb,
.block_size = 16,
.key_len = 24,
.iv_len = 0,
.flags = 0 | EVP_CIPH_ECB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_192_ecb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_192_ecb(void)
{
return &camellia_192_ecb;
}
static int
camellia_256_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
while (inl >= EVP_MAXCHUNK) {
Camellia_cbc_encrypt(in, out, EVP_MAXCHUNK, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
inl -= EVP_MAXCHUNK;
in += EVP_MAXCHUNK;
out += EVP_MAXCHUNK;
}
if (inl)
Camellia_cbc_encrypt(in, out, inl, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
return 1;
}
static int
camellia_256_cfb128_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = EVP_MAXCHUNK;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
Camellia_cfb128_encrypt(in, out, chunk, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static int
camellia_256_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t i, bl;
bl = ctx->cipher->block_size;
if (inl < bl)
return 1;
inl -= bl;
for (i = 0; i <= inl; i += bl)
Camellia_ecb_encrypt(in + i, out + i, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->encrypt);
return 1;
}
static int
camellia_256_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
while (inl >= EVP_MAXCHUNK) {
Camellia_ofb128_encrypt(in, out, EVP_MAXCHUNK, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
inl -= EVP_MAXCHUNK;
in += EVP_MAXCHUNK;
out += EVP_MAXCHUNK;
}
if (inl)
Camellia_ofb128_encrypt(in, out, inl, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
return 1;
}
static const EVP_CIPHER camellia_256_cbc = {
.nid = NID_camellia_256_cbc,
.block_size = 16,
.key_len = 32,
.iv_len = 16,
.flags = 0 | EVP_CIPH_CBC_MODE,
.init = camellia_init_key,
.do_cipher = camellia_256_cbc_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_256_cbc(void)
{
return &camellia_256_cbc;
}
static const EVP_CIPHER camellia_256_cfb128 = {
.nid = NID_camellia_256_cfb128,
.block_size = 1,
.key_len = 32,
.iv_len = 16,
.flags = 0 | EVP_CIPH_CFB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_256_cfb128_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_256_cfb128(void)
{
return &camellia_256_cfb128;
}
static const EVP_CIPHER camellia_256_ofb = {
.nid = NID_camellia_256_ofb128,
.block_size = 1,
.key_len = 32,
.iv_len = 16,
.flags = 0 | EVP_CIPH_OFB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_256_ofb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_256_ofb(void)
{
return &camellia_256_ofb;
}
static const EVP_CIPHER camellia_256_ecb = {
.nid = NID_camellia_256_ecb,
.block_size = 16,
.key_len = 32,
.iv_len = 0,
.flags = 0 | EVP_CIPH_ECB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_256_ecb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_256_ecb(void)
{
return &camellia_256_ecb;
}
static int
camellia_128_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = EVP_MAXCHUNK;
chunk >>= 3;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
Camellia_cfb1_encrypt(in, out, ((1 == 1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ? chunk * 8 : chunk), &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static const EVP_CIPHER camellia_128_cfb1 = {
.nid = NID_camellia_128_cfb1,
.block_size = 1,
.key_len = 128/8,
.iv_len = 16,
.flags = 0 | EVP_CIPH_CFB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_128_cfb1_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_128_cfb1(void)
{
return &camellia_128_cfb1;
}
static int
camellia_192_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = EVP_MAXCHUNK;
chunk >>= 3;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
Camellia_cfb1_encrypt(in, out, ((1 == 1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ? chunk * 8 : chunk), &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static const EVP_CIPHER camellia_192_cfb1 = {
.nid = NID_camellia_192_cfb1,
.block_size = 1,
.key_len = 192/8,
.iv_len = 16,
.flags = 0 | EVP_CIPH_CFB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_192_cfb1_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_192_cfb1(void)
{
return &camellia_192_cfb1;
}
static int
camellia_256_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = EVP_MAXCHUNK;
chunk >>= 3;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
Camellia_cfb1_encrypt(in, out, ((1 == 1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ? chunk * 8 : chunk), &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static const EVP_CIPHER camellia_256_cfb1 = {
.nid = NID_camellia_256_cfb1,
.block_size = 1,
.key_len = 256/8,
.iv_len = 16,
.flags = 0 | EVP_CIPH_CFB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_256_cfb1_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_256_cfb1(void)
{
return &camellia_256_cfb1;
}
static int
camellia_128_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = EVP_MAXCHUNK;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
Camellia_cfb8_encrypt(in, out, chunk, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static const EVP_CIPHER camellia_128_cfb8 = {
.nid = NID_camellia_128_cfb8,
.block_size = 1,
.key_len = 128/8,
.iv_len = 16,
.flags = 0 | EVP_CIPH_CFB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_128_cfb8_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_128_cfb8(void)
{
return &camellia_128_cfb8;
}
static int
camellia_192_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = EVP_MAXCHUNK;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
Camellia_cfb8_encrypt(in, out, chunk, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static const EVP_CIPHER camellia_192_cfb8 = {
.nid = NID_camellia_192_cfb8,
.block_size = 1,
.key_len = 192/8,
.iv_len = 16,
.flags = 0 | EVP_CIPH_CFB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_192_cfb8_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_192_cfb8(void)
{
return &camellia_192_cfb8;
}
static int
camellia_256_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = EVP_MAXCHUNK;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
Camellia_cfb8_encrypt(in, out, chunk, &((EVP_CAMELLIA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static const EVP_CIPHER camellia_256_cfb8 = {
.nid = NID_camellia_256_cfb8,
.block_size = 1,
.key_len = 256/8,
.iv_len = 16,
.flags = 0 | EVP_CIPH_CFB_MODE,
.init = camellia_init_key,
.do_cipher = camellia_256_cfb8_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAMELLIA_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_camellia_256_cfb8(void)
{
return &camellia_256_cfb8;
}
#endif

247
crypto/evp/e_cast.c Normal file
View File

@@ -0,0 +1,247 @@
/* $OpenBSD: e_cast.c,v 1.16 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <limits.h>
#include <stdio.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_CAST
#include <openssl/cast.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include "evp_local.h"
typedef struct {
CAST_KEY ks;
} EVP_CAST_KEY;
#define data(ctx) ((EVP_CAST_KEY *)(ctx)->cipher_data)
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;
}
static int
cast5_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
CAST_cbc_encrypt(in, out, (long)chunk, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
CAST_cbc_encrypt(in, out, (long)inl, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
return 1;
}
static int
cast5_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
CAST_cfb64_encrypt(in, out, (long)chunk, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static int
cast5_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t i, bl;
bl = ctx->cipher->block_size;
if (inl < bl)
return 1;
inl -= bl;
for (i = 0; i <= inl; i += bl)
CAST_ecb_encrypt(in + i, out + i, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->encrypt);
return 1;
}
static int
cast5_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
CAST_ofb64_encrypt(in, out, (long)chunk, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
CAST_ofb64_encrypt(in, out, (long)inl, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
return 1;
}
static const EVP_CIPHER cast5_cbc = {
.nid = NID_cast5_cbc,
.block_size = 8,
.key_len = CAST_KEY_LENGTH,
.iv_len = 8,
.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CBC_MODE,
.init = cast_init_key,
.do_cipher = cast5_cbc_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAST_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_cast5_cbc(void)
{
return &cast5_cbc;
}
static const EVP_CIPHER cast5_cfb64 = {
.nid = NID_cast5_cfb64,
.block_size = 1,
.key_len = CAST_KEY_LENGTH,
.iv_len = 8,
.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CFB_MODE,
.init = cast_init_key,
.do_cipher = cast5_cfb64_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAST_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_cast5_cfb64(void)
{
return &cast5_cfb64;
}
static const EVP_CIPHER cast5_ofb = {
.nid = NID_cast5_ofb64,
.block_size = 1,
.key_len = CAST_KEY_LENGTH,
.iv_len = 8,
.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_OFB_MODE,
.init = cast_init_key,
.do_cipher = cast5_ofb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAST_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_cast5_ofb(void)
{
return &cast5_ofb;
}
static const EVP_CIPHER cast5_ecb = {
.nid = NID_cast5_ecb,
.block_size = 8,
.key_len = CAST_KEY_LENGTH,
.iv_len = 0,
.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ECB_MODE,
.init = cast_init_key,
.do_cipher = cast5_ecb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_CAST_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_cast5_ecb(void)
{
return &cast5_ecb;
}
#endif

76
crypto/evp/e_chacha.c Normal file
View File

@@ -0,0 +1,76 @@
/* $OpenBSD: e_chacha.c,v 1.13 2023/08/24 04:20:57 tb Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_CHACHA
#include <openssl/chacha.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include "evp_local.h"
static int
chacha_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *openssl_iv, int enc)
{
if (key != NULL)
ChaCha_set_key((ChaCha_ctx *)ctx->cipher_data, key,
EVP_CIPHER_CTX_key_length(ctx) * 8);
if (openssl_iv != NULL) {
const unsigned char *iv = openssl_iv + 8;
const unsigned char *counter = openssl_iv;
ChaCha_set_iv((ChaCha_ctx *)ctx->cipher_data, iv, counter);
}
return 1;
}
static int
chacha_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
size_t len)
{
ChaCha((ChaCha_ctx *)ctx->cipher_data, out, in, len);
return 1;
}
static const EVP_CIPHER chacha20_cipher = {
.nid = NID_chacha20,
.block_size = 1,
.key_len = 32,
/*
* The 16-byte EVP IV is split into 4 little-endian 4-byte words
* evpiv[15:12] evpiv[11:8] evpiv[7:4] evpiv[3:0]
* iv[1] iv[0] counter[1] counter[0]
* and passed as iv[] and counter[] to ChaCha_set_iv().
*/
.iv_len = 16,
.flags = EVP_CIPH_STREAM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
EVP_CIPH_CUSTOM_IV,
.init = chacha_init,
.do_cipher = chacha_cipher,
.ctx_size = sizeof(ChaCha_ctx)
};
const EVP_CIPHER *
EVP_chacha20(void)
{
return (&chacha20_cipher);
}
#endif

View File

@@ -0,0 +1,618 @@
/* $OpenBSD: e_chacha20poly1305.c,v 1.32 2023/09/28 11:29:10 tb Exp $ */
/*
* Copyright (c) 2022 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2015 Reyk Floter <reyk@openbsd.org>
* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <limits.h>
#include <stdint.h>
#include <string.h>
#include <openssl/opensslconf.h>
#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/chacha.h>
#include <openssl/poly1305.h>
#include "bytestring.h"
#include "evp_local.h"
#define POLY1305_TAG_LEN 16
#define CHACHA20_CONSTANT_LEN 4
#define CHACHA20_IV_LEN 8
#define CHACHA20_NONCE_LEN (CHACHA20_CONSTANT_LEN + CHACHA20_IV_LEN)
#define XCHACHA20_NONCE_LEN 24
struct aead_chacha20_poly1305_ctx {
unsigned char key[32];
unsigned char tag_len;
};
static int
aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const unsigned char *key,
size_t key_len, size_t tag_len)
{
struct aead_chacha20_poly1305_ctx *c20_ctx;
if (tag_len == 0)
tag_len = POLY1305_TAG_LEN;
if (tag_len > POLY1305_TAG_LEN) {
EVPerror(EVP_R_TOO_LARGE);
return 0;
}
/* Internal error - EVP_AEAD_CTX_init should catch this. */
if (key_len != sizeof(c20_ctx->key))
return 0;
c20_ctx = malloc(sizeof(struct aead_chacha20_poly1305_ctx));
if (c20_ctx == NULL)
return 0;
memcpy(&c20_ctx->key[0], key, key_len);
c20_ctx->tag_len = tag_len;
ctx->aead_state = c20_ctx;
return 1;
}
static void
aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx)
{
struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
freezero(c20_ctx, sizeof(*c20_ctx));
}
static void
poly1305_update_with_length(poly1305_state *poly1305,
const unsigned char *data, size_t data_len)
{
size_t j = data_len;
unsigned char length_bytes[8];
unsigned i;
for (i = 0; i < sizeof(length_bytes); i++) {
length_bytes[i] = j;
j >>= 8;
}
if (data != NULL)
CRYPTO_poly1305_update(poly1305, data, data_len);
CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
}
static void
poly1305_pad16(poly1305_state *poly1305, size_t data_len)
{
static const unsigned char zero_pad16[16];
size_t pad_len;
/* pad16() is defined in RFC 8439 2.8.1. */
if ((pad_len = data_len % 16) == 0)
return;
CRYPTO_poly1305_update(poly1305, zero_pad16, 16 - pad_len);
}
static void
poly1305_update_with_pad16(poly1305_state *poly1305,
const unsigned char *data, size_t data_len)
{
CRYPTO_poly1305_update(poly1305, data, data_len);
poly1305_pad16(poly1305, data_len);
}
static int
aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
size_t *out_len, size_t max_out_len, const unsigned char *nonce,
size_t nonce_len, const unsigned char *in, size_t in_len,
const unsigned char *ad, size_t ad_len)
{
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
unsigned char poly1305_key[32];
poly1305_state poly1305;
const unsigned char *iv;
uint64_t ctr;
if (max_out_len < in_len + c20_ctx->tag_len) {
EVPerror(EVP_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != ctx->aead->nonce_len) {
EVPerror(EVP_R_IV_TOO_LARGE);
return 0;
}
ctr = (uint64_t)((uint32_t)(nonce[0]) | (uint32_t)(nonce[1]) << 8 |
(uint32_t)(nonce[2]) << 16 | (uint32_t)(nonce[3]) << 24) << 32;
iv = nonce + CHACHA20_CONSTANT_LEN;
memset(poly1305_key, 0, sizeof(poly1305_key));
CRYPTO_chacha_20(poly1305_key, poly1305_key,
sizeof(poly1305_key), c20_ctx->key, iv, ctr);
CRYPTO_poly1305_init(&poly1305, poly1305_key);
poly1305_update_with_pad16(&poly1305, ad, ad_len);
CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, iv, ctr + 1);
poly1305_update_with_pad16(&poly1305, out, in_len);
poly1305_update_with_length(&poly1305, NULL, ad_len);
poly1305_update_with_length(&poly1305, NULL, in_len);
if (c20_ctx->tag_len != POLY1305_TAG_LEN) {
unsigned char tag[POLY1305_TAG_LEN];
CRYPTO_poly1305_finish(&poly1305, tag);
memcpy(out + in_len, tag, c20_ctx->tag_len);
*out_len = in_len + c20_ctx->tag_len;
return 1;
}
CRYPTO_poly1305_finish(&poly1305, out + in_len);
*out_len = in_len + POLY1305_TAG_LEN;
return 1;
}
static int
aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
size_t *out_len, size_t max_out_len, const unsigned char *nonce,
size_t nonce_len, const unsigned char *in, size_t in_len,
const unsigned char *ad, size_t ad_len)
{
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
unsigned char mac[POLY1305_TAG_LEN];
unsigned char poly1305_key[32];
const unsigned char *iv = nonce;
poly1305_state poly1305;
size_t plaintext_len;
uint64_t ctr = 0;
if (in_len < c20_ctx->tag_len) {
EVPerror(EVP_R_BAD_DECRYPT);
return 0;
}
if (nonce_len != ctx->aead->nonce_len) {
EVPerror(EVP_R_IV_TOO_LARGE);
return 0;
}
plaintext_len = in_len - c20_ctx->tag_len;
if (max_out_len < plaintext_len) {
EVPerror(EVP_R_BUFFER_TOO_SMALL);
return 0;
}
ctr = (uint64_t)((uint32_t)(nonce[0]) | (uint32_t)(nonce[1]) << 8 |
(uint32_t)(nonce[2]) << 16 | (uint32_t)(nonce[3]) << 24) << 32;
iv = nonce + CHACHA20_CONSTANT_LEN;
memset(poly1305_key, 0, sizeof(poly1305_key));
CRYPTO_chacha_20(poly1305_key, poly1305_key,
sizeof(poly1305_key), c20_ctx->key, iv, ctr);
CRYPTO_poly1305_init(&poly1305, poly1305_key);
poly1305_update_with_pad16(&poly1305, ad, ad_len);
poly1305_update_with_pad16(&poly1305, in, plaintext_len);
poly1305_update_with_length(&poly1305, NULL, ad_len);
poly1305_update_with_length(&poly1305, NULL, plaintext_len);
CRYPTO_poly1305_finish(&poly1305, mac);
if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
EVPerror(EVP_R_BAD_DECRYPT);
return 0;
}
CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, iv, ctr + 1);
*out_len = plaintext_len;
return 1;
}
static int
aead_xchacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
size_t *out_len, size_t max_out_len, const unsigned char *nonce,
size_t nonce_len, const unsigned char *in, size_t in_len,
const unsigned char *ad, size_t ad_len)
{
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
unsigned char poly1305_key[32];
unsigned char subkey[32];
poly1305_state poly1305;
if (max_out_len < in_len + c20_ctx->tag_len) {
EVPerror(EVP_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != ctx->aead->nonce_len) {
EVPerror(EVP_R_IV_TOO_LARGE);
return 0;
}
CRYPTO_hchacha_20(subkey, c20_ctx->key, nonce);
CRYPTO_chacha_20(out, in, in_len, subkey, nonce + 16, 1);
memset(poly1305_key, 0, sizeof(poly1305_key));
CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
subkey, nonce + 16, 0);
CRYPTO_poly1305_init(&poly1305, poly1305_key);
poly1305_update_with_pad16(&poly1305, ad, ad_len);
poly1305_update_with_pad16(&poly1305, out, in_len);
poly1305_update_with_length(&poly1305, NULL, ad_len);
poly1305_update_with_length(&poly1305, NULL, in_len);
if (c20_ctx->tag_len != POLY1305_TAG_LEN) {
unsigned char tag[POLY1305_TAG_LEN];
CRYPTO_poly1305_finish(&poly1305, tag);
memcpy(out + in_len, tag, c20_ctx->tag_len);
*out_len = in_len + c20_ctx->tag_len;
return 1;
}
CRYPTO_poly1305_finish(&poly1305, out + in_len);
*out_len = in_len + POLY1305_TAG_LEN;
return 1;
}
static int
aead_xchacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
size_t *out_len, size_t max_out_len, const unsigned char *nonce,
size_t nonce_len, const unsigned char *in, size_t in_len,
const unsigned char *ad, size_t ad_len)
{
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
unsigned char mac[POLY1305_TAG_LEN];
unsigned char poly1305_key[32];
unsigned char subkey[32];
poly1305_state poly1305;
size_t plaintext_len;
if (in_len < c20_ctx->tag_len) {
EVPerror(EVP_R_BAD_DECRYPT);
return 0;
}
if (nonce_len != ctx->aead->nonce_len) {
EVPerror(EVP_R_IV_TOO_LARGE);
return 0;
}
plaintext_len = in_len - c20_ctx->tag_len;
if (max_out_len < plaintext_len) {
EVPerror(EVP_R_BUFFER_TOO_SMALL);
return 0;
}
CRYPTO_hchacha_20(subkey, c20_ctx->key, nonce);
memset(poly1305_key, 0, sizeof(poly1305_key));
CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
subkey, nonce + 16, 0);
CRYPTO_poly1305_init(&poly1305, poly1305_key);
poly1305_update_with_pad16(&poly1305, ad, ad_len);
poly1305_update_with_pad16(&poly1305, in, plaintext_len);
poly1305_update_with_length(&poly1305, NULL, ad_len);
poly1305_update_with_length(&poly1305, NULL, plaintext_len);
CRYPTO_poly1305_finish(&poly1305, mac);
if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
EVPerror(EVP_R_BAD_DECRYPT);
return 0;
}
CRYPTO_chacha_20(out, in, plaintext_len, subkey, nonce + 16, 1);
*out_len = plaintext_len;
return 1;
}
/* RFC 8439 */
static const EVP_AEAD aead_chacha20_poly1305 = {
.key_len = 32,
.nonce_len = CHACHA20_NONCE_LEN,
.overhead = POLY1305_TAG_LEN,
.max_tag_len = POLY1305_TAG_LEN,
.init = aead_chacha20_poly1305_init,
.cleanup = aead_chacha20_poly1305_cleanup,
.seal = aead_chacha20_poly1305_seal,
.open = aead_chacha20_poly1305_open,
};
const EVP_AEAD *
EVP_aead_chacha20_poly1305()
{
return &aead_chacha20_poly1305;
}
static const EVP_AEAD aead_xchacha20_poly1305 = {
.key_len = 32,
.nonce_len = XCHACHA20_NONCE_LEN,
.overhead = POLY1305_TAG_LEN,
.max_tag_len = POLY1305_TAG_LEN,
.init = aead_chacha20_poly1305_init,
.cleanup = aead_chacha20_poly1305_cleanup,
.seal = aead_xchacha20_poly1305_seal,
.open = aead_xchacha20_poly1305_open,
};
const EVP_AEAD *
EVP_aead_xchacha20_poly1305()
{
return &aead_xchacha20_poly1305;
}
struct chacha20_poly1305_ctx {
ChaCha_ctx chacha;
poly1305_state poly1305;
unsigned char key[32];
unsigned char nonce[CHACHA20_NONCE_LEN];
size_t nonce_len;
unsigned char tag[POLY1305_TAG_LEN];
size_t tag_len;
size_t ad_len;
size_t in_len;
int in_ad;
int started;
};
static int
chacha20_poly1305_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int encrypt)
{
struct chacha20_poly1305_ctx *cpx = ctx->cipher_data;
uint8_t *data;
CBB cbb;
int ret = 0;
memset(&cbb, 0, sizeof(cbb));
if (key == NULL && iv == NULL)
goto done;
cpx->started = 0;
if (key != NULL)
memcpy(cpx->key, key, sizeof(cpx->key));
if (iv != NULL) {
/*
* Left zero pad if configured nonce length is less than ChaCha
* nonce length.
*/
if (!CBB_init_fixed(&cbb, cpx->nonce, sizeof(cpx->nonce)))
goto err;
if (!CBB_add_space(&cbb, &data, sizeof(cpx->nonce) - cpx->nonce_len))
goto err;
if (!CBB_add_bytes(&cbb, iv, cpx->nonce_len))
goto err;
if (!CBB_finish(&cbb, NULL, NULL))
goto err;
}
done:
ret = 1;
err:
CBB_cleanup(&cbb);
return ret;
}
static int
chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t len)
{
struct chacha20_poly1305_ctx *cpx = ctx->cipher_data;
/*
* Since we're making AEAD work within the constraints of EVP_CIPHER...
* If in is non-NULL then this is an update, while if in is NULL then
* this is a final. If in is non-NULL but out is NULL, then the input
* being provided is associated data. Plus we have to handle encryption
* (sealing) and decryption (opening) in the same function.
*/
if (!cpx->started) {
unsigned char poly1305_key[32];
const unsigned char *iv;
uint64_t ctr;
ctr = (uint64_t)((uint32_t)(cpx->nonce[0]) |
(uint32_t)(cpx->nonce[1]) << 8 |
(uint32_t)(cpx->nonce[2]) << 16 |
(uint32_t)(cpx->nonce[3]) << 24) << 32;
iv = cpx->nonce + CHACHA20_CONSTANT_LEN;
ChaCha_set_key(&cpx->chacha, cpx->key, 8 * sizeof(cpx->key));
ChaCha_set_iv(&cpx->chacha, iv, NULL);
/* See chacha.c for details re handling of counter. */
cpx->chacha.input[12] = (uint32_t)ctr;
cpx->chacha.input[13] = (uint32_t)(ctr >> 32);
memset(poly1305_key, 0, sizeof(poly1305_key));
ChaCha(&cpx->chacha, poly1305_key, poly1305_key,
sizeof(poly1305_key));
CRYPTO_poly1305_init(&cpx->poly1305, poly1305_key);
/* Mark remaining key block as used. */
cpx->chacha.unused = 0;
cpx->ad_len = 0;
cpx->in_len = 0;
cpx->in_ad = 0;
cpx->started = 1;
}
if (len > SIZE_MAX - cpx->in_len) {
EVPerror(EVP_R_TOO_LARGE);
return 0;
}
/* Disallow authenticated data after plaintext/ciphertext. */
if (cpx->in_len > 0 && in != NULL && out == NULL)
return -1;
if (cpx->in_ad && (in == NULL || out != NULL)) {
poly1305_pad16(&cpx->poly1305, cpx->ad_len);
cpx->in_ad = 0;
}
/* Update with AD or plaintext/ciphertext. */
if (in != NULL) {
if (out == NULL) {
cpx->ad_len += len;
cpx->in_ad = 1;
} else {
ChaCha(&cpx->chacha, out, in, len);
cpx->in_len += len;
}
if (ctx->encrypt && out != NULL)
CRYPTO_poly1305_update(&cpx->poly1305, out, len);
else
CRYPTO_poly1305_update(&cpx->poly1305, in, len);
return len;
}
/* Final. */
poly1305_pad16(&cpx->poly1305, cpx->in_len);
poly1305_update_with_length(&cpx->poly1305, NULL, cpx->ad_len);
poly1305_update_with_length(&cpx->poly1305, NULL, cpx->in_len);
if (ctx->encrypt) {
CRYPTO_poly1305_finish(&cpx->poly1305, cpx->tag);
cpx->tag_len = sizeof(cpx->tag);
} else {
unsigned char tag[POLY1305_TAG_LEN];
/* Ensure that a tag has been provided. */
if (cpx->tag_len <= 0)
return -1;
CRYPTO_poly1305_finish(&cpx->poly1305, tag);
if (timingsafe_memcmp(tag, cpx->tag, cpx->tag_len) != 0)
return -1;
}
cpx->started = 0;
return len;
}
static int
chacha20_poly1305_cleanup(EVP_CIPHER_CTX *ctx)
{
struct chacha20_poly1305_ctx *cpx = ctx->cipher_data;
explicit_bzero(cpx, sizeof(*cpx));
return 1;
}
static int
chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
{
struct chacha20_poly1305_ctx *cpx = ctx->cipher_data;
switch (type) {
case EVP_CTRL_INIT:
memset(cpx, 0, sizeof(*cpx));
cpx->nonce_len = sizeof(cpx->nonce);
return 1;
case EVP_CTRL_AEAD_GET_IVLEN:
if (cpx->nonce_len > INT_MAX)
return 0;
*(int *)ptr = (int)cpx->nonce_len;
return 1;
case EVP_CTRL_AEAD_SET_IVLEN:
if (arg <= 0 || arg > sizeof(cpx->nonce))
return 0;
cpx->nonce_len = arg;
return 1;
case EVP_CTRL_AEAD_SET_TAG:
if (ctx->encrypt)
return 0;
if (arg <= 0 || arg > sizeof(cpx->tag))
return 0;
if (ptr != NULL) {
memcpy(cpx->tag, ptr, arg);
cpx->tag_len = arg;
}
return 1;
case EVP_CTRL_AEAD_GET_TAG:
if (!ctx->encrypt)
return 0;
if (arg <= 0 || arg > cpx->tag_len)
return 0;
memcpy(ptr, cpx->tag, arg);
return 1;
case EVP_CTRL_AEAD_SET_IV_FIXED:
if (arg != sizeof(cpx->nonce))
return 0;
memcpy(cpx->nonce, ptr, arg);
return 1;
}
return 0;
}
static const EVP_CIPHER cipher_chacha20_poly1305 = {
.nid = NID_chacha20_poly1305,
.block_size = 1,
.key_len = 32,
.iv_len = 12,
.flags = EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_IV_LENGTH |
EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_CUSTOM_CIPHER |
EVP_CIPH_FLAG_DEFAULT_ASN1,
.init = chacha20_poly1305_init,
.do_cipher = chacha20_poly1305_cipher,
.cleanup = chacha20_poly1305_cleanup,
.ctx_size = sizeof(struct chacha20_poly1305_ctx),
.ctrl = chacha20_poly1305_ctrl,
};
const EVP_CIPHER *
EVP_chacha20_poly1305(void)
{
return &cipher_chacha20_poly1305;
}
#endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */

355
crypto/evp/e_des.c Normal file
View File

@@ -0,0 +1,355 @@
/* $OpenBSD: e_des.c,v 1.22 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <limits.h>
#include <stdio.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_DES
#include <openssl/evp.h>
#include <openssl/des.h>
#include <openssl/objects.h>
#include "evp_local.h"
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;
DES_set_key_unchecked(deskey, ctx->cipher_data);
return 1;
}
static int
des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
{
switch (type) {
case EVP_CTRL_RAND_KEY:
if (DES_random_key((DES_cblock *)ptr) == 0)
return 0;
return 1;
default:
return -1;
}
}
static int
des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
size_t i, bl;
bl = ctx->cipher->block_size;
if (inl < bl)
return 1;
inl -= bl;
for (i = 0; i <= inl; i += bl)
DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i),
ctx->cipher_data, ctx->encrypt);
return 1;
}
static int
des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
DES_ofb64_encrypt(in, out, (long)chunk, ctx->cipher_data,
(DES_cblock *)ctx->iv, &ctx->num);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data,
(DES_cblock *)ctx->iv, &ctx->num);
return 1;
}
static int
des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
DES_ncbc_encrypt(in, out, (long)chunk, ctx->cipher_data,
(DES_cblock *)ctx->iv, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data,
(DES_cblock *)ctx->iv, ctx->encrypt);
return 1;
}
static int
des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
DES_cfb64_encrypt(in, out, (long)chunk, ctx->cipher_data,
(DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data,
(DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
return 1;
}
/* Although we have a CFB-r implementation for DES, it doesn't pack the right
way, so wrap it here */
static int
des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
unsigned char c[1], d[1];
size_t chunk = LONG_MAX / 8;
size_t n;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
for (n = 0; n < chunk*8; ++n) {
c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
DES_cfb_encrypt(c, d, 1, 1, ctx->cipher_data,
(DES_cblock *)ctx->iv, ctx->encrypt);
out[n / 8] = (out[n / 8] &
~(0x80 >> (unsigned int)(n % 8))) |
((d[0] & 0x80) >> (unsigned int)(n % 8));
}
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static int
des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
DES_cfb_encrypt(in, out, 8, (long)chunk,
ctx->cipher_data, (DES_cblock *)ctx->iv, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
DES_cfb_encrypt(in, out, 8, (long)inl, ctx->cipher_data,
(DES_cblock *)ctx->iv, ctx->encrypt);
return 1;
}
static const EVP_CIPHER des_cbc = {
.nid = NID_des_cbc,
.block_size = 8,
.key_len = 8,
.iv_len = 8,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CBC_MODE,
.init = des_init_key,
.do_cipher = des_cbc_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_key_schedule),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_cbc(void)
{
return &des_cbc;
}
static const EVP_CIPHER des_cfb64 = {
.nid = NID_des_cfb64,
.block_size = 1,
.key_len = 8,
.iv_len = 8,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE,
.init = des_init_key,
.do_cipher = des_cfb64_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_key_schedule),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_cfb64(void)
{
return &des_cfb64;
}
static const EVP_CIPHER des_ofb = {
.nid = NID_des_ofb64,
.block_size = 1,
.key_len = 8,
.iv_len = 8,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_OFB_MODE,
.init = des_init_key,
.do_cipher = des_ofb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_key_schedule),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_ofb(void)
{
return &des_ofb;
}
static const EVP_CIPHER des_ecb = {
.nid = NID_des_ecb,
.block_size = 8,
.key_len = 8,
.iv_len = 0,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_ECB_MODE,
.init = des_init_key,
.do_cipher = des_ecb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_key_schedule),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_ecb(void)
{
return &des_ecb;
}
static const EVP_CIPHER des_cfb1 = {
.nid = NID_des_cfb1,
.block_size = 1,
.key_len = 8,
.iv_len = 8,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE,
.init = des_init_key,
.do_cipher = des_cfb1_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_key_schedule),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_cfb1(void)
{
return &des_cfb1;
}
static const EVP_CIPHER des_cfb8 = {
.nid = NID_des_cfb8,
.block_size = 1,
.key_len = 8,
.iv_len = 8,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE,
.init = des_init_key,
.do_cipher = des_cfb8_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_key_schedule),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_cfb8(void)
{
return &des_cfb8;
}
#endif

495
crypto/evp/e_des3.c Normal file
View File

@@ -0,0 +1,495 @@
/* $OpenBSD: e_des3.c,v 1.28 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_DES
#include <openssl/des.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include "evp_local.h"
typedef struct {
DES_key_schedule ks1;/* key schedule */
DES_key_schedule ks2;/* key schedule (for ede) */
DES_key_schedule ks3;/* key schedule (for ede3) */
} DES_EDE_KEY;
#define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data)
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_set_key_unchecked(&deskey[0], &data(ctx)->ks1);
DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2);
memcpy(&data(ctx)->ks3, &data(ctx)->ks1,
sizeof(data(ctx)->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_set_key_unchecked(&deskey[0], &data(ctx)->ks1);
DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2);
DES_set_key_unchecked(&deskey[2], &data(ctx)->ks3);
return 1;
}
static int
des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
{
DES_cblock *deskey = ptr;
switch (type) {
case EVP_CTRL_RAND_KEY:
if (DES_random_key(deskey) == 0)
return 0;
if (c->key_len >= 16 && DES_random_key(deskey + 1) == 0)
return 0;
if (c->key_len >= 24 && DES_random_key(deskey + 2) == 0)
return 0;
return 1;
default:
return -1;
}
}
static int
des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
size_t i, bl;
bl = ctx->cipher->block_size;
if (inl < bl)
return 1;
inl -= bl;
for (i = 0; i <= inl; i += bl)
DES_ecb3_encrypt((const_DES_cblock *)(in + i), (DES_cblock *)(out + i),
&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, ctx->encrypt);
return 1;
}
static int
des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
DES_ede3_ofb64_encrypt(in, out, (long)chunk,
&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
(DES_cblock *)ctx->iv, &ctx->num);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
DES_ede3_ofb64_encrypt(in, out, (long)inl,
&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
(DES_cblock *)ctx->iv, &ctx->num);
return 1;
}
static int
des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
DES_ede3_cbc_encrypt(in, out, (long)chunk,
&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
(DES_cblock *)ctx->iv, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
DES_ede3_cbc_encrypt(in, out, (long)inl,
&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
(DES_cblock *)ctx->iv, ctx->encrypt);
return 1;
}
static int
des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
DES_ede3_cfb64_encrypt(in, out, (long)chunk,
&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
(DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
DES_ede3_cfb64_encrypt(in, out, (long)inl,
&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
(DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
return 1;
}
/* Although we have a CFB-r implementation for 3-DES, it doesn't pack the right
way, so wrap it here */
static int
des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
unsigned char c[1], d[1];
size_t n;
if (!(ctx->flags & 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 *)ctx->iv, ctx->encrypt);
out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
((d[0] & 0x80) >> (unsigned int)(n % 8));
}
return 1;
}
static int
des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
DES_ede3_cfb_encrypt(in, out, 8, (long)chunk,
&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
(DES_cblock *)ctx->iv, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
DES_ede3_cfb_encrypt(in, out, 8, (long)inl,
&data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
(DES_cblock *)ctx->iv, ctx->encrypt);
return 1;
}
static const EVP_CIPHER des_ede_cbc = {
.nid = NID_des_ede_cbc,
.block_size = 8,
.key_len = 16,
.iv_len = 8,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CBC_MODE,
.init = des_ede_init_key,
.do_cipher = des_ede_cbc_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_EDE_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des3_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_ede_cbc(void)
{
return &des_ede_cbc;
}
static const EVP_CIPHER des_ede_cfb64 = {
.nid = NID_des_ede_cfb64,
.block_size = 1,
.key_len = 16,
.iv_len = 8,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE,
.init = des_ede_init_key,
.do_cipher = des_ede_cfb64_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_EDE_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des3_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_ede_cfb64(void)
{
return &des_ede_cfb64;
}
static const EVP_CIPHER des_ede_ofb = {
.nid = NID_des_ede_ofb64,
.block_size = 1,
.key_len = 16,
.iv_len = 8,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_OFB_MODE,
.init = des_ede_init_key,
.do_cipher = des_ede_ofb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_EDE_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des3_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_ede_ofb(void)
{
return &des_ede_ofb;
}
static const EVP_CIPHER des_ede_ecb = {
.nid = NID_des_ede_ecb,
.block_size = 8,
.key_len = 16,
.iv_len = 0,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_ECB_MODE,
.init = des_ede_init_key,
.do_cipher = des_ede_ecb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_EDE_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des3_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_ede_ecb(void)
{
return &des_ede_ecb;
}
#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
static const EVP_CIPHER des_ede3_cbc = {
.nid = NID_des_ede3_cbc,
.block_size = 8,
.key_len = 24,
.iv_len = 8,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CBC_MODE,
.init = des_ede3_init_key,
.do_cipher = des_ede3_cbc_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_EDE_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des3_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_ede3_cbc(void)
{
return &des_ede3_cbc;
}
static const EVP_CIPHER des_ede3_cfb64 = {
.nid = NID_des_ede3_cfb64,
.block_size = 1,
.key_len = 24,
.iv_len = 8,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE,
.init = des_ede3_init_key,
.do_cipher = des_ede3_cfb64_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_EDE_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des3_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_ede3_cfb64(void)
{
return &des_ede3_cfb64;
}
static const EVP_CIPHER des_ede3_ofb = {
.nid = NID_des_ede3_ofb64,
.block_size = 1,
.key_len = 24,
.iv_len = 8,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_OFB_MODE,
.init = des_ede3_init_key,
.do_cipher = des_ede3_ofb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_EDE_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des3_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_ede3_ofb(void)
{
return &des_ede3_ofb;
}
static const EVP_CIPHER des_ede3_ecb = {
.nid = NID_des_ede3_ecb,
.block_size = 8,
.key_len = 24,
.iv_len = 0,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_ECB_MODE,
.init = des_ede3_init_key,
.do_cipher = des_ede3_ecb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_EDE_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des3_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_ede3_ecb(void)
{
return &des_ede3_ecb;
}
static const EVP_CIPHER des_ede3_cfb1 = {
.nid = NID_des_ede3_cfb1,
.block_size = 1,
.key_len = 24,
.iv_len = 8,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE,
.init = des_ede3_init_key,
.do_cipher = des_ede3_cfb1_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_EDE_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des3_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_ede3_cfb1(void)
{
return &des_ede3_cfb1;
}
static const EVP_CIPHER des_ede3_cfb8 = {
.nid = NID_des_ede3_cfb8,
.block_size = 1,
.key_len = 24,
.iv_len = 8,
.flags = EVP_CIPH_RAND_KEY | EVP_CIPH_CFB_MODE,
.init = des_ede3_init_key,
.do_cipher = des_ede3_cfb8_cipher,
.cleanup = NULL,
.ctx_size = sizeof(DES_EDE_KEY),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = des3_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_des_ede3_cfb8(void)
{
return &des_ede3_cfb8;
}
const EVP_CIPHER *
EVP_des_ede(void)
{
return &des_ede_ecb;
}
const EVP_CIPHER *
EVP_des_ede3(void)
{
return &des_ede3_ecb;
}
#endif

315
crypto/evp/e_gost2814789.c Normal file
View File

@@ -0,0 +1,315 @@
/* $OpenBSD: e_gost2814789.c,v 1.13 2023/07/07 19:37:53 beck Exp $ */
/*
* Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
* Copyright (c) 2005-2006 Cryptocom LTD
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
#include <string.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_GOST
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/gost.h>
#include "evp_local.h"
typedef struct {
GOST2814789_KEY ks;
int param_nid;
} EVP_GOST2814789_CTX;
static int
gost2814789_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
EVP_GOST2814789_CTX *c = ctx->cipher_data;
return Gost2814789_set_key(&c->ks, key, ctx->key_len * 8);
}
static int
gost2814789_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
{
EVP_GOST2814789_CTX *c = ctx->cipher_data;
switch (type) {
case EVP_CTRL_PBE_PRF_NID:
if (ptr != NULL) {
*((int *)ptr) = NID_id_HMACGostR3411_94;
return 1;
} else {
return 0;
}
case EVP_CTRL_INIT:
/* Default value to have any s-box set at all */
c->param_nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet;
return Gost2814789_set_sbox(&c->ks, c->param_nid);
case EVP_CTRL_GOST_SET_SBOX:
return Gost2814789_set_sbox(&c->ks, arg);
default:
return -1;
}
}
int
gost2814789_set_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
{
int len = 0;
unsigned char *buf = NULL;
unsigned char *p = NULL;
EVP_GOST2814789_CTX *c = ctx->cipher_data;
ASN1_OCTET_STRING *os = NULL;
GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new();
if (gcp == NULL) {
GOSTerror(ERR_R_MALLOC_FAILURE);
return 0;
}
if (ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len) == 0) {
GOST_CIPHER_PARAMS_free(gcp);
GOSTerror(ERR_R_ASN1_LIB);
return 0;
}
ASN1_OBJECT_free(gcp->enc_param_set);
gcp->enc_param_set = OBJ_nid2obj(c->param_nid);
len = i2d_GOST_CIPHER_PARAMS(gcp, NULL);
p = buf = malloc(len);
if (buf == NULL) {
GOST_CIPHER_PARAMS_free(gcp);
GOSTerror(ERR_R_MALLOC_FAILURE);
return 0;
}
i2d_GOST_CIPHER_PARAMS(gcp, &p);
GOST_CIPHER_PARAMS_free(gcp);
os = ASN1_OCTET_STRING_new();
if (os == NULL) {
free(buf);
GOSTerror(ERR_R_MALLOC_FAILURE);
return 0;
}
if (ASN1_OCTET_STRING_set(os, buf, len) == 0) {
ASN1_OCTET_STRING_free(os);
free(buf);
GOSTerror(ERR_R_ASN1_LIB);
return 0;
}
free(buf);
ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
return 1;
}
int
gost2814789_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
{
int ret = -1;
int len;
GOST_CIPHER_PARAMS *gcp = NULL;
EVP_GOST2814789_CTX *c = ctx->cipher_data;
unsigned char *p;
if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE)
return ret;
p = params->value.sequence->data;
gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
params->value.sequence->length);
len = gcp->iv->length;
if (len != ctx->cipher->iv_len) {
GOST_CIPHER_PARAMS_free(gcp);
GOSTerror(GOST_R_INVALID_IV_LENGTH);
return -1;
}
if (!Gost2814789_set_sbox(&c->ks, OBJ_obj2nid(gcp->enc_param_set))) {
GOST_CIPHER_PARAMS_free(gcp);
return -1;
}
c->param_nid = OBJ_obj2nid(gcp->enc_param_set);
memcpy(ctx->oiv, gcp->iv->data, len);
memcpy(ctx->iv, gcp->iv->data, len);
GOST_CIPHER_PARAMS_free(gcp);
return 1;
}
static int
gost2814789_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t i, bl;
bl = ctx->cipher->block_size;
if (inl < bl)
return 1;
inl -= bl;
for (i = 0; i <= inl; i += bl)
Gost2814789_ecb_encrypt(in + i, out + i, &((EVP_GOST2814789_CTX *)ctx->cipher_data)->ks, ctx->encrypt);
return 1;
}
static int
gost2814789_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = EVP_MAXCHUNK;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
Gost2814789_cfb64_encrypt(in, out, chunk, &((EVP_GOST2814789_CTX *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static int
gost2814789_cnt_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
EVP_GOST2814789_CTX *c = ctx->cipher_data;
while (inl >= EVP_MAXCHUNK) {
Gost2814789_cnt_encrypt(in, out, EVP_MAXCHUNK, &c->ks,
ctx->iv, ctx->buf, &ctx->num);
inl -= EVP_MAXCHUNK;
in += EVP_MAXCHUNK;
out += EVP_MAXCHUNK;
}
if (inl)
Gost2814789_cnt_encrypt(in, out, inl, &c->ks, ctx->iv, ctx->buf,
&ctx->num);
return 1;
}
/* gost89 is CFB-64 */
#define NID_gost89_cfb64 NID_id_Gost28147_89
static const EVP_CIPHER gost2814789_ecb = {
.nid = NID_gost89_ecb,
.block_size = 8,
.key_len = 32,
.iv_len = 0,
.flags = EVP_CIPH_NO_PADDING | EVP_CIPH_CTRL_INIT | EVP_CIPH_ECB_MODE,
.init = gost2814789_init_key,
.do_cipher = gost2814789_ecb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_GOST2814789_CTX),
.set_asn1_parameters = gost2814789_set_asn1_params,
.get_asn1_parameters = gost2814789_get_asn1_params,
.ctrl = gost2814789_ctl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_gost2814789_ecb(void)
{
return &gost2814789_ecb;
}
static const EVP_CIPHER gost2814789_cfb64 = {
.nid = NID_gost89_cfb64,
.block_size = 1,
.key_len = 32,
.iv_len = 8,
.flags = EVP_CIPH_NO_PADDING | EVP_CIPH_CTRL_INIT | EVP_CIPH_CFB_MODE,
.init = gost2814789_init_key,
.do_cipher = gost2814789_cfb64_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_GOST2814789_CTX),
.set_asn1_parameters = gost2814789_set_asn1_params,
.get_asn1_parameters = gost2814789_get_asn1_params,
.ctrl = gost2814789_ctl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_gost2814789_cfb64(void)
{
return &gost2814789_cfb64;
}
static const EVP_CIPHER gost2814789_cnt = {
.nid = NID_gost89_cnt,
.block_size = 1,
.key_len = 32,
.iv_len = 8,
.flags = EVP_CIPH_NO_PADDING | EVP_CIPH_CTRL_INIT | EVP_CIPH_OFB_MODE,
.init = gost2814789_init_key,
.do_cipher = gost2814789_cnt_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_GOST2814789_CTX),
.set_asn1_parameters = gost2814789_set_asn1_params,
.get_asn1_parameters = gost2814789_get_asn1_params,
.ctrl = gost2814789_ctl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_gost2814789_cnt(void)
{
return &gost2814789_cnt;
}
#endif

266
crypto/evp/e_idea.c Normal file
View File

@@ -0,0 +1,266 @@
/* $OpenBSD: e_idea.c,v 1.20 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_IDEA
#include <openssl/evp.h>
#include <openssl/idea.h>
#include <openssl/objects.h>
#include "evp_local.h"
/* NB idea_ecb_encrypt doesn't take an 'encrypt' argument so we treat it as a special
* case
*/
static int
idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
if (!enc) {
if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
enc = 1;
else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE)
enc = 1;
}
if (enc)
idea_set_encrypt_key(key, ctx->cipher_data);
else {
IDEA_KEY_SCHEDULE tmp;
idea_set_encrypt_key(key, &tmp);
idea_set_decrypt_key(&tmp, ctx->cipher_data);
explicit_bzero((unsigned char *)&tmp,
sizeof(IDEA_KEY_SCHEDULE));
}
return 1;
}
static int
idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
size_t i, bl;
bl = ctx->cipher->block_size;
if (inl < bl)
return 1;
inl -= bl;
for (i = 0; i <= inl; i += bl)
idea_ecb_encrypt(in + i, out + i, ctx->cipher_data);
return 1;
}
typedef struct {
IDEA_KEY_SCHEDULE ks;
} EVP_IDEA_KEY;
static int
idea_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
idea_cbc_encrypt(in, out, (long)chunk, &((EVP_IDEA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
idea_cbc_encrypt(in, out, (long)inl, &((EVP_IDEA_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
return 1;
}
static int
idea_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
idea_ofb64_encrypt(in, out, (long)chunk, &((EVP_IDEA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
idea_ofb64_encrypt(in, out, (long)inl, &((EVP_IDEA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
return 1;
}
static int
idea_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
idea_cfb64_encrypt(in, out, (long)chunk, &((EVP_IDEA_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static const EVP_CIPHER idea_cbc = {
.nid = NID_idea_cbc,
.block_size = 8,
.key_len = 16,
.iv_len = 8,
.flags = 0 | EVP_CIPH_CBC_MODE,
.init = idea_init_key,
.do_cipher = idea_cbc_cipher,
.cleanup = NULL,
.ctx_size = sizeof(IDEA_KEY_SCHEDULE),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_idea_cbc(void)
{
return &idea_cbc;
}
static const EVP_CIPHER idea_cfb64 = {
.nid = NID_idea_cfb64,
.block_size = 1,
.key_len = 16,
.iv_len = 8,
.flags = 0 | EVP_CIPH_CFB_MODE,
.init = idea_init_key,
.do_cipher = idea_cfb64_cipher,
.cleanup = NULL,
.ctx_size = sizeof(IDEA_KEY_SCHEDULE),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_idea_cfb64(void)
{
return &idea_cfb64;
}
static const EVP_CIPHER idea_ofb = {
.nid = NID_idea_ofb64,
.block_size = 1,
.key_len = 16,
.iv_len = 8,
.flags = 0 | EVP_CIPH_OFB_MODE,
.init = idea_init_key,
.do_cipher = idea_ofb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(IDEA_KEY_SCHEDULE),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_idea_ofb(void)
{
return &idea_ofb;
}
static const EVP_CIPHER idea_ecb = {
.nid = NID_idea_ecb,
.block_size = 8,
.key_len = 16,
.iv_len = 0,
.flags = 0 | EVP_CIPH_ECB_MODE,
.init = idea_init_key,
.do_cipher = idea_ecb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(IDEA_KEY_SCHEDULE),
.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_idea_ecb(void)
{
return &idea_ecb;
}
#endif

107
crypto/evp/e_null.c Normal file
View File

@@ -0,0 +1,107 @@
/* $OpenBSD: e_null.c,v 1.18 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include "evp_local.h"
static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc);
static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl);
static const EVP_CIPHER n_cipher = {
NID_undef,
1, 0, 0,
0,
null_init_key,
null_cipher,
NULL,
0,
NULL,
NULL,
NULL,
NULL
};
const EVP_CIPHER *
EVP_enc_null(void)
{
return (&n_cipher);
}
static int
null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
/* memset(&(ctx->c),0,sizeof(ctx->c));*/
return 1;
}
static int
null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
if (in != out)
memcpy((char *)out, (const char *)in, inl);
return 1;
}

411
crypto/evp/e_rc2.c Normal file
View File

@@ -0,0 +1,411 @@
/* $OpenBSD: e_rc2.c,v 1.22 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <limits.h>
#include <stdio.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_RC2
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/rc2.h>
#include "evp_local.h"
static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc);
static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx);
static int rc2_magic_to_meth(int i);
static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
typedef struct {
int key_bits; /* effective key bits */
RC2_KEY ks; /* key schedule */
} EVP_RC2_KEY;
#define data(ctx) ((EVP_RC2_KEY *)(ctx)->cipher_data)
static int
rc2_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
RC2_cbc_encrypt(in, out, (long)chunk, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
RC2_cbc_encrypt(in, out, (long)inl, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
return 1;
}
static int
rc2_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
RC2_cfb64_encrypt(in, out, (long)chunk, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static int
rc2_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t i, bl;
bl = ctx->cipher->block_size;
if (inl < bl)
return 1;
inl -= bl;
for (i = 0; i <= inl; i += bl)
RC2_ecb_encrypt(in + i, out + i, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->encrypt);
return 1;
}
static int
rc2_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = LONG_MAX & ~0xff;
while (inl >= chunk) {
RC2_ofb64_encrypt(in, out, (long)chunk, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
inl -= chunk;
in += chunk;
out += chunk;
}
if (inl)
RC2_ofb64_encrypt(in, out, (long)inl, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
return 1;
}
static const EVP_CIPHER rc2_cbc = {
.nid = NID_rc2_cbc,
.block_size = 8,
.key_len = RC2_KEY_LENGTH,
.iv_len = 8,
.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT | EVP_CIPH_CBC_MODE,
.init = rc2_init_key,
.do_cipher = rc2_cbc_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_RC2_KEY),
.set_asn1_parameters = rc2_set_asn1_type_and_iv,
.get_asn1_parameters = rc2_get_asn1_type_and_iv,
.ctrl = rc2_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_rc2_cbc(void)
{
return &rc2_cbc;
}
static const EVP_CIPHER rc2_cfb64 = {
.nid = NID_rc2_cfb64,
.block_size = 1,
.key_len = RC2_KEY_LENGTH,
.iv_len = 8,
.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT | EVP_CIPH_CFB_MODE,
.init = rc2_init_key,
.do_cipher = rc2_cfb64_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_RC2_KEY),
.set_asn1_parameters = rc2_set_asn1_type_and_iv,
.get_asn1_parameters = rc2_get_asn1_type_and_iv,
.ctrl = rc2_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_rc2_cfb64(void)
{
return &rc2_cfb64;
}
static const EVP_CIPHER rc2_ofb = {
.nid = NID_rc2_ofb64,
.block_size = 1,
.key_len = RC2_KEY_LENGTH,
.iv_len = 8,
.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT | EVP_CIPH_OFB_MODE,
.init = rc2_init_key,
.do_cipher = rc2_ofb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_RC2_KEY),
.set_asn1_parameters = rc2_set_asn1_type_and_iv,
.get_asn1_parameters = rc2_get_asn1_type_and_iv,
.ctrl = rc2_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_rc2_ofb(void)
{
return &rc2_ofb;
}
static const EVP_CIPHER rc2_ecb = {
.nid = NID_rc2_ecb,
.block_size = 8,
.key_len = RC2_KEY_LENGTH,
.iv_len = 0,
.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT | EVP_CIPH_ECB_MODE,
.init = rc2_init_key,
.do_cipher = rc2_ecb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_RC2_KEY),
.set_asn1_parameters = rc2_set_asn1_type_and_iv,
.get_asn1_parameters = rc2_get_asn1_type_and_iv,
.ctrl = rc2_ctrl,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_rc2_ecb(void)
{
return &rc2_ecb;
}
#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 {
EVPerror(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);
if (l > sizeof(iv)) {
EVPerror(EVP_R_IV_TOO_LARGE);
return -1;
}
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)
return -1;
if (!EVP_CIPHER_CTX_set_key_length(c, key_bits / 8))
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, c->oiv, j);
}
return (i);
}
static int
rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
{
switch (type) {
case EVP_CTRL_INIT:
data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8;
return 1;
case EVP_CTRL_GET_RC2_KEY_BITS:
*(int *)ptr = data(c)->key_bits;
return 1;
case EVP_CTRL_SET_RC2_KEY_BITS:
if (arg > 0) {
data(c)->key_bits = arg;
return 1;
}
return 0;
#ifdef PBE_PRF_TEST
case EVP_CTRL_PBE_PRF_NID:
*(int *)ptr = NID_hmacWithMD5;
return 1;
#endif
default:
return -1;
}
}
#endif

140
crypto/evp/e_rc4.c Normal file
View File

@@ -0,0 +1,140 @@
/* $OpenBSD: e_rc4.c,v 1.17 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_RC4
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/rc4.h>
#include "evp_local.h"
/* FIXME: surely this is available elsewhere? */
#define EVP_RC4_KEY_SIZE 16
typedef struct {
RC4_KEY ks; /* working key */
} EVP_RC4_KEY;
#define data(ctx) ((EVP_RC4_KEY *)(ctx)->cipher_data)
static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc);
static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl);
static const EVP_CIPHER r4_cipher = {
NID_rc4,
1, EVP_RC4_KEY_SIZE, 0,
EVP_CIPH_VARIABLE_LENGTH,
rc4_init_key,
rc4_cipher,
NULL,
sizeof(EVP_RC4_KEY),
NULL,
NULL,
NULL,
NULL
};
static const EVP_CIPHER r4_40_cipher = {
NID_rc4_40,
1, 5 /* 40 bit */, 0,
EVP_CIPH_VARIABLE_LENGTH,
rc4_init_key,
rc4_cipher,
NULL,
sizeof(EVP_RC4_KEY),
NULL,
NULL,
NULL,
NULL
};
const EVP_CIPHER *
EVP_rc4(void)
{
return (&r4_cipher);
}
const EVP_CIPHER *
EVP_rc4_40(void)
{
return (&r4_40_cipher);
}
static int
rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
RC4_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
return 1;
}
static int
rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
RC4(&data(ctx)->ks, inl, in, out);
return 1;
}
#endif

307
crypto/evp/e_rc4_hmac_md5.c Normal file
View File

@@ -0,0 +1,307 @@
/* $OpenBSD: e_rc4_hmac_md5.c,v 1.12 2023/07/07 19:37:53 beck Exp $ */
/* ====================================================================
* Copyright (c) 2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
#include <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5)
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/rc4.h>
#include <openssl/md5.h>
#include "evp_local.h"
/* FIXME: surely this is available elsewhere? */
#define EVP_RC4_KEY_SIZE 16
typedef struct {
RC4_KEY ks;
MD5_CTX head, tail, md;
size_t payload_length;
} EVP_RC4_HMAC_MD5;
#define NO_PAYLOAD_LENGTH ((size_t)-1)
void rc4_md5_enc (RC4_KEY *key, const void *in0, void *out,
MD5_CTX *ctx, const void *inp, size_t blocks);
#define data(ctx) ((EVP_RC4_HMAC_MD5 *)(ctx)->cipher_data)
static int
rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *inkey,
const unsigned char *iv, int enc)
{
EVP_RC4_HMAC_MD5 *key = data(ctx);
RC4_set_key(&key->ks, EVP_CIPHER_CTX_key_length(ctx), inkey);
MD5_Init(&key->head); /* handy when benchmarking */
key->tail = key->head;
key->md = key->head;
key->payload_length = NO_PAYLOAD_LENGTH;
return 1;
}
#if !defined(OPENSSL_NO_ASM) && defined(RC4_MD5_ASM) && ( \
defined(__x86_64) || defined(__x86_64__) || \
defined(_M_AMD64) || defined(_M_X64) || \
defined(__INTEL__) ) && \
!(defined(__APPLE__) && defined(__MACH__))
#define STITCHED_CALL
#include "x86_arch.h"
#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;
#endif
size_t plen = key->payload_length;
if (plen != NO_PAYLOAD_LENGTH && len != (plen + MD5_DIGEST_LENGTH))
return 0;
if (ctx->encrypt) {
if (plen == NO_PAYLOAD_LENGTH)
plen = len;
#if defined(STITCHED_CALL)
/* cipher has to "fall behind" */
if (rc4_off > md5_off)
md5_off += MD5_CBLOCK;
if (plen > md5_off &&
(blocks = (plen - md5_off) / MD5_CBLOCK) &&
(OPENSSL_cpu_caps() & CPUCAP_MASK_INTELP4) == 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_cpu_caps() & CPUCAP_MASK_INTELP4) == 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 (memcmp(out + plen, mac, MD5_DIGEST_LENGTH))
return 0;
} else {
MD5_Update(&key->md, out + md5_off, len - md5_off);
}
}
key->payload_length = NO_PAYLOAD_LENGTH;
return 1;
}
static int
rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
{
EVP_RC4_HMAC_MD5 *key = data(ctx);
switch (type) {
case EVP_CTRL_AEAD_SET_MAC_KEY:
{
unsigned int i;
unsigned char hmac_key[64];
memset (hmac_key, 0, sizeof(hmac_key));
if (arg > (int)sizeof(hmac_key)) {
MD5_Init(&key->head);
MD5_Update(&key->head, ptr, arg);
MD5_Final(hmac_key, &key->head);
} else {
memcpy(hmac_key, ptr, arg);
}
for (i = 0; i < sizeof(hmac_key); i++)
hmac_key[i] ^= 0x36; /* ipad */
MD5_Init(&key->head);
MD5_Update(&key->head, hmac_key, sizeof(hmac_key));
for (i = 0; i < sizeof(hmac_key); i++)
hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */
MD5_Init(&key->tail);
MD5_Update(&key->tail, hmac_key, sizeof(hmac_key));
return 1;
}
case EVP_CTRL_AEAD_TLS1_AAD:
{
unsigned char *p = ptr;
unsigned int len = p[arg - 2] << 8 | p[arg - 1];
if (!ctx->encrypt) {
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

267
crypto/evp/e_sm4.c Normal file
View File

@@ -0,0 +1,267 @@
/* $OpenBSD: e_sm4.c,v 1.9 2023/07/07 19:37:53 beck Exp $ */
/*
* Copyright (c) 2017, 2019 Ribose Inc
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_SM4
#include <openssl/evp.h>
#include <openssl/modes.h>
#include <openssl/sm4.h>
#include "evp_local.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, ctx->cipher_data);
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);
}
static int
sm4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
while (inl >= EVP_MAXCHUNK) {
sm4_cbc_encrypt(in, out, EVP_MAXCHUNK, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
inl -= EVP_MAXCHUNK;
in += EVP_MAXCHUNK;
out += EVP_MAXCHUNK;
}
if (inl)
sm4_cbc_encrypt(in, out, inl, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
return 1;
}
static int
sm4_cfb128_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t chunk = EVP_MAXCHUNK;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
sm4_cfb128_encrypt(in, out, chunk, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
}
return 1;
}
static int
sm4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
size_t i, bl;
bl = ctx->cipher->block_size;
if (inl < bl)
return 1;
inl -= bl;
for (i = 0; i <= inl; i += bl)
sm4_ecb_encrypt(in + i, out + i, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->encrypt);
return 1;
}
static int
sm4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
while (inl >= EVP_MAXCHUNK) {
sm4_ofb128_encrypt(in, out, EVP_MAXCHUNK, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
inl -= EVP_MAXCHUNK;
in += EVP_MAXCHUNK;
out += EVP_MAXCHUNK;
}
if (inl)
sm4_ofb128_encrypt(in, out, inl, &((EVP_SM4_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
return 1;
}
static const EVP_CIPHER sm4_cbc = {
.nid = NID_sm4_cbc,
.block_size = 16,
.key_len = 16,
.iv_len = 16,
.flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CBC_MODE,
.init = sm4_init_key,
.do_cipher = sm4_cbc_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_SM4_KEY),
.set_asn1_parameters = 0,
.get_asn1_parameters = 0,
.ctrl = 0,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_sm4_cbc(void)
{
return &sm4_cbc;
}
static const EVP_CIPHER sm4_cfb128 = {
.nid = NID_sm4_cfb128,
.block_size = 1,
.key_len = 16,
.iv_len = 16,
.flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CFB_MODE,
.init = sm4_init_key,
.do_cipher = sm4_cfb128_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_SM4_KEY),
.set_asn1_parameters = 0,
.get_asn1_parameters = 0,
.ctrl = 0,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_sm4_cfb128(void)
{
return &sm4_cfb128;
}
static const EVP_CIPHER sm4_ofb = {
.nid = NID_sm4_ofb128,
.block_size = 1,
.key_len = 16,
.iv_len = 16,
.flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_OFB_MODE,
.init = sm4_init_key,
.do_cipher = sm4_ofb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_SM4_KEY),
.set_asn1_parameters = 0,
.get_asn1_parameters = 0,
.ctrl = 0,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_sm4_ofb(void)
{
return &sm4_ofb;
}
static const EVP_CIPHER sm4_ecb = {
.nid = NID_sm4_ecb,
.block_size = 16,
.key_len = 16,
.iv_len = 0,
.flags = EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_ECB_MODE,
.init = sm4_init_key,
.do_cipher = sm4_ecb_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_SM4_KEY),
.set_asn1_parameters = 0,
.get_asn1_parameters = 0,
.ctrl = 0,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_sm4_ecb(void)
{
return &sm4_ecb;
}
static int
sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
size_t len)
{
EVP_SM4_KEY *key = ((EVP_SM4_KEY *)(ctx)->cipher_data);
CRYPTO_ctr128_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf,
&ctx->num, (block128_f)SM4_encrypt);
return 1;
}
static const EVP_CIPHER sm4_ctr_mode = {
.nid = NID_sm4_ctr,
.block_size = 1,
.key_len = 16,
.iv_len = 16,
.flags = EVP_CIPH_CTR_MODE,
.init = sm4_init_key,
.do_cipher = sm4_ctr_cipher,
.cleanup = NULL,
.ctx_size = sizeof(EVP_SM4_KEY),
.set_asn1_parameters = NULL,
.get_asn1_parameters = NULL,
.ctrl = NULL,
.app_data = NULL,
};
const EVP_CIPHER *
EVP_sm4_ctr(void)
{
return &sm4_ctr_mode;
}
#endif

137
crypto/evp/e_xcbc_d.c Normal file
View File

@@ -0,0 +1,137 @@
/* $OpenBSD: e_xcbc_d.c,v 1.15 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_DES
#include <openssl/des.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include "evp_local.h"
static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc);
static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl);
typedef struct {
DES_key_schedule ks;/* key schedule */
DES_cblock inw;
DES_cblock outw;
} DESX_CBC_KEY;
#define data(ctx) ((DESX_CBC_KEY *)(ctx)->cipher_data)
static const EVP_CIPHER d_xcbc_cipher = {
NID_desx_cbc,
8, 24, 8,
EVP_CIPH_CBC_MODE,
desx_cbc_init_key,
desx_cbc_cipher,
NULL,
sizeof(DESX_CBC_KEY),
EVP_CIPHER_set_asn1_iv,
EVP_CIPHER_get_asn1_iv,
NULL,
NULL
};
const EVP_CIPHER *
EVP_desx_cbc(void)
{
return (&d_xcbc_cipher);
}
static int
desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
DES_cblock *deskey = (DES_cblock *)key;
DES_set_key_unchecked(deskey, &data(ctx)->ks);
memcpy(&data(ctx)->inw[0], &key[8], 8);
memcpy(&data(ctx)->outw[0], &key[16], 8);
return 1;
}
static int
desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
while (inl >= EVP_MAXCHUNK) {
DES_xcbc_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks,
(DES_cblock *)&(ctx->iv[0]), &data(ctx)->inw,
&data(ctx)->outw, ctx->encrypt);
inl -= EVP_MAXCHUNK;
in += EVP_MAXCHUNK;
out += EVP_MAXCHUNK;
}
if (inl)
DES_xcbc_encrypt(in, out, (long)inl, &data(ctx)->ks,
(DES_cblock *)&(ctx->iv[0]), &data(ctx)->inw,
&data(ctx)->outw, ctx->encrypt);
return 1;
}
#endif

414
crypto/evp/encode.c Normal file
View File

@@ -0,0 +1,414 @@
/* $OpenBSD: encode.c,v 1.32 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include "evp_local.h"
static unsigned char conv_ascii2bin(unsigned char a);
#define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f])
/* 64 char lines
* pad input with 0
* left over chars are set to =
* 1 byte => xx==
* 2 bytes => xxx=
* 3 bytes => xxxx
*/
#define BIN_PER_LINE (64/4*3)
#define CHUNKS_PER_LINE (64/4)
#define CHAR_PER_LINE (64+1)
static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz0123456789+/";
/* 0xF0 is a EOLN
* 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
* 0xF2 is EOF
* 0xE0 is ignore at start of line.
* 0xFF is error
*/
#define B64_EOLN 0xF0
#define B64_CR 0xF1
#define B64_EOF 0xF2
#define B64_WS 0xE0
#define B64_ERROR 0xFF
#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3)
#define B64_BASE64(a) !B64_NOT_BASE64(a)
static const unsigned char data_ascii2bin[128] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static unsigned char
conv_ascii2bin(unsigned char a)
{
if (a & 0x80)
return B64_ERROR;
return data_ascii2bin[a];
}
EVP_ENCODE_CTX *
EVP_ENCODE_CTX_new(void)
{
return calloc(1, sizeof(EVP_ENCODE_CTX));
}
void
EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx)
{
free(ctx);
}
void
EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
{
ctx->length = 48;
ctx->num = 0;
ctx->line_num = 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(out, ctx->enc_data, ctx->length);
ctx->num = 0;
out += j;
*(out++) = '\n';
*out = '\0';
total = j + 1;
}
while (inl >= ctx->length && total <= INT_MAX) {
j = EVP_EncodeBlock(out, in, ctx->length);
in += ctx->length;
inl -= ctx->length;
out += j;
*(out++) = '\n';
*out = '\0';
total += j + 1;
}
if (total > INT_MAX) {
/* Too much output data! */
*outl = 0;
return 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(out, ctx->enc_data, ctx->num);
out[ret++] = '\n';
out[ret] = '\0';
ctx->num = 0;
}
*outl = ret;
}
int
EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
{
int i, ret = 0;
unsigned long l;
for (i = dlen; i > 0; i -= 3) {
if (i >= 3) {
l = (((unsigned long)f[0]) << 16L) |
(((unsigned long)f[1]) << 8L) | f[2];
*(t++) = conv_bin2ascii(l >> 18L);
*(t++) = conv_bin2ascii(l >> 12L);
*(t++) = conv_bin2ascii(l >> 6L);
*(t++) = conv_bin2ascii(l );
} else {
l = ((unsigned long)f[0]) << 16L;
if (i == 2)
l |= ((unsigned long)f[1] << 8L);
*(t++) = conv_bin2ascii(l >> 18L);
*(t++) = conv_bin2ascii(l >> 12L);
*(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L);
*(t++) = '=';
}
ret += 4;
f += 3;
}
*t = '\0';
return (ret);
}
void
EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
{
ctx->num = 0;
ctx->length = 0;
ctx->line_num = 0;
ctx->expect_nl = 0;
}
int
EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
const unsigned char *in, int inl)
{
int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len;
unsigned char *d;
n = ctx->num;
d = ctx->enc_data;
if (n > 0 && d[n - 1] == '=') {
eof++;
if (n > 1 && d[n - 2] == '=')
eof++;
}
/* Legacy behaviour: an empty input chunk signals end of input. */
if (inl == 0) {
rv = 0;
goto end;
}
for (i = 0; i < inl; i++) {
tmp = *(in++);
v = conv_ascii2bin(tmp);
if (v == B64_ERROR) {
rv = -1;
goto end;
}
if (tmp == '=') {
eof++;
} else if (eof > 0 && B64_BASE64(v)) {
/* More data after padding. */
rv = -1;
goto end;
}
if (eof > 2) {
rv = -1;
goto end;
}
if (v == B64_EOF) {
seof = 1;
goto tail;
}
/* Only save valid base64 characters. */
if (B64_BASE64(v)) {
if (n >= 64) {
/*
* We increment n once per loop, and empty the
* buffer as soon as we reach 64 characters, so
* this can only happen if someone's manually
* messed with the ctx. Refuse to write any
* more data.
*/
rv = -1;
goto end;
}
OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
d[n++] = tmp;
}
if (n == 64) {
decoded_len = EVP_DecodeBlock(out, d, n);
n = 0;
if (decoded_len < 0 || eof > decoded_len) {
rv = -1;
goto end;
}
ret += decoded_len - eof;
out += decoded_len - eof;
}
}
/*
* Legacy behaviour: if the current line is a full base64-block (i.e.,
* has 0 mod 4 base64 characters), it is processed immediately. We keep
* this behaviour as applications may not be calling EVP_DecodeFinal
* properly.
*/
tail:
if (n > 0) {
if ((n & 3) == 0) {
decoded_len = EVP_DecodeBlock(out, d, n);
n = 0;
if (decoded_len < 0 || eof > decoded_len) {
rv = -1;
goto end;
}
ret += (decoded_len - eof);
} else if (seof) {
/* EOF in the middle of a base64 block. */
rv = -1;
goto end;
}
}
rv = seof || (n == 0 && eof) ? 0 : 1;
end:
/* Legacy behaviour. This should probably rather be zeroed on error. */
*outl = ret;
ctx->num = n;
return (rv);
}
int
EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
{
int i, ret = 0, a, b, c, d;
unsigned long l;
/* trim white space from the start of the line. */
while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) {
f++;
n--;
}
/* strip off stuff at the end of the line
* ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */
while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1]))))
n--;
if (n % 4 != 0)
return (-1);
for (i = 0; i < n; i += 4) {
a = conv_ascii2bin(*(f++));
b = conv_ascii2bin(*(f++));
c = conv_ascii2bin(*(f++));
d = conv_ascii2bin(*(f++));
if ((a & 0x80) || (b & 0x80) ||
(c & 0x80) || (d & 0x80))
return (-1);
l = ((((unsigned long)a) << 18L) |
(((unsigned long)b) << 12L) |
(((unsigned long)c) << 6L) |
(((unsigned long)d)));
*(t++) = (unsigned char)(l >> 16L) & 0xff;
*(t++) = (unsigned char)(l >> 8L) & 0xff;
*(t++) = (unsigned char)(l) & 0xff;
ret += 3;
}
return (ret);
}
int
EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
{
int i;
*outl = 0;
if (ctx->num != 0) {
i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
if (i < 0)
return (-1);
ctx->num = 0;
*outl = i;
return (1);
} else
return (1);
}

160
crypto/evp/evp_aead.c Normal file
View File

@@ -0,0 +1,160 @@
/* $OpenBSD: evp_aead.c,v 1.10 2023/07/07 19:37:53 beck Exp $ */
/*
* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <limits.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include "evp_local.h"
size_t
EVP_AEAD_key_length(const EVP_AEAD *aead)
{
return aead->key_len;
}
size_t
EVP_AEAD_nonce_length(const EVP_AEAD *aead)
{
return aead->nonce_len;
}
size_t
EVP_AEAD_max_overhead(const EVP_AEAD *aead)
{
return aead->overhead;
}
size_t
EVP_AEAD_max_tag_len(const EVP_AEAD *aead)
{
return aead->max_tag_len;
}
int
EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
const unsigned char *key, size_t key_len, size_t tag_len, ENGINE *impl)
{
ctx->aead = aead;
if (key_len != aead->key_len) {
EVPerror(EVP_R_UNSUPPORTED_KEY_SIZE);
return 0;
}
return aead->init(ctx, key, key_len, tag_len);
}
void
EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx)
{
if (ctx->aead == NULL)
return;
ctx->aead->cleanup(ctx);
ctx->aead = NULL;
}
EVP_AEAD_CTX *
EVP_AEAD_CTX_new(void)
{
return calloc(1, sizeof(EVP_AEAD_CTX));
}
void
EVP_AEAD_CTX_free(EVP_AEAD_CTX *ctx)
{
if (ctx == NULL)
return;
EVP_AEAD_CTX_cleanup(ctx);
free(ctx);
}
/* check_alias returns 0 if out points within the buffer determined by in
* and in_len and 1 otherwise.
*
* When processing, there's only an issue if out points within in[:in_len]
* and isn't equal to in. If that's the case then writing the output will
* stomp input that hasn't been read yet.
*
* This function checks for that case. */
static int
check_alias(const unsigned char *in, size_t in_len, const unsigned char *out)
{
if (out <= in)
return 1;
if (in + in_len <= out)
return 1;
return 0;
}
int
EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
const unsigned char *in, size_t in_len, const unsigned char *ad,
size_t ad_len)
{
size_t possible_out_len = in_len + ctx->aead->overhead;
/* Overflow. */
if (possible_out_len < in_len) {
EVPerror(EVP_R_TOO_LARGE);
goto error;
}
if (!check_alias(in, in_len, out)) {
EVPerror(EVP_R_OUTPUT_ALIASES_INPUT);
goto error;
}
if (ctx->aead->seal(ctx, out, out_len, max_out_len, nonce, nonce_len,
in, in_len, ad, ad_len)) {
return 1;
}
error:
/* In the event of an error, clear the output buffer so that a caller
* that doesn't check the return value doesn't send raw data. */
memset(out, 0, max_out_len);
*out_len = 0;
return 0;
}
int
EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
const unsigned char *in, size_t in_len, const unsigned char *ad,
size_t ad_len)
{
if (!check_alias(in, in_len, out)) {
EVPerror(EVP_R_OUTPUT_ALIASES_INPUT);
goto error;
}
if (ctx->aead->open(ctx, out, out_len, max_out_len, nonce, nonce_len,
in, in_len, ad, ad_len)) {
return 1;
}
error:
/* In the event of an error, clear the output buffer so that a caller
* that doesn't check the return value doesn't try and process bad
* data. */
memset(out, 0, max_out_len);
*out_len = 0;
return 0;
}

725
crypto/evp/evp_enc.c Normal file
View File

@@ -0,0 +1,725 @@
/* $OpenBSD: evp_enc.c,v 1.53 2023/09/10 16:53:56 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <openssl/opensslconf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#include "evp_local.h"
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_cleanup(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 || (cipher && (cipher->nid == ctx->cipher->nid))))
goto skip_to_init;
#endif
if (cipher) {
/* Ensure a context left lying around from last time is cleared
* (the previous check attempted to avoid this if the same
* ENGINE and EVP_CIPHER could be used). */
if (ctx->cipher) {
unsigned long flags = ctx->flags;
EVP_CIPHER_CTX_cleanup(ctx);
/* Restore encrypt and flags */
ctx->encrypt = enc;
ctx->flags = flags;
}
#ifndef OPENSSL_NO_ENGINE
if (impl) {
if (!ENGINE_init(impl)) {
EVPerror(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) {
EVPerror(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 = calloc(1, ctx->cipher->ctx_size);
if (ctx->cipher_data == NULL) {
EVPerror(ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
ctx->cipher_data = NULL;
}
ctx->key_len = cipher->key_len;
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)) {
EVPerror(EVP_R_INITIALIZATION_ERROR);
return 0;
}
}
} else if (!ctx->cipher) {
EVPerror(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 */
if (ctx->cipher->block_size != 1 &&
ctx->cipher->block_size != 8 &&
ctx->cipher->block_size != 16) {
EVPerror(EVP_R_BAD_BLOCK_LENGTH);
return 0;
}
if (!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW) &&
EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_WRAP_MODE) {
EVPerror(EVP_R_WRAP_MODE_NOT_ALLOWED);
return 0;
}
if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
switch (EVP_CIPHER_CTX_mode(ctx)) {
case EVP_CIPH_STREAM_CIPHER:
case EVP_CIPH_ECB_MODE:
break;
case EVP_CIPH_CFB_MODE:
case EVP_CIPH_OFB_MODE:
ctx->num = 0;
/* fall-through */
case EVP_CIPH_CBC_MODE:
if ((size_t)EVP_CIPHER_CTX_iv_length(ctx) >
sizeof(ctx->iv)) {
EVPerror(EVP_R_IV_TOO_LARGE);
return 0;
}
if (iv)
memcpy(ctx->oiv, iv,
EVP_CIPHER_CTX_iv_length(ctx));
memcpy(ctx->iv, ctx->oiv,
EVP_CIPHER_CTX_iv_length(ctx));
break;
case EVP_CIPH_CTR_MODE:
ctx->num = 0;
/* Don't reuse IV for CTR mode */
if (iv)
memcpy(ctx->iv, iv,
EVP_CIPHER_CTX_iv_length(ctx));
break;
default:
return 0;
break;
}
}
if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
if (!ctx->cipher->init(ctx, key, iv, enc))
return 0;
}
ctx->buf_len = 0;
ctx->final_used = 0;
ctx->block_mask = ctx->cipher->block_size - 1;
return 1;
}
int
EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
const unsigned char *in, int inl)
{
if (ctx->encrypt)
return EVP_EncryptUpdate(ctx, out, outl, in, inl);
else
return EVP_DecryptUpdate(ctx, out, outl, in, inl);
}
int
EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
if (ctx->encrypt)
return EVP_EncryptFinal_ex(ctx, out, outl);
else
return EVP_DecryptFinal_ex(ctx, out, outl);
}
__warn_references(EVP_CipherFinal,
"EVP_CipherFinal is often misused, please use EVP_CipherFinal_ex and EVP_CIPHER_CTX_cleanup");
int
EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int ret;
if (ctx->encrypt)
ret = EVP_EncryptFinal_ex(ctx, out, outl);
else
ret = EVP_DecryptFinal_ex(ctx, out, outl);
return ret;
}
int
EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
const unsigned char *key, const unsigned char *iv)
{
return EVP_CipherInit(ctx, cipher, key, iv, 1);
}
int
EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
const unsigned char *key, const unsigned char *iv)
{
return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
}
int
EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
const unsigned char *key, const unsigned char *iv)
{
return EVP_CipherInit(ctx, cipher, key, iv, 0);
}
int
EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
const unsigned char *key, const unsigned char *iv)
{
return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
}
int
EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
const unsigned char *in, int inl)
{
int i, j, bl;
*outl = 0;
if (inl < 0)
return 0;
if (inl == 0 && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE)
return 1;
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
i = ctx->cipher->do_cipher(ctx, out, in, inl);
if (i < 0)
return 0;
else
*outl = i;
return 1;
}
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;
bl = ctx->cipher->block_size;
if ((size_t)bl > sizeof(ctx->buf)) {
EVPerror(EVP_R_BAD_BLOCK_LENGTH);
*outl = 0;
return 0;
}
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;
/*
* Once we've processed the first j bytes from in, the
* amount of data left that is a multiple of the block
* length is (inl - j) & ~(bl - 1). Ensure this plus
* the block processed from ctx-buf doesn't overflow.
*/
if (((inl - j) & ~(bl - 1)) > INT_MAX - bl) {
EVPerror(EVP_R_TOO_LARGE);
return 0;
}
memcpy(&(ctx->buf[i]), in, j);
if (!ctx->cipher->do_cipher(ctx, out, ctx->buf, bl))
return 0;
inl -= j;
in += j;
out += bl;
*outl = bl;
}
} else
*outl = 0;
i = inl&(bl - 1);
inl -= i;
if (inl > 0) {
if (!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;
}
__warn_references(EVP_EncryptFinal,
"EVP_EncryptFinal is often misused, please use EVP_EncryptFinal_ex and EVP_CIPHER_CTX_cleanup");
int
EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int ret;
ret = EVP_EncryptFinal_ex(ctx, out, outl);
return ret;
}
int
EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int n, ret;
unsigned int i, b, bl;
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
ret = ctx->cipher->do_cipher(ctx, out, NULL, 0);
if (ret < 0)
return 0;
else
*outl = ret;
return 1;
}
b = ctx->cipher->block_size;
if (b > sizeof ctx->buf) {
EVPerror(EVP_R_BAD_BLOCK_LENGTH);
return 0;
}
if (b == 1) {
*outl = 0;
return 1;
}
bl = ctx->buf_len;
if (ctx->flags & EVP_CIPH_NO_PADDING) {
if (bl) {
EVPerror(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;
unsigned int b;
*outl = 0;
if (inl < 0)
return 0;
if (inl == 0 && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE)
return 1;
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
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 (ctx->flags & EVP_CIPH_NO_PADDING)
return EVP_EncryptUpdate(ctx, out, outl, in, inl);
b = ctx->cipher->block_size;
if (b > sizeof ctx->final) {
EVPerror(EVP_R_BAD_BLOCK_LENGTH);
return 0;
}
if (ctx->final_used) {
/*
* final_used is only ever set if buf_len is 0. Therefore the
* maximum length output we will ever see from EVP_EncryptUpdate
* is inl & ~(b - 1). Since final_used is set, the final output
* length is (inl & ~(b - 1)) + b. Ensure it doesn't overflow.
*/
if ((inl & ~(b - 1)) > INT_MAX - b) {
EVPerror(EVP_R_TOO_LARGE);
return 0;
}
memcpy(out, ctx->final, b);
out += b;
fix_len = 1;
} else
fix_len = 0;
if (!EVP_EncryptUpdate(ctx, out, outl, in, inl))
return 0;
/* if we have 'decrypted' a multiple of block size, make sure
* we have a copy of this last block */
if (b > 1 && !ctx->buf_len) {
*outl -= b;
ctx->final_used = 1;
memcpy(ctx->final, &out[*outl], b);
} else
ctx->final_used = 0;
if (fix_len)
*outl += b;
return 1;
}
__warn_references(EVP_DecryptFinal,
"EVP_DecryptFinal is often misused, please use EVP_DecryptFinal_ex and EVP_CIPHER_CTX_cleanup");
int
EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int ret;
ret = EVP_DecryptFinal_ex(ctx, out, outl);
return ret;
}
int
EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int i, n;
unsigned int b;
*outl = 0;
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
i = 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) {
EVPerror(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
return 0;
}
*outl = 0;
return 1;
}
if (b > 1) {
if (ctx->buf_len || !ctx->final_used) {
EVPerror(EVP_R_WRONG_FINAL_BLOCK_LENGTH);
return (0);
}
if (b > sizeof ctx->final) {
EVPerror(EVP_R_BAD_BLOCK_LENGTH);
return 0;
}
n = ctx->final[b - 1];
if (n == 0 || n > (int)b) {
EVPerror(EVP_R_BAD_DECRYPT);
return (0);
}
for (i = 0; i < n; i++) {
if (ctx->final[--b] != n) {
EVPerror(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);
}
EVP_CIPHER_CTX *
EVP_CIPHER_CTX_new(void)
{
return calloc(1, sizeof(EVP_CIPHER_CTX));
}
void
EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
{
if (ctx == NULL)
return;
EVP_CIPHER_CTX_cleanup(ctx);
free(ctx);
}
void
EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
{
memset(ctx, 0, sizeof(EVP_CIPHER_CTX));
}
int
EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *a)
{
return EVP_CIPHER_CTX_cleanup(a);
}
int
EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
{
if (c->cipher != NULL) {
/* XXX - Avoid leaks, so ignore return value of cleanup()... */
if (c->cipher->cleanup != NULL)
c->cipher->cleanup(c);
if (c->cipher_data != NULL)
explicit_bzero(c->cipher_data, c->cipher->ctx_size);
}
/* XXX - store size of cipher_data so we can always freezero(). */
free(c->cipher_data);
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(c->engine);
#endif
explicit_bzero(c, sizeof(EVP_CIPHER_CTX));
return 1;
}
int
EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
{
if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH,
keylen, NULL);
if (c->key_len == keylen)
return 1;
if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) {
c->key_len = keylen;
return 1;
}
EVPerror(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) {
EVPerror(EVP_R_NO_CIPHER_SET);
return 0;
}
if (!ctx->cipher->ctrl) {
EVPerror(EVP_R_CTRL_NOT_IMPLEMENTED);
return 0;
}
ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
if (ret == -1) {
EVPerror(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);
arc4random_buf(key, ctx->key_len);
return 1;
}
int
EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
{
if ((in == NULL) || (in->cipher == NULL)) {
EVPerror(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)) {
EVPerror(ERR_R_ENGINE_LIB);
return 0;
}
#endif
EVP_CIPHER_CTX_cleanup(out);
memcpy(out, in, sizeof *out);
if (in->cipher_data && in->cipher->ctx_size) {
out->cipher_data = calloc(1, in->cipher->ctx_size);
if (out->cipher_data == NULL) {
EVPerror(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)) {
/*
* If the custom copy control failed, assume that there
* may still be pointers copied in the cipher_data that
* we do not own. This may result in a leak from a bad
* custom copy control, but that's preferable to a
* double free...
*/
freezero(out->cipher_data, in->cipher->ctx_size);
out->cipher_data = NULL;
return 0;
}
}
return 1;
}

166
crypto/evp/evp_err.c Normal file
View File

@@ -0,0 +1,166 @@
/* $OpenBSD: evp_err.c,v 1.32 2023/07/07 19:37:53 beck Exp $ */
/* ====================================================================
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#ifndef OPENSSL_NO_ERR
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_EVP,func,0)
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_EVP,0,reason)
static ERR_STRING_DATA EVP_str_functs[] = {
{ERR_FUNC(0xfff), "CRYPTO_internal"},
{0, NULL}
};
static ERR_STRING_DATA EVP_str_reasons[] = {
{ERR_REASON(EVP_R_AES_IV_SETUP_FAILED) , "aes iv setup failed"},
{ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED) , "aes key setup failed"},
{ERR_REASON(EVP_R_ASN1_LIB) , "asn1 lib"},
{ERR_REASON(EVP_R_BAD_BLOCK_LENGTH) , "bad block length"},
{ERR_REASON(EVP_R_BAD_DECRYPT) , "bad decrypt"},
{ERR_REASON(EVP_R_BAD_KEY_LENGTH) , "bad key length"},
{ERR_REASON(EVP_R_BN_DECODE_ERROR) , "bn decode error"},
{ERR_REASON(EVP_R_BN_PUBKEY_ERROR) , "bn pubkey error"},
{ERR_REASON(EVP_R_BUFFER_TOO_SMALL) , "buffer too small"},
{ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED), "camellia key setup failed"},
{ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR), "cipher parameter error"},
{ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED) , "command not supported"},
{ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED) , "ctrl not implemented"},
{ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED), "ctrl operation not implemented"},
{ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH), "data not multiple of block length"},
{ERR_REASON(EVP_R_DECODE_ERROR) , "decode error"},
{ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES) , "different key types"},
{ERR_REASON(EVP_R_DIFFERENT_PARAMETERS) , "different parameters"},
{ERR_REASON(EVP_R_DISABLED_FOR_FIPS) , "disabled for fips"},
{ERR_REASON(EVP_R_ENCODE_ERROR) , "encode error"},
{ERR_REASON(EVP_R_ERROR_LOADING_SECTION) , "error loading section"},
{ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE), "error setting fips mode"},
{ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR), "evp pbe cipherinit error"},
{ERR_REASON(EVP_R_EXPECTING_AN_HMAC_KEY), "expecting an hmac key"},
{ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY) , "expecting an rsa key"},
{ERR_REASON(EVP_R_EXPECTING_A_DH_KEY) , "expecting a dh key"},
{ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY) , "expecting a dsa key"},
{ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) , "expecting a ecdsa key"},
{ERR_REASON(EVP_R_EXPECTING_A_EC_KEY) , "expecting a ec key"},
{ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"},
{ERR_REASON(EVP_R_GET_RAW_KEY_FAILED) , "get raw key failed"},
{ERR_REASON(EVP_R_INITIALIZATION_ERROR) , "initialization error"},
{ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) , "input not initialized"},
{ERR_REASON(EVP_R_INVALID_DIGEST) , "invalid digest"},
{ERR_REASON(EVP_R_INVALID_FIPS_MODE) , "invalid fips mode"},
{ERR_REASON(EVP_R_INVALID_IV_LENGTH) , "invalid iv length"},
{ERR_REASON(EVP_R_INVALID_KEY_LENGTH) , "invalid key length"},
{ERR_REASON(EVP_R_INVALID_OPERATION) , "invalid operation"},
{ERR_REASON(EVP_R_IV_TOO_LARGE) , "iv too large"},
{ERR_REASON(EVP_R_KEYGEN_FAILURE) , "keygen failure"},
{ERR_REASON(EVP_R_KEY_SETUP_FAILED) , "key setup failed"},
{ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL), "message digest is null"},
{ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED) , "method not supported"},
{ERR_REASON(EVP_R_MISSING_PARAMETERS) , "missing parameters"},
{ERR_REASON(EVP_R_NO_CIPHER_SET) , "no cipher set"},
{ERR_REASON(EVP_R_NO_DEFAULT_DIGEST) , "no default digest"},
{ERR_REASON(EVP_R_NO_DIGEST_SET) , "no digest set"},
{ERR_REASON(EVP_R_NO_DSA_PARAMETERS) , "no dsa parameters"},
{ERR_REASON(EVP_R_NO_KEY_SET) , "no key set"},
{ERR_REASON(EVP_R_NO_OPERATION_SET) , "no operation set"},
{ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED), "no sign function configured"},
{ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED), "no verify function configured"},
{ERR_REASON(EVP_R_ONLY_ONESHOT_SUPPORTED), "only oneshot supported"},
{ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), "operation not supported for this keytype"},
{ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"},
{ERR_REASON(EVP_R_OUTPUT_ALIASES_INPUT) , "output aliases input"},
{ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE), "pkcs8 unknown broken type"},
{ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"},
{ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR), "private key encode error"},
{ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) , "public key not rsa"},
{ERR_REASON(EVP_R_TAG_TOO_LARGE) , "tag too large"},
{ERR_REASON(EVP_R_TOO_LARGE) , "too large"},
{ERR_REASON(EVP_R_UNKNOWN_CIPHER) , "unknown cipher"},
{ERR_REASON(EVP_R_UNKNOWN_DIGEST) , "unknown digest"},
{ERR_REASON(EVP_R_UNKNOWN_OPTION) , "unknown option"},
{ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) , "unknown pbe algorithm"},
{ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS), "unsuported number of rounds"},
{ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) , "unsupported algorithm"},
{ERR_REASON(EVP_R_UNSUPPORTED_CIPHER) , "unsupported cipher"},
{ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH) , "unsupported keylength"},
{ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION), "unsupported key derivation function"},
{ERR_REASON(EVP_R_UNSUPPORTED_KEY_SIZE) , "unsupported key size"},
{ERR_REASON(EVP_R_UNSUPPORTED_PRF) , "unsupported prf"},
{ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM), "unsupported private key algorithm"},
{ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE) , "unsupported salt type"},
{ERR_REASON(EVP_R_WRAP_MODE_NOT_ALLOWED), "wrap mode not allowed"},
{ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"},
{ERR_REASON(EVP_R_WRONG_PUBLIC_KEY_TYPE) , "wrong public key type"},
{0, NULL}
};
#endif
void
ERR_load_EVP_strings(void)
{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) {
ERR_load_strings(0, EVP_str_functs);
ERR_load_strings(0, EVP_str_reasons);
}
#endif
}

212
crypto/evp/evp_key.c Normal file
View File

@@ -0,0 +1,212 @@
/* $OpenBSD: evp_key.c,v 1.30 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/ui.h>
#include <openssl/x509.h>
#include "evp_local.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 {
strlcpy(prompt_string, prompt, sizeof(prompt_string));
}
}
char *
EVP_get_pw_prompt(void)
{
if (prompt_string[0] == '\0')
return (NULL);
else
return (prompt_string);
}
int
EVP_read_pw_string(char *buf, int len, const char *prompt, int verify)
{
return EVP_read_pw_string_min(buf, 0, len, prompt, verify);
}
int
EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt,
int verify)
{
int ret;
char buff[BUFSIZ];
UI *ui;
if (len > BUFSIZ)
len = BUFSIZ;
/* Ensure that 0 <= min <= len - 1. In particular, 1 <= len. */
if (min < 0 || len - 1 < min)
return -1;
if ((prompt == NULL) && (prompt_string[0] != '\0'))
prompt = prompt_string;
ui = UI_new();
if (ui == NULL)
return -1;
if (UI_add_input_string(ui, prompt, 0, buf, min, len - 1) < 0)
return -1;
if (verify) {
if (UI_add_verify_string(ui, prompt, 0, buff, min, len - 1, buf)
< 0)
return -1;
}
ret = UI_process(ui);
UI_free(ui);
explicit_bzero(buff, BUFSIZ);
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 = type->key_len;
niv = type->iv_len;
if ((size_t)nkey > EVP_MAX_KEY_LENGTH) {
EVPerror(EVP_R_BAD_KEY_LENGTH);
return 0;
}
if ((size_t)niv > EVP_MAX_IV_LENGTH) {
EVPerror(EVP_R_IV_TOO_LARGE);
return 0;
}
if (data == NULL)
return (nkey);
EVP_MD_CTX_init(&c);
for (;;) {
if (!EVP_DigestInit_ex(&c, md, NULL))
goto err;
if (addmd++)
if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds))
goto err;
if (!EVP_DigestUpdate(&c, data, datal))
goto err;
if (salt != NULL)
if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN))
goto err;
if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds))
goto err;
for (i = 1; i < (unsigned int)count; i++) {
if (!EVP_DigestInit_ex(&c, md, NULL))
goto err;
if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds))
goto err;
if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds))
goto err;
}
i = 0;
if (nkey) {
for (;;) {
if (nkey == 0)
break;
if (i == mds)
break;
if (key != NULL)
*(key++) = md_buf[i];
nkey--;
i++;
}
}
if (niv && (i != mds)) {
for (;;) {
if (niv == 0)
break;
if (i == mds)
break;
if (iv != NULL)
*(iv++) = md_buf[i];
niv--;
i++;
}
}
if ((nkey == 0) && (niv == 0))
break;
}
rv = type->key_len;
err:
EVP_MD_CTX_cleanup(&c);
explicit_bzero(md_buf, sizeof md_buf);
return rv;
}

572
crypto/evp/evp_lib.c Normal file
View File

@@ -0,0 +1,572 @@
/* $OpenBSD: evp_lib.c,v 1.28 2023/09/28 11:29:10 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include "asn1_local.h"
#include "evp_local.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)
ret = EVP_CIPHER_set_asn1_iv(c, type);
else
ret = -1;
return (ret);
}
int
EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
{
int ret;
if (c->cipher->get_asn1_parameters != NULL)
ret = c->cipher->get_asn1_parameters(c, type);
else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
ret = EVP_CIPHER_get_asn1_iv(c, type);
else
ret = -1;
return (ret);
}
int
EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
{
int i = 0;
unsigned int l;
if (type != NULL) {
l = EVP_CIPHER_CTX_iv_length(c);
if (l > sizeof(c->iv)) {
EVPerror(EVP_R_IV_TOO_LARGE);
return 0;
}
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);
if (j > sizeof(c->iv)) {
EVPerror(EVP_R_IV_TOO_LARGE);
return 0;
}
i = ASN1_TYPE_set_octetstring(type, c->oiv, j);
}
return (i);
}
/* Convert the various cipher NIDs and dummies to a proper OID NID */
int
EVP_CIPHER_type(const EVP_CIPHER *ctx)
{
int nid;
ASN1_OBJECT *otmp;
nid = EVP_CIPHER_nid(ctx);
switch (nid) {
case NID_rc2_cbc:
case NID_rc2_64_cbc:
case NID_rc2_40_cbc:
return NID_rc2_cbc;
case NID_rc4:
case NID_rc4_40:
return NID_rc4;
case NID_aes_128_cfb128:
case NID_aes_128_cfb8:
case NID_aes_128_cfb1:
return NID_aes_128_cfb128;
case NID_aes_192_cfb128:
case NID_aes_192_cfb8:
case NID_aes_192_cfb1:
return NID_aes_192_cfb128;
case NID_aes_256_cfb128:
case NID_aes_256_cfb8:
case NID_aes_256_cfb1:
return NID_aes_256_cfb128;
case NID_des_cfb64:
case NID_des_cfb8:
case NID_des_cfb1:
return NID_des_cfb64;
case NID_des_ede3_cfb64:
case NID_des_ede3_cfb8:
case NID_des_ede3_cfb1:
return NID_des_cfb64;
default:
/* Check it has an OID and it is valid */
otmp = OBJ_nid2obj(nid);
if (!otmp || !otmp->data)
nid = NID_undef;
ASN1_OBJECT_free(otmp);
return nid;
}
}
int
EVP_CIPHER_block_size(const EVP_CIPHER *e)
{
return e->block_size;
}
int
EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
{
return ctx->cipher->block_size;
}
int
EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
unsigned int inl)
{
return ctx->cipher->do_cipher(ctx, out, in, inl);
}
const EVP_CIPHER *
EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx)
{
return ctx->cipher;
}
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;
}
unsigned long
EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
{
return ctx->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)
{
int iv_length = 0;
if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_IV_LENGTH) == 0)
return ctx->cipher->iv_len;
/*
* XXX - sanity would suggest to pass the size of the pointer along,
* but unfortunately we have to match the other crowd.
*/
if (EVP_CIPHER_CTX_ctrl((EVP_CIPHER_CTX *)ctx, EVP_CTRL_GET_IVLEN, 0,
&iv_length) != 1)
return -1;
return iv_length;
}
unsigned char *
EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx)
{
return ctx->buf;
}
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_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx, unsigned char *iv, size_t len)
{
if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx))
return 0;
if (len > EVP_MAX_IV_LENGTH)
return 0; /* sanity check; shouldn't happen */
/*
* Skip the memcpy entirely when the requested IV length is zero,
* since the iv pointer may be NULL or invalid.
*/
if (len != 0) {
if (iv == NULL)
return 0;
memcpy(iv, ctx->iv, len);
}
return 1;
}
int
EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, const unsigned char *iv, size_t len)
{
if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx))
return 0;
if (len > EVP_MAX_IV_LENGTH)
return 0; /* sanity check; shouldn't happen */
/*
* Skip the memcpy entirely when the requested IV length is zero,
* since the iv pointer may be NULL or invalid.
*/
if (len != 0) {
if (iv == NULL)
return 0;
memcpy(ctx->iv, iv, len);
}
return 1;
}
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) {
EVPerror(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;
if ((md = calloc(1, sizeof(*md))) == NULL)
return 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;
if ((to = EVP_MD_meth_new(md->type, md->pkey_type)) == NULL)
return NULL;
memcpy(to, md, sizeof(*to));
return to;
}
void
EVP_MD_meth_free(EVP_MD *md)
{
freezero(md, sizeof(*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 result_size)
{
md->md_size = result_size;
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;
}
const EVP_MD *
EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
{
if (!ctx)
return NULL;
return ctx->digest;
}
void *
EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx)
{
return ctx->md_data;
}
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)
{
if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) {
EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
} else {
EVP_PKEY_CTX_free(ctx->pctx);
}
ctx->pctx = pctx;
if (pctx != NULL) {
/*
* For unclear reasons it was decided that the caller keeps
* ownership of pctx. So a flag was invented to make sure we
* don't free it in EVP_MD_CTX_cleanup(). We also need to
* unset it in EVP_MD_CTX_copy_ex(). Fortunately, the flag
* isn't public...
*/
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
}
}
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);
}

330
crypto/evp/evp_local.h Normal file
View File

@@ -0,0 +1,330 @@
/* $OpenBSD: evp_local.h,v 1.5 2023/09/28 11:29:10 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#ifndef HEADER_EVP_LOCAL_H
#define HEADER_EVP_LOCAL_H
__BEGIN_HIDDEN_DECLS
/* XXX - move these to evp.h after unlock. */
#define EVP_CTRL_GET_IVLEN 0x25
#define EVP_CIPH_FLAG_CUSTOM_IV_LENGTH 0x400000
#define EVP_CTRL_AEAD_GET_IVLEN EVP_CTRL_GET_IVLEN
/*
* Don't free md_ctx->pctx in EVP_MD_CTX_cleanup(). Needed for ownership
* handling in EVP_MD_CTX_set_pkey_ctx().
*/
#define EVP_MD_CTX_FLAG_KEEP_PKEY_CTX 0x0400
typedef int evp_sign_method(int type, const unsigned char *m,
unsigned int m_length, unsigned char *sigret, unsigned int *siglen,
void *key);
typedef int evp_verify_method(int type, const unsigned char *m,
unsigned int m_length, const unsigned char *sigbuf, unsigned int siglen,
void *key);
struct ecx_key_st {
int nid;
int key_len;
uint8_t *priv_key;
size_t priv_key_len;
uint8_t *pub_key;
size_t pub_key_len;
};
/* Type needs to be a bit field
* Sub-type needs to be for variations on the method, as in, can it do
* arbitrary encryption.... */
struct evp_pkey_st {
int type;
int save_type;
int references;
const EVP_PKEY_ASN1_METHOD *ameth;
ENGINE *engine;
union {
void *ptr;
#ifndef OPENSSL_NO_RSA
struct rsa_st *rsa; /* RSA */
#endif
#ifndef OPENSSL_NO_DSA
struct dsa_st *dsa; /* DSA */
#endif
#ifndef OPENSSL_NO_DH
struct dh_st *dh; /* DH */
#endif
#ifndef OPENSSL_NO_EC
struct ec_key_st *ec; /* ECC */
struct ecx_key_st *ecx; /* ECX */
#endif
#ifndef OPENSSL_NO_GOST
struct gost_key_st *gost; /* GOST */
#endif
} pkey;
int save_parameters;
STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
} /* EVP_PKEY */;
struct evp_md_st {
int type;
int pkey_type;
int md_size;
unsigned long flags;
int (*init)(EVP_MD_CTX *ctx);
int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count);
int (*final)(EVP_MD_CTX *ctx, unsigned char *md);
int (*copy)(EVP_MD_CTX *to, const EVP_MD_CTX *from);
int (*cleanup)(EVP_MD_CTX *ctx);
int block_size;
int ctx_size; /* how big does the ctx->md_data need to be */
/* control function */
int (*md_ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
} /* EVP_MD */;
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_st {
int nid;
int block_size;
int key_len; /* Default value for variable length ciphers */
int iv_len;
unsigned long flags; /* Various flags */
int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc); /* init key */
int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl);/* encrypt/decrypt data */
int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
int ctx_size; /* how big ctx->cipher_data needs to be */
int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */
int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */
void *app_data; /* Application data */
} /* EVP_CIPHER */;
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 */
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 */;
struct evp_Encode_Ctx_st {
int num; /* number saved in a partial encode/decode */
int length; /* 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 */
unsigned char enc_data[80]; /* data to encode */
int line_num; /* number read on current line */
int expect_nl;
} /* EVP_ENCODE_CTX */;
#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2))
struct evp_pkey_ctx_st {
/* Method associated with this operation */
const EVP_PKEY_METHOD *pmeth;
/* Engine that implements this method or NULL if builtin */
ENGINE *engine;
/* Key: may be NULL */
EVP_PKEY *pkey;
/* Peer key for key agreement, may be NULL */
EVP_PKEY *peerkey;
/* Actual operation */
int operation;
/* Algorithm specific data */
void *data;
/* Application specific data */
void *app_data;
/* Keygen callback */
EVP_PKEY_gen_cb *pkey_gencb;
/* implementation specific keygen data */
int *keygen_info;
int keygen_info_count;
} /* EVP_PKEY_CTX */;
#define EVP_PKEY_FLAG_DYNAMIC 1
struct evp_pkey_method_st {
int pkey_id;
int flags;
int (*init)(EVP_PKEY_CTX *ctx);
int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
void (*cleanup)(EVP_PKEY_CTX *ctx);
int (*paramgen_init)(EVP_PKEY_CTX *ctx);
int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
int (*keygen_init)(EVP_PKEY_CTX *ctx);
int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
int (*sign_init)(EVP_PKEY_CTX *ctx);
int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen);
int (*verify_init)(EVP_PKEY_CTX *ctx);
int (*verify)(EVP_PKEY_CTX *ctx,
const unsigned char *sig, size_t siglen,
const unsigned char *tbs, size_t tbslen);
int (*verify_recover_init)(EVP_PKEY_CTX *ctx);
int (*verify_recover)(EVP_PKEY_CTX *ctx,
unsigned char *rout, size_t *routlen,
const unsigned char *sig, size_t siglen);
int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
EVP_MD_CTX *mctx);
int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,
int siglen, EVP_MD_CTX *mctx);
int (*encrypt_init)(EVP_PKEY_CTX *ctx);
int (*encrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen);
int (*decrypt_init)(EVP_PKEY_CTX *ctx);
int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen);
int (*derive_init)(EVP_PKEY_CTX *ctx);
int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value);
int (*digestsign)(EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen);
int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig,
size_t siglen, const unsigned char *tbs, size_t tbslen);
int (*check)(EVP_PKEY *pkey);
int (*public_check)(EVP_PKEY *pkey);
int (*param_check)(EVP_PKEY *pkey);
} /* EVP_PKEY_METHOD */;
void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, int en_de);
/* EVP_AEAD represents a specific AEAD algorithm. */
struct evp_aead_st {
unsigned char key_len;
unsigned char nonce_len;
unsigned char overhead;
unsigned char max_tag_len;
int (*init)(struct evp_aead_ctx_st*, const unsigned char *key,
size_t key_len, size_t tag_len);
void (*cleanup)(struct evp_aead_ctx_st*);
int (*seal)(const struct evp_aead_ctx_st *ctx, unsigned char *out,
size_t *out_len, size_t max_out_len, const unsigned char *nonce,
size_t nonce_len, const unsigned char *in, size_t in_len,
const unsigned char *ad, size_t ad_len);
int (*open)(const struct evp_aead_ctx_st *ctx, unsigned char *out,
size_t *out_len, size_t max_out_len, const unsigned char *nonce,
size_t nonce_len, const unsigned char *in, size_t in_len,
const unsigned char *ad, size_t ad_len);
};
/* An EVP_AEAD_CTX represents an AEAD algorithm configured with a specific key
* and message-independent IV. */
struct evp_aead_ctx_st {
const EVP_AEAD *aead;
/* aead_state is an opaque pointer to the AEAD specific state. */
void *aead_state;
};
int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str);
int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex);
int EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md_name);
__END_HIDDEN_DECLS
#endif /* !HEADER_EVP_LOCAL_H */

312
crypto/evp/evp_pbe.c Normal file
View File

@@ -0,0 +1,312 @@
/* $OpenBSD: evp_pbe.c,v 1.29 2023/07/07 19:37:53 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
#include "evp_local.h"
/* Password based encryption (PBE) functions */
DECLARE_STACK_OF(EVP_PBE_CTL)
static STACK_OF(EVP_PBE_CTL) *pbe_algs;
/* Setup a cipher context from a PBE algorithm */
typedef struct {
int pbe_type;
int pbe_nid;
int cipher_nid;
int md_nid;
EVP_PBE_KEYGEN *keygen;
} EVP_PBE_CTL;
static const EVP_PBE_CTL builtin_pbe[] = {
{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC, NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC, NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC, NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
#ifndef OPENSSL_NO_HMAC
{EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
#endif
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4, NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4, NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC, NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC, NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen},
#ifndef OPENSSL_NO_HMAC
{EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
#endif
{EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC, NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC, NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen},
{EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC, NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen},
{EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0},
{EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0},
{EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0},
{EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0},
{EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0},
{EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0},
{EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0},
{EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_12_256, -1, NID_id_tc26_gost3411_2012_256, 0},
{EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_12_512, -1, NID_id_tc26_gost3411_2012_512, 0},
};
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];
EVPerror(EVP_R_UNKNOWN_PBE_ALGORITHM);
if (!pbe_obj)
strlcpy(obj_tmp, "NULL", sizeof obj_tmp);
else
i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
ERR_asprintf_error_data("TYPE=%s", 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) {
EVPerror(EVP_R_UNKNOWN_CIPHER);
return 0;
}
}
if (md_nid == -1)
md = NULL;
else {
md = EVP_get_digestbynid(md_nid);
if (!md) {
EVPerror(EVP_R_UNKNOWN_DIGEST);
return 0;
}
}
if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) {
EVPerror(EVP_R_KEYGEN_FAILURE);
return 0;
}
return 1;
}
static int pbe2_cmp_BSEARCH_CMP_FN(const void *, const void *);
static int pbe2_cmp(EVP_PBE_CTL const *, EVP_PBE_CTL const *);
static EVP_PBE_CTL *OBJ_bsearch_pbe2(EVP_PBE_CTL *key, EVP_PBE_CTL const *base, int num);
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;
}
static int
pbe2_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)
{
EVP_PBE_CTL const *a = a_;
EVP_PBE_CTL const *b = b_;
return pbe2_cmp(a, b);
}
static EVP_PBE_CTL *
OBJ_bsearch_pbe2(EVP_PBE_CTL *key, EVP_PBE_CTL const *base, int num)
{
return (EVP_PBE_CTL *)OBJ_bsearch_(key, base, num, sizeof(EVP_PBE_CTL),
pbe2_cmp_BSEARCH_CMP_FN);
}
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) {
EVPerror(ERR_R_MALLOC_FAILURE);
return 0;
}
}
pbe_tmp = malloc(sizeof(EVP_PBE_CTL));
if (pbe_tmp == NULL) {
EVPerror(ERR_R_MALLOC_FAILURE);
return 0;
}
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) == 0) {
free(pbe_tmp);
EVPerror(ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
}
int
EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
EVP_PBE_KEYGEN *keygen)
{
int cipher_nid, md_nid;
if (cipher)
cipher_nid = EVP_CIPHER_nid(cipher);
else
cipher_nid = -1;
if (md)
md_nid = EVP_MD_type(md);
else
md_nid = -1;
return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid,
cipher_nid, md_nid, keygen);
}
int
EVP_PBE_find(int type, int pbe_nid,
int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
{
EVP_PBE_CTL *pbetmp = NULL, pbelu;
int i;
if (pbe_nid == NID_undef)
return 0;
pbelu.pbe_type = type;
pbelu.pbe_nid = pbe_nid;
if (pbe_algs) {
i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
if (i != -1)
pbetmp = sk_EVP_PBE_CTL_value (pbe_algs, i);
}
if (pbetmp == NULL) {
pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe,
sizeof(builtin_pbe)/sizeof(EVP_PBE_CTL));
}
if (pbetmp == NULL)
return 0;
if (pcnid)
*pcnid = pbetmp->cipher_nid;
if (pmnid)
*pmnid = pbetmp->md_nid;
if (pkeygen)
*pkeygen = pbetmp->keygen;
return 1;
}
static void
free_evp_pbe_ctl(EVP_PBE_CTL *pbe)
{
free(pbe);
}
void
EVP_PBE_cleanup(void)
{
sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
pbe_algs = NULL;
}

209
crypto/evp/evp_pkey.c Normal file
View File

@@ -0,0 +1,209 @@
/* $OpenBSD: evp_pkey.c,v 1.27 2023/07/07 19:37:53 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include "asn1_local.h"
#include "evp_local.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())) {
EVPerror(ERR_R_MALLOC_FAILURE);
return NULL;
}
if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
EVPerror(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
ERR_asprintf_error_data("TYPE=%s", obj_tmp);
goto error;
}
if (pkey->ameth->priv_decode) {
if (!pkey->ameth->priv_decode(pkey, p8)) {
EVPerror(EVP_R_PRIVATE_KEY_DECODE_ERROR);
goto error;
}
} else {
EVPerror(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;
if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
EVPerror(ERR_R_MALLOC_FAILURE);
return NULL;
}
if (pkey->ameth) {
if (pkey->ameth->priv_encode) {
if (!pkey->ameth->priv_encode(p8, pkey)) {
EVPerror(EVP_R_PRIVATE_KEY_ENCODE_ERROR);
goto error;
}
} else {
EVPerror(EVP_R_METHOD_NOT_SUPPORTED);
goto error;
}
} else {
EVPerror(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;
}

113
crypto/evp/m_gost2814789.c Normal file
View File

@@ -0,0 +1,113 @@
/* $OpenBSD: m_gost2814789.c,v 1.6 2023/07/07 19:37:53 beck Exp $ */
/*
* Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
* Copyright (c) 2005-2006 Cryptocom LTD
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_GOST
#include <openssl/evp.h>
#include <openssl/gost.h>
#include <openssl/objects.h>
#include "evp_local.h"
static int
gost2814789_init(EVP_MD_CTX *ctx)
{
return GOST2814789IMIT_Init(ctx->md_data,
NID_id_Gost28147_89_CryptoPro_A_ParamSet);
}
static int
gost2814789_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return GOST2814789IMIT_Update(ctx->md_data, data, count);
}
static int
gost2814789_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return GOST2814789IMIT_Final(md, ctx->md_data);
}
static int
gost2814789_md_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
{
GOST2814789IMIT_CTX *gctx = ctx->md_data;
switch (cmd) {
case EVP_MD_CTRL_SET_KEY:
return Gost2814789_set_key(&gctx->cipher, p2, p1);
case EVP_MD_CTRL_GOST_SET_SBOX:
return Gost2814789_set_sbox(&gctx->cipher, p1);
}
return -2;
}
static const EVP_MD gost2814789imit_md = {
.type = NID_id_Gost28147_89_MAC,
.pkey_type = NID_undef,
.md_size = GOST2814789IMIT_LENGTH,
.flags = 0,
.init = gost2814789_init,
.update = gost2814789_update,
.final = gost2814789_final,
.block_size = GOST2814789IMIT_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(GOST2814789IMIT_CTX),
.md_ctrl = gost2814789_md_ctrl,
};
const EVP_MD *
EVP_gost2814789imit(void)
{
return (&gost2814789imit_md);
}
#endif

100
crypto/evp/m_gostr341194.c Normal file
View File

@@ -0,0 +1,100 @@
/* $OpenBSD: m_gostr341194.c,v 1.7 2023/07/07 19:37:53 beck Exp $ */
/*
* Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
* Copyright (c) 2005-2006 Cryptocom LTD
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_GOST
#include <openssl/evp.h>
#include <openssl/gost.h>
#include <openssl/objects.h>
#include "evp_local.h"
static int
gostr341194_init(EVP_MD_CTX *ctx)
{
return GOSTR341194_Init(ctx->md_data,
NID_id_GostR3411_94_CryptoProParamSet);
}
static int
gostr341194_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return GOSTR341194_Update(ctx->md_data, data, count);
}
static int
gostr341194_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return GOSTR341194_Final(md, ctx->md_data);
}
static const EVP_MD gostr341194_md = {
.type = NID_id_GostR3411_94,
.pkey_type = NID_undef,
.md_size = GOSTR341194_LENGTH,
.flags = 0,
.init = gostr341194_init,
.update = gostr341194_update,
.final = gostr341194_final,
.block_size = GOSTR341194_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(GOSTR341194_CTX),
};
const EVP_MD *
EVP_gostr341194(void)
{
return (&gostr341194_md);
}
#endif

113
crypto/evp/m_md4.c Normal file
View File

@@ -0,0 +1,113 @@
/* $OpenBSD: m_md4.c,v 1.21 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_MD4
#include <openssl/evp.h>
#include <openssl/md4.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#include "evp_local.h"
static int
init(EVP_MD_CTX *ctx)
{
return MD4_Init(ctx->md_data);
}
static int
update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return MD4_Update(ctx->md_data, data, count);
}
static int
final(EVP_MD_CTX *ctx, unsigned char *md)
{
return MD4_Final(md, ctx->md_data);
}
static const EVP_MD md4_md = {
.type = NID_md4,
.pkey_type = NID_md4WithRSAEncryption,
.md_size = MD4_DIGEST_LENGTH,
.flags = 0,
.init = init,
.update = update,
.final = final,
.copy = NULL,
.cleanup = NULL,
.block_size = MD4_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(MD4_CTX),
};
const EVP_MD *
EVP_md4(void)
{
return (&md4_md);
}
#endif

113
crypto/evp/m_md5.c Normal file
View File

@@ -0,0 +1,113 @@
/* $OpenBSD: m_md5.c,v 1.20 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_MD5
#include <openssl/evp.h>
#include <openssl/md5.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#include "evp_local.h"
static int
init(EVP_MD_CTX *ctx)
{
return MD5_Init(ctx->md_data);
}
static int
update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return MD5_Update(ctx->md_data, data, count);
}
static int
final(EVP_MD_CTX *ctx, unsigned char *md)
{
return MD5_Final(md, ctx->md_data);
}
static const EVP_MD md5_md = {
.type = NID_md5,
.pkey_type = NID_md5WithRSAEncryption,
.md_size = MD5_DIGEST_LENGTH,
.flags = 0,
.init = init,
.update = update,
.final = final,
.copy = NULL,
.cleanup = NULL,
.block_size = MD5_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(MD5_CTX),
};
const EVP_MD *
EVP_md5(void)
{
return (&md5_md);
}
#endif

89
crypto/evp/m_md5_sha1.c Normal file
View File

@@ -0,0 +1,89 @@
/* $OpenBSD: m_md5_sha1.c,v 1.8 2023/09/02 04:55:18 tb Exp $ */
/*
* Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <openssl/evp.h>
#include <openssl/md5.h>
#include <openssl/objects.h>
#include <openssl/sha.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#include "evp_local.h"
struct md5_sha1_ctx {
MD5_CTX md5;
SHA_CTX sha1;
};
static int
md5_sha1_init(EVP_MD_CTX *ctx)
{
struct md5_sha1_ctx *mdctx = ctx->md_data;
if (!MD5_Init(&mdctx->md5))
return 0;
if (!SHA1_Init(&mdctx->sha1))
return 0;
return 1;
}
static int
md5_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
struct md5_sha1_ctx *mdctx = ctx->md_data;
if (!MD5_Update(&mdctx->md5, data, count))
return 0;
if (!SHA1_Update(&mdctx->sha1, data, count))
return 0;
return 1;
}
static int
md5_sha1_final(EVP_MD_CTX *ctx, unsigned char *out)
{
struct md5_sha1_ctx *mdctx = ctx->md_data;
if (!MD5_Final(out, &mdctx->md5))
return 0;
if (!SHA1_Final(out + MD5_DIGEST_LENGTH, &mdctx->sha1))
return 0;
return 1;
}
static const EVP_MD md5_sha1_md = {
.type = NID_md5_sha1,
.pkey_type = NID_md5_sha1,
.md_size = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
.flags = 0,
.init = md5_sha1_init,
.update = md5_sha1_update,
.final = md5_sha1_final,
.block_size = MD5_CBLOCK, /* MD5_CBLOCK == SHA_CBLOCK */
.ctx_size = sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx),
};
const EVP_MD *
EVP_md5_sha1(void)
{
return &md5_sha1_md;
}

103
crypto/evp/m_null.c Normal file
View File

@@ -0,0 +1,103 @@
/* $OpenBSD: m_null.c,v 1.14 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "evp_local.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 = {
.type = NID_undef,
.pkey_type = NID_undef,
.md_size = 0,
.flags = 0,
.init = init,
.update = update,
.final = final,
.copy = NULL,
.cleanup = NULL,
.block_size = 0,
.ctx_size = sizeof(EVP_MD *),
};
const EVP_MD *
EVP_md_null(void)
{
return (&null_md);
}

113
crypto/evp/m_ripemd.c Normal file
View File

@@ -0,0 +1,113 @@
/* $OpenBSD: m_ripemd.c,v 1.17 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_RIPEMD
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/ripemd.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#include "evp_local.h"
static int
init(EVP_MD_CTX *ctx)
{
return RIPEMD160_Init(ctx->md_data);
}
static int
update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return RIPEMD160_Update(ctx->md_data, data, count);
}
static int
final(EVP_MD_CTX *ctx, unsigned char *md)
{
return RIPEMD160_Final(md, ctx->md_data);
}
static const EVP_MD ripemd160_md = {
.type = NID_ripemd160,
.pkey_type = NID_ripemd160WithRSA,
.md_size = RIPEMD160_DIGEST_LENGTH,
.flags = 0,
.init = init,
.update = update,
.final = final,
.copy = NULL,
.cleanup = NULL,
.block_size = RIPEMD160_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX),
};
const EVP_MD *
EVP_ripemd160(void)
{
return (&ripemd160_md);
}
#endif

351
crypto/evp/m_sha1.c Normal file
View File

@@ -0,0 +1,351 @@
/* $OpenBSD: m_sha1.c,v 1.25 2023/07/07 19:37:53 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_SHA
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/sha.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#include "evp_local.h"
#include "sha_internal.h"
static int
sha1_init(EVP_MD_CTX *ctx)
{
return SHA1_Init(ctx->md_data);
}
static int
sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return SHA1_Update(ctx->md_data, data, count);
}
static int
sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return SHA1_Final(md, ctx->md_data);
}
static const EVP_MD sha1_md = {
.type = NID_sha1,
.pkey_type = NID_sha1WithRSAEncryption,
.md_size = SHA_DIGEST_LENGTH,
.flags = EVP_MD_FLAG_DIGALGID_ABSENT,
.init = sha1_init,
.update = sha1_update,
.final = sha1_final,
.copy = NULL,
.cleanup = NULL,
.block_size = SHA_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(SHA_CTX),
};
const EVP_MD *
EVP_sha1(void)
{
return &sha1_md;
}
#endif
#ifndef OPENSSL_NO_SHA256
static int
sha224_init(EVP_MD_CTX *ctx)
{
return SHA224_Init(ctx->md_data);
}
static int
sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
/*
* Even though there're separate SHA224_[Update|Final], we call
* SHA256 functions even in SHA224 context. This is what happens
* there anyway, so we can spare few CPU cycles:-)
*/
return SHA256_Update(ctx->md_data, data, count);
}
static int
sha224_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return SHA224_Final(md, ctx->md_data);
}
static const EVP_MD sha224_md = {
.type = NID_sha224,
.pkey_type = NID_sha224WithRSAEncryption,
.md_size = SHA224_DIGEST_LENGTH,
.flags = EVP_MD_FLAG_DIGALGID_ABSENT,
.init = sha224_init,
.update = sha224_update,
.final = sha224_final,
.copy = NULL,
.cleanup = NULL,
.block_size = SHA256_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(SHA256_CTX),
};
const EVP_MD *
EVP_sha224(void)
{
return &sha224_md;
}
static int
sha256_init(EVP_MD_CTX *ctx)
{
return SHA256_Init(ctx->md_data);
}
static int
sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return SHA256_Update(ctx->md_data, data, count);
}
static int
sha256_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return SHA256_Final(md, ctx->md_data);
}
static const EVP_MD sha256_md = {
.type = NID_sha256,
.pkey_type = NID_sha256WithRSAEncryption,
.md_size = SHA256_DIGEST_LENGTH,
.flags = EVP_MD_FLAG_DIGALGID_ABSENT,
.init = sha256_init,
.update = sha256_update,
.final = sha256_final,
.copy = NULL,
.cleanup = NULL,
.block_size = SHA256_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(SHA256_CTX),
};
const EVP_MD *
EVP_sha256(void)
{
return &sha256_md;
}
#endif /* ifndef OPENSSL_NO_SHA256 */
#ifndef OPENSSL_NO_SHA512
static int
sha384_init(EVP_MD_CTX *ctx)
{
return SHA384_Init(ctx->md_data);
}
static int
sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
/* See comment in SHA224/256 section */
return SHA512_Update(ctx->md_data, data, count);
}
static int
sha384_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return SHA384_Final(md, ctx->md_data);
}
static const EVP_MD sha384_md = {
.type = NID_sha384,
.pkey_type = NID_sha384WithRSAEncryption,
.md_size = SHA384_DIGEST_LENGTH,
.flags = EVP_MD_FLAG_DIGALGID_ABSENT,
.init = sha384_init,
.update = sha384_update,
.final = sha384_final,
.copy = NULL,
.cleanup = NULL,
.block_size = SHA512_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(SHA512_CTX),
};
const EVP_MD *
EVP_sha384(void)
{
return &sha384_md;
}
static int
sha512_init(EVP_MD_CTX *ctx)
{
return SHA512_Init(ctx->md_data);
}
static int
sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return SHA512_Update(ctx->md_data, data, count);
}
static int
sha512_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return SHA512_Final(md, ctx->md_data);
}
static const EVP_MD sha512_md = {
.type = NID_sha512,
.pkey_type = NID_sha512WithRSAEncryption,
.md_size = SHA512_DIGEST_LENGTH,
.flags = EVP_MD_FLAG_DIGALGID_ABSENT,
.init = sha512_init,
.update = sha512_update,
.final = sha512_final,
.copy = NULL,
.cleanup = NULL,
.block_size = SHA512_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(SHA512_CTX),
};
const EVP_MD *
EVP_sha512(void)
{
return &sha512_md;
}
static int
sha512_224_init(EVP_MD_CTX *ctx)
{
return SHA512_224_Init(ctx->md_data);
}
static int
sha512_224_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return SHA512_224_Update(ctx->md_data, data, count);
}
static int
sha512_224_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return SHA512_224_Final(md, ctx->md_data);
}
static const EVP_MD sha512_224_md = {
.type = NID_sha512_224,
.pkey_type = NID_sha512_224WithRSAEncryption,
.md_size = SHA512_224_DIGEST_LENGTH,
.flags = EVP_MD_FLAG_DIGALGID_ABSENT,
.init = sha512_224_init,
.update = sha512_224_update,
.final = sha512_224_final,
.copy = NULL,
.cleanup = NULL,
.block_size = SHA512_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(SHA512_CTX),
};
const EVP_MD *
EVP_sha512_224(void)
{
return &sha512_224_md;
}
static int
sha512_256_init(EVP_MD_CTX *ctx)
{
return SHA512_256_Init(ctx->md_data);
}
static int
sha512_256_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return SHA512_256_Update(ctx->md_data, data, count);
}
static int
sha512_256_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return SHA512_256_Final(md, ctx->md_data);
}
static const EVP_MD sha512_256_md = {
.type = NID_sha512_256,
.pkey_type = NID_sha512_256WithRSAEncryption,
.md_size = SHA512_256_DIGEST_LENGTH,
.flags = EVP_MD_FLAG_DIGALGID_ABSENT,
.init = sha512_256_init,
.update = sha512_256_update,
.final = sha512_256_final,
.copy = NULL,
.cleanup = NULL,
.block_size = SHA512_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(SHA512_CTX),
};
const EVP_MD *
EVP_sha512_256(void)
{
return &sha512_256_md;
}
#endif /* ifndef OPENSSL_NO_SHA512 */

173
crypto/evp/m_sha3.c Normal file
View File

@@ -0,0 +1,173 @@
/* $OpenBSD: m_sha3.c,v 1.3 2023/07/07 19:37:53 beck Exp $ */
/*
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <openssl/evp.h>
#include "evp_local.h"
#include "sha3_internal.h"
static int
sha3_224_init(EVP_MD_CTX *ctx)
{
return sha3_init(ctx->md_data, SHA3_224_DIGEST_LENGTH);
}
static int
sha3_224_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return sha3_update(ctx->md_data, data, count);
}
static int
sha3_224_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return sha3_final(md, ctx->md_data);
}
static const EVP_MD sha3_224_md = {
.type = NID_sha3_224,
.pkey_type = NID_RSA_SHA3_224,
.md_size = SHA3_224_DIGEST_LENGTH,
.flags = EVP_MD_FLAG_DIGALGID_ABSENT,
.init = sha3_224_init,
.update = sha3_224_update,
.final = sha3_224_final,
.copy = NULL,
.cleanup = NULL,
.block_size = SHA3_224_BLOCK_SIZE,
.ctx_size = sizeof(EVP_MD *) + sizeof(sha3_ctx),
};
const EVP_MD *
EVP_sha3_224(void)
{
return &sha3_224_md;
}
static int
sha3_256_init(EVP_MD_CTX *ctx)
{
return sha3_init(ctx->md_data, SHA3_256_DIGEST_LENGTH);
}
static int
sha3_256_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return sha3_update(ctx->md_data, data, count);
}
static int
sha3_256_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return sha3_final(md, ctx->md_data);
}
static const EVP_MD sha3_256_md = {
.type = NID_sha3_256,
.pkey_type = NID_RSA_SHA3_256,
.md_size = SHA3_256_DIGEST_LENGTH,
.flags = EVP_MD_FLAG_DIGALGID_ABSENT,
.init = sha3_256_init,
.update = sha3_256_update,
.final = sha3_256_final,
.copy = NULL,
.cleanup = NULL,
.block_size = SHA3_256_BLOCK_SIZE,
.ctx_size = sizeof(EVP_MD *) + sizeof(sha3_ctx),
};
const EVP_MD *
EVP_sha3_256(void)
{
return &sha3_256_md;
}
static int
sha3_384_init(EVP_MD_CTX *ctx)
{
return sha3_init(ctx->md_data, SHA3_384_DIGEST_LENGTH);
}
static int
sha3_384_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return sha3_update(ctx->md_data, data, count);
}
static int
sha3_384_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return sha3_final(md, ctx->md_data);
}
static const EVP_MD sha3_384_md = {
.type = NID_sha3_384,
.pkey_type = NID_RSA_SHA3_384,
.md_size = SHA3_384_DIGEST_LENGTH,
.flags = EVP_MD_FLAG_DIGALGID_ABSENT,
.init = sha3_384_init,
.update = sha3_384_update,
.final = sha3_384_final,
.copy = NULL,
.cleanup = NULL,
.block_size = SHA3_384_BLOCK_SIZE,
.ctx_size = sizeof(EVP_MD *) + sizeof(sha3_ctx),
};
const EVP_MD *
EVP_sha3_384(void)
{
return &sha3_384_md;
}
static int
sha3_512_init(EVP_MD_CTX *ctx)
{
return sha3_init(ctx->md_data, SHA3_512_DIGEST_LENGTH);
}
static int
sha3_512_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return sha3_update(ctx->md_data, data, count);
}
static int
sha3_512_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return sha3_final(md, ctx->md_data);
}
static const EVP_MD sha3_512_md = {
.type = NID_sha3_512,
.pkey_type = NID_RSA_SHA3_512,
.md_size = SHA3_512_DIGEST_LENGTH,
.flags = EVP_MD_FLAG_DIGALGID_ABSENT,
.init = sha3_512_init,
.update = sha3_512_update,
.final = sha3_512_final,
.copy = NULL,
.cleanup = NULL,
.block_size = SHA3_512_BLOCK_SIZE,
.ctx_size = sizeof(EVP_MD *) + sizeof(sha3_ctx),
};
const EVP_MD *
EVP_sha3_512(void)
{
return &sha3_512_md;
}

257
crypto/evp/m_sigver.c Normal file
View File

@@ -0,0 +1,257 @@
/* $OpenBSD: m_sigver.c,v 1.13 2023/07/07 19:37:53 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
/* ====================================================================
* Copyright (c) 2006,2007 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "evp_local.h"
static int
update_oneshot_only(EVP_MD_CTX *ctx, const void *data, size_t datalen)
{
EVPerror(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) {
EVPerror(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 != NULL) {
ctx->pctx->operation = EVP_PKEY_OP_VERIFY;
ctx->update = update_oneshot_only;
} 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 != NULL) {
ctx->pctx->operation = EVP_PKEY_OP_SIGN;
ctx->update = update_oneshot_only;
} else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
return 0;
}
if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
return 0;
if (pctx)
*pctx = ctx->pctx;
if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
return 1;
if (!EVP_DigestInit_ex(ctx, type, e))
return 0;
return 1;
}
int
EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
ENGINE *e, EVP_PKEY *pkey)
{
return do_sigver_init(ctx, pctx, type, e, pkey, 0);
}
int
EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
ENGINE *e, EVP_PKEY *pkey)
{
return do_sigver_init(ctx, pctx, type, e, pkey, 1);
}
int
EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
{
EVP_PKEY_CTX *pctx = ctx->pctx;
int sctx;
int r = 0;
if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
EVP_PKEY_CTX *dctx;
if (sigret == NULL)
return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
/* XXX - support EVP_MD_CTX_FLAG_FINALISE? */
if ((dctx = EVP_PKEY_CTX_dup(ctx->pctx)) == NULL)
return 0;
r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
EVP_PKEY_CTX_free(dctx);
return r;
}
if (ctx->pctx->pmeth->signctx)
sctx = 1;
else
sctx = 0;
if (sigret) {
EVP_MD_CTX tmp_ctx;
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int mdlen = 0;
EVP_MD_CTX_init(&tmp_ctx);
if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
return 0;
if (sctx)
r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx,
sigret, siglen, &tmp_ctx);
else
r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
EVP_MD_CTX_cleanup(&tmp_ctx);
if (sctx || !r)
return r;
if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
return 0;
} else {
if (sctx) {
if (ctx->pctx->pmeth->signctx(ctx->pctx, sigret,
siglen, ctx) <= 0)
return 0;
} else {
int s = EVP_MD_size(ctx->digest);
if (s < 0 || EVP_PKEY_sign(ctx->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) {
if (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)
{
EVP_MD_CTX tmp_ctx;
unsigned char md[EVP_MAX_MD_SIZE];
int r;
unsigned int mdlen = 0;
int vctx;
if (ctx->pctx->pmeth->verifyctx)
vctx = 1;
else
vctx = 0;
EVP_MD_CTX_init(&tmp_ctx);
if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
return -1;
if (vctx) {
r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx, sig,
siglen, &tmp_ctx);
} else
r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
EVP_MD_CTX_cleanup(&tmp_ctx);
if (vctx || !r)
return r;
return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
}
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);
}

68
crypto/evp/m_sm3.c Normal file
View File

@@ -0,0 +1,68 @@
/* $OpenBSD: m_sm3.c,v 1.6 2023/07/07 19:37:53 beck Exp $ */
/*
* Copyright (c) 2018, Ribose Inc
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_SM3
#include <openssl/evp.h>
#include <openssl/sm3.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#include "evp_local.h"
static int
sm3_init(EVP_MD_CTX *ctx)
{
return SM3_Init(ctx->md_data);
}
static int
sm3_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return SM3_Update(ctx->md_data, data, count);
}
static int
sm3_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return SM3_Final(md, ctx->md_data);
}
static const EVP_MD sm3_md = {
.type = NID_sm3,
.pkey_type = NID_sm3WithRSAEncryption,
.md_size = SM3_DIGEST_LENGTH,
.flags = EVP_MD_FLAG_DIGALGID_ABSENT,
.init = sm3_init,
.update = sm3_update,
.final = sm3_final,
.copy = NULL,
.cleanup = NULL,
.block_size = SM3_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(SM3_CTX),
};
const EVP_MD *
EVP_sm3(void)
{
return &sm3_md;
}
#endif /* OPENSSL_NO_SM3 */

133
crypto/evp/m_streebog.c Normal file
View File

@@ -0,0 +1,133 @@
/* $OpenBSD: m_streebog.c,v 1.7 2023/07/07 19:37:54 beck Exp $ */
/*
* Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
* Copyright (c) 2005-2006 Cryptocom LTD
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_GOST
#include <openssl/evp.h>
#include <openssl/gost.h>
#include <openssl/objects.h>
#include "evp_local.h"
static int
streebog_init256(EVP_MD_CTX *ctx)
{
return STREEBOG256_Init(ctx->md_data);
}
static int
streebog_update256(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return STREEBOG256_Update(ctx->md_data, data, count);
}
static int
streebog_final256(EVP_MD_CTX *ctx, unsigned char *md)
{
return STREEBOG256_Final(md, ctx->md_data);
}
static int
streebog_init512(EVP_MD_CTX *ctx)
{
return STREEBOG512_Init(ctx->md_data);
}
static int
streebog_update512(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return STREEBOG512_Update(ctx->md_data, data, count);
}
static int
streebog_final512(EVP_MD_CTX *ctx, unsigned char *md)
{
return STREEBOG512_Final(md, ctx->md_data);
}
static const EVP_MD streebog256_md = {
.type = NID_id_tc26_gost3411_2012_256,
.pkey_type = NID_undef,
.md_size = STREEBOG256_LENGTH,
.flags = 0,
.init = streebog_init256,
.update = streebog_update256,
.final = streebog_final256,
.block_size = STREEBOG_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(STREEBOG_CTX),
};
static const EVP_MD streebog512_md = {
.type = NID_id_tc26_gost3411_2012_512,
.pkey_type = NID_undef,
.md_size = STREEBOG512_LENGTH,
.flags = 0,
.init = streebog_init512,
.update = streebog_update512,
.final = streebog_final512,
.block_size = STREEBOG_CBLOCK,
.ctx_size = sizeof(EVP_MD *) + sizeof(STREEBOG_CTX),
};
const EVP_MD *
EVP_streebog256(void)
{
return (&streebog256_md);
}
const EVP_MD *
EVP_streebog512(void)
{
return (&streebog512_md);
}
#endif

53
crypto/evp/m_wp.c Normal file
View File

@@ -0,0 +1,53 @@
/* $OpenBSD: m_wp.c,v 1.13 2023/07/07 19:37:54 beck Exp $ */
#include <stdio.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_WHIRLPOOL
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/whrlpool.h>
#include "evp_local.h"
static int
init(EVP_MD_CTX *ctx)
{
return WHIRLPOOL_Init(ctx->md_data);
}
static int
update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return WHIRLPOOL_Update(ctx->md_data, data, count);
}
static int
final(EVP_MD_CTX *ctx, unsigned char *md)
{
return WHIRLPOOL_Final(md, ctx->md_data);
}
static const EVP_MD whirlpool_md = {
.type = NID_whirlpool,
.pkey_type = 0,
.md_size = WHIRLPOOL_DIGEST_LENGTH,
.flags = 0,
.init = init,
.update = update,
.final = final,
.copy = NULL,
.cleanup = NULL,
.block_size = WHIRLPOOL_BBLOCK / 8,
.ctx_size = sizeof(EVP_MD *) + sizeof(WHIRLPOOL_CTX),
};
const EVP_MD *
EVP_whirlpool(void)
{
return (&whirlpool_md);
}
#endif

240
crypto/evp/names.c Normal file
View File

@@ -0,0 +1,240 @@
/* $OpenBSD: names.c,v 1.21 2023/08/26 02:59:13 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "evp_local.h"
extern int obj_cleanup_defer;
void check_defer(int nid);
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);
check_defer(c->nid);
r = OBJ_NAME_add(OBJ_nid2ln(c->nid), OBJ_NAME_TYPE_CIPHER_METH,
(const char *)c);
return (r);
}
int
EVP_add_digest(const EVP_MD *md)
{
int r;
const char *name;
name = OBJ_nid2sn(md->type);
r = OBJ_NAME_add(name, OBJ_NAME_TYPE_MD_METH, (const char *)md);
if (r == 0)
return (0);
check_defer(md->type);
r = OBJ_NAME_add(OBJ_nid2ln(md->type), OBJ_NAME_TYPE_MD_METH,
(const char *)md);
if (r == 0)
return (0);
if (md->pkey_type && md->type != md->pkey_type) {
r = OBJ_NAME_add(OBJ_nid2sn(md->pkey_type),
OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS, name);
if (r == 0)
return (0);
check_defer(md->pkey_type);
r = OBJ_NAME_add(OBJ_nid2ln(md->pkey_type),
OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS, name);
}
return (r);
}
const EVP_CIPHER *
EVP_get_cipherbyname(const char *name)
{
if (!OPENSSL_init_crypto(0, NULL))
return NULL;
return (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH);
}
const EVP_MD *
EVP_get_digestbyname(const char *name)
{
if (!OPENSSL_init_crypto(0, NULL))
return NULL;
return (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
}
void
EVP_cleanup(void)
{
OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
/* The above calls will only clean out the contents of the name
hash table, but not the hash table itself. The following line
does that part. -- Richard Levitte */
OBJ_NAME_cleanup(-1);
EVP_PBE_cleanup();
if (obj_cleanup_defer == 2) {
obj_cleanup_defer = 0;
OBJ_cleanup();
}
}
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;
/* Prayer and clean living lets you ignore errors, OpenSSL style */
(void) OPENSSL_init_crypto(0, 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;
/* Prayer and clean living lets you ignore errors, OpenSSL style */
(void) OPENSSL_init_crypto(0, 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;
/* Prayer and clean living lets you ignore errors, OpenSSL style */
(void) OPENSSL_init_crypto(0, 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;
/* Prayer and clean living lets you ignore errors, OpenSSL style */
(void) OPENSSL_init_crypto(0, NULL);
dc.fn = fn;
dc.arg = arg;
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
}

163
crypto/evp/p5_crpt.c Normal file
View File

@@ -0,0 +1,163 @@
/* $OpenBSD: p5_crpt.c,v 1.23 2023/07/07 19:37:54 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include "evp_local.h"
/* Doesn't do anything now: Builtin PBE algorithms in static table.
*/
void
PKCS5_PBE_add(void)
{
}
int
PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de)
{
EVP_MD_CTX ctx;
unsigned char md_tmp[EVP_MAX_MD_SIZE];
unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
int i;
PBEPARAM *pbe;
int saltlen, iter;
unsigned char *salt;
const unsigned char *pbuf;
int mdsize;
int rv = 0;
/* Extract useful info from parameter */
if (param == NULL || param->type != V_ASN1_SEQUENCE ||
param->value.sequence == NULL) {
EVPerror(EVP_R_DECODE_ERROR);
return 0;
}
mdsize = EVP_MD_size(md);
if (mdsize < 0)
return 0;
pbuf = param->value.sequence->data;
if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) {
EVPerror(EVP_R_DECODE_ERROR);
return 0;
}
if (!pbe->iter)
iter = 1;
else if ((iter = ASN1_INTEGER_get(pbe->iter)) <= 0) {
EVPerror(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS);
PBEPARAM_free(pbe);
return 0;
}
salt = pbe->salt->data;
saltlen = pbe->salt->length;
if (!pass)
passlen = 0;
else if (passlen == -1)
passlen = strlen(pass);
EVP_MD_CTX_init(&ctx);
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;
if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL))
goto err;
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;
}
if ((size_t)EVP_CIPHER_key_length(cipher) > sizeof(md_tmp)) {
EVPerror(EVP_R_BAD_KEY_LENGTH);
goto err;
}
memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher));
if ((size_t)EVP_CIPHER_iv_length(cipher) > 16) {
EVPerror(EVP_R_IV_TOO_LARGE);
goto err;
}
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;
explicit_bzero(md_tmp, EVP_MAX_MD_SIZE);
explicit_bzero(key, EVP_MAX_KEY_LENGTH);
explicit_bzero(iv, EVP_MAX_IV_LENGTH);
rv = 1;
err:
EVP_MD_CTX_cleanup(&ctx);
PBEPARAM_free(pbe);
return rv;
}

307
crypto/evp/p5_crpt2.c Normal file
View File

@@ -0,0 +1,307 @@
/* $OpenBSD: p5_crpt2.c,v 1.27 2023/07/07 19:37:54 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/opensslconf.h>
#if !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA)
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/x509.h>
#include "evp_local.h"
#include "hmac_local.h"
/* This is an implementation of PKCS#5 v2.0 password based encryption key
* derivation function PBKDF2.
* SHA1 version verified against test vectors posted by Peter Gutmann
* <pgut001@cs.auckland.ac.nz> to the PKCS-TNG <pkcs-tng@rsa.com> mailing list.
*/
int
PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt,
int saltlen, int iter, const EVP_MD *digest, int keylen, unsigned char *out)
{
unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
int cplen, j, k, tkeylen, mdlen;
unsigned long i = 1;
HMAC_CTX hctx_tpl, hctx;
mdlen = EVP_MD_size(digest);
if (mdlen < 0)
return 0;
HMAC_CTX_init(&hctx_tpl);
p = out;
tkeylen = keylen;
if (!pass)
passlen = 0;
else if (passlen == -1)
passlen = strlen(pass);
if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) {
HMAC_CTX_cleanup(&hctx_tpl);
return 0;
}
while (tkeylen) {
if (tkeylen > mdlen)
cplen = mdlen;
else
cplen = tkeylen;
/* We are unlikely to ever use more than 256 blocks (5120 bits!)
* but just in case...
*/
itmp[0] = (unsigned char)((i >> 24) & 0xff);
itmp[1] = (unsigned char)((i >> 16) & 0xff);
itmp[2] = (unsigned char)((i >> 8) & 0xff);
itmp[3] = (unsigned char)(i & 0xff);
if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
HMAC_CTX_cleanup(&hctx_tpl);
return 0;
}
if (!HMAC_Update(&hctx, salt, saltlen) ||
!HMAC_Update(&hctx, itmp, 4) ||
!HMAC_Final(&hctx, digtmp, NULL)) {
HMAC_CTX_cleanup(&hctx_tpl);
HMAC_CTX_cleanup(&hctx);
return 0;
}
HMAC_CTX_cleanup(&hctx);
memcpy(p, digtmp, cplen);
for (j = 1; j < iter; j++) {
if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
HMAC_CTX_cleanup(&hctx_tpl);
return 0;
}
if (!HMAC_Update(&hctx, digtmp, mdlen) ||
!HMAC_Final(&hctx, digtmp, NULL)) {
HMAC_CTX_cleanup(&hctx_tpl);
HMAC_CTX_cleanup(&hctx);
return 0;
}
HMAC_CTX_cleanup(&hctx);
for (k = 0; k < cplen; k++)
p[k] ^= digtmp[k];
}
tkeylen -= cplen;
i++;
p += cplen;
}
HMAC_CTX_cleanup(&hctx_tpl);
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)
{
const unsigned char *pbuf;
int plen;
PBE2PARAM *pbe2 = NULL;
const EVP_CIPHER *cipher;
int rv = 0;
if (param == NULL || param->type != V_ASN1_SEQUENCE ||
param->value.sequence == NULL) {
EVPerror(EVP_R_DECODE_ERROR);
goto err;
}
pbuf = param->value.sequence->data;
plen = param->value.sequence->length;
if (!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) {
EVPerror(EVP_R_DECODE_ERROR);
goto err;
}
/* See if we recognise the key derivation function */
if (OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) {
EVPerror(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) {
EVPerror(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) {
EVPerror(EVP_R_CIPHER_PARAMETER_ERROR);
goto err;
}
rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen,
pbe2->keyfunc->parameter, c, md, en_de);
err:
PBE2PARAM_free(pbe2);
return rv;
}
int
PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, int en_de)
{
unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
const unsigned char *pbuf;
int saltlen, iter, plen;
int rv = 0;
unsigned int keylen = 0;
int prf_nid, hmac_md_nid;
PBKDF2PARAM *kdf = NULL;
const EVP_MD *prfmd;
if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
EVPerror(EVP_R_NO_CIPHER_SET);
return 0;
}
keylen = EVP_CIPHER_CTX_key_length(ctx);
if (keylen > sizeof key) {
EVPerror(EVP_R_BAD_KEY_LENGTH);
return 0;
}
/* Decode parameter */
if (!param || (param->type != V_ASN1_SEQUENCE)) {
EVPerror(EVP_R_DECODE_ERROR);
return 0;
}
pbuf = param->value.sequence->data;
plen = param->value.sequence->length;
if (!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen)) ) {
EVPerror(EVP_R_DECODE_ERROR);
return 0;
}
/* Now check the parameters of the kdf */
if (kdf->keylength &&
(ASN1_INTEGER_get(kdf->keylength) != (int)keylen)){
EVPerror(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)) {
EVPerror(EVP_R_UNSUPPORTED_PRF);
goto err;
}
prfmd = EVP_get_digestbynid(hmac_md_nid);
if (prfmd == NULL) {
EVPerror(EVP_R_UNSUPPORTED_PRF);
goto err;
}
if (kdf->salt->type != V_ASN1_OCTET_STRING) {
EVPerror(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;
if ((iter = ASN1_INTEGER_get(kdf->iter)) <= 0) {
EVPerror(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS);
goto err;
}
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:
explicit_bzero(key, keylen);
PBKDF2PARAM_free(kdf);
return rv;
}
#endif

94
crypto/evp/p_dec.c Normal file
View File

@@ -0,0 +1,94 @@
/* $OpenBSD: p_dec.c,v 1.15 2023/07/07 19:37:54 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#include "evp_local.h"
int
EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
EVP_PKEY *priv)
{
int ret = -1;
#ifndef OPENSSL_NO_RSA
if (priv->type != EVP_PKEY_RSA) {
#endif
EVPerror(EVP_R_PUBLIC_KEY_NOT_RSA);
#ifndef OPENSSL_NO_RSA
goto err;
}
ret = RSA_private_decrypt(ekl, ek, key, priv->pkey.rsa,
RSA_PKCS1_PADDING);
err:
#endif
return (ret);
}

91
crypto/evp/p_enc.c Normal file
View File

@@ -0,0 +1,91 @@
/* $OpenBSD: p_enc.c,v 1.15 2023/07/07 19:37:54 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#include "evp_local.h"
int
EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key, int key_len,
EVP_PKEY *pubk)
{
int ret = 0;
#ifndef OPENSSL_NO_RSA
if (pubk->type != EVP_PKEY_RSA) {
#endif
EVPerror(EVP_R_PUBLIC_KEY_NOT_RSA);
#ifndef OPENSSL_NO_RSA
goto err;
}
ret = RSA_public_encrypt(key_len, key, ek, pubk->pkey.rsa, RSA_PKCS1_PADDING);
err:
#endif
return (ret);
}

681
crypto/evp/p_lib.c Normal file
View File

@@ -0,0 +1,681 @@
/* $OpenBSD: p_lib.c,v 1.37 2023/09/10 17:32:17 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#include <openssl/bn.h>
#include <openssl/cmac.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_DH
#include <openssl/dh.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#include "asn1_local.h"
#include "evp_local.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 == NULL || pkey->ameth->pkey_security_bits == NULL)
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 != from->type) {
EVPerror(EVP_R_DIFFERENT_KEY_TYPES);
goto err;
}
if (EVP_PKEY_missing_parameters(from)) {
EVPerror(EVP_R_MISSING_PARAMETERS);
goto err;
}
if (from->ameth && from->ameth->param_copy)
return from->ameth->param_copy(to, from);
err:
return 0;
}
int
EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
{
if (pkey->ameth && pkey->ameth->param_missing)
return pkey->ameth->param_missing(pkey);
return 0;
}
int
EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
{
if (a->type != b->type)
return -1;
if (a->ameth && a->ameth->param_cmp)
return a->ameth->param_cmp(a, b);
return -2;
}
int
EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
{
if (a->type != b->type)
return -1;
if (a->ameth) {
int ret;
/* Compare parameters if the algorithm has them */
if (a->ameth->param_cmp) {
ret = a->ameth->param_cmp(a, b);
if (ret <= 0)
return ret;
}
if (a->ameth->pub_cmp)
return a->ameth->pub_cmp(a, b);
}
return -2;
}
EVP_PKEY *
EVP_PKEY_new(void)
{
EVP_PKEY *ret;
ret = malloc(sizeof(EVP_PKEY));
if (ret == NULL) {
EVPerror(ERR_R_MALLOC_FAILURE);
return (NULL);
}
ret->type = EVP_PKEY_NONE;
ret->save_type = EVP_PKEY_NONE;
ret->references = 1;
ret->ameth = NULL;
ret->engine = NULL;
ret->pkey.ptr = NULL;
ret->attributes = NULL;
ret->save_parameters = 1;
return (ret);
}
int
EVP_PKEY_up_ref(EVP_PKEY *pkey)
{
int refs = CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
return ((refs > 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 = NULL;
if (e == NULL)
eptr = &e;
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
ENGINE_finish(pkey->engine);
pkey->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) {
EVPerror(EVP_R_UNSUPPORTED_ALGORITHM);
return 0;
}
if (pkey) {
pkey->ameth = ameth;
pkey->engine = e;
pkey->type = pkey->ameth->pkey_id;
pkey->save_type = type;
}
return 1;
}
int
EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
{
return pkey_set_type(pkey, NULL, type, NULL, -1);
}
EVP_PKEY *
EVP_PKEY_new_raw_private_key(int type, ENGINE *engine,
const unsigned char *private_key, size_t len)
{
EVP_PKEY *ret;
if ((ret = EVP_PKEY_new()) == NULL)
goto err;
if (!pkey_set_type(ret, engine, type, NULL, -1))
goto err;
if (ret->ameth->set_priv_key == NULL) {
EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
goto err;
}
if (!ret->ameth->set_priv_key(ret, private_key, len)) {
EVPerror(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 *engine,
const unsigned char *public_key, size_t len)
{
EVP_PKEY *ret;
if ((ret = EVP_PKEY_new()) == NULL)
goto err;
if (!pkey_set_type(ret, engine, type, NULL, -1))
goto err;
if (ret->ameth->set_pub_key == NULL) {
EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
goto err;
}
if (!ret->ameth->set_pub_key(ret, public_key, len)) {
EVPerror(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 *out_private_key, size_t *out_len)
{
if (pkey->ameth->get_priv_key == NULL) {
EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (!pkey->ameth->get_priv_key(pkey, out_private_key, out_len)) {
EVPerror(EVP_R_GET_RAW_KEY_FAILED);
return 0;
}
return 1;
}
int
EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey,
unsigned char *out_public_key, size_t *out_len)
{
if (pkey->ameth->get_pub_key == NULL) {
EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (!pkey->ameth->get_pub_key(pkey, out_public_key, out_len)) {
EVPerror(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)
{
EVP_PKEY *ret = NULL;
CMAC_CTX *cmctx = NULL;
if ((ret = EVP_PKEY_new()) == NULL)
goto err;
if ((cmctx = CMAC_CTX_new()) == NULL)
goto err;
if (!pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1))
goto err;
if (!CMAC_Init(cmctx, priv, len, cipher, e)) {
EVPerror(EVP_R_KEY_SETUP_FAILED);
goto err;
}
ret->pkey.ptr = cmctx;
return ret;
err:
EVP_PKEY_free(ret);
CMAC_CTX_free(cmctx);
return NULL;
}
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_assign(EVP_PKEY *pkey, int type, void *key)
{
if (!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;
if (pkey->type != EVP_PKEY_HMAC) {
EVPerror(EVP_R_EXPECTING_AN_HMAC_KEY);
return NULL;
}
os = EVP_PKEY_get0(pkey);
*len = os->length;
return os->data;
}
#ifndef OPENSSL_NO_RSA
RSA *
EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
{
if (pkey->type == EVP_PKEY_RSA || pkey->type == EVP_PKEY_RSA_PSS)
return pkey->pkey.rsa;
EVPerror(EVP_R_EXPECTING_AN_RSA_KEY);
return NULL;
}
RSA *
EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
{
RSA *rsa;
if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL)
return NULL;
RSA_up_ref(rsa);
return rsa;
}
int
EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
{
int ret = EVP_PKEY_assign_RSA(pkey, key);
if (ret != 0)
RSA_up_ref(key);
return ret;
}
#endif
#ifndef OPENSSL_NO_DSA
DSA *
EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
{
if (pkey->type != EVP_PKEY_DSA) {
EVPerror(EVP_R_EXPECTING_A_DSA_KEY);
return NULL;
}
return pkey->pkey.dsa;
}
DSA *
EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
{
DSA *dsa;
if ((dsa = EVP_PKEY_get0_DSA(pkey)) == NULL)
return NULL;
DSA_up_ref(dsa);
return dsa;
}
int
EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
{
int ret = EVP_PKEY_assign_DSA(pkey, key);
if (ret != 0)
DSA_up_ref(key);
return ret;
}
#endif
#ifndef OPENSSL_NO_EC
EC_KEY *
EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
{
if (pkey->type != EVP_PKEY_EC) {
EVPerror(EVP_R_EXPECTING_A_EC_KEY);
return NULL;
}
return pkey->pkey.ec;
}
EC_KEY *
EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
{
EC_KEY *key;
if ((key = EVP_PKEY_get0_EC_KEY(pkey)) == NULL)
return NULL;
EC_KEY_up_ref(key);
return key;
}
int
EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
{
int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
if (ret != 0)
EC_KEY_up_ref(key);
return ret;
}
#endif
#ifndef OPENSSL_NO_DH
DH *
EVP_PKEY_get0_DH(EVP_PKEY *pkey)
{
if (pkey->type != EVP_PKEY_DH) {
EVPerror(EVP_R_EXPECTING_A_DH_KEY);
return NULL;
}
return pkey->pkey.dh;
}
DH *
EVP_PKEY_get1_DH(EVP_PKEY *pkey)
{
DH *dh;
if ((dh = EVP_PKEY_get0_DH(pkey)) == NULL)
return NULL;
DH_up_ref(dh);
return dh;
}
int
EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
{
int ret = EVP_PKEY_assign_DH(pkey, key);
if (ret != 0)
DH_up_ref(key);
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;
i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY);
if (i > 0)
return;
EVP_PKEY_free_it(x);
if (x->attributes)
sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
free(x);
}
static void
EVP_PKEY_free_it(EVP_PKEY *x)
{
if (x->ameth && x->ameth->pkey_free) {
x->ameth->pkey_free(x);
x->pkey.ptr = NULL;
}
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(x->engine);
x->engine = NULL;
#endif
}
static int
unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, const char *kstr)
{
if (!BIO_indent(out, indent, 128))
return 0;
BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
kstr, OBJ_nid2ln(pkey->type));
return 1;
}
int
EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx)
{
if (pkey->ameth && pkey->ameth->pub_print)
return pkey->ameth->pub_print(out, pkey, indent, pctx);
return unsup_alg(out, pkey, indent, "Public Key");
}
int
EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx)
{
if (pkey->ameth && pkey->ameth->priv_print)
return pkey->ameth->priv_print(out, pkey, indent, pctx);
return unsup_alg(out, pkey, indent, "Private Key");
}
int
EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx)
{
if (pkey->ameth && pkey->ameth->param_print)
return pkey->ameth->param_print(out, pkey, indent, pctx);
return unsup_alg(out, pkey, indent, "Parameters");
}
int
EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
{
if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
return -2;
return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
0, pnid);
}

128
crypto/evp/p_open.c Normal file
View File

@@ -0,0 +1,128 @@
/* $OpenBSD: p_open.c,v 1.23 2023/07/07 19:37:54 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#include "evp_local.h"
int
EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
const unsigned char *ek, int ekl, const unsigned char *iv, EVP_PKEY *priv)
{
unsigned char *key = NULL;
int i, size = 0, ret = 0;
if (type) {
EVP_CIPHER_CTX_init(ctx);
if (!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL))
return 0;
}
if (!priv)
return 1;
if (priv->type != EVP_PKEY_RSA) {
EVPerror(EVP_R_PUBLIC_KEY_NOT_RSA);
goto err;
}
size = RSA_size(priv->pkey.rsa);
key = malloc(size + 2);
if (key == NULL) {
/* ERROR */
EVPerror(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:
freezero(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

124
crypto/evp/p_seal.c Normal file
View File

@@ -0,0 +1,124 @@
/* $OpenBSD: p_seal.c,v 1.16 2023/07/07 19:37:54 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <stdlib.h>
#include <openssl/opensslconf.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
int
EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek,
int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk)
{
unsigned char key[EVP_MAX_KEY_LENGTH];
int i;
if (type) {
EVP_CIPHER_CTX_init(ctx);
if (!EVP_EncryptInit_ex(ctx, type, NULL, NULL, NULL))
return 0;
}
if ((npubk <= 0) || !pubk)
return 1;
if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
return 0;
if (EVP_CIPHER_CTX_iv_length(ctx))
arc4random_buf(iv, EVP_CIPHER_CTX_iv_length(ctx));
if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
return 0;
for (i = 0; i < npubk; i++) {
ekl[i] = EVP_PKEY_encrypt_old(ek[i], key,
EVP_CIPHER_CTX_key_length(ctx), pubk[i]);
if (ekl[i] <= 0)
return (-1);
}
return (npubk);
}
/* MACRO
void EVP_SealUpdate(ctx,out,outl,in,inl)
EVP_CIPHER_CTX *ctx;
unsigned char *out;
int *outl;
unsigned char *in;
int inl;
{
EVP_EncryptUpdate(ctx,out,outl,in,inl);
}
*/
int
EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int i;
i = EVP_EncryptFinal_ex(ctx, out, outl);
if (i)
i = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, NULL);
return i;
}

104
crypto/evp/p_sign.c Normal file
View File

@@ -0,0 +1,104 @@
/* $OpenBSD: p_sign.c,v 1.19 2023/07/07 19:37:54 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "evp_local.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;
EVP_MD_CTX tmp_ctx;
EVP_PKEY_CTX *pkctx = NULL;
size_t sltmp;
int ret = 0;
*siglen = 0;
EVP_MD_CTX_init(&tmp_ctx);
if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
goto err;
if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len))
goto err;
EVP_MD_CTX_cleanup(&tmp_ctx);
sltmp = (size_t)EVP_PKEY_size(pkey);
if ((pkctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL)
goto err;
if (EVP_PKEY_sign_init(pkctx) <= 0)
goto err;
if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
goto err;
if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0)
goto err;
*siglen = sltmp;
ret = 1;
err:
EVP_PKEY_CTX_free(pkctx);
return ret;
}

97
crypto/evp/p_verify.c Normal file
View File

@@ -0,0 +1,97 @@
/* $OpenBSD: p_verify.c,v 1.18 2023/07/07 19:37:54 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "evp_local.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;
EVP_MD_CTX tmp_ctx;
EVP_PKEY_CTX *pkctx = NULL;
int ret = 0;
EVP_MD_CTX_init(&tmp_ctx);
if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx))
goto err;
if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len))
goto err;
EVP_MD_CTX_cleanup(&tmp_ctx);
ret = -1;
if ((pkctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL)
goto err;
if (EVP_PKEY_verify_init(pkctx) <= 0)
goto err;
if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
goto err;
ret = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
err:
EVP_PKEY_CTX_free(pkctx);
return ret;
}

345
crypto/evp/pmeth_fn.c Normal file
View File

@@ -0,0 +1,345 @@
/* $OpenBSD: pmeth_fn.c,v 1.9 2023/07/07 19:37:54 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include "evp_local.h"
#define M_check_autoarg(ctx, arg, arglen, err) \
if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
{ \
size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
if (!arg) \
{ \
*arglen = pksize; \
return 1; \
} \
else if (*arglen < pksize) \
{ \
EVPerror(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) {
EVPerror(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) {
EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
if (ctx->operation != EVP_PKEY_OP_SIGN) {
EVPerror(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) {
EVPerror(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) {
EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
if (ctx->operation != EVP_PKEY_OP_VERIFY) {
EVPerror(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) {
EVPerror(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) {
EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
EVPerror(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) {
EVPerror(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) {
EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
EVPerror(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) {
EVPerror(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) {
EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
EVPerror(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) {
EVPerror(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) {
EVPerror(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) {
EVPerror(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) {
EVPerror(EVP_R_NO_KEY_SET);
return -1;
}
if (ctx->pkey->type != peer->type) {
EVPerror(EVP_R_DIFFERENT_KEY_TYPES);
return -1;
}
/* ran@cryptocom.ru: For clarity. The error is if parameters in peer are
* present (!missing) but don't match. EVP_PKEY_cmp_parameters may return
* 1 (match), 0 (don't match) and -2 (comparison is not defined). -1
* (different key types) is impossible here because it is checked earlier.
* -2 is OK for us here, as well as 1, so we can check for 0 only. */
if (!EVP_PKEY_missing_parameters(peer) &&
!EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
EVPerror(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;
}
CRYPTO_add(&peer->references, 1, CRYPTO_LOCK_EVP_PKEY);
return 1;
}
int
EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
{
if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
if (ctx->operation != EVP_PKEY_OP_DERIVE) {
EVPerror(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);
}

288
crypto/evp/pmeth_gn.c Normal file
View File

@@ -0,0 +1,288 @@
/* $OpenBSD: pmeth_gn.c,v 1.13 2023/07/07 19:37:54 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include "asn1_local.h"
#include "bn_local.h"
#include "evp_local.h"
int
EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
{
int ret;
if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
EVPerror(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) {
EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
if (ctx->operation != EVP_PKEY_OP_PARAMGEN) {
EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
return -1;
}
if (!ppkey)
return -1;
if (!*ppkey)
*ppkey = EVP_PKEY_new();
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) {
EVPerror(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) {
EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
if (ctx->operation != EVP_PKEY_OP_KEYGEN) {
EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
return -1;
}
if (!ppkey)
return -1;
if (!*ppkey)
*ppkey = EVP_PKEY_new();
ret = ctx->pmeth->keygen(ctx, *ppkey);
if (ret <= 0) {
EVP_PKEY_free(*ppkey);
*ppkey = NULL;
}
return ret;
}
void
EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
{
ctx->pkey_gencb = cb;
}
EVP_PKEY_gen_cb *
EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx)
{
return ctx->pkey_gencb;
}
/* "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB
* style callbacks.
*/
static int
trans_cb(int a, int b, BN_GENCB *gcb)
{
EVP_PKEY_CTX *ctx = gcb->arg;
ctx->keygen_info[0] = a;
ctx->keygen_info[1] = b;
return ctx->pkey_gencb(ctx);
}
void
evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
{
BN_GENCB_set(cb, trans_cb, ctx);
}
int
EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
{
if (idx == -1)
return ctx->keygen_info_count;
if (idx < 0 || idx > ctx->keygen_info_count)
return 0;
return ctx->keygen_info[idx];
}
EVP_PKEY *
EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, int keylen)
{
EVP_PKEY_CTX *mac_ctx = NULL;
EVP_PKEY *mac_key = NULL;
mac_ctx = EVP_PKEY_CTX_new_id(type, e);
if (!mac_ctx)
return NULL;
if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
goto merr;
if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_SET_MAC_KEY, keylen, (void *)key) <= 0)
goto merr;
if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
goto merr;
merr:
EVP_PKEY_CTX_free(mac_ctx);
return mac_key;
}
int
EVP_PKEY_check(EVP_PKEY_CTX *ctx)
{
EVP_PKEY *pkey;
if ((pkey = ctx->pkey) == NULL) {
EVPerror(EVP_R_NO_KEY_SET);
return 0;
}
if (ctx->pmeth->check != NULL)
return ctx->pmeth->check(pkey);
if (pkey->ameth == NULL || pkey->ameth->pkey_check == NULL) {
EVPerror(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;
if ((pkey = ctx->pkey) == NULL) {
EVPerror(EVP_R_NO_KEY_SET);
return 0;
}
if (ctx->pmeth->public_check != NULL)
return ctx->pmeth->public_check(pkey);
if (pkey->ameth == NULL || pkey->ameth->pkey_public_check == NULL) {
EVPerror(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;
if ((pkey = ctx->pkey) == NULL) {
EVPerror(EVP_R_NO_KEY_SET);
return 0;
}
if (ctx->pmeth->param_check != NULL)
return ctx->pmeth->param_check(pkey);
if (pkey->ameth == NULL || pkey->ameth->pkey_param_check == NULL) {
EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
return pkey->ameth->pkey_param_check(pkey);
}

627
crypto/evp/pmeth_lib.c Normal file
View File

@@ -0,0 +1,627 @@
/* $OpenBSD: pmeth_lib.c,v 1.33 2023/07/07 19:37:54 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/opensslconf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509v3.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#include "asn1_local.h"
#include "evp_local.h"
DECLARE_STACK_OF(EVP_PKEY_METHOD)
STACK_OF(EVP_PKEY_METHOD) *pkey_app_methods = NULL;
extern const EVP_PKEY_METHOD cmac_pkey_meth;
extern const EVP_PKEY_METHOD dh_pkey_meth;
extern const EVP_PKEY_METHOD dsa_pkey_meth;
extern const EVP_PKEY_METHOD ec_pkey_meth;
extern const EVP_PKEY_METHOD ed25519_pkey_meth;
extern const EVP_PKEY_METHOD gostimit_pkey_meth;
extern const EVP_PKEY_METHOD gostr01_pkey_meth;
extern const EVP_PKEY_METHOD hkdf_pkey_meth;
extern const EVP_PKEY_METHOD hmac_pkey_meth;
extern const EVP_PKEY_METHOD rsa_pkey_meth;
extern const EVP_PKEY_METHOD rsa_pss_pkey_meth;
extern const EVP_PKEY_METHOD x25519_pkey_meth;
static const EVP_PKEY_METHOD *pkey_methods[] = {
&cmac_pkey_meth,
&dh_pkey_meth,
&dsa_pkey_meth,
&ec_pkey_meth,
&ed25519_pkey_meth,
&gostimit_pkey_meth,
&gostr01_pkey_meth,
&hkdf_pkey_meth,
&hmac_pkey_meth,
&rsa_pkey_meth,
&rsa_pss_pkey_meth,
&x25519_pkey_meth,
};
static const size_t pkey_methods_count =
sizeof(pkey_methods) / sizeof(pkey_methods[0]);
int
evp_pkey_meth_get_count(void)
{
int num = pkey_methods_count;
if (pkey_app_methods != NULL)
num += sk_EVP_PKEY_METHOD_num(pkey_app_methods);
return num;
}
const EVP_PKEY_METHOD *
evp_pkey_meth_get0(int idx)
{
int num = pkey_methods_count;
if (idx < 0)
return NULL;
if (idx < num)
return pkey_methods[idx];
idx -= num;
return sk_EVP_PKEY_METHOD_value(pkey_app_methods, idx);
}
const EVP_PKEY_METHOD *
EVP_PKEY_meth_find(int type)
{
const EVP_PKEY_METHOD *pmeth;
int i;
for (i = evp_pkey_meth_get_count() - 1; i >= 0; i--) {
pmeth = evp_pkey_meth_get0(i);
if (pmeth->pkey_id == type)
return pmeth;
}
return NULL;
}
static EVP_PKEY_CTX *
evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *engine, int id)
{
EVP_PKEY_CTX *pkey_ctx = NULL;
const EVP_PKEY_METHOD *pmeth;
if (id == -1) {
if (pkey == NULL || pkey->ameth == NULL)
return NULL;
id = pkey->ameth->pkey_id;
}
#ifndef OPENSSL_NO_ENGINE
if (pkey != NULL && pkey->engine != NULL)
engine = pkey->engine;
/* Try to find an ENGINE which implements this method. */
if (engine != NULL) {
if (!ENGINE_init(engine)) {
EVPerror(ERR_R_ENGINE_LIB);
return NULL;
}
} else
engine = ENGINE_get_pkey_meth_engine(id);
/* Look up method handler in ENGINE or use internal tables. */
if (engine != NULL)
pmeth = ENGINE_get_pkey_meth(engine, id);
else
#endif
pmeth = EVP_PKEY_meth_find(id);
if (pmeth == NULL) {
EVPerror(EVP_R_UNSUPPORTED_ALGORITHM);
goto err;
}
if ((pkey_ctx = calloc(1, sizeof(*pkey_ctx))) == NULL) {
EVPerror(ERR_R_MALLOC_FAILURE);
goto err;
}
pkey_ctx->engine = engine;
engine = NULL;
pkey_ctx->pmeth = pmeth;
pkey_ctx->operation = EVP_PKEY_OP_UNDEFINED;
if ((pkey_ctx->pkey = pkey) != NULL)
EVP_PKEY_up_ref(pkey_ctx->pkey);
if (pmeth->init != NULL) {
if (pmeth->init(pkey_ctx) <= 0)
goto err;
}
return pkey_ctx;
err:
EVP_PKEY_CTX_free(pkey_ctx);
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(engine);
#endif
return NULL;
}
EVP_PKEY_METHOD*
EVP_PKEY_meth_new(int id, int flags)
{
EVP_PKEY_METHOD *pmeth;
if ((pmeth = calloc(1, sizeof(EVP_PKEY_METHOD))) == NULL)
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)
{
EVP_PKEY_METHOD preserve;
preserve.pkey_id = dst->pkey_id;
preserve.flags = dst->flags;
*dst = *src;
dst->pkey_id = preserve.pkey_id;
dst->flags = preserve.flags;
}
void
EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
{
if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
free(pmeth);
}
EVP_PKEY_CTX *
EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *engine)
{
return evp_pkey_ctx_new(pkey, engine, -1);
}
EVP_PKEY_CTX *
EVP_PKEY_CTX_new_id(int id, ENGINE *engine)
{
return evp_pkey_ctx_new(NULL, engine, id);
}
EVP_PKEY_CTX *
EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
{
EVP_PKEY_CTX *rctx = NULL;
if (pctx->pmeth == NULL || pctx->pmeth->copy == NULL)
goto err;
#ifndef OPENSSL_NO_ENGINE
/* Make sure it's safe to copy a pkey context using an ENGINE */
if (pctx->engine != NULL && !ENGINE_init(pctx->engine)) {
EVPerror(ERR_R_ENGINE_LIB);
goto err;
}
#endif
if ((rctx = calloc(1, sizeof(*rctx))) == NULL) {
EVPerror(ERR_R_MALLOC_FAILURE);
goto err;
}
rctx->pmeth = pctx->pmeth;
#ifndef OPENSSL_NO_ENGINE
rctx->engine = pctx->engine;
#endif
if ((rctx->pkey = pctx->pkey) != NULL)
EVP_PKEY_up_ref(rctx->pkey);
if ((rctx->peerkey = pctx->peerkey) != NULL)
EVP_PKEY_up_ref(rctx->peerkey);
rctx->operation = pctx->operation;
if (pctx->pmeth->copy(rctx, pctx) <= 0)
goto err;
return rctx;
err:
EVP_PKEY_CTX_free(rctx);
return NULL;
}
int
EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
{
if (pkey_app_methods == NULL) {
pkey_app_methods = sk_EVP_PKEY_METHOD_new(NULL);
if (pkey_app_methods == NULL)
return 0;
}
if (!sk_EVP_PKEY_METHOD_push(pkey_app_methods, pmeth))
return 0;
return 1;
}
void
EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
{
if (ctx == NULL)
return;
if (ctx->pmeth && ctx->pmeth->cleanup)
ctx->pmeth->cleanup(ctx);
EVP_PKEY_free(ctx->pkey);
EVP_PKEY_free(ctx->peerkey);
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(ctx->engine);
#endif
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) {
EVPerror(EVP_R_COMMAND_NOT_SUPPORTED);
return -2;
}
if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
return -1;
if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
EVPerror(EVP_R_NO_OPERATION_SET);
return -1;
}
if ((optype != -1) && !(ctx->operation & optype)) {
EVPerror(EVP_R_INVALID_OPERATION);
return -1;
}
ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
if (ret == -2)
EVPerror(EVP_R_COMMAND_NOT_SUPPORTED);
return ret;
}
int
EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *name, const char *value)
{
if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
EVPerror(EVP_R_COMMAND_NOT_SUPPORTED);
return -2;
}
if (!strcmp(name, "digest")) {
return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_MD, value);
}
return ctx->pmeth->ctrl_str(ctx, name, value);
}
int
EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str)
{
size_t len;
if ((len = strlen(str)) > 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 *hexstr)
{
unsigned char *hex = NULL;
long length;
int ret = 0;
if ((hex = string_to_hex(hexstr, &length)) == NULL)
goto err;
if (length < 0 || length > INT_MAX) {
ret = -1;
goto err;
}
ret = ctx->pmeth->ctrl(ctx, cmd, length, hex);
err:
free(hex);
return ret;
}
int
EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md_name)
{
const EVP_MD *md;
if ((md = EVP_get_digestbyname(md_name)) == NULL) {
EVPerror(EVP_R_INVALID_DIGEST);
return 0;
}
return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, 0, (void *)md);
}
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 (*public_check)(EVP_PKEY *pkey))
{
pmeth->public_check = public_check;
}
void
EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth,
int (*param_check)(EVP_PKEY *pkey))
{
pmeth->param_check = param_check;
}