sync with OpenBSD -current

This commit is contained in:
purplerain 2023-12-21 17:12:07 +00:00
parent 659ea2942e
commit 0f27a61c5c
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
131 changed files with 2461 additions and 5218 deletions

View file

@ -1,4 +1,4 @@
/* $OpenBSD: malloc.c,v 1.294 2023/12/04 07:01:45 otto Exp $ */
/* $OpenBSD: malloc.c,v 1.295 2023/12/19 06:59:28 otto Exp $ */
/*
* Copyright (c) 2008, 2010, 2011, 2016, 2023 Otto Moerbeek <otto@drijf.net>
* Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
@ -288,6 +288,7 @@ caller(struct dir_info *d)
{
struct btnode p;
int level = DO_STATS;
if (level == 0)
return NULL;
@ -1165,8 +1166,7 @@ fill_canary(char *ptr, size_t sz, size_t allocated)
static void *
malloc_bytes(struct dir_info *d, size_t size)
{
u_int i, k, r, bucket, listnum;
int j;
u_int i, j, k, r, bucket, listnum;
u_short *lp;
struct chunk_info *bp;
void *p;
@ -1177,7 +1177,7 @@ malloc_bytes(struct dir_info *d, size_t size)
bucket = find_bucket(size);
r = ((u_int)getrbyte(d) << 8) | getrbyte(d);
r = getrbyte(d);
listnum = r % MALLOC_CHUNK_LISTS;
/* If it's empty, make a page more of that size chunks */
@ -1190,39 +1190,39 @@ malloc_bytes(struct dir_info *d, size_t size)
if (bp->canary != (u_short)d->canary1 || bucket != bp->bucket)
wrterror(d, "chunk info corrupted");
r /= MALLOC_CHUNK_LISTS;
/* do we need more random bits? */
if (bp->total > 256 / MALLOC_CHUNK_LISTS)
r = r << 8 | getrbyte(d);
/* bias, as bp->total is not a power of 2 */
i = (r / MALLOC_CHUNK_LISTS) % bp->total;
i = r % bp->total;
/* potentially start somewhere in a short */
lp = &bp->bits[i / MALLOC_BITS];
j = i % MALLOC_BITS; /* j must be signed */
if (*lp >> j) {
k = ffs(*lp >> j);
if (k != 0) {
k += j - 1;
goto found;
}
}
/* no bit halfway, go to next full short */
j = i % MALLOC_BITS;
i /= MALLOC_BITS;
for (;;) {
if (++i >= bp->offset)
i = 0;
lp = &bp->bits[i];
if (*lp) {
k = ffs(*lp) - 1;
break;
lp = &bp->bits[i];
/* potentially start somewhere in a short */
if (j > 0 && *lp >> j)
k = ffs(*lp >> j) + j;
else {
/* no bit halfway, go to next full short */
for (;;) {
if (*lp) {
k = ffs(*lp);
break;
}
if (++i >= bp->offset)
i = 0;
lp = &bp->bits[i];
}
}
found:
*lp ^= 1 << k;
*lp ^= 1 << --k;
/* If there are no more free, remove from free-list */
if (--bp->free == 0)
LIST_REMOVE(bp, entries);
/* Adjust to the real offset of that chunk */
k += (lp - bp->bits) * MALLOC_BITS;
k += i * MALLOC_BITS;
if (mopts.chunk_canaries && size > 0)
bp->bits[bp->offset + k] = size;
@ -1232,9 +1232,7 @@ found:
STATS_SETFN(r, k, d->caller);
}
k *= B2ALLOC(bucket);
p = (char *)bp->page + k;
p = (char *)bp->page + k * B2ALLOC(bucket);
if (bucket > 0) {
validate_junk(d, p, B2SIZE(bucket));
if (mopts.chunk_canaries)

View file

@ -1,4 +1,4 @@
.\" $OpenBSD: pinsyscalls.2,v 1.1 2023/12/11 00:34:24 deraadt Exp $
.\" $OpenBSD: pinsyscalls.2,v 1.4 2023/12/19 19:39:52 deraadt Exp $
.\"
.\" Copyright (c) 2023 Theo de Raadt <deraadt@openbsd.org>
.\"
@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: December 11 2023 $
.Dd $Mdocdate: December 19 2023 $
.Dt PINSYSCALLS 2
.Os
.Sh NAME
@ -23,7 +23,7 @@
.Sh SYNOPSIS
.In sys/types.h
.Ft int
.Fn pinsyscalls "void *start" "size_t len" "uint *pintable" "size_t pintablesize"
.Fn pinsyscalls "void *start" "size_t len" "u_int *pintable" "int npins"
.Sh DESCRIPTION
The
.Fn pinsyscalls
@ -31,17 +31,24 @@ system call specifies the
.Va start
to
.Va start + len
range in the address space where the system call entry instructions are found,
and furthermore provides a table of uint offsets from that
.Va start
(indexed by the system call number) to
provide the precise location for the system call instruction required
for that system call number.
address space range where the system call entry instructions are found,
and a
.Va npins Ns
-sized array of u_int entries (indexed by the system call number)
which are offsets from the
.Va start .
.Pp
This provides the precise location for the system call instruction
required for each system call number.
Attempting to use a different system call entry instruction to perform
a non-corresponding system call operation will fail with signal
.Dv SIGABRT .
.Pp
.Fn pinsyscalls
is only called by the shared library linker
.Xr ld.so 1
to tell the kernel where system calls are found in the dynamic library
to tell the kernel where the text / executable region containing
system calls is found in the dynamic library
.Pa libc.so
(the filename is actually /usr/lib/libc.so.major.minor).
.Pp
@ -49,25 +56,22 @@ A similar setup operation is done automatically by the kernel for
the system calls found in
.Xr ld.so 1
and in static executables.
.Pp
Once the kernel knows the specific location in the address space where
a specific system call must be entered from, any attempt to use a different
system call entry instruction to perform a non-corresponding system call
operation will fail with signal
.Dv SIGABRT .
.Sh RETURN VALUES
.Rv -std
.Sh ERRORS
.Fn pinsyscalls
will fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
Process already has a system call pinning table loaded.
.It Bq Er E2BIG
Implausible number of system calls provided.
.It Bq Er ENOMEM
Insufficient memory to service the request.
.It Bq Er EPERM
A static binary tried to call
.Fn pinsyscalls .
.Fn pinsyscalls , or it was called a second time.
.It Bq Er ERANGE
At least one system call offset is out of bounds.
At least one system call offset is beyond the bounds of
.Ar len .
.El
.Sh HISTORY
The

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.156 2023/11/12 10:49:27 robert Exp $
# $OpenBSD: Makefile,v 1.159 2023/12/20 13:52:17 tb Exp $
LIB= crypto
LIBREBUILD=y
@ -284,7 +284,6 @@ SRCS+= ofb64enc.c
SRCS+= ofb_enc.c
SRCS+= pcbc_enc.c
SRCS+= qud_cksm.c
SRCS+= rand_key.c
SRCS+= set_key.c
SRCS+= str2key.c
SRCS+= xcbc_enc.c
@ -393,11 +392,8 @@ SRCS+= m_wp.c
SRCS+= names.c
SRCS+= p5_crpt.c
SRCS+= p5_crpt2.c
SRCS+= p_dec.c
SRCS+= p_enc.c
SRCS+= p_legacy.c
SRCS+= p_lib.c
SRCS+= p_open.c
SRCS+= p_seal.c
SRCS+= p_sign.c
SRCS+= p_verify.c
SRCS+= pmeth_fn.c

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tasn_prn.c,v 1.25 2023/07/05 21:23:36 beck Exp $ */
/* $OpenBSD: tasn_prn.c,v 1.26 2023/12/20 14:26:47 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@ -395,15 +395,9 @@ static int
asn1_print_fsname(BIO *out, int indent, const char *fname, const char *sname,
const ASN1_PCTX *pctx)
{
static char spaces[] = " ";
const int nspaces = sizeof(spaces) - 1;
while (indent > nspaces) {
if (BIO_write(out, spaces, nspaces) != nspaces)
return 0;
indent -= nspaces;
}
if (BIO_write(out, spaces, indent) != indent)
if (indent < 0)
return 0;
if (!BIO_indent(out, indent, indent))
return 0;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
sname = NULL;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: cms_pwri.c,v 1.29 2023/07/08 08:26:26 beck Exp $ */
/* $OpenBSD: cms_pwri.c,v 1.30 2023/12/20 18:38:19 tb Exp $ */
/*
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
@ -52,18 +52,20 @@
* ====================================================================
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/cms.h>
#include <openssl/rand.h>
#include <openssl/aes.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "cms_local.h"
#include "asn1/asn1_local.h"
#include "evp_local.h"
int
CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, unsigned char *pass,

View file

@ -1,68 +0,0 @@
/* $OpenBSD: rand_key.c,v 1.9 2023/07/08 07:11:07 beck Exp $ */
/* ====================================================================
* Copyright (c) 1998-2000 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 <stdlib.h>
#include <openssl/des.h>
int
DES_random_key(DES_cblock *ret)
{
do {
arc4random_buf(ret, sizeof(DES_cblock));
DES_set_odd_parity(ret);
} while (DES_is_weak_key(ret));
return (1);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: set_key.c,v 1.23 2023/07/08 07:34:34 jsing Exp $ */
/* $OpenBSD: set_key.c,v 1.26 2023/12/20 06:30:04 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -56,14 +56,10 @@
* [including the GNU Public Licence.]
*/
/* set_key.c v 1.4 eay 24/9/91
* 1.4 Speed up by 400% :-)
* 1.3 added register declarations.
* 1.2 unrolled make_key_sched a bit more
* 1.1 added norm_expand_bits
* 1.0 First working version
*/
#include <stdlib.h>
#include <openssl/crypto.h>
#include "des_local.h"
int DES_check_key = 0; /* defaults to false */
@ -398,10 +394,13 @@ DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule)
{
return (DES_set_key(key, schedule));
}
/*
#undef des_fixup_key_parity
void des_fixup_key_parity(des_cblock *key)
{
des_set_odd_parity(key);
}
*/
int
DES_random_key(DES_cblock *ret)
{
do {
arc4random_buf(ret, sizeof(DES_cblock));
DES_set_odd_parity(ret);
} while (DES_is_weak_key(ret));
return (1);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: cipher_method_lib.c,v 1.10 2023/07/07 19:37:53 beck Exp $ */
/* $OpenBSD: cipher_method_lib.c,v 1.11 2023/12/20 14:05:58 tb Exp $ */
/*
* Written by Richard Levitte (levitte@openssl.org) for the OpenSSL project
* 2015.
@ -68,6 +68,13 @@ EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len)
{
EVP_CIPHER *cipher;
if (cipher_type < 0 || key_len < 0)
return NULL;
/* EVP_CipherInit() will fail for any other value. */
if (block_size != 1 && block_size != 8 && block_size != 16)
return NULL;
if ((cipher = calloc(1, sizeof(*cipher))) == NULL)
return NULL;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: evp_enc.c,v 1.63 2023/12/16 17:40:22 tb Exp $ */
/* $OpenBSD: evp_enc.c,v 1.73 2023/12/20 14:15:19 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -78,7 +78,7 @@ EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
}
int
EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *engine,
const unsigned char *key, const unsigned char *iv, int enc)
{
if (enc == -1)
@ -122,7 +122,8 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
EVPerror(EVP_R_NO_CIPHER_SET);
return 0;
}
/* we assume block size is a power of 2 in *cryptUpdate */
/* Block sizes must be a power of 2 due to the use of block_mask. */
if (ctx->cipher->block_size != 1 &&
ctx->cipher->block_size != 8 &&
ctx->cipher->block_size != 16) {
@ -184,38 +185,39 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
if (!ctx->cipher->init(ctx, key, iv, enc))
return 0;
}
ctx->buf_len = 0;
ctx->partial_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)
EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len,
const unsigned char *in, int in_len)
{
if (ctx->encrypt)
return EVP_EncryptUpdate(ctx, out, outl, in, inl);
return EVP_EncryptUpdate(ctx, out, out_len, in, in_len);
return EVP_DecryptUpdate(ctx, out, outl, in, inl);
return EVP_DecryptUpdate(ctx, out, out_len, in, in_len);
}
int
EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len)
{
if (ctx->encrypt)
return EVP_EncryptFinal_ex(ctx, out, outl);
return EVP_EncryptFinal_ex(ctx, out, out_len);
return EVP_DecryptFinal_ex(ctx, out, outl);
return EVP_DecryptFinal_ex(ctx, out, out_len);
}
int
EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len)
{
if (ctx->encrypt)
return EVP_EncryptFinal_ex(ctx, out, outl);
return EVP_EncryptFinal_ex(ctx, out, out_len);
return EVP_DecryptFinal_ex(ctx, out, outl);
return EVP_DecryptFinal_ex(ctx, out, out_len);
}
int
@ -226,7 +228,7 @@ EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
}
int
EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *engine,
const unsigned char *key, const unsigned char *iv)
{
return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1);
@ -240,7 +242,7 @@ EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
}
int
EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *engine,
const unsigned char *key, const unsigned char *iv)
{
return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0);
@ -260,9 +262,9 @@ EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
*/
int
EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
unsigned int inl)
unsigned int in_len)
{
return ctx->cipher->do_cipher(ctx, out, in, inl);
return ctx->cipher->do_cipher(ctx, out, in, in_len);
}
static int
@ -293,245 +295,254 @@ evp_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len,
}
int
EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
const unsigned char *in, int inl)
EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len,
const unsigned char *in, int in_len)
{
const int block_size = ctx->cipher->block_size;
const int block_mask = ctx->block_mask;
int buf_offset = ctx->buf_len;
const int block_mask = block_size - 1;
int partial_len = ctx->partial_len;
int len = 0, total_len = 0;
*outl = 0;
*out_len = 0;
if (inl < 0)
if ((block_size & block_mask) != 0)
return 0;
if (inl == 0 && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE)
if (in_len < 0)
return 0;
if (in_len == 0 && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE)
return 1;
if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0)
return evp_cipher(ctx, out, outl, in, inl);
return evp_cipher(ctx, out, out_len, in, in_len);
if (buf_offset == 0 && (inl & block_mask) == 0)
return evp_cipher(ctx, out, outl, in, inl);
if (partial_len == 0 && (in_len & block_mask) == 0)
return evp_cipher(ctx, out, out_len, in, in_len);
/* XXX - check that block_size > buf_offset. */
/* XXX - check that block_size > partial_len. */
if (block_size > sizeof(ctx->buf)) {
EVPerror(EVP_R_BAD_BLOCK_LENGTH);
return 0;
}
if (buf_offset != 0) {
int buf_avail;
if (partial_len != 0) {
int partial_needed;
if ((buf_avail = block_size - buf_offset) > inl) {
memcpy(&ctx->buf[buf_offset], in, inl);
ctx->buf_len += inl;
if ((partial_needed = block_size - partial_len) > in_len) {
memcpy(&ctx->buf[partial_len], in, in_len);
ctx->partial_len += in_len;
return 1;
}
/*
* Once the first buf_avail bytes from in are processed, the
* amount of data left that is a multiple of the block length is
* (inl - buf_avail) & ~block_mask. Ensure that this plus the
* block processed from ctx->buf doesn't overflow.
* Once the first partial_needed bytes from in are processed,
* the number of multiples of block_size of data remaining is
* (in_len - partial_needed) & ~block_mask. Ensure that this
* plus the block processed from ctx->buf doesn't overflow.
*/
if (((inl - buf_avail) & ~block_mask) > INT_MAX - block_size) {
if (((in_len - partial_needed) & ~block_mask) > INT_MAX - block_size) {
EVPerror(EVP_R_TOO_LARGE);
return 0;
}
memcpy(&ctx->buf[buf_offset], in, buf_avail);
memcpy(&ctx->buf[partial_len], in, partial_needed);
len = 0;
if (!evp_cipher(ctx, out, &len, ctx->buf, block_size))
return 0;
total_len = len;
inl -= buf_avail;
in += buf_avail;
in_len -= partial_needed;
in += partial_needed;
out += len;
}
buf_offset = inl & block_mask;
if ((inl -= buf_offset) > 0) {
if (INT_MAX - inl < total_len)
partial_len = in_len & block_mask;
if ((in_len -= partial_len) > 0) {
if (INT_MAX - in_len < total_len)
return 0;
len = 0;
if (!evp_cipher(ctx, out, &len, in, inl))
if (!evp_cipher(ctx, out, &len, in, in_len))
return 0;
if (INT_MAX - len < total_len)
return 0;
total_len += len;
}
if (buf_offset != 0)
memcpy(ctx->buf, &in[inl], buf_offset);
ctx->buf_len = buf_offset;
if (partial_len != 0)
memcpy(ctx->buf, &in[in_len], partial_len);
ctx->partial_len = partial_len;
*outl = total_len;
*out_len = total_len;
return 1;
}
int
EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len)
{
return EVP_EncryptFinal_ex(ctx, out, outl);
return EVP_EncryptFinal_ex(ctx, out, out_len);
}
int
EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len)
{
int n;
unsigned int i, b, bl;
const int block_size = ctx->cipher->block_size;
int partial_len = ctx->partial_len;
int pad;
*outl = 0;
*out_len = 0;
if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0)
return evp_cipher(ctx, out, outl, NULL, 0);
return evp_cipher(ctx, out, out_len, NULL, 0);
b = ctx->cipher->block_size;
if (b > sizeof ctx->buf) {
/* XXX - check that block_size > partial_len. */
if (block_size > sizeof(ctx->buf)) {
EVPerror(EVP_R_BAD_BLOCK_LENGTH);
return 0;
}
if (b == 1) {
*outl = 0;
if (block_size == 1)
return 1;
}
bl = ctx->buf_len;
if (ctx->flags & EVP_CIPH_NO_PADDING) {
if (bl) {
if ((ctx->flags & EVP_CIPH_NO_PADDING) != 0) {
if (partial_len != 0) {
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;
pad = block_size - partial_len;
memset(&ctx->buf[partial_len], pad, pad);
return evp_cipher(ctx, out, outl, ctx->buf, b);
return evp_cipher(ctx, out, out_len, ctx->buf, block_size);
}
int
EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
const unsigned char *in, int inl)
EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len,
const unsigned char *in, int in_len)
{
int fix_len;
unsigned int b;
const int block_size = ctx->cipher->block_size;
const int block_mask = block_size - 1;
int len = 0, total_len = 0;
*outl = 0;
*out_len = 0;
if (inl < 0)
if ((block_size & block_mask) != 0)
return 0;
if (inl == 0 && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE)
if (in_len < 0)
return 0;
if (in_len == 0 && EVP_CIPHER_mode(ctx->cipher) != EVP_CIPH_CCM_MODE)
return 1;
if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0)
return evp_cipher(ctx, out, outl, in, inl);
return evp_cipher(ctx, out, out_len, in, in_len);
if (ctx->flags & EVP_CIPH_NO_PADDING)
return EVP_EncryptUpdate(ctx, out, outl, in, inl);
if ((ctx->flags & EVP_CIPH_NO_PADDING) != 0)
return EVP_EncryptUpdate(ctx, out, out_len, in, in_len);
b = ctx->cipher->block_size;
if (b > sizeof ctx->final) {
if (block_size > 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.
* final_used is only set if partial_len is 0. Therefore the
* output from EVP_EncryptUpdate() is in_len & ~block_mask.
* Ensure (in_len & ~block_mask) + block_size doesn't overflow.
*/
if ((inl & ~(b - 1)) > INT_MAX - b) {
if ((in_len & ~block_mask) > INT_MAX - block_size) {
EVPerror(EVP_R_TOO_LARGE);
return 0;
}
memcpy(out, ctx->final, b);
out += b;
fix_len = 1;
} else
fix_len = 0;
memcpy(out, ctx->final, block_size);
out += block_size;
total_len = block_size;
}
ctx->final_used = 0;
if (!EVP_EncryptUpdate(ctx, out, outl, in, inl))
len = 0;
if (!EVP_EncryptUpdate(ctx, out, &len, in, in_len))
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;
/* Keep copy of last block if a multiple of block_size was decrypted. */
if (block_size > 1 && ctx->partial_len == 0) {
if (len < block_size)
return 0;
len -= block_size;
memcpy(ctx->final, &out[len], block_size);
ctx->final_used = 1;
memcpy(ctx->final, &out[*outl], b);
} else
ctx->final_used = 0;
}
if (fix_len)
*outl += b;
if (len > INT_MAX - total_len)
return 0;
total_len += len;
*out_len = total_len;
return 1;
}
int
EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len)
{
return EVP_DecryptFinal_ex(ctx, out, outl);
return EVP_DecryptFinal_ex(ctx, out, out_len);
}
int
EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len)
{
int i, n;
unsigned int b;
const int block_size = ctx->cipher->block_size;
int partial_len = ctx->partial_len;
int i, pad, plain_len;
*outl = 0;
*out_len = 0;
if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0)
return evp_cipher(ctx, out, outl, NULL, 0);
return evp_cipher(ctx, out, out_len, NULL, 0);
b = ctx->cipher->block_size;
if (ctx->flags & EVP_CIPH_NO_PADDING) {
if (ctx->buf_len) {
if ((ctx->flags & EVP_CIPH_NO_PADDING) != 0) {
if (partial_len != 0) {
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);
if (block_size == 1)
return 1;
if (partial_len != 0 || !ctx->final_used) {
EVPerror(EVP_R_WRONG_FINAL_BLOCK_LENGTH);
return 0;
}
if (block_size > sizeof(ctx->final)) {
EVPerror(EVP_R_BAD_BLOCK_LENGTH);
return 0;
}
pad = ctx->final[block_size - 1];
if (pad <= 0 || pad > block_size) {
EVPerror(EVP_R_BAD_DECRYPT);
return 0;
}
plain_len = block_size - pad;
for (i = plain_len; i < block_size; i++) {
if (ctx->final[i] != pad) {
EVPerror(EVP_R_BAD_DECRYPT);
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);
}
memcpy(out, ctx->final, plain_len);
*out_len = plain_len;
return 1;
}
EVP_CIPHER_CTX *

View file

@ -1,4 +1,4 @@
/* $OpenBSD: evp_local.h,v 1.6 2023/11/29 21:35:57 tb Exp $ */
/* $OpenBSD: evp_local.h,v 1.8 2023/12/20 14:10:03 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@ -168,7 +168,7 @@ struct evp_cipher_st {
struct evp_cipher_ctx_st {
const EVP_CIPHER *cipher;
int encrypt; /* encrypt or decrypt */
int buf_len; /* number we have left */
int partial_len; /* number of bytes written to buf */
unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */
unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */
@ -180,7 +180,6 @@ struct evp_cipher_ctx_st {
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 */;

View file

@ -1,94 +0,0 @@
/* $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);
}

View file

@ -1,91 +0,0 @@
/* $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);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: p_open.c,v 1.23 2023/07/07 19:37:54 beck Exp $ */
/* $OpenBSD: p_legacy.c,v 1.2 2023/12/20 13:52:17 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -56,21 +56,41 @@
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#include "evp_local.h"
int
EVP_PKEY_decrypt_old(unsigned char *to, const unsigned char *from, int from_len,
EVP_PKEY *pkey)
{
if (pkey->type != EVP_PKEY_RSA) {
EVPerror(EVP_R_PUBLIC_KEY_NOT_RSA);
return -1;
}
return RSA_private_decrypt(from_len, from, to, pkey->pkey.rsa,
RSA_PKCS1_PADDING);
}
int
EVP_PKEY_encrypt_old(unsigned char *to, const unsigned char *from, int from_len,
EVP_PKEY *pkey)
{
if (pkey->type != EVP_PKEY_RSA) {
EVPerror(EVP_R_PUBLIC_KEY_NOT_RSA);
return 0;
}
return RSA_public_encrypt(from_len, from, to, pkey->pkey.rsa,
RSA_PKCS1_PADDING);
}
int
EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
const unsigned char *ek, int ekl, const unsigned char *iv, EVP_PKEY *priv)
@ -125,4 +145,48 @@ EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
i = EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL);
return (i);
}
#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, iv_len;
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;
/* XXX - upper bound? */
if ((iv_len = EVP_CIPHER_CTX_iv_length(ctx)) < 0)
return 0;
if (iv_len > 0)
arc4random_buf(iv, iv_len);
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);
}
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;
}

View file

@ -1,127 +0,0 @@
/* $OpenBSD: p_seal.c,v 1.17 2023/11/18 09:37:15 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 <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, iv_len;
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;
/* XXX - upper bound? */
if ((iv_len = EVP_CIPHER_CTX_iv_length(ctx)) < 0)
return 0;
if (iv_len > 0)
arc4random_buf(iv, iv_len);
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;
}