Latest update (add quic)
This commit is contained in:
@@ -18,11 +18,6 @@
|
||||
#include <openssl/aes.h>
|
||||
#include "aes_local.h"
|
||||
|
||||
#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
|
||||
typedef struct {
|
||||
unsigned long data[N_WORDS];
|
||||
} aes_block_t;
|
||||
|
||||
/* XXX: probably some better way to do this */
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
# define UNALIGNED_MEMOPS_ARE_FAST 1
|
||||
@@ -30,6 +25,15 @@ typedef struct {
|
||||
# define UNALIGNED_MEMOPS_ARE_FAST 0
|
||||
#endif
|
||||
|
||||
#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
|
||||
typedef struct {
|
||||
unsigned long data[N_WORDS];
|
||||
#if defined(__GNUC__) && UNALIGNED_MEMOPS_ARE_FAST
|
||||
} aes_block_t __attribute((__aligned__(1)));
|
||||
#else
|
||||
} aes_block_t;
|
||||
#endif
|
||||
|
||||
#if UNALIGNED_MEMOPS_ARE_FAST
|
||||
# define load_block(d, s) (d) = *(const aes_block_t *)(s)
|
||||
# define store_block(d, s) *(aes_block_t *)(d) = (s)
|
||||
|
||||
@@ -277,7 +277,7 @@ void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
|
||||
|
||||
void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
int (*pub_decode) (EVP_PKEY *pk,
|
||||
X509_PUBKEY *pub),
|
||||
const X509_PUBKEY *pub),
|
||||
int (*pub_encode) (X509_PUBKEY *pub,
|
||||
const EVP_PKEY *pk),
|
||||
int (*pub_cmp) (const EVP_PKEY *a,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -635,7 +635,11 @@ fmtfp(char **sbuffer,
|
||||
fvalue = tmpvalue;
|
||||
}
|
||||
ufvalue = abs_val(fvalue);
|
||||
if (ufvalue > ULONG_MAX) {
|
||||
/*
|
||||
* By subtracting 65535 (2^16-1) we cancel the low order 15 bits
|
||||
* of ULONG_MAX to avoid using imprecise floating point values.
|
||||
*/
|
||||
if (ufvalue >= (double)(ULONG_MAX - 65535) + 65536.0) {
|
||||
/* Number too big */
|
||||
return 0;
|
||||
}
|
||||
|
||||
+2
-34
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "bio_local.h"
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
# define SOCKET_PROTOCOL IPPROTO_TCP
|
||||
@@ -23,13 +24,6 @@
|
||||
static int wsa_init_done = 0;
|
||||
# endif
|
||||
|
||||
# ifndef _WIN32
|
||||
# include <unistd.h>
|
||||
# include <sys/select.h>
|
||||
# else
|
||||
# include <winsock.h> /* for type fd_set */
|
||||
# endif
|
||||
|
||||
# ifndef OPENSSL_NO_DEPRECATED_1_1_0
|
||||
int BIO_get_host_ip(const char *str, unsigned char *ip)
|
||||
{
|
||||
@@ -375,30 +369,4 @@ int BIO_sock_info(int sock,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* TODO simplify by BIO_socket_wait() further other uses of select() in apps/ */
|
||||
/*
|
||||
* Wait on fd at most until max_time; succeed immediately if max_time == 0.
|
||||
* If for_read == 0 then assume to wait for writing, else wait for reading.
|
||||
* Returns -1 on error, 0 on timeout, and 1 on success.
|
||||
*/
|
||||
int BIO_socket_wait(int fd, int for_read, time_t max_time)
|
||||
{
|
||||
fd_set confds;
|
||||
struct timeval tv;
|
||||
time_t now;
|
||||
|
||||
if (max_time == 0)
|
||||
return 1;
|
||||
|
||||
now = time(NULL);
|
||||
if (max_time <= now)
|
||||
return 0;
|
||||
|
||||
FD_ZERO(&confds);
|
||||
openssl_fdset(fd, &confds);
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = (long)(max_time - now); /* might overflow */
|
||||
return select(fd + 1, for_read ? &confds : NULL,
|
||||
for_read ? NULL : &confds, NULL, &tv);
|
||||
}
|
||||
#endif /* !defined(OPENSSL_NO_SOCK) */
|
||||
#endif
|
||||
@@ -22,7 +22,6 @@ static const ERR_STRING_DATA BIO_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BAD_FOPEN_MODE), "bad fopen mode"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BROKEN_PIPE), "broken pipe"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_ERROR), "connect error"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_TIMEOUT), "connect timeout"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET),
|
||||
"gethostbyname addr is not af inet"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETSOCKNAME_ERROR), "getsockname error"},
|
||||
@@ -46,8 +45,6 @@ static const ERR_STRING_DATA BIO_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_PORT_DEFINED), "no port defined"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_SUCH_FILE), "no such file"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NULL_PARAMETER), "null parameter"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_ERROR), "transfer error"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_TIMEOUT), "transfer timeout"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_BIND_SOCKET),
|
||||
"unable to bind socket"},
|
||||
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_CREATE_SOCKET),
|
||||
|
||||
@@ -784,102 +784,3 @@ void bio_cleanup(void)
|
||||
CRYPTO_THREAD_lock_free(bio_type_lock);
|
||||
bio_type_lock = NULL;
|
||||
}
|
||||
|
||||
/* Internal variant of the below BIO_wait() not calling BIOerr() */
|
||||
static int bio_wait(BIO *bio, time_t max_time, unsigned int milliseconds)
|
||||
{
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
int fd;
|
||||
#endif
|
||||
|
||||
if (max_time == 0)
|
||||
return 1;
|
||||
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
if (BIO_get_fd(bio, &fd) > 0)
|
||||
return BIO_socket_wait(fd, BIO_should_read(bio), max_time);
|
||||
#endif
|
||||
if (milliseconds > 1000) {
|
||||
long sec_diff = (long)(max_time - time(NULL)); /* might overflow */
|
||||
|
||||
if (sec_diff <= 0)
|
||||
return 0; /* timeout */
|
||||
if ((unsigned long)sec_diff < milliseconds / 1000)
|
||||
milliseconds = (unsigned long)sec_diff * 1000;
|
||||
}
|
||||
ossl_sleep(milliseconds);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait on (typically socket-based) BIO at most until max_time.
|
||||
* Succeed immediately if max_time == 0. If sockets are not available succeed
|
||||
* after waiting at most given milliseconds in order to avoid a tight busy loop.
|
||||
* Call BIOerr(...) unless success.
|
||||
* Returns -1 on error, 0 on timeout, and 1 on success.
|
||||
*/
|
||||
int BIO_wait(BIO *bio, time_t max_time, unsigned int milliseconds)
|
||||
{
|
||||
int rv = bio_wait(bio, max_time, milliseconds);
|
||||
|
||||
if (rv <= 0)
|
||||
BIOerr(0, rv == 0 ? BIO_R_TRANSFER_TIMEOUT : BIO_R_TRANSFER_ERROR);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect via given BIO using BIO_do_handshake() until success/timeout/error.
|
||||
* Parameter timeout == 0 means infinite, < 0 leads to immediate timeout error.
|
||||
* Returns -1 on error, 0 on timeout, and 1 on success.
|
||||
*/
|
||||
int BIO_connect_retry(BIO *bio, int timeout)
|
||||
{
|
||||
int blocking = timeout == 0;
|
||||
time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
|
||||
int rv;
|
||||
|
||||
if (bio == NULL) {
|
||||
BIOerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (timeout < 0) {
|
||||
BIOerr(0, BIO_R_CONNECT_TIMEOUT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!blocking)
|
||||
BIO_set_nbio(bio, 1);
|
||||
|
||||
retry: /* it does not help here to set SSL_MODE_AUTO_RETRY */
|
||||
rv = BIO_do_handshake(bio); /* This indirectly calls ERR_clear_error(); */
|
||||
|
||||
if (rv <= 0) {
|
||||
if (get_last_sys_error() == ETIMEDOUT) {
|
||||
/*
|
||||
* if blocking, despite blocking BIO, BIO_do_handshake() timed out
|
||||
* when non-blocking, BIO_do_handshake() timed out early
|
||||
* with rv == -1 and get_last_sys_error() == 0
|
||||
*/
|
||||
ERR_clear_error();
|
||||
(void)BIO_reset(bio);
|
||||
/*
|
||||
* unless using BIO_reset(), blocking next connect() may crash and
|
||||
* non-blocking next BIO_do_handshake() will fail
|
||||
*/
|
||||
goto retry;
|
||||
} else if (BIO_should_retry(bio)) {
|
||||
/* will not actually wait if timeout == 0 (i.e., blocking BIO) */
|
||||
rv = bio_wait(bio, max_time, 100 /* milliseconds */);
|
||||
if (rv > 0)
|
||||
goto retry;
|
||||
BIOerr(0, rv == 0 ? BIO_R_CONNECT_TIMEOUT : BIO_R_CONNECT_ERROR);
|
||||
} else {
|
||||
rv = -1;
|
||||
if (ERR_peek_error() == 0) /* missing error queue entry */
|
||||
BIOerr(0, BIO_R_CONNECT_ERROR); /* workaround: general error */
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
+10
-1
@@ -188,8 +188,17 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
|
||||
|
||||
case BIO_CONN_S_BLOCKED_CONNECT:
|
||||
i = BIO_sock_error(b->num);
|
||||
if (i) {
|
||||
if (i != 0) {
|
||||
BIO_clear_retry_flags(b);
|
||||
if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter)) != NULL) {
|
||||
/*
|
||||
* if there are more addresses to try, do that first
|
||||
*/
|
||||
BIO_closesocket(b->num);
|
||||
c->state = BIO_CONN_S_CREATE_SOCKET;
|
||||
ERR_clear_error();
|
||||
break;
|
||||
}
|
||||
ERR_raise_data(ERR_LIB_SYS, i,
|
||||
"calling connect(%s, %s)",
|
||||
c->param_hostname, c->param_service);
|
||||
|
||||
@@ -154,10 +154,11 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
long ret = 1;
|
||||
int *ip;
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
size_t crypto_info_len;
|
||||
# ifdef __FreeBSD__
|
||||
struct tls_enable *crypto_info;
|
||||
# else
|
||||
struct tls12_crypto_info_aes_gcm_128 *crypto_info;
|
||||
struct tls_crypto_info_all *crypto_info;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
@@ -191,10 +192,12 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
case BIO_CTRL_SET_KTLS:
|
||||
# ifdef __FreeBSD__
|
||||
crypto_info = (struct tls_enable *)ptr;
|
||||
crypto_info_len = sizeof(*crypto_info);
|
||||
# else
|
||||
crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr;
|
||||
crypto_info = (struct tls_crypto_info_all *)ptr;
|
||||
crypto_info_len = crypto_info->tls_crypto_info_len;
|
||||
# endif
|
||||
ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num);
|
||||
ret = ktls_start(b->num, crypto_info, crypto_info_len, num);
|
||||
if (ret)
|
||||
BIO_set_ktls_flag(b, num);
|
||||
break;
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
* The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }
|
||||
*
|
||||
* RFC3526 specifies a generator of 2.
|
||||
* RFC2312 specifies a generator of 22.
|
||||
* RFC2412 specifies a generator of 22.
|
||||
*/
|
||||
static const BN_ULONG modp_1536_p[] = {
|
||||
BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0xCA237327, 0xF1746C08),
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -45,7 +45,7 @@ BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain)
|
||||
int neg = 0;
|
||||
BIGNUM *a = NULL;
|
||||
|
||||
if (n < 4) {
|
||||
if (n < 4 || (d[0] & 0x80) != 0) {
|
||||
BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 conf \
|
||||
md2 md4 md5 sha mdc2 hmac ripemd whrlpool poly1305 \
|
||||
siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \
|
||||
seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \
|
||||
err comp http ocsp cms ts srp cmac ct async ess crmf cmp serializer \
|
||||
err comp ocsp cms ts srp cmac ct async ess crmf cmp serializer \
|
||||
ffc
|
||||
|
||||
LIBS=../libcrypto
|
||||
|
||||
@@ -2,7 +2,7 @@ LIBS=../../libcrypto
|
||||
|
||||
$CASTASM=c_enc.c
|
||||
# CAST assembly source is not PIC
|
||||
IF[{- !$disabled{asm} && !$disabled{pic} -}]
|
||||
IF[{- !$disabled{asm} && $disabled{pic} -}]
|
||||
$CASTASM_x86=cast-586.s
|
||||
|
||||
# Now that we have defined all the arch specific variables, use the
|
||||
|
||||
@@ -31,9 +31,9 @@ static int cmac_size(const EVP_PKEY *pkey)
|
||||
static void cmac_key_free(EVP_PKEY *pkey)
|
||||
{
|
||||
EVP_MAC_CTX *cmctx = EVP_PKEY_get0(pkey);
|
||||
EVP_MAC *mac = cmctx == NULL ? NULL : EVP_MAC_CTX_mac(cmctx);
|
||||
EVP_MAC *mac = cmctx == NULL ? NULL : EVP_MAC_get_ctx_mac(cmctx);
|
||||
|
||||
EVP_MAC_CTX_free(cmctx);
|
||||
EVP_MAC_free_ctx(cmctx);
|
||||
EVP_MAC_free(mac);
|
||||
}
|
||||
|
||||
|
||||
+12
-6
@@ -125,12 +125,18 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
|
||||
return 1;
|
||||
}
|
||||
/* Initialise context */
|
||||
if (cipher && !EVP_EncryptInit_ex(ctx->cctx, cipher, impl, NULL, NULL))
|
||||
return 0;
|
||||
if (cipher != NULL) {
|
||||
/* Ensure we can't use this ctx until we also have a key */
|
||||
ctx->nlast_block = -1;
|
||||
if (!EVP_EncryptInit_ex(ctx->cctx, cipher, impl, NULL, NULL))
|
||||
return 0;
|
||||
}
|
||||
/* Non-NULL key means initialisation complete */
|
||||
if (key) {
|
||||
if (key != NULL) {
|
||||
int bl;
|
||||
|
||||
/* If anything fails then ensure we can't use this ctx */
|
||||
ctx->nlast_block = -1;
|
||||
if (!EVP_CIPHER_CTX_cipher(ctx->cctx))
|
||||
return 0;
|
||||
if (!EVP_CIPHER_CTX_set_key_length(ctx->cctx, keylen))
|
||||
@@ -139,7 +145,7 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
|
||||
return 0;
|
||||
if ((bl = EVP_CIPHER_CTX_block_size(ctx->cctx)) < 0)
|
||||
return 0;
|
||||
if (!EVP_Cipher(ctx->cctx, ctx->tbl, zero_iv, bl))
|
||||
if (EVP_Cipher(ctx->cctx, ctx->tbl, zero_iv, bl) <= 0)
|
||||
return 0;
|
||||
make_kn(ctx->k1, ctx->tbl, bl);
|
||||
make_kn(ctx->k2, ctx->k1, bl);
|
||||
@@ -180,12 +186,12 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
|
||||
return 1;
|
||||
data += nleft;
|
||||
/* Else not final block so encrypt it */
|
||||
if (!EVP_Cipher(ctx->cctx, ctx->tbl, ctx->last_block, bl))
|
||||
if (EVP_Cipher(ctx->cctx, ctx->tbl, ctx->last_block, bl) <= 0)
|
||||
return 0;
|
||||
}
|
||||
/* Encrypt all but one of the complete blocks left */
|
||||
while (dlen > (size_t)bl) {
|
||||
if (!EVP_Cipher(ctx->cctx, ctx->tbl, data, bl))
|
||||
if (EVP_Cipher(ctx->cctx, ctx->tbl, data, bl) <= 0)
|
||||
return 0;
|
||||
dlen -= bl;
|
||||
data += bl;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]= cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \
|
||||
cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c \
|
||||
cmp_server.c cmp_client.c cmp_http.c
|
||||
cmp_server.c cmp_client.c
|
||||
@@ -146,7 +146,7 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
|
||||
OSSL_CMP_transfer_cb_t transfer_cb = ctx->transfer_cb;
|
||||
|
||||
if (transfer_cb == NULL)
|
||||
transfer_cb = OSSL_CMP_MSG_http_perform;
|
||||
transfer_cb = NULL; /* TODO: will be OSSL_CMP_MSG_http_perform of chunk 10 */
|
||||
|
||||
*rep = NULL;
|
||||
msg_timeout = ctx->msg_timeout; /* backup original value */
|
||||
@@ -189,8 +189,8 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
|
||||
*/
|
||||
ossl_cmp_log1(INFO, ctx, "received %s", ossl_cmp_bodytype_to_string(bt));
|
||||
|
||||
if ((bt = ossl_cmp_msg_check_received(ctx, *rep, unprotected_exception,
|
||||
expected_type)) < 0)
|
||||
if (!ossl_cmp_msg_check_update(ctx, *rep, unprotected_exception,
|
||||
expected_type))
|
||||
return 0;
|
||||
|
||||
if (bt == expected_type
|
||||
|
||||
+148
-39
@@ -43,6 +43,7 @@ X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx)
|
||||
* Set certificate store containing trusted (root) CA certs and possibly CRLs
|
||||
* and a cert verification callback function used for CMP server authentication.
|
||||
* Any already existing store entry is freed. Given NULL, the entry is reset.
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store)
|
||||
{
|
||||
@@ -55,7 +56,9 @@ int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get current list of non-trusted intermediate certs */
|
||||
/*
|
||||
* Get current list of non-trusted intermediate certs
|
||||
*/
|
||||
STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -68,6 +71,7 @@ STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Set untrusted certificates for path construction in authentication of
|
||||
* the CMP server and potentially others (TLS server, newly enrolled cert).
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_untrusted_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs)
|
||||
{
|
||||
@@ -104,6 +108,8 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void)
|
||||
ctx->status = -1;
|
||||
ctx->failInfoCode = -1;
|
||||
|
||||
ctx->serverPort = OSSL_CMP_DEFAULT_PORT;
|
||||
ctx->proxyPort = OSSL_CMP_DEFAULT_PORT;
|
||||
ctx->msg_timeout = 2 * 60;
|
||||
|
||||
if ((ctx->untrusted_certs = sk_X509_new_null()) == NULL)
|
||||
@@ -126,7 +132,9 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX */
|
||||
/*
|
||||
* Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX
|
||||
*/
|
||||
int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -147,16 +155,17 @@ int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx)
|
||||
&& ossl_cmp_ctx_set1_recipNonce(ctx, NULL);
|
||||
}
|
||||
|
||||
/* Frees OSSL_CMP_CTX variables allocated in OSSL_CMP_CTX_new() */
|
||||
/*
|
||||
* Frees OSSL_CMP_CTX variables allocated in OSSL_CMP_CTX_new()
|
||||
*/
|
||||
void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
OPENSSL_free(ctx->serverPath);
|
||||
OPENSSL_free(ctx->server);
|
||||
OPENSSL_free(ctx->proxy);
|
||||
OPENSSL_free(ctx->no_proxy);
|
||||
OPENSSL_free(ctx->serverName);
|
||||
OPENSSL_free(ctx->proxyName);
|
||||
|
||||
X509_free(ctx->srvCert);
|
||||
X509_free(ctx->validatedSrvCert);
|
||||
@@ -250,7 +259,11 @@ int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set callback function for checking if the cert is ok or should be rejected */
|
||||
/*
|
||||
* Set callback function for checking if the cert is ok or should
|
||||
* it be rejected.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -264,6 +277,7 @@ int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb)
|
||||
/*
|
||||
* Set argument, respectively a pointer to a structure containing arguments,
|
||||
* optionally to be used by the certConf callback.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_certConf_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
|
||||
{
|
||||
@@ -373,7 +387,10 @@ int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx,
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Set a callback function for error reporting and logging messages */
|
||||
/*
|
||||
* Set a callback function for error reporting and logging messages.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -393,7 +410,7 @@ int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb)
|
||||
}
|
||||
|
||||
/* Print OpenSSL and CMP errors via the log cb of the ctx or ERR_print_errors */
|
||||
void OSSL_CMP_CTX_print_errors(OSSL_CMP_CTX *ctx)
|
||||
void OSSL_CMP_CTX_print_errors(const OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
OSSL_CMP_print_errors_cb(ctx == NULL ? NULL : ctx->log_cb);
|
||||
}
|
||||
@@ -401,6 +418,7 @@ void OSSL_CMP_CTX_print_errors(OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Set or clear the reference value to be used for identification
|
||||
* (i.e., the user name) when using PBMAC.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx,
|
||||
const unsigned char *ref, int len)
|
||||
@@ -413,7 +431,10 @@ int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx,
|
||||
len);
|
||||
}
|
||||
|
||||
/* Set or clear the password to be used for protecting messages with PBMAC */
|
||||
/*
|
||||
* Set or clear the password to be used for protecting messages with PBMAC.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, const unsigned char *sec,
|
||||
const int len)
|
||||
{
|
||||
@@ -451,6 +472,7 @@ STACK_OF(X509) *OSSL_CMP_CTX_get1_extraCertsIn(const OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Copies any given stack of inbound X509 certificates to extraCertsIn
|
||||
* of the OSSL_CMP_CTX structure so that they may be retrieved later.
|
||||
* Returns 1 on success, 0 on error.
|
||||
*/
|
||||
int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx,
|
||||
STACK_OF(X509) *extraCertsIn)
|
||||
@@ -468,6 +490,7 @@ int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx,
|
||||
/*
|
||||
* Duplicate and set the given stack as the new stack of X509
|
||||
* certificates to send out in the extraCerts field.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx,
|
||||
STACK_OF(X509) *extraCertsOut)
|
||||
@@ -487,6 +510,7 @@ int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx,
|
||||
/*
|
||||
* Add the given policy info object
|
||||
* to the X509_EXTENSIONS of the requested certificate template.
|
||||
* Returns 1 on success, 0 on error.
|
||||
*/
|
||||
int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo)
|
||||
{
|
||||
@@ -502,7 +526,9 @@ int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo)
|
||||
return sk_POLICYINFO_push(ctx->policies, pinfo);
|
||||
}
|
||||
|
||||
/* Add an ITAV for geninfo of the PKI message header */
|
||||
/*
|
||||
* Add an ITAV for geninfo of the PKI message header
|
||||
*/
|
||||
int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -512,7 +538,9 @@ int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
|
||||
return OSSL_CMP_ITAV_push0_stack_item(&ctx->geninfo_ITAVs, itav);
|
||||
}
|
||||
|
||||
/* Add an itav for the body of outgoing general messages */
|
||||
/*
|
||||
* Add an itav for the body of outgoing general messages
|
||||
*/
|
||||
int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -541,6 +569,7 @@ STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Duplicate and copy the given stack of certificates to the given
|
||||
* OSSL_CMP_CTX structure so that they may be retrieved later.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int ossl_cmp_ctx_set1_caPubs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *caPubs)
|
||||
{
|
||||
@@ -592,25 +621,39 @@ int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \
|
||||
* Pins the server certificate to be directly trusted (even if it is expired)
|
||||
* for verifying response messages.
|
||||
* Cert pointer is not consumed. It may be NULL to clear the entry.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(srvCert, X509)
|
||||
|
||||
/* Set the X509 name of the recipient. Set in the PKIHeader */
|
||||
/*
|
||||
* Set the X509 name of the recipient. Set in the PKIHeader.
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(recipient, X509_NAME)
|
||||
|
||||
/* Store the X509 name of the expected sender in the PKIHeader of responses */
|
||||
/*
|
||||
* Store the X509 name of the expected sender in the PKIHeader of responses.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(expected_sender, X509_NAME)
|
||||
|
||||
/* Set the X509 name of the issuer. Set in the PKIHeader */
|
||||
/*
|
||||
* Set the X509 name of the issuer. Set in the PKIHeader.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(issuer, X509_NAME)
|
||||
|
||||
/*
|
||||
* Set the subject name that will be placed in the certificate
|
||||
* request. This will be the subject name on the received certificate.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(subjectName, X509_NAME)
|
||||
|
||||
/* Set the X.509v3 certificate request extensions to be used in IR/CR/KUR */
|
||||
/*
|
||||
* Set the X.509v3 certificate request extensions to be used in IR/CR/KUR.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set0_reqExtensions(OSSL_CMP_CTX *ctx, X509_EXTENSIONS *exts)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -644,6 +687,7 @@ int OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Add a GENERAL_NAME structure that will be added to the CRMF
|
||||
* request's extensions field to request subject alternative names.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx,
|
||||
const GENERAL_NAME *name)
|
||||
@@ -675,6 +719,7 @@ int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx,
|
||||
/*
|
||||
* Set our own client certificate, used for example in KUR and when
|
||||
* doing the IR with existing certificate.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(cert, X509)
|
||||
|
||||
@@ -683,14 +728,19 @@ DEFINE_OSSL_CMP_CTX_set1_up_ref(cert, X509)
|
||||
* or the certificate to be revoked in RR, respectively.
|
||||
* Also used as reference cert (defaulting to cert) for deriving subject DN
|
||||
* and SANs. Its issuer is used as default recipient in the CMP message header.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(oldCert, X509)
|
||||
|
||||
/* Set the PKCS#10 CSR to be sent in P10CR */
|
||||
/*
|
||||
* Set the PKCS#10 CSR to be sent in P10CR.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(p10CSR, X509_REQ)
|
||||
|
||||
/*
|
||||
* Set the (newly received in IP/KUP/CP) certificate in the context.
|
||||
* Sets the (newly received in IP/KUP/CP) certificate in the context.
|
||||
* Returns 1 on success, 0 on error
|
||||
* TODO: this only permits for one cert to be enrolled at a time.
|
||||
*/
|
||||
int ossl_cmp_ctx_set0_newCert(OSSL_CMP_CTX *ctx, X509 *cert)
|
||||
@@ -716,10 +766,16 @@ X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->newCert;
|
||||
}
|
||||
|
||||
/* Set the client's current private key */
|
||||
/*
|
||||
* Set the client's current private key.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(pkey, EVP_PKEY)
|
||||
|
||||
/* Set new key pair. Used e.g. when doing Key Update */
|
||||
/*
|
||||
* Set new key pair. Used e.g. when doing Key Update.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -733,7 +789,9 @@ int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get the private/public key to use for cert enrollment, or NULL on error */
|
||||
/*
|
||||
* gets the private/public key to use for certificate enrollment, NULL on error
|
||||
*/
|
||||
EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -748,7 +806,10 @@ EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv)
|
||||
return ctx->pkey; /* may be NULL */
|
||||
}
|
||||
|
||||
/* Set the given transactionID to the context */
|
||||
/*
|
||||
* Sets the given transactionID to the context.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *id)
|
||||
{
|
||||
@@ -759,7 +820,11 @@ int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx,
|
||||
return ossl_cmp_asn1_octet_string_set1(&ctx->transactionID, id);
|
||||
}
|
||||
|
||||
/* Set the nonce to be used for the recipNonce in the message created next */
|
||||
/*
|
||||
* sets the given nonce to be used for the recipNonce in the next message to be
|
||||
* created.
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *nonce)
|
||||
{
|
||||
@@ -768,7 +833,10 @@ int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
|
||||
return ossl_cmp_asn1_octet_string_set1(&ctx->recipNonce, nonce);
|
||||
}
|
||||
|
||||
/* Stores the given nonce as the last senderNonce sent out */
|
||||
/*
|
||||
* Stores the given nonce as the last senderNonce sent out.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *nonce)
|
||||
{
|
||||
@@ -779,17 +847,37 @@ int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx,
|
||||
return ossl_cmp_asn1_octet_string_set1(&ctx->senderNonce, nonce);
|
||||
}
|
||||
|
||||
/* Set the proxy server to use for HTTP(S) connections */
|
||||
DEFINE_OSSL_CMP_CTX_set1(proxy, char)
|
||||
/*
|
||||
* Set the host name of the (HTTP) proxy server to use for all connections
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(proxyName, char)
|
||||
|
||||
/* Set the (HTTP) host name of the CMP server */
|
||||
DEFINE_OSSL_CMP_CTX_set1(server, char)
|
||||
/*
|
||||
* Set the (HTTP) host name of the CA server.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(serverName, char)
|
||||
|
||||
/* Set the server exclusion list of the HTTP proxy server */
|
||||
DEFINE_OSSL_CMP_CTX_set1(no_proxy, char)
|
||||
/*
|
||||
* Sets the (HTTP) proxy port to be used.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_proxyPort(OSSL_CMP_CTX *ctx, int port)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
ctx->proxyPort = port;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set the http connect/disconnect callback function to be used for HTTP(S) */
|
||||
int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb)
|
||||
/*
|
||||
* sets the http connect/disconnect callback function to be used for HTTP(S)
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_http_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
@@ -799,7 +887,10 @@ int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set argument optionally to be used by the http connect/disconnect callback */
|
||||
/*
|
||||
* Set argument optionally to be used by the http connect/disconnect callback.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -823,7 +914,10 @@ void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->http_cb_arg;
|
||||
}
|
||||
|
||||
/* Set callback function for sending CMP request and receiving response */
|
||||
/*
|
||||
* Set callback function for sending CMP request and receiving response.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -834,7 +928,10 @@ int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set argument optionally to be used by the transfer callback */
|
||||
/*
|
||||
* Set argument optionally to be used by the transfer callback.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_transfer_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -858,7 +955,10 @@ void *OSSL_CMP_CTX_get_transfer_cb_arg(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->transfer_cb_arg;
|
||||
}
|
||||
|
||||
/** Set the HTTP server port to be used */
|
||||
/*
|
||||
* Sets the (HTTP) server port to be used.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -869,10 +969,16 @@ int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set the HTTP path to be used on the server (e.g "pkix/") */
|
||||
/*
|
||||
* Sets the HTTP path to be used on the server (e.g "pkix/").
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(serverPath, char)
|
||||
|
||||
/* Set the failInfo error code as bit encoding in OSSL_CMP_CTX */
|
||||
/*
|
||||
* Set the failInfo error code as bit encoding in OSSL_CMP_CTX.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int ossl_cmp_ctx_set_failInfoCode(OSSL_CMP_CTX *ctx, int fail_info)
|
||||
{
|
||||
if (!ossl_assert(ctx != NULL))
|
||||
@@ -894,7 +1000,10 @@ int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->failInfoCode;
|
||||
}
|
||||
|
||||
/* Set a Boolean or integer option of the context to the "val" arg */
|
||||
/*
|
||||
* Sets a Boolean or integer option of the context to the "val" arg.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
{
|
||||
int min_val;
|
||||
|
||||
@@ -76,6 +76,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
"error unexpected certconf"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_PROTECTION),
|
||||
"error validating protection"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_SIGNATURE),
|
||||
"error validating signature"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY),
|
||||
"failed extracting pubkey"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILURE_OBTAINING_RANDOM),
|
||||
|
||||
+19
-15
@@ -41,6 +41,14 @@ int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr)
|
||||
return (int)pvno;
|
||||
}
|
||||
|
||||
int ossl_cmp_hdr_get_protection_nid(const OSSL_CMP_PKIHEADER *hdr)
|
||||
{
|
||||
if (!ossl_assert(hdr != NULL)
|
||||
|| hdr->protectionAlg == NULL)
|
||||
return NID_undef;
|
||||
return OBJ_obj2nid(hdr->protectionAlg->algorithm);
|
||||
}
|
||||
|
||||
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const
|
||||
OSSL_CMP_PKIHEADER *hdr)
|
||||
{
|
||||
@@ -300,30 +308,26 @@ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The sender name is copied from the subject of the client cert, if any,
|
||||
* or else from the subject name provided for certification requests.
|
||||
* If neither protection cert nor oldCert nor subject are given,
|
||||
* sender name is not known to the client and thus set to NULL-DN
|
||||
*/
|
||||
sender = ctx->cert != NULL ?
|
||||
X509_get_subject_name(ctx->cert) : ctx->subjectName;
|
||||
sender = ctx->cert != NULL ? X509_get_subject_name(ctx->cert) :
|
||||
ctx->oldCert != NULL ? X509_get_subject_name(ctx->oldCert) :
|
||||
ctx->subjectName;
|
||||
if (!ossl_cmp_hdr_set1_sender(hdr, sender))
|
||||
return 0;
|
||||
|
||||
/* determine recipient entry in PKIHeader */
|
||||
if (ctx->srvCert != NULL) {
|
||||
rcp = X509_get_subject_name(ctx->srvCert);
|
||||
/* set also as expected_sender of responses unless set explicitly */
|
||||
if (ctx->expected_sender == NULL && rcp != NULL
|
||||
&& !OSSL_CMP_CTX_set1_expected_sender(ctx, rcp))
|
||||
return 0;
|
||||
} else if (ctx->recipient != NULL) {
|
||||
if (ctx->recipient != NULL)
|
||||
rcp = ctx->recipient;
|
||||
} else if (ctx->issuer != NULL) {
|
||||
else if (ctx->srvCert != NULL)
|
||||
rcp = X509_get_subject_name(ctx->srvCert);
|
||||
else if (ctx->issuer != NULL)
|
||||
rcp = ctx->issuer;
|
||||
} else if (ctx->oldCert != NULL) {
|
||||
else if (ctx->oldCert != NULL)
|
||||
rcp = X509_get_issuer_name(ctx->oldCert);
|
||||
} else if (ctx->cert != NULL) {
|
||||
else if (ctx->cert != NULL)
|
||||
rcp = X509_get_issuer_name(ctx->cert);
|
||||
}
|
||||
if (!ossl_cmp_hdr_set1_recipient(hdr, rcp))
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright Nokia 2007-2019
|
||||
* Copyright Siemens AG 2015-2019
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/http.h>
|
||||
#include "internal/sockets.h"
|
||||
|
||||
#include "openssl/cmp.h"
|
||||
#include "cmp_local.h"
|
||||
|
||||
/* explicit #includes not strictly needed since implied by the above: */
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/cmp.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
DEFINE_STACK_OF(CONF_VALUE)
|
||||
|
||||
/*
|
||||
* Send the PKIMessage req and on success return the response, else NULL.
|
||||
* Any previous error queue entries will likely be removed by ERR_clear_error().
|
||||
*/
|
||||
OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
char server_port[32] = { '\0' };
|
||||
STACK_OF(CONF_VALUE) *headers = NULL;
|
||||
const char *const content_type_pkix = "application/pkixcmp";
|
||||
OSSL_CMP_MSG *res;
|
||||
|
||||
if (ctx == NULL || req == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!X509V3_add_value("Pragma", "no-cache", &headers))
|
||||
return NULL;
|
||||
|
||||
if (ctx->serverPort != 0)
|
||||
BIO_snprintf(server_port, sizeof(server_port), "%d", ctx->serverPort);
|
||||
|
||||
res = (OSSL_CMP_MSG *)
|
||||
OSSL_HTTP_post_asn1(ctx->server, server_port, ctx->serverPath,
|
||||
OSSL_CMP_CTX_get_http_cb_arg(ctx) != NULL,
|
||||
ctx->proxy, ctx->no_proxy, NULL, NULL,
|
||||
ctx->http_cb, OSSL_CMP_CTX_get_http_cb_arg(ctx),
|
||||
headers, content_type_pkix, (const ASN1_VALUE *)req,
|
||||
ASN1_ITEM_rptr(OSSL_CMP_MSG),
|
||||
0, 0, ctx->msg_timeout, content_type_pkix,
|
||||
ASN1_ITEM_rptr(OSSL_CMP_MSG));
|
||||
|
||||
sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
|
||||
return res;
|
||||
}
|
||||
@@ -36,15 +36,15 @@ struct ossl_cmp_ctx_st {
|
||||
void *transfer_cb_arg; /* allows to store optional argument to cb */
|
||||
/* HTTP-based transfer */
|
||||
char *serverPath;
|
||||
char *server;
|
||||
char *serverName;
|
||||
int serverPort;
|
||||
char *proxy;
|
||||
char *no_proxy;
|
||||
char *proxyName;
|
||||
int proxyPort;
|
||||
int msg_timeout; /* max seconds to wait for each CMP message round trip */
|
||||
int total_timeout; /* max number of seconds an enrollment may take, incl. */
|
||||
/* attempts polling for a response if a 'waiting' PKIStatus is received */
|
||||
time_t end_time; /* session start time + totaltimeout */
|
||||
OSSL_HTTP_bio_cb_t http_cb;
|
||||
OSSL_CMP_http_cb_t http_cb;
|
||||
void *http_cb_arg; /* allows to store optional argument to cb */
|
||||
|
||||
/* server authentication */
|
||||
@@ -283,7 +283,6 @@ struct ossl_cmp_pkisi_st {
|
||||
OSSL_CMP_PKIFREETEXT *statusString;
|
||||
OSSL_CMP_PKIFAILUREINFO *failInfo;
|
||||
} /* OSSL_CMP_PKISI */;
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID)
|
||||
|
||||
/*-
|
||||
* RevReqContent ::= SEQUENCE OF RevDetails
|
||||
@@ -797,6 +796,7 @@ int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int index);
|
||||
/* from cmp_hdr.c */
|
||||
int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno);
|
||||
int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr);
|
||||
int ossl_cmp_hdr_get_protection_nid(const OSSL_CMP_PKIHEADER *hdr);
|
||||
ASN1_OCTET_STRING *ossl_cmp_hdr_get0_senderNonce(const OSSL_CMP_PKIHEADER *hdr);
|
||||
int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name);
|
||||
int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm);
|
||||
@@ -909,8 +909,8 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
|
||||
typedef int (*ossl_cmp_allow_unprotected_cb_t)(const OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *msg,
|
||||
int invalid_protection, int arg);
|
||||
int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
|
||||
int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
|
||||
int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified);
|
||||
|
||||
/* from cmp_client.c */
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
DEFINE_STACK_OF(OSSL_CMP_CERTSTATUS)
|
||||
DEFINE_STACK_OF(OSSL_CMP_ITAV)
|
||||
DEFINE_STACK_OF(GENERAL_NAME)
|
||||
DEFINE_STACK_OF(X509)
|
||||
DEFINE_STACK_OF(X509_EXTENSION)
|
||||
DEFINE_STACK_OF(OSSL_CMP_PKISI)
|
||||
DEFINE_STACK_OF(OSSL_CRMF_MSG)
|
||||
@@ -228,7 +229,7 @@ static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype, int rid)
|
||||
X509_EXTENSIONS *exts = NULL;
|
||||
|
||||
if (rkey == NULL)
|
||||
rkey = ctx->pkey; /* default is independent of ctx->oldClCert */
|
||||
rkey = ctx->pkey; /* default is independent of ctx->oldCert */
|
||||
if (rkey == NULL) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
@@ -426,9 +427,12 @@ OSSL_CMP_MSG *ossl_cmp_certRep_new(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
if (bodytype == OSSL_CMP_PKIBODY_IP && caPubs != NULL
|
||||
&& (repMsg->caPubs = X509_chain_up_ref(caPubs)) == NULL)
|
||||
goto err;
|
||||
if (chain != NULL
|
||||
&& !ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain, 0, 1, 0))
|
||||
if (sk_X509_num(chain) > 0) {
|
||||
msg->extraCerts = sk_X509_new_reserve(NULL, sk_X509_num(chain));
|
||||
if (msg->extraCerts == NULL
|
||||
|| !ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain, 0, 1, 0))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!unprotectedErrors
|
||||
|| ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection)
|
||||
|
||||
@@ -26,8 +26,8 @@ DEFINE_STACK_OF(X509)
|
||||
* Calculate protection for given PKImessage utilizing the given credentials
|
||||
* and the algorithm parameters set inside the message header's protectionAlg.
|
||||
*
|
||||
* Either secret or pkey must be set, the other must be NULL. Attempts doing
|
||||
* PBMAC in case 'secret' is set and signature if 'pkey' is set - but will only
|
||||
* secret or pkey must be set. Attempts doing PBMAC in case 'secret' is set
|
||||
* and else signature if 'pkey' is set - but will only
|
||||
* do the protection already marked in msg->header->protectionAlg.
|
||||
*
|
||||
* returns ptr to ASN1_BIT_STRING containing protection on success, else NULL
|
||||
@@ -73,7 +73,7 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
|
||||
}
|
||||
X509_ALGOR_get0(&algorOID, &pptype, &ppval, msg->header->protectionAlg);
|
||||
|
||||
if (secret != NULL && pkey == NULL) {
|
||||
if (secret != NULL) {
|
||||
if (ppval == NULL) {
|
||||
CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION);
|
||||
goto end;
|
||||
@@ -94,7 +94,7 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
|
||||
secret->data, secret->length,
|
||||
&protection, &sig_len))
|
||||
goto end;
|
||||
} else if (secret == NULL && pkey != NULL) {
|
||||
} else if (pkey != NULL) {
|
||||
/* TODO combine this with large parts of CRMF_poposigningkey_init() */
|
||||
/* EVP_DigestSignInit() checks that pkey type is correct for the alg */
|
||||
|
||||
@@ -259,10 +259,8 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (msg->header->protectionAlg == NULL)
|
||||
if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL)
|
||||
goto err;
|
||||
if (!OBJ_find_sigid_by_algs(&algNID, ctx->digest,
|
||||
EVP_PKEY_id(ctx->pkey))) {
|
||||
CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE);
|
||||
|
||||
+32
-16
@@ -452,8 +452,10 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_CTX *ctx;
|
||||
ASN1_OCTET_STRING *backup_secret;
|
||||
OSSL_CMP_PKIHEADER *hdr;
|
||||
int req_type, rsp_type;
|
||||
int res;
|
||||
OSSL_CMP_MSG *rsp = NULL;
|
||||
|
||||
if (srv_ctx == NULL || srv_ctx->ctx == NULL
|
||||
@@ -463,7 +465,12 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
return 0;
|
||||
}
|
||||
ctx = srv_ctx->ctx;
|
||||
backup_secret = ctx->secretValue;
|
||||
|
||||
/*
|
||||
* Some things need to be done already before validating the message in
|
||||
* order to be able to send an error message as far as needed and possible.
|
||||
*/
|
||||
if (hdr->sender->type != GEN_DIRNAME) {
|
||||
CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
|
||||
goto err;
|
||||
@@ -485,9 +492,10 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
|
||||
tid = OPENSSL_buf2hexstr(ctx->transactionID->data,
|
||||
ctx->transactionID->length);
|
||||
ossl_cmp_log1(WARN, ctx,
|
||||
"Assuming that last transaction with ID=%s got aborted",
|
||||
tid);
|
||||
if (tid != NULL)
|
||||
ossl_cmp_log1(WARN, ctx,
|
||||
"Assuming that last transaction with ID=%s got aborted",
|
||||
tid);
|
||||
OPENSSL_free(tid);
|
||||
}
|
||||
/* start of a new transaction, reset transactionID and senderNonce */
|
||||
@@ -500,16 +508,17 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
if (ctx->transactionID == NULL) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
/* ignore any (extra) error in next two function calls: */
|
||||
(void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID);
|
||||
(void)ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce);
|
||||
goto err;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (ossl_cmp_msg_check_received(ctx, req, unprotected_exception,
|
||||
srv_ctx->acceptUnprotected) < 0)
|
||||
res = ossl_cmp_msg_check_update(ctx, req, unprotected_exception,
|
||||
srv_ctx->acceptUnprotected);
|
||||
if (ctx->secretValue != NULL && ctx->pkey != NULL
|
||||
&& ossl_cmp_hdr_get_protection_nid(hdr) != NID_id_PasswordBasedMAC)
|
||||
ctx->secretValue = NULL; /* use MSG_SIG_ALG when protecting rsp */
|
||||
if (!res)
|
||||
goto err;
|
||||
|
||||
switch (req_type) {
|
||||
@@ -568,16 +577,23 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
/* TODO fail_info could be more specific */
|
||||
OSSL_CMP_PKISI *si = NULL;
|
||||
|
||||
if (ctx->transactionID == NULL) {
|
||||
/* ignore any (extra) error in next two function calls: */
|
||||
(void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID);
|
||||
(void)ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce);
|
||||
}
|
||||
|
||||
if ((si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
|
||||
fail_info, NULL)) == NULL)
|
||||
return 0;
|
||||
if (err != 0 && (flags & ERR_TXT_STRING) != 0)
|
||||
data = ERR_reason_error_string(err);
|
||||
rsp = ossl_cmp_error_new(srv_ctx->ctx, si,
|
||||
err != 0 ? ERR_GET_REASON(err) : -1,
|
||||
data, srv_ctx->sendUnprotectedErrors);
|
||||
OSSL_CMP_PKISI_free(si);
|
||||
fail_info, NULL)) != NULL) {
|
||||
if (err != 0 && (flags & ERR_TXT_STRING) != 0)
|
||||
data = ERR_reason_error_string(err);
|
||||
rsp = ossl_cmp_error_new(srv_ctx->ctx, si,
|
||||
err != 0 ? ERR_GET_REASON(err) : -1,
|
||||
data, srv_ctx->sendUnprotectedErrors);
|
||||
OSSL_CMP_PKISI_free(si);
|
||||
}
|
||||
}
|
||||
ctx->secretValue = backup_secret;
|
||||
|
||||
/* possibly close the transaction */
|
||||
rsp_type =
|
||||
|
||||
+158
-141
@@ -24,7 +24,7 @@
|
||||
|
||||
DEFINE_STACK_OF(X509)
|
||||
|
||||
/*
|
||||
/*-
|
||||
* Verify a message protected by signature according to section 5.1.3.3
|
||||
* (sha1+RSA/DSA or any other algorithm supported by OpenSSL).
|
||||
*
|
||||
@@ -70,7 +70,7 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
|
||||
prot_part_der_len = (size_t) len;
|
||||
|
||||
/* verify signature of protected part */
|
||||
if (!OBJ_find_sigid_algs(OBJ_obj2nid(msg->header->protectionAlg->algorithm),
|
||||
if (!OBJ_find_sigid_algs(ossl_cmp_hdr_get_protection_nid(msg->header),
|
||||
&digest_nid, &pk_nid)
|
||||
|| digest_nid == NID_undef || pk_nid == NID_undef
|
||||
|| (digest = EVP_get_digestbynid(digest_nid)) == NULL) {
|
||||
@@ -95,7 +95,7 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
|
||||
|
||||
sig_err:
|
||||
res = x509_print_ex_brief(bio, cert, X509_FLAG_NO_EXTENSIONS);
|
||||
CMPerr(0, CMP_R_ERROR_VALIDATING_PROTECTION);
|
||||
CMPerr(0, CMP_R_ERROR_VALIDATING_SIGNATURE);
|
||||
if (res)
|
||||
ERR_add_error_mem_bio("\n", bio);
|
||||
res = 0;
|
||||
@@ -132,15 +132,15 @@ static int verify_PBMAC(const OSSL_CMP_MSG *msg,
|
||||
return valid;
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
* Attempt to validate certificate and path using any given store with trusted
|
||||
* certs (possibly including CRLs and a cert verification callback function)
|
||||
* and non-trusted intermediate certs from the given ctx.
|
||||
*
|
||||
* Returns 1 on successful validation and 0 otherwise.
|
||||
*/
|
||||
int OSSL_CMP_validate_cert_path(OSSL_CMP_CTX *ctx, X509_STORE *trusted_store,
|
||||
X509 *cert)
|
||||
int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx,
|
||||
X509_STORE *trusted_store, X509 *cert)
|
||||
{
|
||||
int valid = 0;
|
||||
X509_STORE_CTX *csc = NULL;
|
||||
@@ -176,7 +176,7 @@ int OSSL_CMP_validate_cert_path(OSSL_CMP_CTX *ctx, X509_STORE *trusted_store,
|
||||
}
|
||||
|
||||
/* Return 0 if expect_name != NULL and there is no matching actual_name */
|
||||
static int check_name(OSSL_CMP_CTX *ctx,
|
||||
static int check_name(const OSSL_CMP_CTX *ctx, int log_success,
|
||||
const char *actual_desc, const X509_NAME *actual_name,
|
||||
const char *expect_desc, const X509_NAME *expect_name)
|
||||
{
|
||||
@@ -190,10 +190,16 @@ static int check_name(OSSL_CMP_CTX *ctx,
|
||||
ossl_cmp_log1(WARN, ctx, "missing %s", actual_desc);
|
||||
return 0;
|
||||
}
|
||||
if (X509_NAME_cmp(actual_name, expect_name) == 0)
|
||||
str = X509_NAME_oneline(actual_name, NULL, 0);
|
||||
if (X509_NAME_cmp(actual_name, expect_name) == 0) {
|
||||
if (log_success && str != NULL)
|
||||
ossl_cmp_log2(INFO, ctx, " subject matches %s: %s", expect_desc,
|
||||
str);
|
||||
OPENSSL_free(str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((str = X509_NAME_oneline(actual_name, NULL, 0)) != NULL)
|
||||
if (str != NULL)
|
||||
ossl_cmp_log2(INFO, ctx, " actual name in %s = %s", actual_desc, str);
|
||||
OPENSSL_free(str);
|
||||
if ((str = X509_NAME_oneline(expect_name, NULL, 0)) != NULL)
|
||||
@@ -203,11 +209,11 @@ static int check_name(OSSL_CMP_CTX *ctx,
|
||||
}
|
||||
|
||||
/* Return 0 if skid != NULL and there is no matching subject key ID in cert */
|
||||
static int check_kid(OSSL_CMP_CTX *ctx,
|
||||
X509 *cert, const ASN1_OCTET_STRING *skid)
|
||||
static int check_kid(const OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *ckid,
|
||||
const ASN1_OCTET_STRING *skid)
|
||||
{
|
||||
char *actual, *expect;
|
||||
const ASN1_OCTET_STRING *ckid = X509_get0_subject_key_id(cert);
|
||||
char *str;
|
||||
|
||||
if (skid == NULL)
|
||||
return 1; /* no expectation, thus trivially fulfilled */
|
||||
@@ -217,19 +223,25 @@ static int check_kid(OSSL_CMP_CTX *ctx,
|
||||
ossl_cmp_warn(ctx, "missing Subject Key Identifier in certificate");
|
||||
return 0;
|
||||
}
|
||||
if (ASN1_OCTET_STRING_cmp(ckid, skid) == 0)
|
||||
str = OPENSSL_buf2hexstr(ckid->data, ckid->length);
|
||||
if (ASN1_OCTET_STRING_cmp(ckid, skid) == 0) {
|
||||
if (str != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " subjectKID matches senderKID: %s", str);
|
||||
OPENSSL_free(str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((actual = OPENSSL_buf2hexstr(ckid->data, ckid->length)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " cert Subject Key Identifier = %s", actual);
|
||||
if ((expect = OPENSSL_buf2hexstr(skid->data, skid->length)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " does not match senderKID = %s", expect);
|
||||
OPENSSL_free(expect);
|
||||
OPENSSL_free(actual);
|
||||
if (str != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " cert Subject Key Identifier = %s", str);
|
||||
OPENSSL_free(str);
|
||||
if ((str = OPENSSL_buf2hexstr(skid->data, skid->length)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " does not match senderKID = %s", str);
|
||||
OPENSSL_free(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int already_checked(X509 *cert, const STACK_OF(X509) *already_checked)
|
||||
static int already_checked(const X509 *cert,
|
||||
const STACK_OF(X509) *already_checked)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -239,7 +251,7 @@ static int already_checked(X509 *cert, const STACK_OF(X509) *already_checked)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
* Check if the given cert is acceptable as sender cert of the given message.
|
||||
* The subject DN must match, the subject key ID as well if present in the msg,
|
||||
* and the cert must be current (checked if ctx->trusted is not NULL).
|
||||
@@ -247,7 +259,7 @@ static int already_checked(X509 *cert, const STACK_OF(X509) *already_checked)
|
||||
*
|
||||
* Returns 0 on error or not acceptable, else 1.
|
||||
*/
|
||||
static int cert_acceptable(OSSL_CMP_CTX *ctx,
|
||||
static int cert_acceptable(const OSSL_CMP_CTX *ctx,
|
||||
const char *desc1, const char *desc2, X509 *cert,
|
||||
const STACK_OF(X509) *already_checked1,
|
||||
const STACK_OF(X509) *already_checked2,
|
||||
@@ -285,19 +297,19 @@ static int cert_acceptable(OSSL_CMP_CTX *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!check_name(ctx,
|
||||
if (!check_name(ctx, 1,
|
||||
"cert subject", X509_get_subject_name(cert),
|
||||
"sender field", msg->header->sender->d.directoryName))
|
||||
return 0;
|
||||
|
||||
if (!check_kid(ctx, cert, msg->header->senderKID))
|
||||
if (!check_kid(ctx, X509_get0_subject_key_id(cert), msg->header->senderKID))
|
||||
return 0;
|
||||
/* acceptable also if there is no senderKID in msg header */
|
||||
ossl_cmp_info(ctx, " cert seems acceptable");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int check_msg_valid_cert(OSSL_CMP_CTX *ctx, X509_STORE *store,
|
||||
static int check_msg_valid_cert(const OSSL_CMP_CTX *ctx, X509_STORE *store,
|
||||
X509 *scrt, const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
if (!verify_signature(ctx, msg, scrt)) {
|
||||
@@ -319,7 +331,7 @@ static int check_msg_valid_cert(OSSL_CMP_CTX *ctx, X509_STORE *store,
|
||||
* from extraCerts as trust anchor to validate sender cert and msg -
|
||||
* provided it also can validate the newly enrolled certificate
|
||||
*/
|
||||
static int check_msg_valid_cert_3gpp(OSSL_CMP_CTX *ctx, X509 *scrt,
|
||||
static int check_msg_valid_cert_3gpp(const OSSL_CMP_CTX *ctx, X509 *scrt,
|
||||
const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
int valid = 0;
|
||||
@@ -361,11 +373,21 @@ static int check_msg_valid_cert_3gpp(OSSL_CMP_CTX *ctx, X509 *scrt,
|
||||
return valid;
|
||||
}
|
||||
|
||||
/*
|
||||
static int check_msg_given_cert(const OSSL_CMP_CTX *ctx, X509 *cert,
|
||||
const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
return cert_acceptable(ctx, "previously validated", "sender cert",
|
||||
cert, NULL, NULL, msg)
|
||||
&& (check_msg_valid_cert(ctx, ctx->trusted, cert, msg)
|
||||
|| check_msg_valid_cert_3gpp(ctx, cert, msg));
|
||||
}
|
||||
|
||||
/*-
|
||||
* Try all certs in given list for verifying msg, normally or in 3GPP mode.
|
||||
* If already_checked1 == NULL then certs are assumed to be the msg->extraCerts.
|
||||
* On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
|
||||
*/
|
||||
static int check_msg_with_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs,
|
||||
static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs,
|
||||
const char *desc,
|
||||
const STACK_OF(X509) *already_checked1,
|
||||
const STACK_OF(X509) *already_checked2,
|
||||
@@ -406,9 +428,10 @@ static int check_msg_with_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
* Verify msg trying first ctx->untrusted_certs, which should include extraCerts
|
||||
* at its front, then trying the trusted certs in truststore (if any) of ctx.
|
||||
* On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
|
||||
*/
|
||||
static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
int mode_3gpp)
|
||||
@@ -451,7 +474,10 @@ static int no_log_cb(const char *func, const char *file, int line,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* verify message signature with any acceptable and valid candidate cert */
|
||||
/*-
|
||||
* Verify message signature with any acceptable and valid candidate cert.
|
||||
* On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
|
||||
*/
|
||||
static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
X509 *scrt = ctx->validatedSrvCert; /* previous successful sender cert */
|
||||
@@ -472,29 +498,28 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
/* dump any hitherto errors to avoid confusion when printing further ones */
|
||||
OSSL_CMP_CTX_print_errors(ctx);
|
||||
|
||||
/* enable clearing irrelevant errors in attempts to validate sender certs */
|
||||
(void)ERR_set_mark();
|
||||
ctx->log_cb = no_log_cb; /* temporarily disable logging */
|
||||
|
||||
/*
|
||||
* try first cached scrt, used successfully earlier in same transaction,
|
||||
* for validating this and any further msgs where extraCerts may be left out
|
||||
*/
|
||||
if (scrt != NULL) {
|
||||
(void)ERR_set_mark();
|
||||
ossl_cmp_info(ctx,
|
||||
"trying to verify msg signature with previously validated cert");
|
||||
if (cert_acceptable(ctx, "previously validated", "sender cert", scrt,
|
||||
NULL, NULL, msg)
|
||||
&& (check_msg_valid_cert(ctx, ctx->trusted, scrt, msg)
|
||||
|| check_msg_valid_cert_3gpp(ctx, scrt, msg))) {
|
||||
if (check_msg_given_cert(ctx, scrt, msg)) {
|
||||
ctx->log_cb = backup_log_cb;
|
||||
(void)ERR_pop_to_mark();
|
||||
return 1;
|
||||
}
|
||||
(void)ERR_pop_to_mark();
|
||||
/* cached sender cert has shown to be no more successfully usable */
|
||||
(void)ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL);
|
||||
/* re-do the above check (just) for adding diagnostic information */
|
||||
ossl_cmp_info(ctx,
|
||||
"trying to verify msg signature with previously validated cert");
|
||||
(void)check_msg_given_cert(ctx, scrt, msg);
|
||||
}
|
||||
|
||||
/* enable clearing irrelevant errors in attempts to validate sender certs */
|
||||
(void)ERR_set_mark();
|
||||
ctx->log_cb = no_log_cb; /* temporarily disable logging */
|
||||
res = check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */)
|
||||
|| check_msg_all_certs(ctx, msg, 1 /* 3gpp */);
|
||||
ctx->log_cb = backup_log_cb;
|
||||
@@ -518,8 +543,8 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
else
|
||||
ossl_cmp_info(ctx, "while msg header does not contain senderKID");
|
||||
/* re-do the above checks (just) for adding diagnostic information */
|
||||
check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */);
|
||||
check_msg_all_certs(ctx, msg, 1 /* 3gpp */);
|
||||
(void)check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */);
|
||||
(void)check_msg_all_certs(ctx, msg, 1 /* 3gpp */);
|
||||
}
|
||||
|
||||
CMPerr(0, CMP_R_NO_SUITABLE_SENDER_CERT);
|
||||
@@ -538,12 +563,13 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
* Validate the protection of the given PKIMessage using either password-
|
||||
* based mac (PBM) or a signature algorithm. In the case of signature algorithm,
|
||||
* the sender certificate can have been pinned by providing it in ctx->srvCert,
|
||||
* else it is searched in msg->extraCerts, ctx->untrusted_certs, in ctx->trusted
|
||||
* (in this order) and is path is validated against ctx->trusted.
|
||||
* On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert().
|
||||
*
|
||||
* If ctx->permitTAInExtraCertsForIR is true and when validating a CMP IP msg,
|
||||
* the trust anchor for validating the IP msg may be taken from msg->extraCerts
|
||||
@@ -555,9 +581,6 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
*/
|
||||
int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
X509_ALGOR *alg;
|
||||
int nid = NID_undef, pk_nid = NID_undef;
|
||||
const ASN1_OBJECT *algorOID = NULL;
|
||||
X509 *scrt;
|
||||
|
||||
if (ctx == NULL || msg == NULL
|
||||
@@ -566,17 +589,13 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((alg = msg->header->protectionAlg) == NULL /* unprotected message */
|
||||
if (msg->header->protectionAlg == NULL /* unprotected message */
|
||||
|| msg->protection == NULL || msg->protection->data == NULL) {
|
||||
CMPerr(0, CMP_R_MISSING_PROTECTION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* determine the nid for the used protection algorithm */
|
||||
X509_ALGOR_get0(&algorOID, NULL, NULL, alg);
|
||||
nid = OBJ_obj2nid(algorOID);
|
||||
|
||||
switch (nid) {
|
||||
switch (ossl_cmp_hdr_get_protection_nid(msg->header)) {
|
||||
/* 5.1.3.1. Shared Secret Information */
|
||||
case NID_id_PasswordBasedMAC:
|
||||
if (ctx->secretValue == 0) {
|
||||
@@ -584,34 +603,8 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
break;
|
||||
}
|
||||
|
||||
if (verify_PBMAC(msg, ctx->secretValue)) {
|
||||
/*
|
||||
* RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is
|
||||
* "shared secret information", then any certificate transported in
|
||||
* the caPubs field may be directly trusted as a root CA
|
||||
* certificate by the initiator.'
|
||||
*/
|
||||
switch (ossl_cmp_msg_get_bodytype(msg)) {
|
||||
case -1:
|
||||
return 0;
|
||||
case OSSL_CMP_PKIBODY_IP:
|
||||
case OSSL_CMP_PKIBODY_CP:
|
||||
case OSSL_CMP_PKIBODY_KUP:
|
||||
case OSSL_CMP_PKIBODY_CCP:
|
||||
if (ctx->trusted != NULL) {
|
||||
STACK_OF(X509) *certs = msg->body->value.ip->caPubs;
|
||||
/* value.ip is same for cp, kup, and ccp */
|
||||
|
||||
if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0))
|
||||
/* adds both self-issued and not self-issued certs */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (verify_PBMAC(msg, ctx->secretValue))
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
@@ -626,28 +619,6 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
* 5.1.3.3. Signature
|
||||
*/
|
||||
default:
|
||||
if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), NULL, &pk_nid)
|
||||
|| pk_nid == NID_undef) {
|
||||
CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID);
|
||||
break;
|
||||
}
|
||||
/* validate sender name of received msg */
|
||||
if (msg->header->sender->type != GEN_DIRNAME) {
|
||||
CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
|
||||
break; /* FR#42: support for more than X509_NAME */
|
||||
}
|
||||
/*
|
||||
* Compare actual sender name of response with expected sender name.
|
||||
* Expected name can be set explicitly or the subject of ctx->srvCert.
|
||||
* Mitigates risk to accept misused certificate of an unauthorized
|
||||
* entity of a trusted hierarchy.
|
||||
*/
|
||||
if (!check_name(ctx, "sender DN field",
|
||||
msg->header->sender->d.directoryName,
|
||||
"expected sender", ctx->expected_sender))
|
||||
break;
|
||||
/* Note: if recipient was NULL-DN it could be learned here if needed */
|
||||
|
||||
scrt = ctx->srvCert;
|
||||
if (scrt == NULL) {
|
||||
if (check_msg_find_cert(ctx, msg))
|
||||
@@ -656,9 +627,6 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
/* use ctx->srvCert for signature check even if not acceptable */
|
||||
if (verify_signature(ctx, msg, scrt))
|
||||
return 1;
|
||||
/* call cert_acceptable() for adding diagnostic information */
|
||||
(void)cert_acceptable(ctx, "explicitly set", "sender cert", scrt,
|
||||
NULL, NULL, msg);
|
||||
ossl_cmp_warn(ctx, "msg signature verification failed");
|
||||
CMPerr(0, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG);
|
||||
}
|
||||
@@ -670,9 +638,11 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
|
||||
/*-
|
||||
* Check received message (i.e., response by server or request from client)
|
||||
* Any msg->extraCerts are prepended to ctx->untrusted_certs
|
||||
* Any msg->extraCerts are prepended to ctx->untrusted_certs.
|
||||
*
|
||||
* Ensures that:
|
||||
* its sender is of appropriate type (curently only X509_NAME) and
|
||||
* matches any expected sender or srvCert subject given in the ctx
|
||||
* it has a valid body type
|
||||
* its protection is valid (or invalid/absent, but only if a callback function
|
||||
* is present and yields a positive result using also the supplied argument)
|
||||
@@ -681,30 +651,63 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
*
|
||||
* If everything is fine:
|
||||
* learns the senderNonce from the received message,
|
||||
* learns the transaction ID if it is not yet in ctx.
|
||||
* learns the transaction ID if it is not yet in ctx,
|
||||
* and makes any certs in caPubs directly trusted.
|
||||
*
|
||||
* returns body type (which is >= 0) of the message on success, -1 on error
|
||||
* Returns 1 on success, 0 on error.
|
||||
*/
|
||||
int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg)
|
||||
int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg)
|
||||
{
|
||||
int rcvd_type;
|
||||
OSSL_CMP_PKIHEADER *hdr;
|
||||
const X509_NAME *expected_sender;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && msg != NULL))
|
||||
return -1;
|
||||
if (!ossl_assert(ctx != NULL && msg != NULL && msg->header != NULL))
|
||||
return 0;
|
||||
hdr = OSSL_CMP_MSG_get0_header(msg);
|
||||
|
||||
/* validate sender name of received msg */
|
||||
if (hdr->sender->type != GEN_DIRNAME) {
|
||||
CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
|
||||
return 0; /* TODO FR#42: support for more than X509_NAME */
|
||||
}
|
||||
/*
|
||||
* Compare actual sender name of response with expected sender name.
|
||||
* Mitigates risk to accept misused PBM secret
|
||||
* or misused certificate of an unauthorized entity of a trusted hierarchy.
|
||||
*/
|
||||
expected_sender = ctx->expected_sender;
|
||||
if (expected_sender == NULL && ctx->srvCert != NULL)
|
||||
expected_sender = X509_get_subject_name(ctx->srvCert);
|
||||
if (!check_name(ctx, 0, "sender DN field", hdr->sender->d.directoryName,
|
||||
"expected sender", expected_sender))
|
||||
return 0;
|
||||
/* Note: if recipient was NULL-DN it could be learned here if needed */
|
||||
|
||||
if (sk_X509_num(msg->extraCerts) > 10)
|
||||
ossl_cmp_warn(ctx,
|
||||
"received CMP message contains more than 10 extraCerts");
|
||||
/*
|
||||
* Store any provided extraCerts in ctx for use in OSSL_CMP_validate_msg()
|
||||
* and for future use, such that they are available to ctx->certConf_cb and
|
||||
* the peer does not need to send them again in the same transaction.
|
||||
* Note that it does not help validating the message before storing the
|
||||
* extraCerts because they do not belong to the protected msg part anyway.
|
||||
* For efficiency, the extraCerts are prepended so they get used first.
|
||||
*/
|
||||
if (!ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, msg->extraCerts,
|
||||
0 /* this allows self-issued certs */,
|
||||
1 /* no_dups */, 1 /* prepend */))
|
||||
return 0;
|
||||
|
||||
/* validate message protection */
|
||||
if (msg->header->protectionAlg != 0) {
|
||||
if (hdr->protectionAlg != NULL) {
|
||||
/* detect explicitly permitted exceptions for invalid protection */
|
||||
if (!OSSL_CMP_validate_msg(ctx, msg)
|
||||
&& (cb == NULL || (*cb)(ctx, msg, 1, cb_arg) <= 0)) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_ERROR_VALIDATING_PROTECTION);
|
||||
return -1;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
@@ -712,34 +715,34 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
if (cb == NULL || (*cb)(ctx, msg, 0, cb_arg) <= 0) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_MISSING_PROTECTION);
|
||||
return -1;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* check CMP version number in header */
|
||||
if (ossl_cmp_hdr_get_pvno(OSSL_CMP_MSG_get0_header(msg)) != OSSL_CMP_PVNO) {
|
||||
if (ossl_cmp_hdr_get_pvno(hdr) != OSSL_CMP_PVNO) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PVNO);
|
||||
return -1;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((rcvd_type = ossl_cmp_msg_get_bodytype(msg)) < 0) {
|
||||
if (ossl_cmp_msg_get_bodytype(msg) < 0) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_PKIBODY_ERROR);
|
||||
return -1;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* compare received transactionID with the expected one in previous msg */
|
||||
if (ctx->transactionID != NULL
|
||||
&& (msg->header->transactionID == NULL
|
||||
&& (hdr->transactionID == NULL
|
||||
|| ASN1_OCTET_STRING_cmp(ctx->transactionID,
|
||||
msg->header->transactionID) != 0)) {
|
||||
hdr->transactionID) != 0)) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_TRANSACTIONID_UNMATCHED);
|
||||
return -1;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -747,10 +750,10 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
if (ctx->senderNonce != NULL
|
||||
&& (msg->header->recipNonce == NULL
|
||||
|| ASN1_OCTET_STRING_cmp(ctx->senderNonce,
|
||||
msg->header->recipNonce) != 0)) {
|
||||
hdr->recipNonce) != 0)) {
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
CMPerr(0, CMP_R_RECIPNONCE_UNMATCHED);
|
||||
return -1;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -759,26 +762,40 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
* the senderNonce of the previous message in the transaction.
|
||||
* --> Store for setting in next message
|
||||
*/
|
||||
if (!ossl_cmp_ctx_set1_recipNonce(ctx, msg->header->senderNonce))
|
||||
return -1;
|
||||
if (!ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce))
|
||||
return 0;
|
||||
|
||||
/* if not yet present, learn transactionID */
|
||||
if (ctx->transactionID == NULL
|
||||
&& !OSSL_CMP_CTX_set1_transactionID(ctx, msg->header->transactionID))
|
||||
return -1;
|
||||
&& !OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Store any provided extraCerts in ctx for future use,
|
||||
* such that they are available to ctx->certConf_cb and
|
||||
* the peer does not need to send them again in the same transaction.
|
||||
* For efficiency, the extraCerts are prepended so they get used first.
|
||||
*/
|
||||
if (!ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, msg->extraCerts,
|
||||
0 /* this allows self-issued certs */,
|
||||
1 /* no_dups */, 1 /* prepend */))
|
||||
return -1;
|
||||
if (ossl_cmp_hdr_get_protection_nid(hdr) == NID_id_PasswordBasedMAC) {
|
||||
/*
|
||||
* RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is
|
||||
* "shared secret information", then any certificate transported in
|
||||
* the caPubs field may be directly trusted as a root CA
|
||||
* certificate by the initiator.'
|
||||
*/
|
||||
switch (ossl_cmp_msg_get_bodytype(msg)) {
|
||||
case OSSL_CMP_PKIBODY_IP:
|
||||
case OSSL_CMP_PKIBODY_CP:
|
||||
case OSSL_CMP_PKIBODY_KUP:
|
||||
case OSSL_CMP_PKIBODY_CCP:
|
||||
if (ctx->trusted != NULL) {
|
||||
STACK_OF(X509) *certs = msg->body->value.ip->caPubs;
|
||||
/* value.ip is same for cp, kup, and ccp */
|
||||
|
||||
return rcvd_type;
|
||||
if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0))
|
||||
/* adds both self-issued and not self-issued certs */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified)
|
||||
|
||||
@@ -52,6 +52,10 @@ static const ERR_STRING_DATA CMS_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_KEY), "error setting key"},
|
||||
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_RECIPIENTINFO),
|
||||
"error setting recipientinfo"},
|
||||
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE),
|
||||
"ess no signing certid attribute"},
|
||||
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR),
|
||||
"ess signing certid mismatch error"},
|
||||
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),
|
||||
"invalid encrypted key length"},
|
||||
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER),
|
||||
|
||||
+82
-10
@@ -21,6 +21,9 @@
|
||||
|
||||
DEFINE_STACK_OF(GENERAL_NAMES)
|
||||
DEFINE_STACK_OF(CMS_SignerInfo)
|
||||
DEFINE_STACK_OF(ESS_CERT_ID)
|
||||
DEFINE_STACK_OF(ESS_CERT_ID_V2)
|
||||
DEFINE_STACK_OF(X509)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
|
||||
|
||||
@@ -29,33 +32,100 @@ IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
|
||||
int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
|
||||
{
|
||||
ASN1_STRING *str;
|
||||
CMS_ReceiptRequest *rr = NULL;
|
||||
if (prr)
|
||||
CMS_ReceiptRequest *rr;
|
||||
ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_receiptRequest);
|
||||
|
||||
if (prr != NULL)
|
||||
*prr = NULL;
|
||||
str = CMS_signed_get0_data_by_OBJ(si,
|
||||
OBJ_nid2obj
|
||||
(NID_id_smime_aa_receiptRequest), -3,
|
||||
V_ASN1_SEQUENCE);
|
||||
if (!str)
|
||||
str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE);
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest));
|
||||
if (!rr)
|
||||
if (rr == NULL)
|
||||
return -1;
|
||||
if (prr)
|
||||
if (prr != NULL)
|
||||
*prr = rr;
|
||||
else
|
||||
CMS_ReceiptRequest_free(rr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
First, get the ESS_SIGNING_CERT(V2) signed attribute from |si|.
|
||||
Then check matching of each cert of trust |chain| with one of
|
||||
the |cert_ids|(Hash+IssuerID) list from this ESS_SIGNING_CERT.
|
||||
Derived from ts_check_signing_certs()
|
||||
*/
|
||||
int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain)
|
||||
{
|
||||
ESS_SIGNING_CERT *ss = NULL;
|
||||
ESS_SIGNING_CERT_V2 *ssv2 = NULL;
|
||||
X509 *cert;
|
||||
int i = 0, ret = 0;
|
||||
|
||||
if (cms_signerinfo_get_signing_cert(si, &ss) > 0 && ss->cert_ids != NULL) {
|
||||
STACK_OF(ESS_CERT_ID) *cert_ids = ss->cert_ids;
|
||||
|
||||
cert = sk_X509_value(chain, 0);
|
||||
if (ess_find_cert(cert_ids, cert) != 0)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Check the other certificates of the chain.
|
||||
* Fail if no signing certificate ids found for each certificate.
|
||||
*/
|
||||
if (sk_ESS_CERT_ID_num(cert_ids) > 1) {
|
||||
/* for each chain cert, try to find its cert id */
|
||||
for (i = 1; i < sk_X509_num(chain); ++i) {
|
||||
cert = sk_X509_value(chain, i);
|
||||
if (ess_find_cert(cert_ids, cert) < 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
} else if (cms_signerinfo_get_signing_cert_v2(si, &ssv2) > 0
|
||||
&& ssv2->cert_ids!= NULL) {
|
||||
STACK_OF(ESS_CERT_ID_V2) *cert_ids_v2 = ssv2->cert_ids;
|
||||
|
||||
cert = sk_X509_value(chain, 0);
|
||||
if (ess_find_cert_v2(cert_ids_v2, cert) != 0)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Check the other certificates of the chain.
|
||||
* Fail if no signing certificate ids found for each certificate.
|
||||
*/
|
||||
if (sk_ESS_CERT_ID_V2_num(cert_ids_v2) > 1) {
|
||||
/* for each chain cert, try to find its cert id */
|
||||
for (i = 1; i < sk_X509_num(chain); ++i) {
|
||||
cert = sk_X509_value(chain, i);
|
||||
if (ess_find_cert_v2(cert_ids_v2, cert) < 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CMSerr(CMS_F_ESS_CHECK_SIGNING_CERTS,
|
||||
CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE);
|
||||
return 0;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
if (!ret)
|
||||
CMSerr(CMS_F_ESS_CHECK_SIGNING_CERTS,
|
||||
CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR);
|
||||
|
||||
ESS_SIGNING_CERT_free(ss);
|
||||
ESS_SIGNING_CERT_V2_free(ssv2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
|
||||
int allorfirst,
|
||||
STACK_OF(GENERAL_NAMES)
|
||||
*receiptList, STACK_OF(GENERAL_NAMES)
|
||||
*receiptsTo)
|
||||
{
|
||||
CMS_ReceiptRequest *rr = NULL;
|
||||
CMS_ReceiptRequest *rr;
|
||||
|
||||
rr = CMS_ReceiptRequest_new();
|
||||
if (rr == NULL)
|
||||
@@ -145,6 +215,7 @@ static int cms_msgSigDigest(CMS_SignerInfo *si,
|
||||
unsigned char *dig, unsigned int *diglen)
|
||||
{
|
||||
const EVP_MD *md;
|
||||
|
||||
md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
|
||||
if (md == NULL)
|
||||
return 0;
|
||||
@@ -160,6 +231,7 @@ int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
|
||||
{
|
||||
unsigned char dig[EVP_MAX_MD_SIZE];
|
||||
unsigned int diglen;
|
||||
|
||||
if (!cms_msgSigDigest(src, dig, &diglen)) {
|
||||
CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR);
|
||||
return 0;
|
||||
|
||||
@@ -421,6 +421,9 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *
|
||||
/* SignerInfo routines */
|
||||
int CMS_si_check_attributes(const CMS_SignerInfo *si);
|
||||
|
||||
/* ESS routines */
|
||||
int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain);
|
||||
|
||||
DECLARE_ASN1_ITEM(CMS_CertificateChoices)
|
||||
DECLARE_ASN1_ITEM(CMS_DigestedData)
|
||||
DECLARE_ASN1_ITEM(CMS_EncryptedData)
|
||||
|
||||
+35
-6
@@ -233,7 +233,8 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
|
||||
static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
|
||||
X509_STORE *store,
|
||||
STACK_OF(X509) *certs,
|
||||
STACK_OF(X509_CRL) *crls)
|
||||
STACK_OF(X509_CRL) *crls,
|
||||
STACK_OF(X509) **chain)
|
||||
{
|
||||
X509_STORE_CTX *ctx = X509_STORE_CTX_new();
|
||||
X509 *signer;
|
||||
@@ -262,6 +263,10 @@ static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
|
||||
goto err;
|
||||
}
|
||||
r = 1;
|
||||
|
||||
/* also send back the trust chain when required */
|
||||
if (chain != NULL)
|
||||
*chain = X509_STORE_CTX_get1_chain(ctx);
|
||||
err:
|
||||
X509_STORE_CTX_free(ctx);
|
||||
return r;
|
||||
@@ -275,9 +280,11 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
STACK_OF(CMS_SignerInfo) *sinfos;
|
||||
STACK_OF(X509) *cms_certs = NULL;
|
||||
STACK_OF(X509_CRL) *crls = NULL;
|
||||
STACK_OF(X509) **si_chains = NULL;
|
||||
X509 *signer;
|
||||
int i, scount = 0, ret = 0;
|
||||
BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL;
|
||||
int cadesVerify = (flags & CMS_CADES) != 0;
|
||||
|
||||
if (!dcont && !check_content(cms))
|
||||
return 0;
|
||||
@@ -312,27 +319,44 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
}
|
||||
|
||||
/* Attempt to verify all signers certs */
|
||||
/* at this point scount == sk_CMS_SignerInfo_num(sinfos) */
|
||||
|
||||
if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) {
|
||||
if ((flags & CMS_NO_SIGNER_CERT_VERIFY) == 0 || cadesVerify) {
|
||||
if (cadesVerify) {
|
||||
/* Certificate trust chain is required to check CAdES signature */
|
||||
si_chains = OPENSSL_zalloc(scount * sizeof(si_chains[0]));
|
||||
if (si_chains == NULL) {
|
||||
CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
cms_certs = CMS_get1_certs(cms);
|
||||
if (!(flags & CMS_NOCRL))
|
||||
crls = CMS_get1_crls(cms);
|
||||
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
|
||||
for (i = 0; i < scount; i++) {
|
||||
si = sk_CMS_SignerInfo_value(sinfos, i);
|
||||
if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls))
|
||||
|
||||
if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls,
|
||||
si_chains ? &si_chains[i] : NULL))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Attempt to verify all SignerInfo signed attribute signatures */
|
||||
|
||||
if (!(flags & CMS_NO_ATTR_VERIFY)) {
|
||||
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
|
||||
if ((flags & CMS_NO_ATTR_VERIFY) == 0 || cadesVerify) {
|
||||
for (i = 0; i < scount; i++) {
|
||||
si = sk_CMS_SignerInfo_value(sinfos, i);
|
||||
if (CMS_signed_get_attr_count(si) < 0)
|
||||
continue;
|
||||
if (CMS_SignerInfo_verify(si) <= 0)
|
||||
goto err;
|
||||
if (cadesVerify) {
|
||||
STACK_OF(X509) *si_chain = si_chains ? si_chains[i] : NULL;
|
||||
|
||||
if (ess_check_signing_certs(si, si_chain) <= 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,6 +444,11 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||
BIO_free_all(tmpout);
|
||||
|
||||
err2:
|
||||
if (si_chains != NULL) {
|
||||
for (i = 0; i < scount; ++i)
|
||||
sk_X509_pop_free(si_chains[i], X509_free);
|
||||
OPENSSL_free(si_chains);
|
||||
}
|
||||
sk_X509_pop_free(cms_certs, X509_free);
|
||||
sk_X509_CRL_pop_free(crls, X509_CRL_free);
|
||||
|
||||
|
||||
@@ -516,25 +516,23 @@ void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
|
||||
|
||||
char *CONF_get1_default_config_file(void)
|
||||
{
|
||||
const char *t;
|
||||
char *file, *sep = "";
|
||||
int len;
|
||||
size_t size;
|
||||
|
||||
if ((file = ossl_safe_getenv("OPENSSL_CONF")) != NULL)
|
||||
return OPENSSL_strdup(file);
|
||||
|
||||
len = strlen(X509_get_default_cert_area());
|
||||
t = X509_get_default_cert_area();
|
||||
#ifndef OPENSSL_SYS_VMS
|
||||
len++;
|
||||
sep = "/";
|
||||
#endif
|
||||
len += strlen(OPENSSL_CONF);
|
||||
|
||||
file = OPENSSL_malloc(len + 1);
|
||||
size = strlen(t) + strlen(sep) + strlen(OPENSSL_CONF) + 1;
|
||||
file = OPENSSL_malloc(size);
|
||||
|
||||
if (file == NULL)
|
||||
return NULL;
|
||||
BIO_snprintf(file, len + 1, "%s%s%s", X509_get_default_cert_area(),
|
||||
sep, OPENSSL_CONF);
|
||||
BIO_snprintf(file, size, "%s%s%s", t, sep, OPENSSL_CONF);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
+44
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -16,8 +16,11 @@
|
||||
struct algorithm_data_st {
|
||||
OPENSSL_CTX *libctx;
|
||||
int operation_id; /* May be zero for finding them all */
|
||||
int (*pre)(OSSL_PROVIDER *, int operation_id, void *data, int *result);
|
||||
void (*fn)(OSSL_PROVIDER *, const OSSL_ALGORITHM *, int no_store,
|
||||
void *data);
|
||||
int (*post)(OSSL_PROVIDER *, int operation_id, int no_store, void *data,
|
||||
int *result);
|
||||
void *data;
|
||||
};
|
||||
|
||||
@@ -36,19 +39,48 @@ static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata)
|
||||
for (cur_operation = first_operation;
|
||||
cur_operation <= last_operation;
|
||||
cur_operation++) {
|
||||
const OSSL_ALGORITHM *map =
|
||||
ossl_provider_query_operation(provider, cur_operation,
|
||||
&no_store);
|
||||
const OSSL_ALGORITHM *map = NULL;
|
||||
int ret;
|
||||
|
||||
/* Do we fulfill pre-conditions? */
|
||||
if (data->pre == NULL) {
|
||||
/* If there is no pre-condition function, assume "yes" */
|
||||
ret = 1;
|
||||
} else {
|
||||
if (!data->pre(provider, cur_operation, data->data, &ret))
|
||||
/* Error, bail out! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If pre-condition not fulfilled, go to the next operation */
|
||||
if (!ret)
|
||||
continue;
|
||||
|
||||
map = ossl_provider_query_operation(provider, cur_operation,
|
||||
&no_store);
|
||||
if (map == NULL)
|
||||
continue;
|
||||
|
||||
ok = 1; /* As long as we've found *something* */
|
||||
while (map->algorithm_names != NULL) {
|
||||
const OSSL_ALGORITHM *thismap = map++;
|
||||
|
||||
data->fn(provider, thismap, no_store, data->data);
|
||||
}
|
||||
|
||||
/* Do we fulfill post-conditions? */
|
||||
if (data->post == NULL) {
|
||||
/* If there is no post-condition function, assume "yes" */
|
||||
ret = 1;
|
||||
} else {
|
||||
if (!data->post(provider, cur_operation, no_store, data->data,
|
||||
&ret))
|
||||
/* Error, bail out! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If post-condition fulfilled, set general success */
|
||||
if (ret)
|
||||
ok = 1;
|
||||
}
|
||||
|
||||
return ok;
|
||||
@@ -56,16 +88,22 @@ static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata)
|
||||
|
||||
void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id,
|
||||
OSSL_PROVIDER *provider,
|
||||
int (*pre)(OSSL_PROVIDER *, int operation_id,
|
||||
void *data, int *result),
|
||||
void (*fn)(OSSL_PROVIDER *provider,
|
||||
const OSSL_ALGORITHM *algo,
|
||||
int no_store, void *data),
|
||||
int (*post)(OSSL_PROVIDER *, int operation_id,
|
||||
int no_store, void *data, int *result),
|
||||
void *data)
|
||||
{
|
||||
struct algorithm_data_st cbdata;
|
||||
struct algorithm_data_st cbdata = { 0, };
|
||||
|
||||
cbdata.libctx = libctx;
|
||||
cbdata.operation_id = operation_id;
|
||||
cbdata.pre = pre;
|
||||
cbdata.fn = fn;
|
||||
cbdata.post = post;
|
||||
cbdata.data = data;
|
||||
|
||||
if (provider == NULL)
|
||||
|
||||
+41
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -24,6 +24,42 @@ struct construct_data_st {
|
||||
void *mcm_data;
|
||||
};
|
||||
|
||||
static int ossl_method_construct_precondition(OSSL_PROVIDER *provider,
|
||||
int operation_id, void *cbdata,
|
||||
int *result)
|
||||
{
|
||||
if (!ossl_assert(result != NULL)) {
|
||||
ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ossl_provider_test_operation_bit(provider, operation_id, result))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The result we get tells if methods have already been constructed.
|
||||
* However, we want to tell whether construction should happen (true)
|
||||
* or not (false), which is the opposite of what we got.
|
||||
*/
|
||||
*result = !*result;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ossl_method_construct_postcondition(OSSL_PROVIDER *provider,
|
||||
int operation_id, int no_store,
|
||||
void *cbdata, int *result)
|
||||
{
|
||||
if (!ossl_assert(result != NULL)) {
|
||||
ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*result = 1;
|
||||
return no_store != 0
|
||||
|| ossl_provider_set_operation_bit(provider, operation_id);
|
||||
}
|
||||
|
||||
static void ossl_method_construct_this(OSSL_PROVIDER *provider,
|
||||
const OSSL_ALGORITHM *algo,
|
||||
int no_store, void *cbdata)
|
||||
@@ -86,7 +122,10 @@ void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id,
|
||||
cbdata.mcm = mcm;
|
||||
cbdata.mcm_data = mcm_data;
|
||||
ossl_algorithm_do_all(libctx, operation_id, NULL,
|
||||
ossl_method_construct_this, &cbdata);
|
||||
ossl_method_construct_precondition,
|
||||
ossl_method_construct_this,
|
||||
ossl_method_construct_postcondition,
|
||||
&cbdata);
|
||||
|
||||
method = mcm->get(libctx, cbdata.store, mcm_data);
|
||||
mcm->dealloc_tmp_store(cbdata.store);
|
||||
|
||||
+1
-20
@@ -461,25 +461,6 @@ int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns 0 for equal, -1 for a < b or error on a, 1 for a > b or error on b */
|
||||
static int X509_PUBKEY_cmp(X509_PUBKEY *a, X509_PUBKEY *b)
|
||||
{
|
||||
X509_ALGOR *algA = NULL, *algB = NULL;
|
||||
int res = 0;
|
||||
|
||||
if (a == b)
|
||||
return 0;
|
||||
if (a == NULL || !X509_PUBKEY_get0_param(NULL, NULL, NULL, &algA, a)
|
||||
|| algA == NULL)
|
||||
return -1;
|
||||
if (b == NULL || !X509_PUBKEY_get0_param(NULL, NULL, NULL, &algB, b)
|
||||
|| algB == NULL)
|
||||
return 1;
|
||||
if ((res = X509_ALGOR_cmp(algA, algB)) != 0)
|
||||
return res;
|
||||
return EVP_PKEY_cmp(X509_PUBKEY_get0(a), X509_PUBKEY_get0(b));
|
||||
}
|
||||
|
||||
/* verifies the Proof-of-Possession of the request with the given rid in reqs */
|
||||
int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
|
||||
int rid, int acceptRAVerified)
|
||||
@@ -522,7 +503,7 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
|
||||
CRMFerr(0, CRMF_R_POPO_MISSING_PUBLIC_KEY);
|
||||
return 0;
|
||||
}
|
||||
if (X509_PUBKEY_cmp(pubkey, sig->poposkInput->publicKey) != 0) {
|
||||
if (X509_PUBKEY_eq(pubkey, sig->poposkInput->publicKey) != 1) {
|
||||
CRMFerr(0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,6 @@ struct ossl_crmf_certid_st {
|
||||
GENERAL_NAME *issuer;
|
||||
ASN1_INTEGER *serialNumber;
|
||||
} /* OSSL_CRMF_CERTID */;
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID)
|
||||
|
||||
/*-
|
||||
* SinglePubInfo ::= SEQUENCE {
|
||||
|
||||
@@ -202,8 +202,8 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
|
||||
macparams[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
|
||||
basekey, bklen);
|
||||
if ((mac = EVP_MAC_fetch(NULL, "HMAC", NULL)) == NULL
|
||||
|| (mctx = EVP_MAC_CTX_new(mac)) == NULL
|
||||
|| !EVP_MAC_CTX_set_params(mctx, macparams)
|
||||
|| (mctx = EVP_MAC_new_ctx(mac)) == NULL
|
||||
|| !EVP_MAC_set_ctx_params(mctx, macparams)
|
||||
|| !EVP_MAC_init(mctx)
|
||||
|| !EVP_MAC_update(mctx, msg, msglen)
|
||||
|| !EVP_MAC_final(mctx, mac_res, outlen, EVP_MAX_MD_SIZE))
|
||||
@@ -214,7 +214,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp,
|
||||
err:
|
||||
/* cleanup */
|
||||
OPENSSL_cleanse(basekey, bklen);
|
||||
EVP_MAC_CTX_free(mctx);
|
||||
EVP_MAC_free_ctx(mctx);
|
||||
EVP_MAC_free(mac);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ static void int_dh_free(EVP_PKEY *pkey)
|
||||
DH_free(pkey->pkey.dh);
|
||||
}
|
||||
|
||||
static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
static int dh_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
|
||||
{
|
||||
const unsigned char *p, *pm;
|
||||
int pklen, pmlen;
|
||||
@@ -438,7 +438,7 @@ static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
|
||||
return dh_buf2key(EVP_PKEY_get0_DH(pkey), arg2, arg1);
|
||||
case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
|
||||
return dh_key2buf(EVP_PKEY_get0_DH(pkey), arg2);
|
||||
return dh_key2buf(EVP_PKEY_get0_DH(pkey), arg2, 0, 1);
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -14,6 +14,7 @@
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
static const ERR_STRING_DATA DH_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_BAD_FFC_PARAMETERS), "bad ffc parameters"},
|
||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_BAD_GENERATOR), "bad generator"},
|
||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_BN_DECODE_ERROR), "bn decode error"},
|
||||
{ERR_PACK(ERR_LIB_DH, 0, DH_R_BN_ERROR), "bn error"},
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ int dh_get_named_group_uid_from_size(int pbits)
|
||||
* Just choose an approved safe prime group.
|
||||
* The alternative to this is to generate FIPS186-4 domain parameters i.e.
|
||||
* return dh_generate_ffc_parameters(ret, prime_len, 0, NULL, cb);
|
||||
* As the FIPS186-4 generated params are for backwards compatability,
|
||||
* As the FIPS186-4 generated params are for backwards compatibility,
|
||||
* the safe prime group should be used as the default.
|
||||
*/
|
||||
int nid;
|
||||
|
||||
+3
-3
@@ -46,7 +46,7 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen,
|
||||
return 0;
|
||||
|
||||
kdf = EVP_KDF_fetch(provctx, OSSL_KDF_NAME_X942KDF, NULL);
|
||||
if ((kctx = EVP_KDF_CTX_new(kdf)) == NULL)
|
||||
if ((kctx = EVP_KDF_new_ctx(kdf)) == NULL)
|
||||
goto err;
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
|
||||
(char *)mdname, 0);
|
||||
@@ -58,10 +58,10 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen,
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG,
|
||||
(char *)oid_sn, 0);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
ret = EVP_KDF_CTX_set_params(kctx, params) > 0
|
||||
ret = EVP_KDF_set_ctx_params(kctx, params) > 0
|
||||
&& EVP_KDF_derive(kctx, out, outlen) > 0;
|
||||
err:
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
EVP_KDF_free(kdf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+25
-15
@@ -351,10 +351,10 @@ err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out)
|
||||
size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out, size_t size, int alloc)
|
||||
{
|
||||
const BIGNUM *pubkey;
|
||||
unsigned char *pbuf;
|
||||
unsigned char *pbuf = NULL;
|
||||
const BIGNUM *p;
|
||||
int p_size;
|
||||
|
||||
@@ -366,19 +366,29 @@ size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out)
|
||||
DHerr(DH_F_DH_KEY2BUF, DH_R_INVALID_PUBKEY);
|
||||
return 0;
|
||||
}
|
||||
if ((pbuf = OPENSSL_malloc(p_size)) == NULL) {
|
||||
DHerr(DH_F_DH_KEY2BUF, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
if (pbuf_out != NULL && (alloc || *pbuf_out != NULL)) {
|
||||
if (!alloc) {
|
||||
if (size >= (size_t)p_size)
|
||||
pbuf = *pbuf_out;
|
||||
} else {
|
||||
pbuf = OPENSSL_malloc(p_size);
|
||||
}
|
||||
|
||||
if (pbuf == NULL) {
|
||||
DHerr(DH_F_DH_KEY2BUF, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* As per Section 4.2.8.1 of RFC 8446 left pad public
|
||||
* key with zeros to the size of p
|
||||
*/
|
||||
if (BN_bn2binpad(pubkey, pbuf, p_size) < 0) {
|
||||
if (alloc)
|
||||
OPENSSL_free(pbuf);
|
||||
DHerr(DH_F_DH_KEY2BUF, DH_R_BN_ERROR);
|
||||
return 0;
|
||||
}
|
||||
*pbuf_out = pbuf;
|
||||
}
|
||||
/*
|
||||
* As per Section 4.2.8.1 of RFC 8446 left pad public
|
||||
* key with zeros to the size of p
|
||||
*/
|
||||
if (BN_bn2binpad(pubkey, pbuf, p_size) < 0) {
|
||||
OPENSSL_free(pbuf);
|
||||
DHerr(DH_F_DH_KEY2BUF, DH_R_BN_ERROR);
|
||||
return 0;
|
||||
}
|
||||
*pbuf_out = pbuf;
|
||||
return p_size;
|
||||
}
|
||||
+3
-3
@@ -475,7 +475,7 @@ int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen)
|
||||
EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL);
|
||||
#endif
|
||||
|
||||
*p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GENERATOR, &gen);
|
||||
*p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_DH_GENERATOR, &gen);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
return EVP_PKEY_CTX_set_params(ctx, params);
|
||||
@@ -500,7 +500,7 @@ int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen)
|
||||
if (name == NULL)
|
||||
return 0;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_GROUP,
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DH_GROUP,
|
||||
(void *)name, 0);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
return EVP_PKEY_CTX_set_params(ctx, params);
|
||||
@@ -531,7 +531,7 @@ int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid)
|
||||
if (name == NULL)
|
||||
return 0;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_GROUP,
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DH_GROUP,
|
||||
(void *)name, 0);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
return EVP_PKEY_CTX_set_params(ctx, params);
|
||||
|
||||
@@ -58,6 +58,3 @@ struct dh_method {
|
||||
int (*generate_params) (DH *dh, int prime_len, int generator,
|
||||
BN_GENCB *cb);
|
||||
};
|
||||
|
||||
int dh_buf2key(DH *key, const unsigned char *buf, size_t len);
|
||||
size_t dh_key2buf(const DH *dh, unsigned char **pbuf);
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "internal/ffc.h"
|
||||
#include "dsa_local.h"
|
||||
|
||||
static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
static int dsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
|
||||
{
|
||||
const unsigned char *p, *pm;
|
||||
int pklen, pmlen;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -14,6 +14,7 @@
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
static const ERR_STRING_DATA DSA_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BAD_FFC_PARAMETERS), "bad ffc parameters"},
|
||||
{ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BAD_Q_VALUE), "bad q value"},
|
||||
{ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BN_DECODE_ERROR), "bn decode error"},
|
||||
{ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BN_ERROR), "bn error"},
|
||||
|
||||
@@ -221,7 +221,7 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
dctx->nbits, dctx->qbits, dctx->pmd,
|
||||
&res, pcb);
|
||||
BN_GENCB_free(pcb);
|
||||
if (ret)
|
||||
if (ret > 0)
|
||||
EVP_PKEY_assign_DSA(pkey, dsa);
|
||||
else
|
||||
DSA_free(dsa);
|
||||
|
||||
@@ -1,2082 +0,0 @@
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright (c) 2014, Intel Corporation. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
#
|
||||
# Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1)
|
||||
# (1) Intel Corporation, Israel Development Center, Haifa, Israel
|
||||
# (2) University of Haifa, Israel
|
||||
#
|
||||
# Reference:
|
||||
# S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with
|
||||
# 256 Bit Primes"
|
||||
|
||||
# $output is the last argument if it looks like a file (it has an extension)
|
||||
# $flavour is the first argument if it doesn't look like a file
|
||||
$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
|
||||
$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
|
||||
|
||||
$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
|
||||
|
||||
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
|
||||
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
|
||||
die "can't locate x86_64-xlate.pl";
|
||||
|
||||
open OUT,"| \"$^X\" $xlate $flavour \"$output\""
|
||||
or die "can't call $xlate: $!";
|
||||
*STDOUT=*OUT;
|
||||
|
||||
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
|
||||
=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
|
||||
$avx = ($1>=2.19) + ($1>=2.22);
|
||||
$addx = ($1>=2.23);
|
||||
}
|
||||
|
||||
if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
|
||||
`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
|
||||
$avx = ($1>=2.09) + ($1>=2.10);
|
||||
$addx = ($1>=2.10);
|
||||
}
|
||||
|
||||
if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
|
||||
`ml64 2>&1` =~ /Version ([0-9]+)\./) {
|
||||
$avx = ($1>=10) + ($1>=11);
|
||||
$addx = ($1>=12);
|
||||
}
|
||||
|
||||
if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+)\.([0-9]+)/) {
|
||||
my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
|
||||
$avx = ($ver>=3.0) + ($ver>=3.01);
|
||||
$addx = ($ver>=3.03);
|
||||
}
|
||||
|
||||
if ($avx>=2) {{
|
||||
$digit_size = "\$29";
|
||||
$n_digits = "\$9";
|
||||
|
||||
$code.=<<___;
|
||||
.text
|
||||
|
||||
.align 64
|
||||
.LAVX2_AND_MASK:
|
||||
.LAVX2_POLY:
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x00040000, 0x00040000, 0x00040000, 0x00040000
|
||||
.quad 0x1fe00000, 0x1fe00000, 0x1fe00000, 0x1fe00000
|
||||
.quad 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff
|
||||
|
||||
.LAVX2_POLY_x2:
|
||||
.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
|
||||
.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
|
||||
.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
|
||||
.quad 0x400007FC, 0x400007FC, 0x400007FC, 0x400007FC
|
||||
.quad 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE
|
||||
.quad 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE
|
||||
.quad 0x400FFFFE, 0x400FFFFE, 0x400FFFFE, 0x400FFFFE
|
||||
.quad 0x7F7FFFFE, 0x7F7FFFFE, 0x7F7FFFFE, 0x7F7FFFFE
|
||||
.quad 0x03FFFFFC, 0x03FFFFFC, 0x03FFFFFC, 0x03FFFFFC
|
||||
|
||||
.LAVX2_POLY_x8:
|
||||
.quad 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8
|
||||
.quad 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8
|
||||
.quad 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8
|
||||
.quad 0x80000FF8, 0x80000FF8, 0x80000FF8, 0x80000FF8
|
||||
.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
|
||||
.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
|
||||
.quad 0x801FFFFC, 0x801FFFFC, 0x801FFFFC, 0x801FFFFC
|
||||
.quad 0xFEFFFFFC, 0xFEFFFFFC, 0xFEFFFFFC, 0xFEFFFFFC
|
||||
.quad 0x07FFFFF8, 0x07FFFFF8, 0x07FFFFF8, 0x07FFFFF8
|
||||
|
||||
.LONE:
|
||||
.quad 0x00000020, 0x00000020, 0x00000020, 0x00000020
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x1fffc000, 0x1fffc000, 0x1fffc000, 0x1fffc000
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1f7fffff, 0x1f7fffff, 0x1f7fffff, 0x1f7fffff
|
||||
.quad 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
|
||||
# RR = 2^266 mod p in AVX2 format, to transform from the native OpenSSL
|
||||
# Montgomery form (*2^256) to our format (*2^261)
|
||||
|
||||
.LTO_MONT_AVX2:
|
||||
.quad 0x00000400, 0x00000400, 0x00000400, 0x00000400
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x1ff80000, 0x1ff80000, 0x1ff80000, 0x1ff80000
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x00000003, 0x00000003, 0x00000003, 0x00000003
|
||||
|
||||
.LFROM_MONT_AVX2:
|
||||
.quad 0x00000001, 0x00000001, 0x00000001, 0x00000001
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.quad 0x1ffffe00, 0x1ffffe00, 0x1ffffe00, 0x1ffffe00
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
|
||||
.quad 0x1ffbffff, 0x1ffbffff, 0x1ffbffff, 0x1ffbffff
|
||||
.quad 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff
|
||||
.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
|
||||
.LIntOne:
|
||||
.long 1,1,1,1,1,1,1,1
|
||||
___
|
||||
|
||||
{
|
||||
# This function receives a pointer to an array of four affine points
|
||||
# (X, Y, <1>) and rearranges the data for AVX2 execution, while
|
||||
# converting it to 2^29 radix redundant form
|
||||
|
||||
my ($X0,$X1,$X2,$X3, $Y0,$Y1,$Y2,$Y3,
|
||||
$T0,$T1,$T2,$T3, $T4,$T5,$T6,$T7)=map("%ymm$_",(0..15));
|
||||
|
||||
$code.=<<___;
|
||||
.globl ecp_nistz256_avx2_transpose_convert
|
||||
.type ecp_nistz256_avx2_transpose_convert,\@function,2
|
||||
.align 64
|
||||
ecp_nistz256_avx2_transpose_convert:
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -8-16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
# Load the data
|
||||
vmovdqa 32*0(%rsi), $X0
|
||||
lea 112(%rsi), %rax # size optimization
|
||||
vmovdqa 32*1(%rsi), $Y0
|
||||
lea .LAVX2_AND_MASK(%rip), %rdx
|
||||
vmovdqa 32*2(%rsi), $X1
|
||||
vmovdqa 32*3(%rsi), $Y1
|
||||
vmovdqa 32*4-112(%rax), $X2
|
||||
vmovdqa 32*5-112(%rax), $Y2
|
||||
vmovdqa 32*6-112(%rax), $X3
|
||||
vmovdqa 32*7-112(%rax), $Y3
|
||||
|
||||
# Transpose X and Y independently
|
||||
vpunpcklqdq $X1, $X0, $T0 # T0 = [B2 A2 B0 A0]
|
||||
vpunpcklqdq $X3, $X2, $T1 # T1 = [D2 C2 D0 C0]
|
||||
vpunpckhqdq $X1, $X0, $T2 # T2 = [B3 A3 B1 A1]
|
||||
vpunpckhqdq $X3, $X2, $T3 # T3 = [D3 C3 D1 C1]
|
||||
|
||||
vpunpcklqdq $Y1, $Y0, $T4
|
||||
vpunpcklqdq $Y3, $Y2, $T5
|
||||
vpunpckhqdq $Y1, $Y0, $T6
|
||||
vpunpckhqdq $Y3, $Y2, $T7
|
||||
|
||||
vperm2i128 \$0x20, $T1, $T0, $X0 # X0 = [D0 C0 B0 A0]
|
||||
vperm2i128 \$0x20, $T3, $T2, $X1 # X1 = [D1 C1 B1 A1]
|
||||
vperm2i128 \$0x31, $T1, $T0, $X2 # X2 = [D2 C2 B2 A2]
|
||||
vperm2i128 \$0x31, $T3, $T2, $X3 # X3 = [D3 C3 B3 A3]
|
||||
|
||||
vperm2i128 \$0x20, $T5, $T4, $Y0
|
||||
vperm2i128 \$0x20, $T7, $T6, $Y1
|
||||
vperm2i128 \$0x31, $T5, $T4, $Y2
|
||||
vperm2i128 \$0x31, $T7, $T6, $Y3
|
||||
vmovdqa (%rdx), $T7
|
||||
|
||||
vpand (%rdx), $X0, $T0 # out[0] = in[0] & mask;
|
||||
vpsrlq \$29, $X0, $X0
|
||||
vpand $T7, $X0, $T1 # out[1] = (in[0] >> shift) & mask;
|
||||
vpsrlq \$29, $X0, $X0
|
||||
vpsllq \$6, $X1, $T2
|
||||
vpxor $X0, $T2, $T2
|
||||
vpand $T7, $T2, $T2 # out[2] = ((in[0] >> (shift*2)) ^ (in[1] << (64-shift*2))) & mask;
|
||||
vpsrlq \$23, $X1, $X1
|
||||
vpand $T7, $X1, $T3 # out[3] = (in[1] >> ((shift*3)%64)) & mask;
|
||||
vpsrlq \$29, $X1, $X1
|
||||
vpsllq \$12, $X2, $T4
|
||||
vpxor $X1, $T4, $T4
|
||||
vpand $T7, $T4, $T4 # out[4] = ((in[1] >> ((shift*4)%64)) ^ (in[2] << (64*2-shift*4))) & mask;
|
||||
vpsrlq \$17, $X2, $X2
|
||||
vpand $T7, $X2, $T5 # out[5] = (in[2] >> ((shift*5)%64)) & mask;
|
||||
vpsrlq \$29, $X2, $X2
|
||||
vpsllq \$18, $X3, $T6
|
||||
vpxor $X2, $T6, $T6
|
||||
vpand $T7, $T6, $T6 # out[6] = ((in[2] >> ((shift*6)%64)) ^ (in[3] << (64*3-shift*6))) & mask;
|
||||
vpsrlq \$11, $X3, $X3
|
||||
vmovdqa $T0, 32*0(%rdi)
|
||||
lea 112(%rdi), %rax # size optimization
|
||||
vpand $T7, $X3, $T0 # out[7] = (in[3] >> ((shift*7)%64)) & mask;
|
||||
vpsrlq \$29, $X3, $X3 # out[8] = (in[3] >> ((shift*8)%64)) & mask;
|
||||
|
||||
vmovdqa $T1, 32*1(%rdi)
|
||||
vmovdqa $T2, 32*2(%rdi)
|
||||
vmovdqa $T3, 32*3(%rdi)
|
||||
vmovdqa $T4, 32*4-112(%rax)
|
||||
vmovdqa $T5, 32*5-112(%rax)
|
||||
vmovdqa $T6, 32*6-112(%rax)
|
||||
vmovdqa $T0, 32*7-112(%rax)
|
||||
vmovdqa $X3, 32*8-112(%rax)
|
||||
lea 448(%rdi), %rax # size optimization
|
||||
|
||||
vpand $T7, $Y0, $T0 # out[0] = in[0] & mask;
|
||||
vpsrlq \$29, $Y0, $Y0
|
||||
vpand $T7, $Y0, $T1 # out[1] = (in[0] >> shift) & mask;
|
||||
vpsrlq \$29, $Y0, $Y0
|
||||
vpsllq \$6, $Y1, $T2
|
||||
vpxor $Y0, $T2, $T2
|
||||
vpand $T7, $T2, $T2 # out[2] = ((in[0] >> (shift*2)) ^ (in[1] << (64-shift*2))) & mask;
|
||||
vpsrlq \$23, $Y1, $Y1
|
||||
vpand $T7, $Y1, $T3 # out[3] = (in[1] >> ((shift*3)%64)) & mask;
|
||||
vpsrlq \$29, $Y1, $Y1
|
||||
vpsllq \$12, $Y2, $T4
|
||||
vpxor $Y1, $T4, $T4
|
||||
vpand $T7, $T4, $T4 # out[4] = ((in[1] >> ((shift*4)%64)) ^ (in[2] << (64*2-shift*4))) & mask;
|
||||
vpsrlq \$17, $Y2, $Y2
|
||||
vpand $T7, $Y2, $T5 # out[5] = (in[2] >> ((shift*5)%64)) & mask;
|
||||
vpsrlq \$29, $Y2, $Y2
|
||||
vpsllq \$18, $Y3, $T6
|
||||
vpxor $Y2, $T6, $T6
|
||||
vpand $T7, $T6, $T6 # out[6] = ((in[2] >> ((shift*6)%64)) ^ (in[3] << (64*3-shift*6))) & mask;
|
||||
vpsrlq \$11, $Y3, $Y3
|
||||
vmovdqa $T0, 32*9-448(%rax)
|
||||
vpand $T7, $Y3, $T0 # out[7] = (in[3] >> ((shift*7)%64)) & mask;
|
||||
vpsrlq \$29, $Y3, $Y3 # out[8] = (in[3] >> ((shift*8)%64)) & mask;
|
||||
|
||||
vmovdqa $T1, 32*10-448(%rax)
|
||||
vmovdqa $T2, 32*11-448(%rax)
|
||||
vmovdqa $T3, 32*12-448(%rax)
|
||||
vmovdqa $T4, 32*13-448(%rax)
|
||||
vmovdqa $T5, 32*14-448(%rax)
|
||||
vmovdqa $T6, 32*15-448(%rax)
|
||||
vmovdqa $T0, 32*16-448(%rax)
|
||||
vmovdqa $Y3, 32*17-448(%rax)
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 16*0(%rsp), %xmm6
|
||||
movaps 16*1(%rsp), %xmm7
|
||||
movaps 16*2(%rsp), %xmm8
|
||||
movaps 16*3(%rsp), %xmm9
|
||||
movaps 16*4(%rsp), %xmm10
|
||||
movaps 16*5(%rsp), %xmm11
|
||||
movaps 16*6(%rsp), %xmm12
|
||||
movaps 16*7(%rsp), %xmm13
|
||||
movaps 16*8(%rsp), %xmm14
|
||||
movaps 16*9(%rsp), %xmm15
|
||||
lea 8+16*10(%rsp), %rsp
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_avx2_transpose_convert,.-ecp_nistz256_avx2_transpose_convert
|
||||
___
|
||||
}
|
||||
{
|
||||
################################################################################
|
||||
# This function receives a pointer to an array of four AVX2 formatted points
|
||||
# (X, Y, Z) convert the data to normal representation, and rearranges the data
|
||||
|
||||
my ($D0,$D1,$D2,$D3, $D4,$D5,$D6,$D7, $D8)=map("%ymm$_",(0..8));
|
||||
my ($T0,$T1,$T2,$T3, $T4,$T5,$T6)=map("%ymm$_",(9..15));
|
||||
|
||||
$code.=<<___;
|
||||
|
||||
.globl ecp_nistz256_avx2_convert_transpose_back
|
||||
.type ecp_nistz256_avx2_convert_transpose_back,\@function,2
|
||||
.align 32
|
||||
ecp_nistz256_avx2_convert_transpose_back:
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -8-16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
mov \$3, %ecx
|
||||
|
||||
.Lconv_loop:
|
||||
vmovdqa 32*0(%rsi), $D0
|
||||
lea 160(%rsi), %rax # size optimization
|
||||
vmovdqa 32*1(%rsi), $D1
|
||||
vmovdqa 32*2(%rsi), $D2
|
||||
vmovdqa 32*3(%rsi), $D3
|
||||
vmovdqa 32*4-160(%rax), $D4
|
||||
vmovdqa 32*5-160(%rax), $D5
|
||||
vmovdqa 32*6-160(%rax), $D6
|
||||
vmovdqa 32*7-160(%rax), $D7
|
||||
vmovdqa 32*8-160(%rax), $D8
|
||||
|
||||
vpsllq \$29, $D1, $D1
|
||||
vpsllq \$58, $D2, $T0
|
||||
vpaddq $D1, $D0, $D0
|
||||
vpaddq $T0, $D0, $D0 # out[0] = (in[0]) ^ (in[1] << shift*1) ^ (in[2] << shift*2);
|
||||
|
||||
vpsrlq \$6, $D2, $D2
|
||||
vpsllq \$23, $D3, $D3
|
||||
vpsllq \$52, $D4, $T1
|
||||
vpaddq $D2, $D3, $D3
|
||||
vpaddq $D3, $T1, $D1 # out[1] = (in[2] >> (64*1-shift*2)) ^ (in[3] << shift*3%64) ^ (in[4] << shift*4%64);
|
||||
|
||||
vpsrlq \$12, $D4, $D4
|
||||
vpsllq \$17, $D5, $D5
|
||||
vpsllq \$46, $D6, $T2
|
||||
vpaddq $D4, $D5, $D5
|
||||
vpaddq $D5, $T2, $D2 # out[2] = (in[4] >> (64*2-shift*4)) ^ (in[5] << shift*5%64) ^ (in[6] << shift*6%64);
|
||||
|
||||
vpsrlq \$18, $D6, $D6
|
||||
vpsllq \$11, $D7, $D7
|
||||
vpsllq \$40, $D8, $T3
|
||||
vpaddq $D6, $D7, $D7
|
||||
vpaddq $D7, $T3, $D3 # out[3] = (in[6] >> (64*3-shift*6)) ^ (in[7] << shift*7%64) ^ (in[8] << shift*8%64);
|
||||
|
||||
vpunpcklqdq $D1, $D0, $T0 # T0 = [B2 A2 B0 A0]
|
||||
vpunpcklqdq $D3, $D2, $T1 # T1 = [D2 C2 D0 C0]
|
||||
vpunpckhqdq $D1, $D0, $T2 # T2 = [B3 A3 B1 A1]
|
||||
vpunpckhqdq $D3, $D2, $T3 # T3 = [D3 C3 D1 C1]
|
||||
|
||||
vperm2i128 \$0x20, $T1, $T0, $D0 # X0 = [D0 C0 B0 A0]
|
||||
vperm2i128 \$0x20, $T3, $T2, $D1 # X1 = [D1 C1 B1 A1]
|
||||
vperm2i128 \$0x31, $T1, $T0, $D2 # X2 = [D2 C2 B2 A2]
|
||||
vperm2i128 \$0x31, $T3, $T2, $D3 # X3 = [D3 C3 B3 A3]
|
||||
|
||||
vmovdqa $D0, 32*0(%rdi)
|
||||
vmovdqa $D1, 32*3(%rdi)
|
||||
vmovdqa $D2, 32*6(%rdi)
|
||||
vmovdqa $D3, 32*9(%rdi)
|
||||
|
||||
lea 32*9(%rsi), %rsi
|
||||
lea 32*1(%rdi), %rdi
|
||||
|
||||
dec %ecx
|
||||
jnz .Lconv_loop
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 16*0(%rsp), %xmm6
|
||||
movaps 16*1(%rsp), %xmm7
|
||||
movaps 16*2(%rsp), %xmm8
|
||||
movaps 16*3(%rsp), %xmm9
|
||||
movaps 16*4(%rsp), %xmm10
|
||||
movaps 16*5(%rsp), %xmm11
|
||||
movaps 16*6(%rsp), %xmm12
|
||||
movaps 16*7(%rsp), %xmm13
|
||||
movaps 16*8(%rsp), %xmm14
|
||||
movaps 16*9(%rsp), %xmm15
|
||||
lea 8+16*10(%rsp), %rsp
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_avx2_convert_transpose_back,.-ecp_nistz256_avx2_convert_transpose_back
|
||||
___
|
||||
}
|
||||
{
|
||||
my ($r_ptr,$a_ptr,$b_ptr,$itr)=("%rdi","%rsi","%rdx","%ecx");
|
||||
my ($ACC0,$ACC1,$ACC2,$ACC3,$ACC4,$ACC5,$ACC6,$ACC7,$ACC8)=map("%ymm$_",(0..8));
|
||||
my ($B,$Y,$T0,$AND_MASK,$OVERFLOW)=map("%ymm$_",(9..13));
|
||||
|
||||
sub NORMALIZE {
|
||||
my $ret=<<___;
|
||||
vpsrlq $digit_size, $ACC0, $T0
|
||||
vpand $AND_MASK, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC1, $ACC1
|
||||
|
||||
vpsrlq $digit_size, $ACC1, $T0
|
||||
vpand $AND_MASK, $ACC1, $ACC1
|
||||
vpaddq $T0, $ACC2, $ACC2
|
||||
|
||||
vpsrlq $digit_size, $ACC2, $T0
|
||||
vpand $AND_MASK, $ACC2, $ACC2
|
||||
vpaddq $T0, $ACC3, $ACC3
|
||||
|
||||
vpsrlq $digit_size, $ACC3, $T0
|
||||
vpand $AND_MASK, $ACC3, $ACC3
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
|
||||
vpsrlq $digit_size, $ACC4, $T0
|
||||
vpand $AND_MASK, $ACC4, $ACC4
|
||||
vpaddq $T0, $ACC5, $ACC5
|
||||
|
||||
vpsrlq $digit_size, $ACC5, $T0
|
||||
vpand $AND_MASK, $ACC5, $ACC5
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpsrlq $digit_size, $ACC6, $T0
|
||||
vpand $AND_MASK, $ACC6, $ACC6
|
||||
vpaddq $T0, $ACC7, $ACC7
|
||||
|
||||
vpsrlq $digit_size, $ACC7, $T0
|
||||
vpand $AND_MASK, $ACC7, $ACC7
|
||||
vpaddq $T0, $ACC8, $ACC8
|
||||
#vpand $AND_MASK, $ACC8, $ACC8
|
||||
___
|
||||
$ret;
|
||||
}
|
||||
|
||||
sub STORE {
|
||||
my $ret=<<___;
|
||||
vmovdqa $ACC0, 32*0(%rdi)
|
||||
lea 160(%rdi), %rax # size optimization
|
||||
vmovdqa $ACC1, 32*1(%rdi)
|
||||
vmovdqa $ACC2, 32*2(%rdi)
|
||||
vmovdqa $ACC3, 32*3(%rdi)
|
||||
vmovdqa $ACC4, 32*4-160(%rax)
|
||||
vmovdqa $ACC5, 32*5-160(%rax)
|
||||
vmovdqa $ACC6, 32*6-160(%rax)
|
||||
vmovdqa $ACC7, 32*7-160(%rax)
|
||||
vmovdqa $ACC8, 32*8-160(%rax)
|
||||
___
|
||||
$ret;
|
||||
}
|
||||
|
||||
$code.=<<___;
|
||||
.type avx2_normalize,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_normalize:
|
||||
vpsrlq $digit_size, $ACC0, $T0
|
||||
vpand $AND_MASK, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC1, $ACC1
|
||||
|
||||
vpsrlq $digit_size, $ACC1, $T0
|
||||
vpand $AND_MASK, $ACC1, $ACC1
|
||||
vpaddq $T0, $ACC2, $ACC2
|
||||
|
||||
vpsrlq $digit_size, $ACC2, $T0
|
||||
vpand $AND_MASK, $ACC2, $ACC2
|
||||
vpaddq $T0, $ACC3, $ACC3
|
||||
|
||||
vpsrlq $digit_size, $ACC3, $T0
|
||||
vpand $AND_MASK, $ACC3, $ACC3
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
|
||||
vpsrlq $digit_size, $ACC4, $T0
|
||||
vpand $AND_MASK, $ACC4, $ACC4
|
||||
vpaddq $T0, $ACC5, $ACC5
|
||||
|
||||
vpsrlq $digit_size, $ACC5, $T0
|
||||
vpand $AND_MASK, $ACC5, $ACC5
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpsrlq $digit_size, $ACC6, $T0
|
||||
vpand $AND_MASK, $ACC6, $ACC6
|
||||
vpaddq $T0, $ACC7, $ACC7
|
||||
|
||||
vpsrlq $digit_size, $ACC7, $T0
|
||||
vpand $AND_MASK, $ACC7, $ACC7
|
||||
vpaddq $T0, $ACC8, $ACC8
|
||||
#vpand $AND_MASK, $ACC8, $ACC8
|
||||
|
||||
ret
|
||||
.size avx2_normalize,.-avx2_normalize
|
||||
|
||||
.type avx2_normalize_n_store,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_normalize_n_store:
|
||||
vpsrlq $digit_size, $ACC0, $T0
|
||||
vpand $AND_MASK, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC1, $ACC1
|
||||
|
||||
vpsrlq $digit_size, $ACC1, $T0
|
||||
vpand $AND_MASK, $ACC1, $ACC1
|
||||
vmovdqa $ACC0, 32*0(%rdi)
|
||||
lea 160(%rdi), %rax # size optimization
|
||||
vpaddq $T0, $ACC2, $ACC2
|
||||
|
||||
vpsrlq $digit_size, $ACC2, $T0
|
||||
vpand $AND_MASK, $ACC2, $ACC2
|
||||
vmovdqa $ACC1, 32*1(%rdi)
|
||||
vpaddq $T0, $ACC3, $ACC3
|
||||
|
||||
vpsrlq $digit_size, $ACC3, $T0
|
||||
vpand $AND_MASK, $ACC3, $ACC3
|
||||
vmovdqa $ACC2, 32*2(%rdi)
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
|
||||
vpsrlq $digit_size, $ACC4, $T0
|
||||
vpand $AND_MASK, $ACC4, $ACC4
|
||||
vmovdqa $ACC3, 32*3(%rdi)
|
||||
vpaddq $T0, $ACC5, $ACC5
|
||||
|
||||
vpsrlq $digit_size, $ACC5, $T0
|
||||
vpand $AND_MASK, $ACC5, $ACC5
|
||||
vmovdqa $ACC4, 32*4-160(%rax)
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpsrlq $digit_size, $ACC6, $T0
|
||||
vpand $AND_MASK, $ACC6, $ACC6
|
||||
vmovdqa $ACC5, 32*5-160(%rax)
|
||||
vpaddq $T0, $ACC7, $ACC7
|
||||
|
||||
vpsrlq $digit_size, $ACC7, $T0
|
||||
vpand $AND_MASK, $ACC7, $ACC7
|
||||
vmovdqa $ACC6, 32*6-160(%rax)
|
||||
vpaddq $T0, $ACC8, $ACC8
|
||||
#vpand $AND_MASK, $ACC8, $ACC8
|
||||
vmovdqa $ACC7, 32*7-160(%rax)
|
||||
vmovdqa $ACC8, 32*8-160(%rax)
|
||||
|
||||
ret
|
||||
.size avx2_normalize_n_store,.-avx2_normalize_n_store
|
||||
|
||||
################################################################################
|
||||
# void avx2_mul_x4(void* RESULTx4, void *Ax4, void *Bx4);
|
||||
.type avx2_mul_x4,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_mul_x4:
|
||||
lea .LAVX2_POLY(%rip), %rax
|
||||
|
||||
vpxor $ACC0, $ACC0, $ACC0
|
||||
vpxor $ACC1, $ACC1, $ACC1
|
||||
vpxor $ACC2, $ACC2, $ACC2
|
||||
vpxor $ACC3, $ACC3, $ACC3
|
||||
vpxor $ACC4, $ACC4, $ACC4
|
||||
vpxor $ACC5, $ACC5, $ACC5
|
||||
vpxor $ACC6, $ACC6, $ACC6
|
||||
vpxor $ACC7, $ACC7, $ACC7
|
||||
|
||||
vmovdqa 32*7(%rax), %ymm14
|
||||
vmovdqa 32*8(%rax), %ymm15
|
||||
|
||||
mov $n_digits, $itr
|
||||
lea -512($a_ptr), $a_ptr # strategic bias to control u-op density
|
||||
jmp .Lavx2_mul_x4_loop
|
||||
|
||||
.align 32
|
||||
.Lavx2_mul_x4_loop:
|
||||
vmovdqa 32*0($b_ptr), $B
|
||||
lea 32*1($b_ptr), $b_ptr
|
||||
|
||||
vpmuludq 32*0+512($a_ptr), $B, $T0
|
||||
vpmuludq 32*1+512($a_ptr), $B, $OVERFLOW # borrow $OVERFLOW
|
||||
vpaddq $T0, $ACC0, $ACC0
|
||||
vpmuludq 32*2+512($a_ptr), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC1, $ACC1
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpmuludq 32*3+512($a_ptr), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC2
|
||||
vpmuludq 32*4+512($a_ptr), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC3, $ACC3
|
||||
vpmuludq 32*5+512($a_ptr), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
vpmuludq 32*6+512($a_ptr), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC5, $ACC5
|
||||
vpmuludq 32*7+512($a_ptr), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
# Skip some multiplications, optimizing for the constant poly
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*8+512($a_ptr), $B, $ACC8
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
.byte 0x67
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $OVERFLOW
|
||||
.byte 0x67
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC7, $ACC6
|
||||
vpaddq $OVERFLOW, $ACC8, $ACC7
|
||||
|
||||
dec $itr
|
||||
jnz .Lavx2_mul_x4_loop
|
||||
|
||||
vpxor $ACC8, $ACC8, $ACC8
|
||||
|
||||
ret
|
||||
.size avx2_mul_x4,.-avx2_mul_x4
|
||||
|
||||
# Function optimized for the constant 1
|
||||
################################################################################
|
||||
# void avx2_mul_by1_x4(void* RESULTx4, void *Ax4);
|
||||
.type avx2_mul_by1_x4,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_mul_by1_x4:
|
||||
lea .LAVX2_POLY(%rip), %rax
|
||||
|
||||
vpxor $ACC0, $ACC0, $ACC0
|
||||
vpxor $ACC1, $ACC1, $ACC1
|
||||
vpxor $ACC2, $ACC2, $ACC2
|
||||
vpxor $ACC3, $ACC3, $ACC3
|
||||
vpxor $ACC4, $ACC4, $ACC4
|
||||
vpxor $ACC5, $ACC5, $ACC5
|
||||
vpxor $ACC6, $ACC6, $ACC6
|
||||
vpxor $ACC7, $ACC7, $ACC7
|
||||
vpxor $ACC8, $ACC8, $ACC8
|
||||
|
||||
vmovdqa 32*3+.LONE(%rip), %ymm14
|
||||
vmovdqa 32*7+.LONE(%rip), %ymm15
|
||||
|
||||
mov $n_digits, $itr
|
||||
jmp .Lavx2_mul_by1_x4_loop
|
||||
|
||||
.align 32
|
||||
.Lavx2_mul_by1_x4_loop:
|
||||
vmovdqa 32*0($a_ptr), $B
|
||||
.byte 0x48,0x8d,0xb6,0x20,0,0,0 # lea 32*1($a_ptr), $a_ptr
|
||||
|
||||
vpsllq \$5, $B, $OVERFLOW
|
||||
vpmuludq %ymm14, $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC3
|
||||
.byte 0x67
|
||||
vpmuludq $AND_MASK, $B, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
vpaddq $T0, $ACC5, $ACC5
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
vpsllq \$23, $B, $T0
|
||||
|
||||
.byte 0x67,0x67
|
||||
vpmuludq %ymm15, $B, $OVERFLOW
|
||||
vpsubq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
.byte 0x67,0x67
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $OVERFLOW
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq 32*7(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC6, $ACC5
|
||||
vpaddq $T0, $ACC7, $ACC6
|
||||
vpmuludq 32*8(%rax), $Y, $ACC7
|
||||
|
||||
dec $itr
|
||||
jnz .Lavx2_mul_by1_x4_loop
|
||||
|
||||
ret
|
||||
.size avx2_mul_by1_x4,.-avx2_mul_by1_x4
|
||||
|
||||
################################################################################
|
||||
# void avx2_sqr_x4(void* RESULTx4, void *Ax4, void *Bx4);
|
||||
.type avx2_sqr_x4,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_sqr_x4:
|
||||
lea .LAVX2_POLY(%rip), %rax
|
||||
|
||||
vmovdqa 32*7(%rax), %ymm14
|
||||
vmovdqa 32*8(%rax), %ymm15
|
||||
|
||||
vmovdqa 32*0($a_ptr), $B
|
||||
vmovdqa 32*1($a_ptr), $ACC1
|
||||
vmovdqa 32*2($a_ptr), $ACC2
|
||||
vmovdqa 32*3($a_ptr), $ACC3
|
||||
vmovdqa 32*4($a_ptr), $ACC4
|
||||
vmovdqa 32*5($a_ptr), $ACC5
|
||||
vmovdqa 32*6($a_ptr), $ACC6
|
||||
vmovdqa 32*7($a_ptr), $ACC7
|
||||
vpaddq $ACC1, $ACC1, $ACC1 # 2*$ACC0..7
|
||||
vmovdqa 32*8($a_ptr), $ACC8
|
||||
vpaddq $ACC2, $ACC2, $ACC2
|
||||
vmovdqa $ACC1, 32*0(%rcx)
|
||||
vpaddq $ACC3, $ACC3, $ACC3
|
||||
vmovdqa $ACC2, 32*1(%rcx)
|
||||
vpaddq $ACC4, $ACC4, $ACC4
|
||||
vmovdqa $ACC3, 32*2(%rcx)
|
||||
vpaddq $ACC5, $ACC5, $ACC5
|
||||
vmovdqa $ACC4, 32*3(%rcx)
|
||||
vpaddq $ACC6, $ACC6, $ACC6
|
||||
vmovdqa $ACC5, 32*4(%rcx)
|
||||
vpaddq $ACC7, $ACC7, $ACC7
|
||||
vmovdqa $ACC6, 32*5(%rcx)
|
||||
vpaddq $ACC8, $ACC8, $ACC8
|
||||
vmovdqa $ACC7, 32*6(%rcx)
|
||||
vmovdqa $ACC8, 32*7(%rcx)
|
||||
|
||||
#itr 1
|
||||
vpmuludq $B, $B, $ACC0
|
||||
vpmuludq $B, $ACC1, $ACC1
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpmuludq $B, $ACC2, $ACC2
|
||||
vpmuludq $B, $ACC3, $ACC3
|
||||
vpmuludq $B, $ACC4, $ACC4
|
||||
vpmuludq $B, $ACC5, $ACC5
|
||||
vpmuludq $B, $ACC6, $ACC6
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpmuludq $B, $ACC7, $ACC7
|
||||
vpmuludq $B, $ACC8, $ACC8
|
||||
vmovdqa 32*1($a_ptr), $B
|
||||
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 2
|
||||
vpmuludq $B, $B, $OVERFLOW
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpmuludq 32*1(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC1, $ACC1
|
||||
vpmuludq 32*2(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC2
|
||||
vpmuludq 32*3(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC3, $ACC3
|
||||
vpmuludq 32*4(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
vpmuludq 32*5(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC5, $ACC5
|
||||
vpmuludq 32*6(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*2($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 3
|
||||
vpmuludq $B, $B, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpmuludq 32*2(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC2
|
||||
vpmuludq 32*3(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC3, $ACC3
|
||||
vpmuludq 32*4(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
vpmuludq 32*5(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC5, $ACC5
|
||||
vpmuludq 32*6(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*3($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 4
|
||||
vpmuludq $B, $B, $OVERFLOW
|
||||
vpmuludq 32*3(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC3, $ACC3
|
||||
vpmuludq 32*4(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
vpmuludq 32*5(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC5, $ACC5
|
||||
vpmuludq 32*6(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*4($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 5
|
||||
vpmuludq $B, $B, $T0
|
||||
vpmuludq 32*4(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC4, $ACC4
|
||||
vpmuludq 32*5(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC5, $ACC5
|
||||
vpmuludq 32*6(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*5($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3+.LAVX2_POLY(%rip), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 6
|
||||
vpmuludq $B, $B, $OVERFLOW
|
||||
vpmuludq 32*5(%rcx), $B, $T0
|
||||
vpaddq $OVERFLOW, $ACC5, $ACC5
|
||||
vpmuludq 32*6(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*6($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 7
|
||||
vpmuludq $B, $B, $T0
|
||||
vpmuludq 32*6(%rcx), $B, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC6
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*7($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 8
|
||||
vpmuludq $B, $B, $OVERFLOW
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC7
|
||||
vpmuludq 32*7(%rcx), $B, $ACC8
|
||||
vmovdqa 32*8($a_ptr), $B
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpand $AND_MASK, $ACC0, $Y
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
#itr 9
|
||||
vpmuludq $B, $B, $ACC8
|
||||
|
||||
vpmuludq $AND_MASK, $Y, $T0
|
||||
vpaddq $T0, $ACC0, $OVERFLOW
|
||||
vpsrlq $digit_size, $OVERFLOW, $OVERFLOW
|
||||
vpaddq $T0, $ACC1, $ACC0
|
||||
vpaddq $T0, $ACC2, $ACC1
|
||||
vpmuludq 32*3(%rax), $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC0, $ACC0
|
||||
vpaddq $T0, $ACC3, $ACC2
|
||||
vmovdqa $ACC4, $ACC3
|
||||
vpsllq \$18, $Y, $T0
|
||||
vmovdqa $ACC5, $ACC4
|
||||
vpmuludq %ymm14, $Y, $OVERFLOW
|
||||
vpaddq $T0, $ACC6, $ACC5
|
||||
vpmuludq %ymm15, $Y, $T0
|
||||
vpaddq $OVERFLOW, $ACC7, $ACC6
|
||||
vpaddq $T0, $ACC8, $ACC7
|
||||
|
||||
vpxor $ACC8, $ACC8, $ACC8
|
||||
|
||||
ret
|
||||
.size avx2_sqr_x4,.-avx2_sqr_x4
|
||||
|
||||
################################################################################
|
||||
# void avx2_sub_x4(void* RESULTx4, void *Ax4, void *Bx4);
|
||||
.type avx2_sub_x4,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_sub_x4:
|
||||
vmovdqa 32*0($a_ptr), $ACC0
|
||||
lea 160($a_ptr), $a_ptr
|
||||
lea .LAVX2_POLY_x8+128(%rip), %rax
|
||||
lea 128($b_ptr), $b_ptr
|
||||
vmovdqa 32*1-160($a_ptr), $ACC1
|
||||
vmovdqa 32*2-160($a_ptr), $ACC2
|
||||
vmovdqa 32*3-160($a_ptr), $ACC3
|
||||
vmovdqa 32*4-160($a_ptr), $ACC4
|
||||
vmovdqa 32*5-160($a_ptr), $ACC5
|
||||
vmovdqa 32*6-160($a_ptr), $ACC6
|
||||
vmovdqa 32*7-160($a_ptr), $ACC7
|
||||
vmovdqa 32*8-160($a_ptr), $ACC8
|
||||
|
||||
vpaddq 32*0-128(%rax), $ACC0, $ACC0
|
||||
vpaddq 32*1-128(%rax), $ACC1, $ACC1
|
||||
vpaddq 32*2-128(%rax), $ACC2, $ACC2
|
||||
vpaddq 32*3-128(%rax), $ACC3, $ACC3
|
||||
vpaddq 32*4-128(%rax), $ACC4, $ACC4
|
||||
vpaddq 32*5-128(%rax), $ACC5, $ACC5
|
||||
vpaddq 32*6-128(%rax), $ACC6, $ACC6
|
||||
vpaddq 32*7-128(%rax), $ACC7, $ACC7
|
||||
vpaddq 32*8-128(%rax), $ACC8, $ACC8
|
||||
|
||||
vpsubq 32*0-128($b_ptr), $ACC0, $ACC0
|
||||
vpsubq 32*1-128($b_ptr), $ACC1, $ACC1
|
||||
vpsubq 32*2-128($b_ptr), $ACC2, $ACC2
|
||||
vpsubq 32*3-128($b_ptr), $ACC3, $ACC3
|
||||
vpsubq 32*4-128($b_ptr), $ACC4, $ACC4
|
||||
vpsubq 32*5-128($b_ptr), $ACC5, $ACC5
|
||||
vpsubq 32*6-128($b_ptr), $ACC6, $ACC6
|
||||
vpsubq 32*7-128($b_ptr), $ACC7, $ACC7
|
||||
vpsubq 32*8-128($b_ptr), $ACC8, $ACC8
|
||||
|
||||
ret
|
||||
.size avx2_sub_x4,.-avx2_sub_x4
|
||||
|
||||
.type avx2_select_n_store,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_select_n_store:
|
||||
vmovdqa `8+32*9*8`(%rsp), $Y
|
||||
vpor `8+32*9*8+32`(%rsp), $Y, $Y
|
||||
|
||||
vpandn $ACC0, $Y, $ACC0
|
||||
vpandn $ACC1, $Y, $ACC1
|
||||
vpandn $ACC2, $Y, $ACC2
|
||||
vpandn $ACC3, $Y, $ACC3
|
||||
vpandn $ACC4, $Y, $ACC4
|
||||
vpandn $ACC5, $Y, $ACC5
|
||||
vpandn $ACC6, $Y, $ACC6
|
||||
vmovdqa `8+32*9*8+32`(%rsp), $B
|
||||
vpandn $ACC7, $Y, $ACC7
|
||||
vpandn `8+32*9*8`(%rsp), $B, $B
|
||||
vpandn $ACC8, $Y, $ACC8
|
||||
|
||||
vpand 32*0(%rsi), $B, $T0
|
||||
lea 160(%rsi), %rax
|
||||
vpand 32*1(%rsi), $B, $Y
|
||||
vpxor $T0, $ACC0, $ACC0
|
||||
vpand 32*2(%rsi), $B, $T0
|
||||
vpxor $Y, $ACC1, $ACC1
|
||||
vpand 32*3(%rsi), $B, $Y
|
||||
vpxor $T0, $ACC2, $ACC2
|
||||
vpand 32*4-160(%rax), $B, $T0
|
||||
vpxor $Y, $ACC3, $ACC3
|
||||
vpand 32*5-160(%rax), $B, $Y
|
||||
vpxor $T0, $ACC4, $ACC4
|
||||
vpand 32*6-160(%rax), $B, $T0
|
||||
vpxor $Y, $ACC5, $ACC5
|
||||
vpand 32*7-160(%rax), $B, $Y
|
||||
vpxor $T0, $ACC6, $ACC6
|
||||
vpand 32*8-160(%rax), $B, $T0
|
||||
vmovdqa `8+32*9*8+32`(%rsp), $B
|
||||
vpxor $Y, $ACC7, $ACC7
|
||||
|
||||
vpand 32*0(%rdx), $B, $Y
|
||||
lea 160(%rdx), %rax
|
||||
vpxor $T0, $ACC8, $ACC8
|
||||
vpand 32*1(%rdx), $B, $T0
|
||||
vpxor $Y, $ACC0, $ACC0
|
||||
vpand 32*2(%rdx), $B, $Y
|
||||
vpxor $T0, $ACC1, $ACC1
|
||||
vpand 32*3(%rdx), $B, $T0
|
||||
vpxor $Y, $ACC2, $ACC2
|
||||
vpand 32*4-160(%rax), $B, $Y
|
||||
vpxor $T0, $ACC3, $ACC3
|
||||
vpand 32*5-160(%rax), $B, $T0
|
||||
vpxor $Y, $ACC4, $ACC4
|
||||
vpand 32*6-160(%rax), $B, $Y
|
||||
vpxor $T0, $ACC5, $ACC5
|
||||
vpand 32*7-160(%rax), $B, $T0
|
||||
vpxor $Y, $ACC6, $ACC6
|
||||
vpand 32*8-160(%rax), $B, $Y
|
||||
vpxor $T0, $ACC7, $ACC7
|
||||
vpxor $Y, $ACC8, $ACC8
|
||||
`&STORE`
|
||||
|
||||
ret
|
||||
.size avx2_select_n_store,.-avx2_select_n_store
|
||||
___
|
||||
$code.=<<___ if (0); # inlined
|
||||
################################################################################
|
||||
# void avx2_mul_by2_x4(void* RESULTx4, void *Ax4);
|
||||
.type avx2_mul_by2_x4,\@abi-omnipotent
|
||||
.align 32
|
||||
avx2_mul_by2_x4:
|
||||
vmovdqa 32*0($a_ptr), $ACC0
|
||||
lea 160($a_ptr), %rax
|
||||
vmovdqa 32*1($a_ptr), $ACC1
|
||||
vmovdqa 32*2($a_ptr), $ACC2
|
||||
vmovdqa 32*3($a_ptr), $ACC3
|
||||
vmovdqa 32*4-160(%rax), $ACC4
|
||||
vmovdqa 32*5-160(%rax), $ACC5
|
||||
vmovdqa 32*6-160(%rax), $ACC6
|
||||
vmovdqa 32*7-160(%rax), $ACC7
|
||||
vmovdqa 32*8-160(%rax), $ACC8
|
||||
|
||||
vpaddq $ACC0, $ACC0, $ACC0
|
||||
vpaddq $ACC1, $ACC1, $ACC1
|
||||
vpaddq $ACC2, $ACC2, $ACC2
|
||||
vpaddq $ACC3, $ACC3, $ACC3
|
||||
vpaddq $ACC4, $ACC4, $ACC4
|
||||
vpaddq $ACC5, $ACC5, $ACC5
|
||||
vpaddq $ACC6, $ACC6, $ACC6
|
||||
vpaddq $ACC7, $ACC7, $ACC7
|
||||
vpaddq $ACC8, $ACC8, $ACC8
|
||||
|
||||
ret
|
||||
.size avx2_mul_by2_x4,.-avx2_mul_by2_x4
|
||||
___
|
||||
my ($r_ptr_in,$a_ptr_in,$b_ptr_in)=("%rdi","%rsi","%rdx");
|
||||
my ($r_ptr,$a_ptr,$b_ptr)=("%r8","%r9","%r10");
|
||||
|
||||
$code.=<<___;
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_point_add_affine_x4(void* RESULTx4, void *Ax4, void *Bx4);
|
||||
.globl ecp_nistz256_avx2_point_add_affine_x4
|
||||
.type ecp_nistz256_avx2_point_add_affine_x4,\@function,3
|
||||
.align 32
|
||||
ecp_nistz256_avx2_point_add_affine_x4:
|
||||
mov %rsp, %rax
|
||||
push %rbp
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
lea -8(%rax), %rbp
|
||||
|
||||
# Result + 32*0 = Result.X
|
||||
# Result + 32*9 = Result.Y
|
||||
# Result + 32*18 = Result.Z
|
||||
|
||||
# A + 32*0 = A.X
|
||||
# A + 32*9 = A.Y
|
||||
# A + 32*18 = A.Z
|
||||
|
||||
# B + 32*0 = B.X
|
||||
# B + 32*9 = B.Y
|
||||
|
||||
sub \$`32*9*8+32*2+32*8`, %rsp
|
||||
and \$-64, %rsp
|
||||
|
||||
mov $r_ptr_in, $r_ptr
|
||||
mov $a_ptr_in, $a_ptr
|
||||
mov $b_ptr_in, $b_ptr
|
||||
|
||||
vmovdqa 32*0($a_ptr_in), %ymm0
|
||||
vmovdqa .LAVX2_AND_MASK(%rip), $AND_MASK
|
||||
vpxor %ymm1, %ymm1, %ymm1
|
||||
lea 256($a_ptr_in), %rax # size optimization
|
||||
vpor 32*1($a_ptr_in), %ymm0, %ymm0
|
||||
vpor 32*2($a_ptr_in), %ymm0, %ymm0
|
||||
vpor 32*3($a_ptr_in), %ymm0, %ymm0
|
||||
vpor 32*4-256(%rax), %ymm0, %ymm0
|
||||
lea 256(%rax), %rcx # size optimization
|
||||
vpor 32*5-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*6-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*7-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*8-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*9-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*10-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*11-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*12-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*13-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*14-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*15-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*16-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*17-512(%rcx), %ymm0, %ymm0
|
||||
vpcmpeqq %ymm1, %ymm0, %ymm0
|
||||
vmovdqa %ymm0, `32*9*8`(%rsp)
|
||||
|
||||
vpxor %ymm1, %ymm1, %ymm1
|
||||
vmovdqa 32*0($b_ptr), %ymm0
|
||||
lea 256($b_ptr), %rax # size optimization
|
||||
vpor 32*1($b_ptr), %ymm0, %ymm0
|
||||
vpor 32*2($b_ptr), %ymm0, %ymm0
|
||||
vpor 32*3($b_ptr), %ymm0, %ymm0
|
||||
vpor 32*4-256(%rax), %ymm0, %ymm0
|
||||
lea 256(%rax), %rcx # size optimization
|
||||
vpor 32*5-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*6-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*7-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*8-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*9-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*10-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*11-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*12-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*13-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*14-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*15-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*16-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*17-512(%rcx), %ymm0, %ymm0
|
||||
vpcmpeqq %ymm1, %ymm0, %ymm0
|
||||
vmovdqa %ymm0, `32*9*8+32`(%rsp)
|
||||
|
||||
# Z1^2 = Z1*Z1
|
||||
lea `32*9*2`($a_ptr), %rsi
|
||||
lea `32*9*2`(%rsp), %rdi
|
||||
lea `32*9*8+32*2`(%rsp), %rcx # temporary vector
|
||||
call avx2_sqr_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# U2 = X2*Z1^2
|
||||
lea `32*9*0`($b_ptr), %rsi
|
||||
lea `32*9*2`(%rsp), %rdx
|
||||
lea `32*9*0`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
#call avx2_normalize
|
||||
`&STORE`
|
||||
|
||||
# S2 = Z1*Z1^2 = Z1^3
|
||||
lea `32*9*2`($a_ptr), %rsi
|
||||
lea `32*9*2`(%rsp), %rdx
|
||||
lea `32*9*1`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# S2 = S2*Y2 = Y2*Z1^3
|
||||
lea `32*9*1`($b_ptr), %rsi
|
||||
lea `32*9*1`(%rsp), %rdx
|
||||
lea `32*9*1`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# H = U2 - U1 = U2 - X1
|
||||
lea `32*9*0`(%rsp), %rsi
|
||||
lea `32*9*0`($a_ptr), %rdx
|
||||
lea `32*9*3`(%rsp), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# R = S2 - S1 = S2 - Y1
|
||||
lea `32*9*1`(%rsp), %rsi
|
||||
lea `32*9*1`($a_ptr), %rdx
|
||||
lea `32*9*4`(%rsp), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# Z3 = H*Z1*Z2
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*2`($a_ptr), %rdx
|
||||
lea `32*9*2`($r_ptr), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize
|
||||
|
||||
lea .LONE(%rip), %rsi
|
||||
lea `32*9*2`($a_ptr), %rdx
|
||||
call avx2_select_n_store
|
||||
|
||||
# R^2 = R^2
|
||||
lea `32*9*4`(%rsp), %rsi
|
||||
lea `32*9*6`(%rsp), %rdi
|
||||
lea `32*9*8+32*2`(%rsp), %rcx # temporary vector
|
||||
call avx2_sqr_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# H^2 = H^2
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*5`(%rsp), %rdi
|
||||
call avx2_sqr_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# H^3 = H^2*H
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*5`(%rsp), %rdx
|
||||
lea `32*9*7`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# U2 = U1*H^2
|
||||
lea `32*9*0`($a_ptr), %rsi
|
||||
lea `32*9*5`(%rsp), %rdx
|
||||
lea `32*9*0`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
#call avx2_normalize
|
||||
`&STORE`
|
||||
|
||||
# Hsqr = U2*2
|
||||
#lea 32*9*0(%rsp), %rsi
|
||||
#lea 32*9*5(%rsp), %rdi
|
||||
#call avx2_mul_by2_x4
|
||||
|
||||
vpaddq $ACC0, $ACC0, $ACC0 # inlined avx2_mul_by2_x4
|
||||
lea `32*9*5`(%rsp), %rdi
|
||||
vpaddq $ACC1, $ACC1, $ACC1
|
||||
vpaddq $ACC2, $ACC2, $ACC2
|
||||
vpaddq $ACC3, $ACC3, $ACC3
|
||||
vpaddq $ACC4, $ACC4, $ACC4
|
||||
vpaddq $ACC5, $ACC5, $ACC5
|
||||
vpaddq $ACC6, $ACC6, $ACC6
|
||||
vpaddq $ACC7, $ACC7, $ACC7
|
||||
vpaddq $ACC8, $ACC8, $ACC8
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# X3 = R^2 - H^3
|
||||
#lea 32*9*6(%rsp), %rsi
|
||||
#lea 32*9*7(%rsp), %rdx
|
||||
#lea 32*9*5(%rsp), %rcx
|
||||
#lea 32*9*0($r_ptr), %rdi
|
||||
#call avx2_sub_x4
|
||||
#NORMALIZE
|
||||
#STORE
|
||||
|
||||
# X3 = X3 - U2*2
|
||||
#lea 32*9*0($r_ptr), %rsi
|
||||
#lea 32*9*0($r_ptr), %rdi
|
||||
#call avx2_sub_x4
|
||||
#NORMALIZE
|
||||
#STORE
|
||||
|
||||
lea `32*9*6+128`(%rsp), %rsi
|
||||
lea .LAVX2_POLY_x2+128(%rip), %rax
|
||||
lea `32*9*7+128`(%rsp), %rdx
|
||||
lea `32*9*5+128`(%rsp), %rcx
|
||||
lea `32*9*0`($r_ptr), %rdi
|
||||
|
||||
vmovdqa 32*0-128(%rsi), $ACC0
|
||||
vmovdqa 32*1-128(%rsi), $ACC1
|
||||
vmovdqa 32*2-128(%rsi), $ACC2
|
||||
vmovdqa 32*3-128(%rsi), $ACC3
|
||||
vmovdqa 32*4-128(%rsi), $ACC4
|
||||
vmovdqa 32*5-128(%rsi), $ACC5
|
||||
vmovdqa 32*6-128(%rsi), $ACC6
|
||||
vmovdqa 32*7-128(%rsi), $ACC7
|
||||
vmovdqa 32*8-128(%rsi), $ACC8
|
||||
|
||||
vpaddq 32*0-128(%rax), $ACC0, $ACC0
|
||||
vpaddq 32*1-128(%rax), $ACC1, $ACC1
|
||||
vpaddq 32*2-128(%rax), $ACC2, $ACC2
|
||||
vpaddq 32*3-128(%rax), $ACC3, $ACC3
|
||||
vpaddq 32*4-128(%rax), $ACC4, $ACC4
|
||||
vpaddq 32*5-128(%rax), $ACC5, $ACC5
|
||||
vpaddq 32*6-128(%rax), $ACC6, $ACC6
|
||||
vpaddq 32*7-128(%rax), $ACC7, $ACC7
|
||||
vpaddq 32*8-128(%rax), $ACC8, $ACC8
|
||||
|
||||
vpsubq 32*0-128(%rdx), $ACC0, $ACC0
|
||||
vpsubq 32*1-128(%rdx), $ACC1, $ACC1
|
||||
vpsubq 32*2-128(%rdx), $ACC2, $ACC2
|
||||
vpsubq 32*3-128(%rdx), $ACC3, $ACC3
|
||||
vpsubq 32*4-128(%rdx), $ACC4, $ACC4
|
||||
vpsubq 32*5-128(%rdx), $ACC5, $ACC5
|
||||
vpsubq 32*6-128(%rdx), $ACC6, $ACC6
|
||||
vpsubq 32*7-128(%rdx), $ACC7, $ACC7
|
||||
vpsubq 32*8-128(%rdx), $ACC8, $ACC8
|
||||
|
||||
vpsubq 32*0-128(%rcx), $ACC0, $ACC0
|
||||
vpsubq 32*1-128(%rcx), $ACC1, $ACC1
|
||||
vpsubq 32*2-128(%rcx), $ACC2, $ACC2
|
||||
vpsubq 32*3-128(%rcx), $ACC3, $ACC3
|
||||
vpsubq 32*4-128(%rcx), $ACC4, $ACC4
|
||||
vpsubq 32*5-128(%rcx), $ACC5, $ACC5
|
||||
vpsubq 32*6-128(%rcx), $ACC6, $ACC6
|
||||
vpsubq 32*7-128(%rcx), $ACC7, $ACC7
|
||||
vpsubq 32*8-128(%rcx), $ACC8, $ACC8
|
||||
call avx2_normalize
|
||||
|
||||
lea 32*0($b_ptr), %rsi
|
||||
lea 32*0($a_ptr), %rdx
|
||||
call avx2_select_n_store
|
||||
|
||||
# H = U2 - X3
|
||||
lea `32*9*0`(%rsp), %rsi
|
||||
lea `32*9*0`($r_ptr), %rdx
|
||||
lea `32*9*3`(%rsp), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
#
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*4`(%rsp), %rdx
|
||||
lea `32*9*3`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
#
|
||||
lea `32*9*7`(%rsp), %rsi
|
||||
lea `32*9*1`($a_ptr), %rdx
|
||||
lea `32*9*1`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
#
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*1`(%rsp), %rdx
|
||||
lea `32*9*1`($r_ptr), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize
|
||||
|
||||
lea 32*9($b_ptr), %rsi
|
||||
lea 32*9($a_ptr), %rdx
|
||||
call avx2_select_n_store
|
||||
|
||||
#lea 32*9*0($r_ptr), %rsi
|
||||
#lea 32*9*0($r_ptr), %rdi
|
||||
#call avx2_mul_by1_x4
|
||||
#NORMALIZE
|
||||
#STORE
|
||||
|
||||
lea `32*9*1`($r_ptr), %rsi
|
||||
lea `32*9*1`($r_ptr), %rdi
|
||||
call avx2_mul_by1_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps %xmm6, -16*10(%rbp)
|
||||
movaps %xmm7, -16*9(%rbp)
|
||||
movaps %xmm8, -16*8(%rbp)
|
||||
movaps %xmm9, -16*7(%rbp)
|
||||
movaps %xmm10, -16*6(%rbp)
|
||||
movaps %xmm11, -16*5(%rbp)
|
||||
movaps %xmm12, -16*4(%rbp)
|
||||
movaps %xmm13, -16*3(%rbp)
|
||||
movaps %xmm14, -16*2(%rbp)
|
||||
movaps %xmm15, -16*1(%rbp)
|
||||
___
|
||||
$code.=<<___;
|
||||
mov %rbp, %rsp
|
||||
pop %rbp
|
||||
ret
|
||||
.size ecp_nistz256_avx2_point_add_affine_x4,.-ecp_nistz256_avx2_point_add_affine_x4
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_point_add_affines_x4(void* RESULTx4, void *Ax4, void *Bx4);
|
||||
.globl ecp_nistz256_avx2_point_add_affines_x4
|
||||
.type ecp_nistz256_avx2_point_add_affines_x4,\@function,3
|
||||
.align 32
|
||||
ecp_nistz256_avx2_point_add_affines_x4:
|
||||
mov %rsp, %rax
|
||||
push %rbp
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
lea -8(%rax), %rbp
|
||||
|
||||
# Result + 32*0 = Result.X
|
||||
# Result + 32*9 = Result.Y
|
||||
# Result + 32*18 = Result.Z
|
||||
|
||||
# A + 32*0 = A.X
|
||||
# A + 32*9 = A.Y
|
||||
|
||||
# B + 32*0 = B.X
|
||||
# B + 32*9 = B.Y
|
||||
|
||||
sub \$`32*9*8+32*2+32*8`, %rsp
|
||||
and \$-64, %rsp
|
||||
|
||||
mov $r_ptr_in, $r_ptr
|
||||
mov $a_ptr_in, $a_ptr
|
||||
mov $b_ptr_in, $b_ptr
|
||||
|
||||
vmovdqa 32*0($a_ptr_in), %ymm0
|
||||
vmovdqa .LAVX2_AND_MASK(%rip), $AND_MASK
|
||||
vpxor %ymm1, %ymm1, %ymm1
|
||||
lea 256($a_ptr_in), %rax # size optimization
|
||||
vpor 32*1($a_ptr_in), %ymm0, %ymm0
|
||||
vpor 32*2($a_ptr_in), %ymm0, %ymm0
|
||||
vpor 32*3($a_ptr_in), %ymm0, %ymm0
|
||||
vpor 32*4-256(%rax), %ymm0, %ymm0
|
||||
lea 256(%rax), %rcx # size optimization
|
||||
vpor 32*5-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*6-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*7-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*8-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*9-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*10-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*11-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*12-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*13-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*14-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*15-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*16-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*17-512(%rcx), %ymm0, %ymm0
|
||||
vpcmpeqq %ymm1, %ymm0, %ymm0
|
||||
vmovdqa %ymm0, `32*9*8`(%rsp)
|
||||
|
||||
vpxor %ymm1, %ymm1, %ymm1
|
||||
vmovdqa 32*0($b_ptr), %ymm0
|
||||
lea 256($b_ptr), %rax # size optimization
|
||||
vpor 32*1($b_ptr), %ymm0, %ymm0
|
||||
vpor 32*2($b_ptr), %ymm0, %ymm0
|
||||
vpor 32*3($b_ptr), %ymm0, %ymm0
|
||||
vpor 32*4-256(%rax), %ymm0, %ymm0
|
||||
lea 256(%rax), %rcx # size optimization
|
||||
vpor 32*5-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*6-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*7-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*8-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*9-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*10-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*11-256(%rax), %ymm0, %ymm0
|
||||
vpor 32*12-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*13-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*14-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*15-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*16-512(%rcx), %ymm0, %ymm0
|
||||
vpor 32*17-512(%rcx), %ymm0, %ymm0
|
||||
vpcmpeqq %ymm1, %ymm0, %ymm0
|
||||
vmovdqa %ymm0, `32*9*8+32`(%rsp)
|
||||
|
||||
# H = U2 - U1 = X2 - X1
|
||||
lea `32*9*0`($b_ptr), %rsi
|
||||
lea `32*9*0`($a_ptr), %rdx
|
||||
lea `32*9*3`(%rsp), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# R = S2 - S1 = Y2 - Y1
|
||||
lea `32*9*1`($b_ptr), %rsi
|
||||
lea `32*9*1`($a_ptr), %rdx
|
||||
lea `32*9*4`(%rsp), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# Z3 = H*Z1*Z2 = H
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*2`($r_ptr), %rdi
|
||||
call avx2_mul_by1_x4
|
||||
call avx2_normalize
|
||||
|
||||
vmovdqa `32*9*8`(%rsp), $B
|
||||
vpor `32*9*8+32`(%rsp), $B, $B
|
||||
|
||||
vpandn $ACC0, $B, $ACC0
|
||||
lea .LONE+128(%rip), %rax
|
||||
vpandn $ACC1, $B, $ACC1
|
||||
vpandn $ACC2, $B, $ACC2
|
||||
vpandn $ACC3, $B, $ACC3
|
||||
vpandn $ACC4, $B, $ACC4
|
||||
vpandn $ACC5, $B, $ACC5
|
||||
vpandn $ACC6, $B, $ACC6
|
||||
vpandn $ACC7, $B, $ACC7
|
||||
|
||||
vpand 32*0-128(%rax), $B, $T0
|
||||
vpandn $ACC8, $B, $ACC8
|
||||
vpand 32*1-128(%rax), $B, $Y
|
||||
vpxor $T0, $ACC0, $ACC0
|
||||
vpand 32*2-128(%rax), $B, $T0
|
||||
vpxor $Y, $ACC1, $ACC1
|
||||
vpand 32*3-128(%rax), $B, $Y
|
||||
vpxor $T0, $ACC2, $ACC2
|
||||
vpand 32*4-128(%rax), $B, $T0
|
||||
vpxor $Y, $ACC3, $ACC3
|
||||
vpand 32*5-128(%rax), $B, $Y
|
||||
vpxor $T0, $ACC4, $ACC4
|
||||
vpand 32*6-128(%rax), $B, $T0
|
||||
vpxor $Y, $ACC5, $ACC5
|
||||
vpand 32*7-128(%rax), $B, $Y
|
||||
vpxor $T0, $ACC6, $ACC6
|
||||
vpand 32*8-128(%rax), $B, $T0
|
||||
vpxor $Y, $ACC7, $ACC7
|
||||
vpxor $T0, $ACC8, $ACC8
|
||||
`&STORE`
|
||||
|
||||
# R^2 = R^2
|
||||
lea `32*9*4`(%rsp), %rsi
|
||||
lea `32*9*6`(%rsp), %rdi
|
||||
lea `32*9*8+32*2`(%rsp), %rcx # temporary vector
|
||||
call avx2_sqr_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# H^2 = H^2
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*5`(%rsp), %rdi
|
||||
call avx2_sqr_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# H^3 = H^2*H
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*5`(%rsp), %rdx
|
||||
lea `32*9*7`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# U2 = U1*H^2
|
||||
lea `32*9*0`($a_ptr), %rsi
|
||||
lea `32*9*5`(%rsp), %rdx
|
||||
lea `32*9*0`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
#call avx2_normalize
|
||||
`&STORE`
|
||||
|
||||
# Hsqr = U2*2
|
||||
#lea 32*9*0(%rsp), %rsi
|
||||
#lea 32*9*5(%rsp), %rdi
|
||||
#call avx2_mul_by2_x4
|
||||
|
||||
vpaddq $ACC0, $ACC0, $ACC0 # inlined avx2_mul_by2_x4
|
||||
lea `32*9*5`(%rsp), %rdi
|
||||
vpaddq $ACC1, $ACC1, $ACC1
|
||||
vpaddq $ACC2, $ACC2, $ACC2
|
||||
vpaddq $ACC3, $ACC3, $ACC3
|
||||
vpaddq $ACC4, $ACC4, $ACC4
|
||||
vpaddq $ACC5, $ACC5, $ACC5
|
||||
vpaddq $ACC6, $ACC6, $ACC6
|
||||
vpaddq $ACC7, $ACC7, $ACC7
|
||||
vpaddq $ACC8, $ACC8, $ACC8
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# X3 = R^2 - H^3
|
||||
#lea 32*9*6(%rsp), %rsi
|
||||
#lea 32*9*7(%rsp), %rdx
|
||||
#lea 32*9*5(%rsp), %rcx
|
||||
#lea 32*9*0($r_ptr), %rdi
|
||||
#call avx2_sub_x4
|
||||
#NORMALIZE
|
||||
#STORE
|
||||
|
||||
# X3 = X3 - U2*2
|
||||
#lea 32*9*0($r_ptr), %rsi
|
||||
#lea 32*9*0($r_ptr), %rdi
|
||||
#call avx2_sub_x4
|
||||
#NORMALIZE
|
||||
#STORE
|
||||
|
||||
lea `32*9*6+128`(%rsp), %rsi
|
||||
lea .LAVX2_POLY_x2+128(%rip), %rax
|
||||
lea `32*9*7+128`(%rsp), %rdx
|
||||
lea `32*9*5+128`(%rsp), %rcx
|
||||
lea `32*9*0`($r_ptr), %rdi
|
||||
|
||||
vmovdqa 32*0-128(%rsi), $ACC0
|
||||
vmovdqa 32*1-128(%rsi), $ACC1
|
||||
vmovdqa 32*2-128(%rsi), $ACC2
|
||||
vmovdqa 32*3-128(%rsi), $ACC3
|
||||
vmovdqa 32*4-128(%rsi), $ACC4
|
||||
vmovdqa 32*5-128(%rsi), $ACC5
|
||||
vmovdqa 32*6-128(%rsi), $ACC6
|
||||
vmovdqa 32*7-128(%rsi), $ACC7
|
||||
vmovdqa 32*8-128(%rsi), $ACC8
|
||||
|
||||
vpaddq 32*0-128(%rax), $ACC0, $ACC0
|
||||
vpaddq 32*1-128(%rax), $ACC1, $ACC1
|
||||
vpaddq 32*2-128(%rax), $ACC2, $ACC2
|
||||
vpaddq 32*3-128(%rax), $ACC3, $ACC3
|
||||
vpaddq 32*4-128(%rax), $ACC4, $ACC4
|
||||
vpaddq 32*5-128(%rax), $ACC5, $ACC5
|
||||
vpaddq 32*6-128(%rax), $ACC6, $ACC6
|
||||
vpaddq 32*7-128(%rax), $ACC7, $ACC7
|
||||
vpaddq 32*8-128(%rax), $ACC8, $ACC8
|
||||
|
||||
vpsubq 32*0-128(%rdx), $ACC0, $ACC0
|
||||
vpsubq 32*1-128(%rdx), $ACC1, $ACC1
|
||||
vpsubq 32*2-128(%rdx), $ACC2, $ACC2
|
||||
vpsubq 32*3-128(%rdx), $ACC3, $ACC3
|
||||
vpsubq 32*4-128(%rdx), $ACC4, $ACC4
|
||||
vpsubq 32*5-128(%rdx), $ACC5, $ACC5
|
||||
vpsubq 32*6-128(%rdx), $ACC6, $ACC6
|
||||
vpsubq 32*7-128(%rdx), $ACC7, $ACC7
|
||||
vpsubq 32*8-128(%rdx), $ACC8, $ACC8
|
||||
|
||||
vpsubq 32*0-128(%rcx), $ACC0, $ACC0
|
||||
vpsubq 32*1-128(%rcx), $ACC1, $ACC1
|
||||
vpsubq 32*2-128(%rcx), $ACC2, $ACC2
|
||||
vpsubq 32*3-128(%rcx), $ACC3, $ACC3
|
||||
vpsubq 32*4-128(%rcx), $ACC4, $ACC4
|
||||
vpsubq 32*5-128(%rcx), $ACC5, $ACC5
|
||||
vpsubq 32*6-128(%rcx), $ACC6, $ACC6
|
||||
vpsubq 32*7-128(%rcx), $ACC7, $ACC7
|
||||
vpsubq 32*8-128(%rcx), $ACC8, $ACC8
|
||||
call avx2_normalize
|
||||
|
||||
lea 32*0($b_ptr), %rsi
|
||||
lea 32*0($a_ptr), %rdx
|
||||
call avx2_select_n_store
|
||||
|
||||
# H = U2 - X3
|
||||
lea `32*9*0`(%rsp), %rsi
|
||||
lea `32*9*0`($r_ptr), %rdx
|
||||
lea `32*9*3`(%rsp), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# H = H*R
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*4`(%rsp), %rdx
|
||||
lea `32*9*3`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
# S2 = S1 * H^3
|
||||
lea `32*9*7`(%rsp), %rsi
|
||||
lea `32*9*1`($a_ptr), %rdx
|
||||
lea `32*9*1`(%rsp), %rdi
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
#
|
||||
lea `32*9*3`(%rsp), %rsi
|
||||
lea `32*9*1`(%rsp), %rdx
|
||||
lea `32*9*1`($r_ptr), %rdi
|
||||
call avx2_sub_x4
|
||||
call avx2_normalize
|
||||
|
||||
lea 32*9($b_ptr), %rsi
|
||||
lea 32*9($a_ptr), %rdx
|
||||
call avx2_select_n_store
|
||||
|
||||
#lea 32*9*0($r_ptr), %rsi
|
||||
#lea 32*9*0($r_ptr), %rdi
|
||||
#call avx2_mul_by1_x4
|
||||
#NORMALIZE
|
||||
#STORE
|
||||
|
||||
lea `32*9*1`($r_ptr), %rsi
|
||||
lea `32*9*1`($r_ptr), %rdi
|
||||
call avx2_mul_by1_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps %xmm6, -16*10(%rbp)
|
||||
movaps %xmm7, -16*9(%rbp)
|
||||
movaps %xmm8, -16*8(%rbp)
|
||||
movaps %xmm9, -16*7(%rbp)
|
||||
movaps %xmm10, -16*6(%rbp)
|
||||
movaps %xmm11, -16*5(%rbp)
|
||||
movaps %xmm12, -16*4(%rbp)
|
||||
movaps %xmm13, -16*3(%rbp)
|
||||
movaps %xmm14, -16*2(%rbp)
|
||||
movaps %xmm15, -16*1(%rbp)
|
||||
___
|
||||
$code.=<<___;
|
||||
mov %rbp, %rsp
|
||||
pop %rbp
|
||||
ret
|
||||
.size ecp_nistz256_avx2_point_add_affines_x4,.-ecp_nistz256_avx2_point_add_affines_x4
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_to_mont(void* RESULTx4, void *Ax4);
|
||||
.globl ecp_nistz256_avx2_to_mont
|
||||
.type ecp_nistz256_avx2_to_mont,\@function,2
|
||||
.align 32
|
||||
ecp_nistz256_avx2_to_mont:
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -8-16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
vmovdqa .LAVX2_AND_MASK(%rip), $AND_MASK
|
||||
lea .LTO_MONT_AVX2(%rip), %rdx
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 16*0(%rsp), %xmm6
|
||||
movaps 16*1(%rsp), %xmm7
|
||||
movaps 16*2(%rsp), %xmm8
|
||||
movaps 16*3(%rsp), %xmm9
|
||||
movaps 16*4(%rsp), %xmm10
|
||||
movaps 16*5(%rsp), %xmm11
|
||||
movaps 16*6(%rsp), %xmm12
|
||||
movaps 16*7(%rsp), %xmm13
|
||||
movaps 16*8(%rsp), %xmm14
|
||||
movaps 16*9(%rsp), %xmm15
|
||||
lea 8+16*10(%rsp), %rsp
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_avx2_to_mont,.-ecp_nistz256_avx2_to_mont
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_from_mont(void* RESULTx4, void *Ax4);
|
||||
.globl ecp_nistz256_avx2_from_mont
|
||||
.type ecp_nistz256_avx2_from_mont,\@function,2
|
||||
.align 32
|
||||
ecp_nistz256_avx2_from_mont:
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -8-16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
vmovdqa .LAVX2_AND_MASK(%rip), $AND_MASK
|
||||
lea .LFROM_MONT_AVX2(%rip), %rdx
|
||||
call avx2_mul_x4
|
||||
call avx2_normalize_n_store
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 16*0(%rsp), %xmm6
|
||||
movaps 16*1(%rsp), %xmm7
|
||||
movaps 16*2(%rsp), %xmm8
|
||||
movaps 16*3(%rsp), %xmm9
|
||||
movaps 16*4(%rsp), %xmm10
|
||||
movaps 16*5(%rsp), %xmm11
|
||||
movaps 16*6(%rsp), %xmm12
|
||||
movaps 16*7(%rsp), %xmm13
|
||||
movaps 16*8(%rsp), %xmm14
|
||||
movaps 16*9(%rsp), %xmm15
|
||||
lea 8+16*10(%rsp), %rsp
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_avx2_from_mont,.-ecp_nistz256_avx2_from_mont
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_set1(void* RESULTx4);
|
||||
.globl ecp_nistz256_avx2_set1
|
||||
.type ecp_nistz256_avx2_set1,\@function,1
|
||||
.align 32
|
||||
ecp_nistz256_avx2_set1:
|
||||
lea .LONE+128(%rip), %rax
|
||||
lea 128(%rdi), %rdi
|
||||
vzeroupper
|
||||
vmovdqa 32*0-128(%rax), %ymm0
|
||||
vmovdqa 32*1-128(%rax), %ymm1
|
||||
vmovdqa 32*2-128(%rax), %ymm2
|
||||
vmovdqa 32*3-128(%rax), %ymm3
|
||||
vmovdqa 32*4-128(%rax), %ymm4
|
||||
vmovdqa 32*5-128(%rax), %ymm5
|
||||
vmovdqa %ymm0, 32*0-128(%rdi)
|
||||
vmovdqa 32*6-128(%rax), %ymm0
|
||||
vmovdqa %ymm1, 32*1-128(%rdi)
|
||||
vmovdqa 32*7-128(%rax), %ymm1
|
||||
vmovdqa %ymm2, 32*2-128(%rdi)
|
||||
vmovdqa 32*8-128(%rax), %ymm2
|
||||
vmovdqa %ymm3, 32*3-128(%rdi)
|
||||
vmovdqa %ymm4, 32*4-128(%rdi)
|
||||
vmovdqa %ymm5, 32*5-128(%rdi)
|
||||
vmovdqa %ymm0, 32*6-128(%rdi)
|
||||
vmovdqa %ymm1, 32*7-128(%rdi)
|
||||
vmovdqa %ymm2, 32*8-128(%rdi)
|
||||
|
||||
vzeroupper
|
||||
ret
|
||||
.size ecp_nistz256_avx2_set1,.-ecp_nistz256_avx2_set1
|
||||
___
|
||||
}
|
||||
{
|
||||
################################################################################
|
||||
# void ecp_nistz256_avx2_multi_gather_w7(void* RESULT, void *in,
|
||||
# int index0, int index1, int index2, int index3);
|
||||
################################################################################
|
||||
|
||||
my ($val,$in_t,$index0,$index1,$index2,$index3)=("%rdi","%rsi","%edx","%ecx","%r8d","%r9d");
|
||||
my ($INDEX0,$INDEX1,$INDEX2,$INDEX3)=map("%ymm$_",(0..3));
|
||||
my ($R0a,$R0b,$R1a,$R1b,$R2a,$R2b,$R3a,$R3b)=map("%ymm$_",(4..11));
|
||||
my ($M0,$T0,$T1,$TMP0)=map("%ymm$_",(12..15));
|
||||
|
||||
$code.=<<___;
|
||||
.globl ecp_nistz256_avx2_multi_gather_w7
|
||||
.type ecp_nistz256_avx2_multi_gather_w7,\@function,6
|
||||
.align 32
|
||||
ecp_nistz256_avx2_multi_gather_w7:
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -8-16*10(%rsp), %rsp
|
||||
vmovaps %xmm6, -8-16*10(%rax)
|
||||
vmovaps %xmm7, -8-16*9(%rax)
|
||||
vmovaps %xmm8, -8-16*8(%rax)
|
||||
vmovaps %xmm9, -8-16*7(%rax)
|
||||
vmovaps %xmm10, -8-16*6(%rax)
|
||||
vmovaps %xmm11, -8-16*5(%rax)
|
||||
vmovaps %xmm12, -8-16*4(%rax)
|
||||
vmovaps %xmm13, -8-16*3(%rax)
|
||||
vmovaps %xmm14, -8-16*2(%rax)
|
||||
vmovaps %xmm15, -8-16*1(%rax)
|
||||
___
|
||||
$code.=<<___;
|
||||
lea .LIntOne(%rip), %rax
|
||||
|
||||
vmovd $index0, %xmm0
|
||||
vmovd $index1, %xmm1
|
||||
vmovd $index2, %xmm2
|
||||
vmovd $index3, %xmm3
|
||||
|
||||
vpxor $R0a, $R0a, $R0a
|
||||
vpxor $R0b, $R0b, $R0b
|
||||
vpxor $R1a, $R1a, $R1a
|
||||
vpxor $R1b, $R1b, $R1b
|
||||
vpxor $R2a, $R2a, $R2a
|
||||
vpxor $R2b, $R2b, $R2b
|
||||
vpxor $R3a, $R3a, $R3a
|
||||
vpxor $R3b, $R3b, $R3b
|
||||
vmovdqa (%rax), $M0
|
||||
|
||||
vpermd $INDEX0, $R0a, $INDEX0
|
||||
vpermd $INDEX1, $R0a, $INDEX1
|
||||
vpermd $INDEX2, $R0a, $INDEX2
|
||||
vpermd $INDEX3, $R0a, $INDEX3
|
||||
|
||||
mov \$64, %ecx
|
||||
lea 112($val), $val # size optimization
|
||||
jmp .Lmulti_select_loop_avx2
|
||||
|
||||
# INDEX=0, corresponds to the point at infty (0,0)
|
||||
.align 32
|
||||
.Lmulti_select_loop_avx2:
|
||||
vpcmpeqd $INDEX0, $M0, $TMP0
|
||||
|
||||
vmovdqa `32*0+32*64*2*0`($in_t), $T0
|
||||
vmovdqa `32*1+32*64*2*0`($in_t), $T1
|
||||
vpand $TMP0, $T0, $T0
|
||||
vpand $TMP0, $T1, $T1
|
||||
vpxor $T0, $R0a, $R0a
|
||||
vpxor $T1, $R0b, $R0b
|
||||
|
||||
vpcmpeqd $INDEX1, $M0, $TMP0
|
||||
|
||||
vmovdqa `32*0+32*64*2*1`($in_t), $T0
|
||||
vmovdqa `32*1+32*64*2*1`($in_t), $T1
|
||||
vpand $TMP0, $T0, $T0
|
||||
vpand $TMP0, $T1, $T1
|
||||
vpxor $T0, $R1a, $R1a
|
||||
vpxor $T1, $R1b, $R1b
|
||||
|
||||
vpcmpeqd $INDEX2, $M0, $TMP0
|
||||
|
||||
vmovdqa `32*0+32*64*2*2`($in_t), $T0
|
||||
vmovdqa `32*1+32*64*2*2`($in_t), $T1
|
||||
vpand $TMP0, $T0, $T0
|
||||
vpand $TMP0, $T1, $T1
|
||||
vpxor $T0, $R2a, $R2a
|
||||
vpxor $T1, $R2b, $R2b
|
||||
|
||||
vpcmpeqd $INDEX3, $M0, $TMP0
|
||||
|
||||
vmovdqa `32*0+32*64*2*3`($in_t), $T0
|
||||
vmovdqa `32*1+32*64*2*3`($in_t), $T1
|
||||
vpand $TMP0, $T0, $T0
|
||||
vpand $TMP0, $T1, $T1
|
||||
vpxor $T0, $R3a, $R3a
|
||||
vpxor $T1, $R3b, $R3b
|
||||
|
||||
vpaddd (%rax), $M0, $M0 # increment
|
||||
lea 32*2($in_t), $in_t
|
||||
|
||||
dec %ecx
|
||||
jnz .Lmulti_select_loop_avx2
|
||||
|
||||
vmovdqu $R0a, 32*0-112($val)
|
||||
vmovdqu $R0b, 32*1-112($val)
|
||||
vmovdqu $R1a, 32*2-112($val)
|
||||
vmovdqu $R1b, 32*3-112($val)
|
||||
vmovdqu $R2a, 32*4-112($val)
|
||||
vmovdqu $R2b, 32*5-112($val)
|
||||
vmovdqu $R3a, 32*6-112($val)
|
||||
vmovdqu $R3b, 32*7-112($val)
|
||||
|
||||
vzeroupper
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps 16*0(%rsp), %xmm6
|
||||
movaps 16*1(%rsp), %xmm7
|
||||
movaps 16*2(%rsp), %xmm8
|
||||
movaps 16*3(%rsp), %xmm9
|
||||
movaps 16*4(%rsp), %xmm10
|
||||
movaps 16*5(%rsp), %xmm11
|
||||
movaps 16*6(%rsp), %xmm12
|
||||
movaps 16*7(%rsp), %xmm13
|
||||
movaps 16*8(%rsp), %xmm14
|
||||
movaps 16*9(%rsp), %xmm15
|
||||
lea 8+16*10(%rsp), %rsp
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size ecp_nistz256_avx2_multi_gather_w7,.-ecp_nistz256_avx2_multi_gather_w7
|
||||
|
||||
.extern OPENSSL_ia32cap_P
|
||||
.globl ecp_nistz_avx2_eligible
|
||||
.type ecp_nistz_avx2_eligible,\@abi-omnipotent
|
||||
.align 32
|
||||
ecp_nistz_avx2_eligible:
|
||||
mov OPENSSL_ia32cap_P+8(%rip),%eax
|
||||
shr \$5,%eax
|
||||
and \$1,%eax
|
||||
ret
|
||||
.size ecp_nistz_avx2_eligible,.-ecp_nistz_avx2_eligible
|
||||
___
|
||||
}
|
||||
}} else {{ # assembler is too old
|
||||
$code.=<<___;
|
||||
.text
|
||||
|
||||
.globl ecp_nistz256_avx2_transpose_convert
|
||||
.globl ecp_nistz256_avx2_convert_transpose_back
|
||||
.globl ecp_nistz256_avx2_point_add_affine_x4
|
||||
.globl ecp_nistz256_avx2_point_add_affines_x4
|
||||
.globl ecp_nistz256_avx2_to_mont
|
||||
.globl ecp_nistz256_avx2_from_mont
|
||||
.globl ecp_nistz256_avx2_set1
|
||||
.globl ecp_nistz256_avx2_multi_gather_w7
|
||||
.type ecp_nistz256_avx2_multi_gather_w7,\@abi-omnipotent
|
||||
ecp_nistz256_avx2_transpose_convert:
|
||||
ecp_nistz256_avx2_convert_transpose_back:
|
||||
ecp_nistz256_avx2_point_add_affine_x4:
|
||||
ecp_nistz256_avx2_point_add_affines_x4:
|
||||
ecp_nistz256_avx2_to_mont:
|
||||
ecp_nistz256_avx2_from_mont:
|
||||
ecp_nistz256_avx2_set1:
|
||||
ecp_nistz256_avx2_multi_gather_w7:
|
||||
.byte 0x0f,0x0b # ud2
|
||||
ret
|
||||
.size ecp_nistz256_avx2_multi_gather_w7,.-ecp_nistz256_avx2_multi_gather_w7
|
||||
|
||||
.globl ecp_nistz_avx2_eligible
|
||||
.type ecp_nistz_avx2_eligible,\@abi-omnipotent
|
||||
ecp_nistz_avx2_eligible:
|
||||
xor %eax,%eax
|
||||
ret
|
||||
.size ecp_nistz_avx2_eligible,.-ecp_nistz_avx2_eligible
|
||||
___
|
||||
}}
|
||||
|
||||
foreach (split("\n",$code)) {
|
||||
s/\`([^\`]*)\`/eval($1)/geo;
|
||||
|
||||
print $_,"\n";
|
||||
}
|
||||
|
||||
close STDOUT or die "error closing STDOUT: $!";
|
||||
@@ -489,7 +489,8 @@ int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
|
||||
/* point is its own inverse */
|
||||
return 1;
|
||||
|
||||
if (!EC_POINT_make_affine(group, point, ctx))
|
||||
if (group->meth->make_affine == NULL
|
||||
|| !group->meth->make_affine(group, point, ctx))
|
||||
return 0;
|
||||
return BN_GF2m_add(point->Y, point->X, point->Y);
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ static EC_KEY *eckey_type2param(int ptype, const void *pval)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
|
||||
{
|
||||
const unsigned char *p = NULL;
|
||||
const void *pval;
|
||||
|
||||
+4
-7
@@ -27,8 +27,7 @@ int EC_GROUP_get_basis_type(const EC_GROUP *group)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
|
||||
NID_X9_62_characteristic_two_field)
|
||||
if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field)
|
||||
/* everything else is currently not supported */
|
||||
return 0;
|
||||
|
||||
@@ -53,8 +52,7 @@ int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
|
||||
if (group == NULL)
|
||||
return 0;
|
||||
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
|
||||
NID_X9_62_characteristic_two_field
|
||||
if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field
|
||||
|| !((group->poly[0] != 0) && (group->poly[1] != 0)
|
||||
&& (group->poly[2] == 0))) {
|
||||
ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS,
|
||||
@@ -74,8 +72,7 @@ int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
|
||||
if (group == NULL)
|
||||
return 0;
|
||||
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
|
||||
NID_X9_62_characteristic_two_field
|
||||
if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field
|
||||
|| !((group->poly[0] != 0) && (group->poly[1] != 0)
|
||||
&& (group->poly[2] != 0) && (group->poly[3] != 0)
|
||||
&& (group->poly[4] == 0))) {
|
||||
@@ -262,7 +259,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
|
||||
ASN1_OBJECT_free(field->fieldType);
|
||||
ASN1_TYPE_free(field->p.other);
|
||||
|
||||
nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
|
||||
nid = EC_GROUP_get_field_type(group);
|
||||
/* set OID for the field */
|
||||
if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) {
|
||||
ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
|
||||
|
||||
@@ -19,15 +19,10 @@
|
||||
* implementations alike.
|
||||
*/
|
||||
|
||||
int ec_set_param_ecdh_cofactor_mode(EC_KEY *ec, const OSSL_PARAM *p)
|
||||
int ec_set_ecdh_cofactor_mode(EC_KEY *ec, int mode)
|
||||
{
|
||||
const EC_GROUP *ecg = EC_KEY_get0_group(ec);
|
||||
const BIGNUM *cofactor;
|
||||
int mode;
|
||||
|
||||
if (!OSSL_PARAM_get_int(p, &mode))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* mode can be only 0 for disable, or 1 for enable here.
|
||||
*
|
||||
@@ -224,8 +219,12 @@ int ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
|
||||
return 0;
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH);
|
||||
if (p != NULL && !ec_set_param_ecdh_cofactor_mode(ec, p))
|
||||
return 0;
|
||||
if (p != NULL) {
|
||||
int mode;
|
||||
|
||||
if (!OSSL_PARAM_get_int(p, &mode)
|
||||
|| !ec_set_ecdh_cofactor_mode(ec, mode))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -3195,7 +3195,7 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx,
|
||||
|
||||
/* If no curve data curve method must handle everything */
|
||||
if (curve.data == NULL)
|
||||
return EC_GROUP_new_ex(libctx,
|
||||
return ec_group_new_ex(libctx,
|
||||
curve.meth != NULL ? curve.meth() : NULL);
|
||||
|
||||
if ((ctx = BN_CTX_new_ex(libctx)) == NULL) {
|
||||
@@ -3218,7 +3218,7 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx,
|
||||
|
||||
if (curve.meth != 0) {
|
||||
meth = curve.meth();
|
||||
if (((group = EC_GROUP_new_ex(libctx, meth)) == NULL) ||
|
||||
if (((group = ec_group_new_ex(libctx, meth)) == NULL) ||
|
||||
(!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
@@ -3388,17 +3388,13 @@ int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx)
|
||||
unsigned char *param_bytes = NULL;
|
||||
const EC_CURVE_DATA *data;
|
||||
const EC_POINT *generator = NULL;
|
||||
const EC_METHOD *meth;
|
||||
const BIGNUM *cofactor = NULL;
|
||||
/* An array of BIGNUMs for (p, a, b, x, y, order) */
|
||||
BIGNUM *bn[NUM_BN_FIELDS] = {NULL, NULL, NULL, NULL, NULL, NULL};
|
||||
|
||||
meth = EC_GROUP_method_of(group);
|
||||
if (meth == NULL)
|
||||
return -1;
|
||||
/* Use the optional named curve nid as a search field */
|
||||
nid = EC_GROUP_get_curve_name(group);
|
||||
field_type = EC_METHOD_get_field_type(meth);
|
||||
field_type = EC_GROUP_get_field_type(group);
|
||||
seed_len = EC_GROUP_get_seed_len(group);
|
||||
seed = EC_GROUP_get0_seed(group);
|
||||
cofactor = EC_GROUP_get0_cofactor(group);
|
||||
|
||||
+2
-2
@@ -54,7 +54,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
|
||||
meth = EC_GFp_mont_method();
|
||||
#endif
|
||||
|
||||
ret = EC_GROUP_new_ex(bn_get_lib_ctx(ctx), meth);
|
||||
ret = ec_group_new_ex(bn_get_lib_ctx(ctx), meth);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -75,7 +75,7 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
|
||||
|
||||
meth = EC_GF2m_simple_method();
|
||||
|
||||
ret = EC_GROUP_new_ex(bn_get_lib_ctx(ctx), meth);
|
||||
ret = ec_group_new_ex(bn_get_lib_ctx(ctx), meth);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
+4
-3
@@ -117,10 +117,9 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
|
||||
dest->libctx = src->libctx;
|
||||
/* copy the parameters */
|
||||
if (src->group != NULL) {
|
||||
const EC_METHOD *meth = EC_GROUP_method_of(src->group);
|
||||
/* clear the old group */
|
||||
EC_GROUP_free(dest->group);
|
||||
dest->group = EC_GROUP_new_ex(src->libctx, meth);
|
||||
dest->group = ec_group_new_ex(src->libctx, src->group->meth);
|
||||
if (dest->group == NULL)
|
||||
return NULL;
|
||||
if (!EC_GROUP_copy(dest->group, src->group))
|
||||
@@ -398,7 +397,7 @@ static int ec_key_public_range_check(BN_CTX *ctx, const EC_KEY *key)
|
||||
if (!EC_POINT_get_affine_coordinates(key->group, key->pub_key, x, y, ctx))
|
||||
goto err;
|
||||
|
||||
if (EC_METHOD_get_field_type(key->group->meth) == NID_X9_62_prime_field) {
|
||||
if (EC_GROUP_get_field_type(key->group) == NID_X9_62_prime_field) {
|
||||
if (BN_is_negative(x)
|
||||
|| BN_cmp(x, key->group->field) >= 0
|
||||
|| BN_is_negative(y)
|
||||
@@ -781,12 +780,14 @@ void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
|
||||
EC_GROUP_set_asn1_flag(key->group, flag);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
|
||||
{
|
||||
if (key->group == NULL)
|
||||
return 0;
|
||||
return EC_GROUP_precompute_mult(key->group, ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
int EC_KEY_get_flags(const EC_KEY *key)
|
||||
{
|
||||
|
||||
+24
-10
@@ -23,7 +23,7 @@
|
||||
|
||||
/* functions for EC_GROUP objects */
|
||||
|
||||
EC_GROUP *EC_GROUP_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth)
|
||||
EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth)
|
||||
{
|
||||
EC_GROUP *ret;
|
||||
|
||||
@@ -65,11 +65,13 @@ EC_GROUP *EC_GROUP_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
# ifndef FIPS_MODULE
|
||||
EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
|
||||
{
|
||||
return EC_GROUP_new_ex(NULL, meth);
|
||||
return ec_group_new_ex(NULL, meth);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
void EC_pre_comp_free(EC_GROUP *group)
|
||||
@@ -255,7 +257,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
|
||||
if (a == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((t = EC_GROUP_new_ex(a->libctx, a->meth)) == NULL)
|
||||
if ((t = ec_group_new_ex(a->libctx, a->meth)) == NULL)
|
||||
return NULL;
|
||||
if (!EC_GROUP_copy(t, a))
|
||||
goto err;
|
||||
@@ -270,6 +272,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
|
||||
return t;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
|
||||
{
|
||||
return group->meth;
|
||||
@@ -279,6 +282,7 @@ int EC_METHOD_get_field_type(const EC_METHOD *meth)
|
||||
{
|
||||
return meth->field_type;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ec_precompute_mont_data(EC_GROUP *);
|
||||
|
||||
@@ -475,6 +479,11 @@ const BIGNUM *EC_GROUP_get0_field(const EC_GROUP *group)
|
||||
return group->field;
|
||||
}
|
||||
|
||||
int EC_GROUP_get_field_type(const EC_GROUP *group)
|
||||
{
|
||||
return group->meth->field_type;
|
||||
}
|
||||
|
||||
void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
|
||||
{
|
||||
group->asn1_flag = flag;
|
||||
@@ -602,8 +611,7 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
|
||||
#endif
|
||||
|
||||
/* compare the field types */
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
|
||||
EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
|
||||
if (EC_GROUP_get_field_type(a) != EC_GROUP_get_field_type(b))
|
||||
return 1;
|
||||
/* compare the curve name (if present in both) */
|
||||
if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
|
||||
@@ -777,10 +785,12 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
|
||||
return t;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
|
||||
{
|
||||
return point->meth;
|
||||
}
|
||||
#endif
|
||||
|
||||
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
|
||||
{
|
||||
@@ -1004,6 +1014,7 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
|
||||
return group->meth->point_cmp(group, a, b, ctx);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
|
||||
{
|
||||
if (group->meth->make_affine == 0) {
|
||||
@@ -1034,6 +1045,7 @@ int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
|
||||
}
|
||||
return group->meth->points_make_affine(group, num, points, ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Functions for point multiplication. If group->meth->mul is 0, we use the
|
||||
@@ -1093,6 +1105,7 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
|
||||
const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t num;
|
||||
#ifndef FIPS_MODULE
|
||||
BN_CTX *new_ctx = NULL;
|
||||
#endif
|
||||
@@ -1115,13 +1128,12 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
|
||||
return 0;
|
||||
}
|
||||
|
||||
num = (point != NULL && p_scalar != NULL) ? 1 : 0;
|
||||
if (group->meth->mul != NULL)
|
||||
ret = group->meth->mul(group, r, g_scalar, point != NULL
|
||||
&& p_scalar != NULL, &point, &p_scalar, ctx);
|
||||
ret = group->meth->mul(group, r, g_scalar, num, &point, &p_scalar, ctx);
|
||||
else
|
||||
/* use default */
|
||||
ret = ec_wNAF_mul(group, r, g_scalar, point != NULL
|
||||
&& p_scalar != NULL, &point, &p_scalar, ctx);
|
||||
ret = ec_wNAF_mul(group, r, g_scalar, num, &point, &p_scalar, ctx);
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
BN_CTX_free(new_ctx);
|
||||
@@ -1129,6 +1141,7 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
{
|
||||
if (group->meth->mul == 0)
|
||||
@@ -1153,6 +1166,7 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
|
||||
return 0; /* cannot tell whether precomputation has
|
||||
* been performed */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ec_precompute_mont_data sets |group->mont_data| from |group->order| and
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
/* Curve does not support signing operations */
|
||||
#define EC_FLAGS_NO_SIGN 0x4
|
||||
|
||||
#ifdef OPENSSL_NO_DEPRECATED_3_0
|
||||
typedef struct ec_method_st EC_METHOD;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Structure details are not part of the exported interface, so all this may
|
||||
* change in future versions.
|
||||
@@ -585,6 +589,15 @@ void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
|
||||
#endif
|
||||
int ec_group_simple_order_bits(const EC_GROUP *group);
|
||||
|
||||
/**
|
||||
* Creates a new EC_GROUP object
|
||||
* \param libctx The associated library context or NULL for the default
|
||||
* library context
|
||||
* \param meth EC_METHOD to use
|
||||
* \return newly created EC_GROUP object or NULL in case of an error.
|
||||
*/
|
||||
EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth);
|
||||
|
||||
#ifdef ECP_NISTZ256_ASM
|
||||
/** Returns GFp methods using montgomery multiplication, with x86-64 optimized
|
||||
* P256. See http://eprint.iacr.org/2013/816.
|
||||
|
||||
+6
-3
@@ -267,7 +267,8 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
|
||||
}
|
||||
|
||||
/* ensure input point is in affine coords for ladder step efficiency */
|
||||
if (!p->Z_is_one && !EC_POINT_make_affine(group, p, ctx)) {
|
||||
if (!p->Z_is_one && (group->meth->make_affine == NULL
|
||||
|| !group->meth->make_affine(group, p, ctx))) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -711,7 +712,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
}
|
||||
}
|
||||
|
||||
if (!EC_POINTs_make_affine(group, num_val, val, ctx))
|
||||
if (group->meth->points_make_affine == NULL
|
||||
|| !group->meth->points_make_affine(group, num_val, val, ctx))
|
||||
goto err;
|
||||
|
||||
r_is_at_infinity = 1;
|
||||
@@ -949,7 +951,8 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
if (!EC_POINTs_make_affine(group, num, points, ctx))
|
||||
if (group->meth->points_make_affine == NULL
|
||||
|| !group->meth->points_make_affine(group, num, points, ctx))
|
||||
goto err;
|
||||
|
||||
pre_comp->group = group;
|
||||
|
||||
@@ -32,7 +32,7 @@ int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
|
||||
const char *mdname = EVP_MD_name(md);
|
||||
EVP_KDF *kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_X963KDF, NULL);
|
||||
|
||||
if ((kctx = EVP_KDF_CTX_new(kdf)) != NULL) {
|
||||
if ((kctx = EVP_KDF_new_ctx(kdf)) != NULL) {
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
|
||||
(char *)mdname, 0);
|
||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
|
||||
@@ -41,9 +41,9 @@ int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
|
||||
(void *)sinfo, sinfolen);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
|
||||
ret = EVP_KDF_CTX_set_params(kctx, params) > 0
|
||||
ret = EVP_KDF_set_ctx_params(kctx, params) > 0
|
||||
&& EVP_KDF_derive(kctx, out, outlen) > 0;
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
}
|
||||
EVP_KDF_free(kdf);
|
||||
return ret;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
@@ -115,7 +115,7 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
|
||||
/* explicit parameters */
|
||||
int is_char_two = 0;
|
||||
point_conversion_form_t form;
|
||||
int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
|
||||
int tmp_nid = EC_GROUP_get_field_type(x);
|
||||
|
||||
if (tmp_nid == NID_X9_62_characteristic_two_field)
|
||||
is_char_two = 1;
|
||||
|
||||
@@ -75,6 +75,7 @@ typedef uint64_t u64;
|
||||
*/
|
||||
|
||||
typedef uint64_t limb;
|
||||
typedef uint64_t limb_aX __attribute((__aligned__(1)));
|
||||
typedef uint128_t widelimb;
|
||||
|
||||
typedef limb felem[4];
|
||||
@@ -311,10 +312,10 @@ const EC_METHOD *EC_GFp_nistp224_method(void)
|
||||
*/
|
||||
static void bin28_to_felem(felem out, const u8 in[28])
|
||||
{
|
||||
out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
|
||||
out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff;
|
||||
out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff;
|
||||
out[3] = (*((const uint64_t *)(in+20))) >> 8;
|
||||
out[0] = *((const limb *)(in)) & 0x00ffffffffffffff;
|
||||
out[1] = (*((const limb_aX *)(in + 7))) & 0x00ffffffffffffff;
|
||||
out[2] = (*((const limb_aX *)(in + 14))) & 0x00ffffffffffffff;
|
||||
out[3] = (*((const limb_aX *)(in + 20))) >> 8;
|
||||
}
|
||||
|
||||
static void felem_to_bin28(u8 out[28], const felem in)
|
||||
|
||||
+17
-16
@@ -131,6 +131,7 @@ static const felem_bytearray nistp521_curve_params[5] = {
|
||||
#define NLIMBS 9
|
||||
|
||||
typedef uint64_t limb;
|
||||
typedef limb limb_aX __attribute((__aligned__(1)));
|
||||
typedef limb felem[NLIMBS];
|
||||
typedef uint128_t largefelem[NLIMBS];
|
||||
|
||||
@@ -144,14 +145,14 @@ static const limb bottom58bits = 0x3ffffffffffffff;
|
||||
static void bin66_to_felem(felem out, const u8 in[66])
|
||||
{
|
||||
out[0] = (*((limb *) & in[0])) & bottom58bits;
|
||||
out[1] = (*((limb *) & in[7]) >> 2) & bottom58bits;
|
||||
out[2] = (*((limb *) & in[14]) >> 4) & bottom58bits;
|
||||
out[3] = (*((limb *) & in[21]) >> 6) & bottom58bits;
|
||||
out[4] = (*((limb *) & in[29])) & bottom58bits;
|
||||
out[5] = (*((limb *) & in[36]) >> 2) & bottom58bits;
|
||||
out[6] = (*((limb *) & in[43]) >> 4) & bottom58bits;
|
||||
out[7] = (*((limb *) & in[50]) >> 6) & bottom58bits;
|
||||
out[8] = (*((limb *) & in[58])) & bottom57bits;
|
||||
out[1] = (*((limb_aX *) & in[7]) >> 2) & bottom58bits;
|
||||
out[2] = (*((limb_aX *) & in[14]) >> 4) & bottom58bits;
|
||||
out[3] = (*((limb_aX *) & in[21]) >> 6) & bottom58bits;
|
||||
out[4] = (*((limb_aX *) & in[29])) & bottom58bits;
|
||||
out[5] = (*((limb_aX *) & in[36]) >> 2) & bottom58bits;
|
||||
out[6] = (*((limb_aX *) & in[43]) >> 4) & bottom58bits;
|
||||
out[7] = (*((limb_aX *) & in[50]) >> 6) & bottom58bits;
|
||||
out[8] = (*((limb_aX *) & in[58])) & bottom57bits;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -162,14 +163,14 @@ static void felem_to_bin66(u8 out[66], const felem in)
|
||||
{
|
||||
memset(out, 0, 66);
|
||||
(*((limb *) & out[0])) = in[0];
|
||||
(*((limb *) & out[7])) |= in[1] << 2;
|
||||
(*((limb *) & out[14])) |= in[2] << 4;
|
||||
(*((limb *) & out[21])) |= in[3] << 6;
|
||||
(*((limb *) & out[29])) = in[4];
|
||||
(*((limb *) & out[36])) |= in[5] << 2;
|
||||
(*((limb *) & out[43])) |= in[6] << 4;
|
||||
(*((limb *) & out[50])) |= in[7] << 6;
|
||||
(*((limb *) & out[58])) = in[8];
|
||||
(*((limb_aX *) & out[7])) |= in[1] << 2;
|
||||
(*((limb_aX *) & out[14])) |= in[2] << 4;
|
||||
(*((limb_aX *) & out[21])) |= in[3] << 6;
|
||||
(*((limb_aX *) & out[29])) = in[4];
|
||||
(*((limb_aX *) & out[36])) |= in[5] << 2;
|
||||
(*((limb_aX *) & out[43])) |= in[6] << 4;
|
||||
(*((limb_aX *) & out[50])) |= in[7] << 6;
|
||||
(*((limb_aX *) & out[58])) = in[8];
|
||||
}
|
||||
|
||||
/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
|
||||
|
||||
+49
-256
@@ -897,7 +897,8 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
|
||||
* It would be faster to use EC_POINTs_make_affine and
|
||||
* make multiple points affine at the same time.
|
||||
*/
|
||||
if (!EC_POINT_make_affine(group, P, ctx))
|
||||
if (group->meth->make_affine == NULL
|
||||
|| !group->meth->make_affine(group, P, ctx))
|
||||
goto err;
|
||||
if (!ecp_nistz256_bignum_to_field_elem(temp.X, P->X) ||
|
||||
!ecp_nistz256_bignum_to_field_elem(temp.Y, P->Y)) {
|
||||
@@ -935,207 +936,6 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that by default ECP_NISTZ256_AVX2 is undefined. While it's great
|
||||
* code processing 4 points in parallel, corresponding serial operation
|
||||
* is several times slower, because it uses 29x29=58-bit multiplication
|
||||
* as opposite to 64x64=128-bit in integer-only scalar case. As result
|
||||
* it doesn't provide *significant* performance improvement. Note that
|
||||
* just defining ECP_NISTZ256_AVX2 is not sufficient to make it work,
|
||||
* you'd need to compile even asm/ecp_nistz256-avx.pl module.
|
||||
*/
|
||||
#if defined(ECP_NISTZ256_AVX2)
|
||||
# if !(defined(__x86_64) || defined(__x86_64__) || \
|
||||
defined(_M_AMD64) || defined(_M_X64)) || \
|
||||
!(defined(__GNUC__) || defined(_MSC_VER)) /* this is for ALIGN32 */
|
||||
# undef ECP_NISTZ256_AVX2
|
||||
# else
|
||||
/* Constant time access, loading four values, from four consecutive tables */
|
||||
void ecp_nistz256_avx2_multi_gather_w7(void *result, const void *in,
|
||||
int index0, int index1, int index2,
|
||||
int index3);
|
||||
void ecp_nistz256_avx2_transpose_convert(void *RESULTx4, const void *in);
|
||||
void ecp_nistz256_avx2_convert_transpose_back(void *result, const void *Ax4);
|
||||
void ecp_nistz256_avx2_point_add_affine_x4(void *RESULTx4, const void *Ax4,
|
||||
const void *Bx4);
|
||||
void ecp_nistz256_avx2_point_add_affines_x4(void *RESULTx4, const void *Ax4,
|
||||
const void *Bx4);
|
||||
void ecp_nistz256_avx2_to_mont(void *RESULTx4, const void *Ax4);
|
||||
void ecp_nistz256_avx2_from_mont(void *RESULTx4, const void *Ax4);
|
||||
void ecp_nistz256_avx2_set1(void *RESULTx4);
|
||||
int ecp_nistz_avx2_eligible(void);
|
||||
|
||||
static void booth_recode_w7(unsigned char *sign,
|
||||
unsigned char *digit, unsigned char in)
|
||||
{
|
||||
unsigned char s, d;
|
||||
|
||||
s = ~((in >> 7) - 1);
|
||||
d = (1 << 8) - in - 1;
|
||||
d = (d & s) | (in & ~s);
|
||||
d = (d >> 1) + (d & 1);
|
||||
|
||||
*sign = s & 1;
|
||||
*digit = d;
|
||||
}
|
||||
|
||||
/*
|
||||
* ecp_nistz256_avx2_mul_g performs multiplication by G, using only the
|
||||
* precomputed table. It does 4 affine point additions in parallel,
|
||||
* significantly speeding up point multiplication for a fixed value.
|
||||
*/
|
||||
static void ecp_nistz256_avx2_mul_g(P256_POINT *r,
|
||||
unsigned char p_str[33],
|
||||
const P256_POINT_AFFINE(*preComputedTable)[64])
|
||||
{
|
||||
const unsigned int window_size = 7;
|
||||
const unsigned int mask = (1 << (window_size + 1)) - 1;
|
||||
unsigned int wvalue;
|
||||
/* Using 4 windows at a time */
|
||||
unsigned char sign0, digit0;
|
||||
unsigned char sign1, digit1;
|
||||
unsigned char sign2, digit2;
|
||||
unsigned char sign3, digit3;
|
||||
unsigned int idx = 0;
|
||||
BN_ULONG tmp[P256_LIMBS];
|
||||
int i;
|
||||
|
||||
ALIGN32 BN_ULONG aX4[4 * 9 * 3] = { 0 };
|
||||
ALIGN32 BN_ULONG bX4[4 * 9 * 2] = { 0 };
|
||||
ALIGN32 P256_POINT_AFFINE point_arr[4];
|
||||
ALIGN32 P256_POINT res_point_arr[4];
|
||||
|
||||
/* Initial four windows */
|
||||
wvalue = *((u16 *) & p_str[0]);
|
||||
wvalue = (wvalue << 1) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign0, &digit0, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign1, &digit1, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign2, &digit2, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign3, &digit3, wvalue);
|
||||
|
||||
ecp_nistz256_avx2_multi_gather_w7(point_arr, preComputedTable[0],
|
||||
digit0, digit1, digit2, digit3);
|
||||
|
||||
ecp_nistz256_neg(tmp, point_arr[0].Y);
|
||||
copy_conditional(point_arr[0].Y, tmp, sign0);
|
||||
ecp_nistz256_neg(tmp, point_arr[1].Y);
|
||||
copy_conditional(point_arr[1].Y, tmp, sign1);
|
||||
ecp_nistz256_neg(tmp, point_arr[2].Y);
|
||||
copy_conditional(point_arr[2].Y, tmp, sign2);
|
||||
ecp_nistz256_neg(tmp, point_arr[3].Y);
|
||||
copy_conditional(point_arr[3].Y, tmp, sign3);
|
||||
|
||||
ecp_nistz256_avx2_transpose_convert(aX4, point_arr);
|
||||
ecp_nistz256_avx2_to_mont(aX4, aX4);
|
||||
ecp_nistz256_avx2_to_mont(&aX4[4 * 9], &aX4[4 * 9]);
|
||||
ecp_nistz256_avx2_set1(&aX4[4 * 9 * 2]);
|
||||
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign0, &digit0, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign1, &digit1, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign2, &digit2, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign3, &digit3, wvalue);
|
||||
|
||||
ecp_nistz256_avx2_multi_gather_w7(point_arr, preComputedTable[4 * 1],
|
||||
digit0, digit1, digit2, digit3);
|
||||
|
||||
ecp_nistz256_neg(tmp, point_arr[0].Y);
|
||||
copy_conditional(point_arr[0].Y, tmp, sign0);
|
||||
ecp_nistz256_neg(tmp, point_arr[1].Y);
|
||||
copy_conditional(point_arr[1].Y, tmp, sign1);
|
||||
ecp_nistz256_neg(tmp, point_arr[2].Y);
|
||||
copy_conditional(point_arr[2].Y, tmp, sign2);
|
||||
ecp_nistz256_neg(tmp, point_arr[3].Y);
|
||||
copy_conditional(point_arr[3].Y, tmp, sign3);
|
||||
|
||||
ecp_nistz256_avx2_transpose_convert(bX4, point_arr);
|
||||
ecp_nistz256_avx2_to_mont(bX4, bX4);
|
||||
ecp_nistz256_avx2_to_mont(&bX4[4 * 9], &bX4[4 * 9]);
|
||||
/* Optimized when both inputs are affine */
|
||||
ecp_nistz256_avx2_point_add_affines_x4(aX4, aX4, bX4);
|
||||
|
||||
for (i = 2; i < 9; i++) {
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign0, &digit0, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign1, &digit1, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign2, &digit2, wvalue);
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
booth_recode_w7(&sign3, &digit3, wvalue);
|
||||
|
||||
ecp_nistz256_avx2_multi_gather_w7(point_arr,
|
||||
preComputedTable[4 * i],
|
||||
digit0, digit1, digit2, digit3);
|
||||
|
||||
ecp_nistz256_neg(tmp, point_arr[0].Y);
|
||||
copy_conditional(point_arr[0].Y, tmp, sign0);
|
||||
ecp_nistz256_neg(tmp, point_arr[1].Y);
|
||||
copy_conditional(point_arr[1].Y, tmp, sign1);
|
||||
ecp_nistz256_neg(tmp, point_arr[2].Y);
|
||||
copy_conditional(point_arr[2].Y, tmp, sign2);
|
||||
ecp_nistz256_neg(tmp, point_arr[3].Y);
|
||||
copy_conditional(point_arr[3].Y, tmp, sign3);
|
||||
|
||||
ecp_nistz256_avx2_transpose_convert(bX4, point_arr);
|
||||
ecp_nistz256_avx2_to_mont(bX4, bX4);
|
||||
ecp_nistz256_avx2_to_mont(&bX4[4 * 9], &bX4[4 * 9]);
|
||||
|
||||
ecp_nistz256_avx2_point_add_affine_x4(aX4, aX4, bX4);
|
||||
}
|
||||
|
||||
ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 0], &aX4[4 * 9 * 0]);
|
||||
ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 1], &aX4[4 * 9 * 1]);
|
||||
ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 2], &aX4[4 * 9 * 2]);
|
||||
|
||||
ecp_nistz256_avx2_convert_transpose_back(res_point_arr, aX4);
|
||||
/* Last window is performed serially */
|
||||
wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
booth_recode_w7(&sign0, &digit0, wvalue);
|
||||
ecp_nistz256_gather_w7((P256_POINT_AFFINE *)r,
|
||||
preComputedTable[36], digit0);
|
||||
ecp_nistz256_neg(tmp, r->Y);
|
||||
copy_conditional(r->Y, tmp, sign0);
|
||||
memcpy(r->Z, ONE, sizeof(ONE));
|
||||
/* Sum the four windows */
|
||||
ecp_nistz256_point_add(r, r, &res_point_arr[0]);
|
||||
ecp_nistz256_point_add(r, r, &res_point_arr[1]);
|
||||
ecp_nistz256_point_add(r, r, &res_point_arr[2]);
|
||||
ecp_nistz256_point_add(r, r, &res_point_arr[3]);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
__owur static int ecp_nistz256_set_from_affine(EC_POINT *out, const EC_GROUP *group,
|
||||
const P256_POINT_AFFINE *in,
|
||||
BN_CTX *ctx)
|
||||
@@ -1225,6 +1025,8 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
if (preComputedTable) {
|
||||
BN_ULONG infty;
|
||||
|
||||
if ((BN_num_bits(scalar) > 256)
|
||||
|| BN_is_negative(scalar)) {
|
||||
if ((tmp_scalar = BN_CTX_get(ctx)) == NULL)
|
||||
@@ -1256,67 +1058,58 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
|
||||
for (; i < 33; i++)
|
||||
p_str[i] = 0;
|
||||
|
||||
#if defined(ECP_NISTZ256_AVX2)
|
||||
if (ecp_nistz_avx2_eligible()) {
|
||||
ecp_nistz256_avx2_mul_g(&p.p, p_str, preComputedTable);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
BN_ULONG infty;
|
||||
/* First window */
|
||||
wvalue = (p_str[0] << 1) & mask;
|
||||
idx += window_size;
|
||||
|
||||
/* First window */
|
||||
wvalue = (p_str[0] << 1) & mask;
|
||||
wvalue = _booth_recode_w7(wvalue);
|
||||
|
||||
ecp_nistz256_gather_w7(&p.a, preComputedTable[0],
|
||||
wvalue >> 1);
|
||||
|
||||
ecp_nistz256_neg(p.p.Z, p.p.Y);
|
||||
copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
|
||||
|
||||
/*
|
||||
* Since affine infinity is encoded as (0,0) and
|
||||
* Jacobian is (,,0), we need to harmonize them
|
||||
* by assigning "one" or zero to Z.
|
||||
*/
|
||||
infty = (p.p.X[0] | p.p.X[1] | p.p.X[2] | p.p.X[3] |
|
||||
p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]);
|
||||
if (P256_LIMBS == 8)
|
||||
infty |= (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] |
|
||||
p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]);
|
||||
|
||||
infty = 0 - is_zero(infty);
|
||||
infty = ~infty;
|
||||
|
||||
p.p.Z[0] = ONE[0] & infty;
|
||||
p.p.Z[1] = ONE[1] & infty;
|
||||
p.p.Z[2] = ONE[2] & infty;
|
||||
p.p.Z[3] = ONE[3] & infty;
|
||||
if (P256_LIMBS == 8) {
|
||||
p.p.Z[4] = ONE[4] & infty;
|
||||
p.p.Z[5] = ONE[5] & infty;
|
||||
p.p.Z[6] = ONE[6] & infty;
|
||||
p.p.Z[7] = ONE[7] & infty;
|
||||
}
|
||||
|
||||
for (i = 1; i < 37; i++) {
|
||||
unsigned int off = (idx - 1) / 8;
|
||||
wvalue = p_str[off] | p_str[off + 1] << 8;
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
|
||||
wvalue = _booth_recode_w7(wvalue);
|
||||
|
||||
ecp_nistz256_gather_w7(&p.a, preComputedTable[0],
|
||||
wvalue >> 1);
|
||||
ecp_nistz256_gather_w7(&t.a,
|
||||
preComputedTable[i], wvalue >> 1);
|
||||
|
||||
ecp_nistz256_neg(p.p.Z, p.p.Y);
|
||||
copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
|
||||
ecp_nistz256_neg(t.p.Z, t.a.Y);
|
||||
copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
|
||||
|
||||
/*
|
||||
* Since affine infinity is encoded as (0,0) and
|
||||
* Jacobian ias (,,0), we need to harmonize them
|
||||
* by assigning "one" or zero to Z.
|
||||
*/
|
||||
infty = (p.p.X[0] | p.p.X[1] | p.p.X[2] | p.p.X[3] |
|
||||
p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]);
|
||||
if (P256_LIMBS == 8)
|
||||
infty |= (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] |
|
||||
p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]);
|
||||
|
||||
infty = 0 - is_zero(infty);
|
||||
infty = ~infty;
|
||||
|
||||
p.p.Z[0] = ONE[0] & infty;
|
||||
p.p.Z[1] = ONE[1] & infty;
|
||||
p.p.Z[2] = ONE[2] & infty;
|
||||
p.p.Z[3] = ONE[3] & infty;
|
||||
if (P256_LIMBS == 8) {
|
||||
p.p.Z[4] = ONE[4] & infty;
|
||||
p.p.Z[5] = ONE[5] & infty;
|
||||
p.p.Z[6] = ONE[6] & infty;
|
||||
p.p.Z[7] = ONE[7] & infty;
|
||||
}
|
||||
|
||||
for (i = 1; i < 37; i++) {
|
||||
unsigned int off = (idx - 1) / 8;
|
||||
wvalue = p_str[off] | p_str[off + 1] << 8;
|
||||
wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
|
||||
idx += window_size;
|
||||
|
||||
wvalue = _booth_recode_w7(wvalue);
|
||||
|
||||
ecp_nistz256_gather_w7(&t.a,
|
||||
preComputedTable[i], wvalue >> 1);
|
||||
|
||||
ecp_nistz256_neg(t.p.Z, t.a.Y);
|
||||
copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
|
||||
|
||||
ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
|
||||
}
|
||||
ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
|
||||
}
|
||||
} else {
|
||||
p_is_infinity = 1;
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* EC_METHOD low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
@@ -126,7 +126,7 @@ static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
static int ecx_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
|
||||
{
|
||||
const unsigned char *p;
|
||||
int pklen;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -171,6 +171,7 @@ void engine_cleanup_int(void)
|
||||
cleanup_stack = NULL;
|
||||
}
|
||||
CRYPTO_THREAD_lock_free(global_engine_lock);
|
||||
global_engine_lock = NULL;
|
||||
}
|
||||
|
||||
/* Now the "ex_data" support */
|
||||
|
||||
@@ -76,7 +76,6 @@ static ERR_STRING_DATA ERR_str_libraries[] = {
|
||||
{ERR_PACK(ERR_LIB_ESS, 0, 0), "ESS routines"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, 0), "Provider routines"},
|
||||
{ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, 0), "SERIALIZER routines"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, 0), "HTTP routines"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "internal/dso.h"
|
||||
#include <openssl/engineerr.h>
|
||||
#include <openssl/uierr.h>
|
||||
#include <openssl/httperr.h>
|
||||
#include <openssl/ocsperr.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/tserr.h>
|
||||
@@ -86,7 +85,6 @@ int err_load_crypto_strings_int(void)
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
ERR_load_ENGINE_strings() == 0 ||
|
||||
# endif
|
||||
ERR_load_HTTP_strings() == 0 ||
|
||||
# ifndef OPENSSL_NO_OCSP
|
||||
ERR_load_OCSP_strings() == 0 ||
|
||||
# endif
|
||||
|
||||
@@ -35,8 +35,9 @@ void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u),
|
||||
func = "unknown function";
|
||||
if ((flags & ERR_TXT_STRING) == 0)
|
||||
data = "";
|
||||
hex = OPENSSL_buf2hexstr((const unsigned char *)&tid, sizeof(tid));
|
||||
BIO_snprintf(buf, sizeof(buf), "%s:error:%s:%s:%s:%s:%d:%s\n",
|
||||
hex = openssl_buf2hexstr_sep((const unsigned char *)&tid, sizeof(tid),
|
||||
'\0');
|
||||
BIO_snprintf(buf, sizeof(buf), "%s:error::%s:%s:%s:%s:%d:%s\n",
|
||||
hex == NULL ? "<null>" : hex, lib, func, reason, file,
|
||||
line, data);
|
||||
OPENSSL_free(hex);
|
||||
|
||||
@@ -41,7 +41,6 @@ L ESS include/openssl/ess.h crypto/ess/ess_err.c
|
||||
L PROP include/internal/property.h crypto/property/property_err.c
|
||||
L PROV providers/common/include/prov/providercommon.h providers/common/provider_err.c
|
||||
L OSSL_SERIALIZER include/openssl/serializer.h crypto/serializer/serializer_err.c
|
||||
L HTTP include/openssl/http.h crypto/http/http_err.c
|
||||
|
||||
# additional header files to be scanned for function names
|
||||
L NONE include/openssl/x509_vfy.h NONE
|
||||
|
||||
+33
-32
@@ -320,6 +320,7 @@ CMS_F_CMS_SET_DETACHED:147:CMS_set_detached
|
||||
CMS_F_CMS_SIGN:148:CMS_sign
|
||||
CMS_F_CMS_SIGNED_DATA_INIT:149:cms_signed_data_init
|
||||
CMS_F_CMS_SIGNERINFO_CONTENT_SIGN:150:cms_SignerInfo_content_sign
|
||||
CMS_F_CMS_SIGNERINFO_GET_CHAIN:184:cms_signerinfo_get_chain
|
||||
CMS_F_CMS_SIGNERINFO_SIGN:151:CMS_SignerInfo_sign
|
||||
CMS_F_CMS_SIGNERINFO_VERIFY:152:CMS_SignerInfo_verify
|
||||
CMS_F_CMS_SIGNERINFO_VERIFY_CERT:153:cms_signerinfo_verify_cert
|
||||
@@ -329,6 +330,7 @@ CMS_F_CMS_SI_CHECK_ATTRIBUTES:183:CMS_si_check_attributes
|
||||
CMS_F_CMS_STREAM:155:CMS_stream
|
||||
CMS_F_CMS_UNCOMPRESS:156:CMS_uncompress
|
||||
CMS_F_CMS_VERIFY:157:CMS_verify
|
||||
CMS_F_ESS_CHECK_SIGNING_CERTS:185:ess_check_signing_certs
|
||||
CMS_F_KEK_UNWRAP_KEY:180:kek_unwrap_key
|
||||
COMP_F_BIO_ZLIB_FLUSH:99:bio_zlib_flush
|
||||
COMP_F_BIO_ZLIB_NEW:100:bio_zlib_new
|
||||
@@ -843,8 +845,6 @@ EVP_F_EVP_KEYEXCH_FETCH:245:EVP_KEYEXCH_fetch
|
||||
EVP_F_EVP_KEYEXCH_FROM_DISPATCH:244:evp_keyexch_from_dispatch
|
||||
EVP_F_EVP_MAC_CTRL:209:EVP_MAC_ctrl
|
||||
EVP_F_EVP_MAC_CTRL_STR:210:EVP_MAC_ctrl_str
|
||||
EVP_F_EVP_MAC_CTX_DUP:211:EVP_MAC_CTX_dup
|
||||
EVP_F_EVP_MAC_CTX_NEW:213:EVP_MAC_CTX_new
|
||||
EVP_F_EVP_MAC_INIT:212:EVP_MAC_init
|
||||
EVP_F_EVP_MD_BLOCK_SIZE:232:EVP_MD_block_size
|
||||
EVP_F_EVP_MD_CTX_COPY_EX:110:EVP_MD_CTX_copy_ex
|
||||
@@ -946,9 +946,11 @@ OCSP_F_OCSP_CHECK_IDS:107:ocsp_check_ids
|
||||
OCSP_F_OCSP_CHECK_ISSUER:108:ocsp_check_issuer
|
||||
OCSP_F_OCSP_CHECK_VALIDITY:115:OCSP_check_validity
|
||||
OCSP_F_OCSP_MATCH_ISSUERID:109:ocsp_match_issuerid
|
||||
OCSP_F_OCSP_PARSE_URL:112:
|
||||
OCSP_F_OCSP_REQUEST_SIGN:110:OCSP_request_sign
|
||||
OCSP_F_OCSP_REQUEST_VERIFY:116:OCSP_request_verify
|
||||
OCSP_F_OCSP_RESPONSE_GET1_BASIC:111:OCSP_response_get1_basic
|
||||
OCSP_F_PARSE_HTTP_LINE1:113:
|
||||
OSSL_STORE_F_FILE_ATTACH:128:
|
||||
OSSL_STORE_F_FILE_CTRL:129:file_ctrl
|
||||
OSSL_STORE_F_FILE_FIND:138:file_find
|
||||
@@ -1320,6 +1322,9 @@ SSL_F_PARSE_CA_NAMES:541:parse_ca_names
|
||||
SSL_F_PITEM_NEW:624:pitem_new
|
||||
SSL_F_PQUEUE_NEW:625:pqueue_new
|
||||
SSL_F_PROCESS_KEY_SHARE_EXT:439:*
|
||||
SSL_F_QUIC_CHANGE_CIPHER_STATE:643:
|
||||
SSL_F_QUIC_GET_MESSAGE:644:
|
||||
SSL_F_QUIC_SET_ENCRYPTION_SECRETS:645:
|
||||
SSL_F_READ_STATE_MACHINE:352:read_state_machine
|
||||
SSL_F_SET_CLIENT_CIPHERSUITE:540:set_client_ciphersuite
|
||||
SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET:595:srp_generate_client_master_secret
|
||||
@@ -1330,7 +1335,9 @@ SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM:130:ssl3_check_cert_and_algorithm
|
||||
SSL_F_SSL3_CTRL:213:ssl3_ctrl
|
||||
SSL_F_SSL3_CTX_CTRL:133:ssl3_ctx_ctrl
|
||||
SSL_F_SSL3_DIGEST_CACHED_RECORDS:293:ssl3_digest_cached_records
|
||||
SSL_F_SSL3_DISPATCH_ALERT:646:
|
||||
SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC:292:ssl3_do_change_cipher_spec
|
||||
SSL_F_SSL3_DO_WRITE:647:
|
||||
SSL_F_SSL3_ENC:608:ssl3_enc
|
||||
SSL_F_SSL3_FINAL_FINISH_MAC:285:ssl3_final_finish_mac
|
||||
SSL_F_SSL3_FINISH_MAC:587:ssl3_finish_mac
|
||||
@@ -1438,6 +1445,8 @@ SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT:311:*
|
||||
SSL_F_SSL_PEEK:270:SSL_peek
|
||||
SSL_F_SSL_PEEK_EX:432:SSL_peek_ex
|
||||
SSL_F_SSL_PEEK_INTERNAL:522:ssl_peek_internal
|
||||
SSL_F_SSL_PROCESS_QUIC_POST_HANDSHAKE:648:
|
||||
SSL_F_SSL_PROVIDE_QUIC_DATA:649:
|
||||
SSL_F_SSL_READ:223:SSL_read
|
||||
SSL_F_SSL_READ_EARLY_DATA:529:SSL_read_early_data
|
||||
SSL_F_SSL_READ_EX:434:SSL_read_ex
|
||||
@@ -1488,6 +1497,7 @@ SSL_F_SSL_WRITE_EARLY_DATA:526:SSL_write_early_data
|
||||
SSL_F_SSL_WRITE_EARLY_FINISH:527:*
|
||||
SSL_F_SSL_WRITE_EX:433:SSL_write_ex
|
||||
SSL_F_SSL_WRITE_INTERNAL:524:ssl_write_internal
|
||||
SSL_F_STATEM_FLUSH:650:
|
||||
SSL_F_STATE_MACHINE:353:state_machine
|
||||
SSL_F_TLS12_CHECK_PEER_SIGALG:333:tls12_check_peer_sigalg
|
||||
SSL_F_TLS12_COPY_SIGALGS:533:tls12_copy_sigalgs
|
||||
@@ -1527,6 +1537,7 @@ SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC:427:tls_construct_change_cipher_spec
|
||||
SSL_F_TLS_CONSTRUCT_CKE_DHE:404:tls_construct_cke_dhe
|
||||
SSL_F_TLS_CONSTRUCT_CKE_ECDHE:405:tls_construct_cke_ecdhe
|
||||
SSL_F_TLS_CONSTRUCT_CKE_GOST:406:tls_construct_cke_gost
|
||||
SSL_F_TLS_CONSTRUCT_CKE_GOST18:641:
|
||||
SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE:407:tls_construct_cke_psk_preamble
|
||||
SSL_F_TLS_CONSTRUCT_CKE_RSA:409:tls_construct_cke_rsa
|
||||
SSL_F_TLS_CONSTRUCT_CKE_SRP:410:tls_construct_cke_srp
|
||||
@@ -1551,6 +1562,7 @@ SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH:619:\
|
||||
tls_construct_ctos_post_handshake_auth
|
||||
SSL_F_TLS_CONSTRUCT_CTOS_PSK:501:tls_construct_ctos_psk
|
||||
SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES:509:tls_construct_ctos_psk_kex_modes
|
||||
SSL_F_TLS_CONSTRUCT_CTOS_QUIC_TRANSPORT_PARAMS:651:
|
||||
SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE:473:tls_construct_ctos_renegotiate
|
||||
SSL_F_TLS_CONSTRUCT_CTOS_SCT:474:tls_construct_ctos_sct
|
||||
SSL_F_TLS_CONSTRUCT_CTOS_SERVER_NAME:475:tls_construct_ctos_server_name
|
||||
@@ -1592,6 +1604,7 @@ SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE:456:tls_construct_stoc_key_share
|
||||
SSL_F_TLS_CONSTRUCT_STOC_MAXFRAGMENTLEN:548:tls_construct_stoc_maxfragmentlen
|
||||
SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG:457:tls_construct_stoc_next_proto_neg
|
||||
SSL_F_TLS_CONSTRUCT_STOC_PSK:504:tls_construct_stoc_psk
|
||||
SSL_F_TLS_CONSTRUCT_STOC_QUIC_TRANSPORT_PARAMS:652:
|
||||
SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE:458:tls_construct_stoc_renegotiate
|
||||
SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME:459:tls_construct_stoc_server_name
|
||||
SSL_F_TLS_CONSTRUCT_STOC_SESSION_TICKET:460:tls_construct_stoc_session_ticket
|
||||
@@ -1620,6 +1633,7 @@ SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN:571:tls_parse_ctos_maxfragmentlen
|
||||
SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH:620:tls_parse_ctos_post_handshake_auth
|
||||
SSL_F_TLS_PARSE_CTOS_PSK:505:tls_parse_ctos_psk
|
||||
SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES:572:tls_parse_ctos_psk_kex_modes
|
||||
SSL_F_TLS_PARSE_CTOS_QUIC_TRANSPORT_PARAMS:653:
|
||||
SSL_F_TLS_PARSE_CTOS_RENEGOTIATE:464:tls_parse_ctos_renegotiate
|
||||
SSL_F_TLS_PARSE_CTOS_SERVER_NAME:573:tls_parse_ctos_server_name
|
||||
SSL_F_TLS_PARSE_CTOS_SESSION_TICKET:574:tls_parse_ctos_session_ticket
|
||||
@@ -1638,6 +1652,7 @@ SSL_F_TLS_PARSE_STOC_KEY_SHARE:445:tls_parse_stoc_key_share
|
||||
SSL_F_TLS_PARSE_STOC_MAXFRAGMENTLEN:581:tls_parse_stoc_maxfragmentlen
|
||||
SSL_F_TLS_PARSE_STOC_NPN:582:tls_parse_stoc_npn
|
||||
SSL_F_TLS_PARSE_STOC_PSK:502:tls_parse_stoc_psk
|
||||
SSL_F_TLS_PARSE_STOC_QUIC_TRANSPORT_PARAMS:654:
|
||||
SSL_F_TLS_PARSE_STOC_RENEGOTIATE:448:tls_parse_stoc_renegotiate
|
||||
SSL_F_TLS_PARSE_STOC_SCT:564:tls_parse_stoc_sct
|
||||
SSL_F_TLS_PARSE_STOC_SERVER_NAME:583:tls_parse_stoc_server_name
|
||||
@@ -1658,6 +1673,7 @@ SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC:363:tls_process_change_cipher_spec
|
||||
SSL_F_TLS_PROCESS_CKE_DHE:411:tls_process_cke_dhe
|
||||
SSL_F_TLS_PROCESS_CKE_ECDHE:412:tls_process_cke_ecdhe
|
||||
SSL_F_TLS_PROCESS_CKE_GOST:413:tls_process_cke_gost
|
||||
SSL_F_TLS_PROCESS_CKE_GOST18:642:
|
||||
SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE:414:tls_process_cke_psk_preamble
|
||||
SSL_F_TLS_PROCESS_CKE_RSA:415:tls_process_cke_rsa
|
||||
SSL_F_TLS_PROCESS_CKE_SRP:416:tls_process_cke_srp
|
||||
@@ -1874,6 +1890,7 @@ X509_F_X509_NAME_PRINT:117:X509_NAME_print
|
||||
X509_F_X509_OBJECT_NEW:150:X509_OBJECT_new
|
||||
X509_F_X509_PRINT_EX_FP:118:X509_print_ex_fp
|
||||
X509_F_X509_PUBKEY_DECODE:148:x509_pubkey_decode
|
||||
X509_F_X509_PUBKEY_GET:166:X509_PUBKEY_get
|
||||
X509_F_X509_PUBKEY_GET0:119:X509_PUBKEY_get0
|
||||
X509_F_X509_PUBKEY_SET:120:X509_PUBKEY_set
|
||||
X509_F_X509_REQ_CHECK_PRIVATE_KEY:144:X509_REQ_check_private_key
|
||||
@@ -2022,7 +2039,6 @@ BIO_R_AMBIGUOUS_HOST_OR_SERVICE:129:ambiguous host or service
|
||||
BIO_R_BAD_FOPEN_MODE:101:bad fopen mode
|
||||
BIO_R_BROKEN_PIPE:124:broken pipe
|
||||
BIO_R_CONNECT_ERROR:103:connect error
|
||||
BIO_R_CONNECT_TIMEOUT:147:connect timeout
|
||||
BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET:107:gethostbyname addr is not af inet
|
||||
BIO_R_GETSOCKNAME_ERROR:132:getsockname error
|
||||
BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS:133:getsockname truncated address
|
||||
@@ -2041,8 +2057,6 @@ BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED:144:no hostname or service specified
|
||||
BIO_R_NO_PORT_DEFINED:113:no port defined
|
||||
BIO_R_NO_SUCH_FILE:128:no such file
|
||||
BIO_R_NULL_PARAMETER:115:null parameter
|
||||
BIO_R_TRANSFER_ERROR:104:transfer error
|
||||
BIO_R_TRANSFER_TIMEOUT:105:transfer timeout
|
||||
BIO_R_UNABLE_TO_BIND_SOCKET:117:unable to bind socket
|
||||
BIO_R_UNABLE_TO_CREATE_SOCKET:118:unable to create socket
|
||||
BIO_R_UNABLE_TO_KEEPALIVE:137:unable to keepalive
|
||||
@@ -2113,6 +2127,7 @@ CMP_R_ERROR_PROTECTING_MESSAGE:127:error protecting message
|
||||
CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash
|
||||
CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf
|
||||
CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection
|
||||
CMP_R_ERROR_VALIDATING_SIGNATURE:171:error validating signature
|
||||
CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey
|
||||
CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random
|
||||
CMP_R_FAIL_INFO_OUT_OF_RANGE:129:fail info out of range
|
||||
@@ -2185,6 +2200,8 @@ CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE:114:\
|
||||
error reading messagedigest attribute
|
||||
CMS_R_ERROR_SETTING_KEY:115:error setting key
|
||||
CMS_R_ERROR_SETTING_RECIPIENTINFO:116:error setting recipientinfo
|
||||
CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE:182:ess no signing certid attribute
|
||||
CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR:183:ess signing certid mismatch error
|
||||
CMS_R_INVALID_ENCRYPTED_KEY_LENGTH:117:invalid encrypted key length
|
||||
CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER:176:invalid key encryption parameter
|
||||
CMS_R_INVALID_KEY_LENGTH:118:invalid key length
|
||||
@@ -2334,6 +2351,7 @@ CT_R_SCT_UNSUPPORTED_VERSION:115:sct unsupported version
|
||||
CT_R_UNRECOGNIZED_SIGNATURE_NID:101:unrecognized signature nid
|
||||
CT_R_UNSUPPORTED_ENTRY_TYPE:102:unsupported entry type
|
||||
CT_R_UNSUPPORTED_VERSION:103:unsupported version
|
||||
DH_R_BAD_FFC_PARAMETERS:127:bad ffc parameters
|
||||
DH_R_BAD_GENERATOR:101:bad generator
|
||||
DH_R_BN_DECODE_ERROR:109:bn decode error
|
||||
DH_R_BN_ERROR:106:bn error
|
||||
@@ -2361,6 +2379,7 @@ DH_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error
|
||||
DH_R_PEER_KEY_ERROR:111:peer key error
|
||||
DH_R_SHARED_INFO_ERROR:113:shared info error
|
||||
DH_R_UNABLE_TO_CHECK_GENERATOR:121:unable to check generator
|
||||
DSA_R_BAD_FFC_PARAMETERS:114:bad ffc parameters
|
||||
DSA_R_BAD_Q_VALUE:102:bad q value
|
||||
DSA_R_BN_DECODE_ERROR:108:bn decode error
|
||||
DSA_R_BN_ERROR:109:bn error
|
||||
@@ -2594,29 +2613,6 @@ EVP_R_WRAP_MODE_NOT_ALLOWED:170:wrap mode not allowed
|
||||
EVP_R_WRONG_FINAL_BLOCK_LENGTH:109:wrong final block length
|
||||
EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE:191:xts data unit is too large
|
||||
EVP_R_XTS_DUPLICATED_KEYS:192:xts duplicated keys
|
||||
HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN:108:asn1 len exceeds max resp len
|
||||
HTTP_R_CONNECT_FAILURE:100:connect failure
|
||||
HTTP_R_ERROR_PARSING_ASN1_LENGTH:109:error parsing asn1 length
|
||||
HTTP_R_ERROR_PARSING_CONTENT_LENGTH:119:error parsing content length
|
||||
HTTP_R_ERROR_PARSING_URL:101:error parsing url
|
||||
HTTP_R_ERROR_RECEIVING:103:error receiving
|
||||
HTTP_R_ERROR_SENDING:102:error sending
|
||||
HTTP_R_INCONSISTENT_CONTENT_LENGTH:120:inconsistent content length
|
||||
HTTP_R_MAX_RESP_LEN_EXCEEDED:117:max resp len exceeded
|
||||
HTTP_R_MISSING_ASN1_ENCODING:110:missing asn1 encoding
|
||||
HTTP_R_MISSING_CONTENT_TYPE:121:missing content type
|
||||
HTTP_R_MISSING_REDIRECT_LOCATION:111:missing redirect location
|
||||
HTTP_R_RECEIVED_ERROR:105:received error
|
||||
HTTP_R_RECEIVED_WRONG_HTTP_VERSION:106:received wrong http version
|
||||
HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP:112:redirection from https to http
|
||||
HTTP_R_REDIRECTION_NOT_ENABLED:116:redirection not enabled
|
||||
HTTP_R_RESPONSE_LINE_TOO_LONG:113:response line too long
|
||||
HTTP_R_RESPONSE_PARSE_ERROR:104:response parse error
|
||||
HTTP_R_SOCK_NOT_SUPPORTED:122:sock not supported
|
||||
HTTP_R_STATUS_CODE_UNSUPPORTED:114:status code unsupported
|
||||
HTTP_R_TLS_NOT_ENABLED:107:tls not enabled
|
||||
HTTP_R_TOO_MANY_REDIRECTIONS:115:too many redirections
|
||||
HTTP_R_UNEXPECTED_CONTENT_TYPE:118:unexpected content type
|
||||
KDF_R_BAD_ENCODING:122:bad encoding
|
||||
KDF_R_BAD_LENGTH:123:bad length
|
||||
KDF_R_BOTH_MODE_AND_MODE_INT:127:both mode and mode int
|
||||
@@ -2651,6 +2647,7 @@ OCSP_R_CERTIFICATE_VERIFY_ERROR:101:certificate verify error
|
||||
OCSP_R_DIGEST_ERR:102:digest err
|
||||
OCSP_R_ERROR_IN_NEXTUPDATE_FIELD:122:error in nextupdate field
|
||||
OCSP_R_ERROR_IN_THISUPDATE_FIELD:123:error in thisupdate field
|
||||
OCSP_R_ERROR_PARSING_URL:121:error parsing url
|
||||
OCSP_R_MISSING_OCSPSIGNING_USAGE:103:missing ocspsigning usage
|
||||
OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE:124:nextupdate before thisupdate
|
||||
OCSP_R_NOT_BASIC_RESPONSE:104:not basic response
|
||||
@@ -2664,6 +2661,8 @@ OCSP_R_REQUEST_NOT_SIGNED:128:request not signed
|
||||
OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA:111:\
|
||||
response contains no revocation data
|
||||
OCSP_R_ROOT_CA_NOT_TRUSTED:112:root ca not trusted
|
||||
OCSP_R_SERVER_RESPONSE_ERROR:114:server response error
|
||||
OCSP_R_SERVER_RESPONSE_PARSE_ERROR:115:server response parse error
|
||||
OCSP_R_SIGNATURE_FAILURE:117:signature failure
|
||||
OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND:118:signer certificate not found
|
||||
OCSP_R_STATUS_EXPIRED:125:status expired
|
||||
@@ -3139,6 +3138,7 @@ SSL_R_INCONSISTENT_EARLY_DATA_ALPN:222:inconsistent early data alpn
|
||||
SSL_R_INCONSISTENT_EARLY_DATA_SNI:231:inconsistent early data sni
|
||||
SSL_R_INCONSISTENT_EXTMS:104:inconsistent extms
|
||||
SSL_R_INSUFFICIENT_SECURITY:241:insufficient security
|
||||
SSL_R_INTERNAL_ERROR:296:internal error
|
||||
SSL_R_INVALID_ALERT:205:invalid alert
|
||||
SSL_R_INVALID_CCS_MESSAGE:260:invalid ccs message
|
||||
SSL_R_INVALID_CERTIFICATE_OR_ALG:238:invalid certificate or alg
|
||||
@@ -3177,8 +3177,8 @@ SSL_R_MISSING_TMP_DH_KEY:171:missing tmp dh key
|
||||
SSL_R_MISSING_TMP_ECDH_KEY:311:missing tmp ecdh key
|
||||
SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA:293:\
|
||||
mixed handshake and non handshake data
|
||||
SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:296:mixed special operator with groups
|
||||
SSL_R_NESTED_GROUP:297:nested group
|
||||
SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:297:mixed special operator with groups
|
||||
SSL_R_NESTED_GROUP:299:nested group
|
||||
SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary
|
||||
SSL_R_NOT_REPLACING_CERTIFICATE:289:not replacing certificate
|
||||
SSL_R_NOT_SERVER:284:not server
|
||||
@@ -3286,9 +3286,9 @@ SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines
|
||||
SSL_R_UNEXPECTED_CCS_MESSAGE:262:unexpected ccs message
|
||||
SSL_R_UNEXPECTED_END_OF_EARLY_DATA:178:unexpected end of early data
|
||||
SSL_R_UNEXPECTED_EOF_WHILE_READING:294:unexpected eof while reading
|
||||
SSL_R_UNEXPECTED_GROUP_CLOSE:299:unexpected group close
|
||||
SSL_R_UNEXPECTED_GROUP_CLOSE:305:unexpected group close
|
||||
SSL_R_UNEXPECTED_MESSAGE:244:unexpected message
|
||||
SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:305:unexpected operator in group
|
||||
SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:310:unexpected operator in group
|
||||
SSL_R_UNEXPECTED_RECORD:245:unexpected record
|
||||
SSL_R_UNINITIALIZED:276:uninitialized
|
||||
SSL_R_UNKNOWN_ALERT_TYPE:246:unknown alert type
|
||||
@@ -3317,6 +3317,7 @@ SSL_R_VERSION_TOO_LOW:396:version too low
|
||||
SSL_R_WRONG_CERTIFICATE_TYPE:383:wrong certificate type
|
||||
SSL_R_WRONG_CIPHER_RETURNED:261:wrong cipher returned
|
||||
SSL_R_WRONG_CURVE:378:wrong curve
|
||||
SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED:313:wrong encryption level received
|
||||
SSL_R_WRONG_SIGNATURE_LENGTH:264:wrong signature length
|
||||
SSL_R_WRONG_SIGNATURE_SIZE:265:wrong signature size
|
||||
SSL_R_WRONG_SIGNATURE_TYPE:370:wrong signature type
|
||||
|
||||
+23
-34
@@ -320,6 +320,7 @@ CMS_F_CMS_SET_DETACHED:147:CMS_set_detached
|
||||
CMS_F_CMS_SIGN:148:CMS_sign
|
||||
CMS_F_CMS_SIGNED_DATA_INIT:149:cms_signed_data_init
|
||||
CMS_F_CMS_SIGNERINFO_CONTENT_SIGN:150:cms_SignerInfo_content_sign
|
||||
CMS_F_CMS_SIGNERINFO_GET_CHAIN:184:cms_signerinfo_get_chain
|
||||
CMS_F_CMS_SIGNERINFO_SIGN:151:CMS_SignerInfo_sign
|
||||
CMS_F_CMS_SIGNERINFO_VERIFY:152:CMS_SignerInfo_verify
|
||||
CMS_F_CMS_SIGNERINFO_VERIFY_CERT:153:cms_signerinfo_verify_cert
|
||||
@@ -329,6 +330,7 @@ CMS_F_CMS_SI_CHECK_ATTRIBUTES:183:CMS_si_check_attributes
|
||||
CMS_F_CMS_STREAM:155:CMS_stream
|
||||
CMS_F_CMS_UNCOMPRESS:156:CMS_uncompress
|
||||
CMS_F_CMS_VERIFY:157:CMS_verify
|
||||
CMS_F_ESS_CHECK_SIGNING_CERTS:185:ess_check_signing_certs
|
||||
CMS_F_KEK_UNWRAP_KEY:180:kek_unwrap_key
|
||||
COMP_F_BIO_ZLIB_FLUSH:99:bio_zlib_flush
|
||||
COMP_F_BIO_ZLIB_NEW:100:bio_zlib_new
|
||||
@@ -696,6 +698,7 @@ EC_F_EC_POINT_INVERT:210:EC_POINT_invert
|
||||
EC_F_EC_POINT_IS_AT_INFINITY:118:EC_POINT_is_at_infinity
|
||||
EC_F_EC_POINT_IS_ON_CURVE:119:EC_POINT_is_on_curve
|
||||
EC_F_EC_POINT_MAKE_AFFINE:120:EC_POINT_make_affine
|
||||
EC_F_EC_POINT_MUL:309:
|
||||
EC_F_EC_POINT_NEW:121:EC_POINT_new
|
||||
EC_F_EC_POINT_OCT2POINT:122:EC_POINT_oct2point
|
||||
EC_F_EC_POINT_POINT2BUF:281:EC_POINT_point2buf
|
||||
@@ -842,8 +845,6 @@ EVP_F_EVP_KEYEXCH_FETCH:245:EVP_KEYEXCH_fetch
|
||||
EVP_F_EVP_KEYEXCH_FROM_DISPATCH:244:evp_keyexch_from_dispatch
|
||||
EVP_F_EVP_MAC_CTRL:209:EVP_MAC_ctrl
|
||||
EVP_F_EVP_MAC_CTRL_STR:210:EVP_MAC_ctrl_str
|
||||
EVP_F_EVP_MAC_CTX_DUP:211:EVP_MAC_CTX_dup
|
||||
EVP_F_EVP_MAC_CTX_NEW:213:EVP_MAC_CTX_new
|
||||
EVP_F_EVP_MAC_INIT:212:EVP_MAC_init
|
||||
EVP_F_EVP_MD_BLOCK_SIZE:232:EVP_MD_block_size
|
||||
EVP_F_EVP_MD_CTX_COPY_EX:110:EVP_MD_CTX_copy_ex
|
||||
@@ -948,6 +949,7 @@ OCSP_F_OCSP_MATCH_ISSUERID:109:ocsp_match_issuerid
|
||||
OCSP_F_OCSP_REQUEST_SIGN:110:OCSP_request_sign
|
||||
OCSP_F_OCSP_REQUEST_VERIFY:116:OCSP_request_verify
|
||||
OCSP_F_OCSP_RESPONSE_GET1_BASIC:111:OCSP_response_get1_basic
|
||||
OSSL_STORE_F_FILE_ATTACH:128:
|
||||
OSSL_STORE_F_FILE_CTRL:129:file_ctrl
|
||||
OSSL_STORE_F_FILE_FIND:138:file_find
|
||||
OSSL_STORE_F_FILE_GET_PASS:118:file_get_pass
|
||||
@@ -955,10 +957,8 @@ OSSL_STORE_F_FILE_LOAD:119:file_load
|
||||
OSSL_STORE_F_FILE_LOAD_TRY_DECODE:124:file_load_try_decode
|
||||
OSSL_STORE_F_FILE_NAME_TO_URI:126:file_name_to_uri
|
||||
OSSL_STORE_F_FILE_OPEN:120:file_open
|
||||
OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO:127:ossl_store_attach_pem_bio
|
||||
OSSL_STORE_F_OSSL_STORE_ATTACH:127:
|
||||
OSSL_STORE_F_OSSL_STORE_EXPECT:130:OSSL_STORE_expect
|
||||
OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT:128:\
|
||||
ossl_store_file_attach_pem_bio_int
|
||||
OSSL_STORE_F_OSSL_STORE_FIND:131:OSSL_STORE_find
|
||||
OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT:100:ossl_store_get0_loader_int
|
||||
OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT:101:OSSL_STORE_INFO_get1_CERT
|
||||
@@ -1001,17 +1001,17 @@ PEM_F_D2I_PKCS8PRIVATEKEY_BIO:120:d2i_PKCS8PrivateKey_bio
|
||||
PEM_F_D2I_PKCS8PRIVATEKEY_FP:121:d2i_PKCS8PrivateKey_fp
|
||||
PEM_F_DO_B2I:132:do_b2i
|
||||
PEM_F_DO_B2I_BIO:133:do_b2i_bio
|
||||
PEM_F_DO_BLOB_HEADER:134:do_blob_header
|
||||
PEM_F_DO_I2B:146:do_i2b
|
||||
PEM_F_DO_PK8PKEY:126:do_pk8pkey
|
||||
PEM_F_DO_PK8PKEY_FP:125:do_pk8pkey_fp
|
||||
PEM_F_DO_PVK_BODY:135:do_PVK_body
|
||||
PEM_F_DO_PVK_HEADER:136:do_PVK_header
|
||||
PEM_F_GET_HEADER_AND_DATA:143:get_header_and_data
|
||||
PEM_F_GET_NAME:144:get_name
|
||||
PEM_F_I2B_PVK:137:i2b_PVK
|
||||
PEM_F_I2B_PVK_BIO:138:i2b_PVK_bio
|
||||
PEM_F_LOAD_IV:101:load_iv
|
||||
PEM_F_OSSL_DO_BLOB_HEADER:134:ossl_do_blob_header
|
||||
PEM_F_OSSL_DO_PVK_HEADER:136:ossl_do_PVK_header
|
||||
PEM_F_PEM_ASN1_READ:102:PEM_ASN1_read
|
||||
PEM_F_PEM_ASN1_READ_BIO:103:PEM_ASN1_read_bio
|
||||
PEM_F_PEM_ASN1_WRITE:104:PEM_ASN1_write
|
||||
@@ -1527,6 +1527,7 @@ SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC:427:tls_construct_change_cipher_spec
|
||||
SSL_F_TLS_CONSTRUCT_CKE_DHE:404:tls_construct_cke_dhe
|
||||
SSL_F_TLS_CONSTRUCT_CKE_ECDHE:405:tls_construct_cke_ecdhe
|
||||
SSL_F_TLS_CONSTRUCT_CKE_GOST:406:tls_construct_cke_gost
|
||||
SSL_F_TLS_CONSTRUCT_CKE_GOST18:641:
|
||||
SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE:407:tls_construct_cke_psk_preamble
|
||||
SSL_F_TLS_CONSTRUCT_CKE_RSA:409:tls_construct_cke_rsa
|
||||
SSL_F_TLS_CONSTRUCT_CKE_SRP:410:tls_construct_cke_srp
|
||||
@@ -1658,6 +1659,7 @@ SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC:363:tls_process_change_cipher_spec
|
||||
SSL_F_TLS_PROCESS_CKE_DHE:411:tls_process_cke_dhe
|
||||
SSL_F_TLS_PROCESS_CKE_ECDHE:412:tls_process_cke_ecdhe
|
||||
SSL_F_TLS_PROCESS_CKE_GOST:413:tls_process_cke_gost
|
||||
SSL_F_TLS_PROCESS_CKE_GOST18:642:
|
||||
SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE:414:tls_process_cke_psk_preamble
|
||||
SSL_F_TLS_PROCESS_CKE_RSA:415:tls_process_cke_rsa
|
||||
SSL_F_TLS_PROCESS_CKE_SRP:416:tls_process_cke_srp
|
||||
@@ -1874,6 +1876,7 @@ X509_F_X509_NAME_PRINT:117:X509_NAME_print
|
||||
X509_F_X509_OBJECT_NEW:150:X509_OBJECT_new
|
||||
X509_F_X509_PRINT_EX_FP:118:X509_print_ex_fp
|
||||
X509_F_X509_PUBKEY_DECODE:148:x509_pubkey_decode
|
||||
X509_F_X509_PUBKEY_GET:166:X509_PUBKEY_get
|
||||
X509_F_X509_PUBKEY_GET0:119:X509_PUBKEY_get0
|
||||
X509_F_X509_PUBKEY_SET:120:X509_PUBKEY_set
|
||||
X509_F_X509_REQ_CHECK_PRIVATE_KEY:144:X509_REQ_check_private_key
|
||||
@@ -2022,7 +2025,6 @@ BIO_R_AMBIGUOUS_HOST_OR_SERVICE:129:ambiguous host or service
|
||||
BIO_R_BAD_FOPEN_MODE:101:bad fopen mode
|
||||
BIO_R_BROKEN_PIPE:124:broken pipe
|
||||
BIO_R_CONNECT_ERROR:103:connect error
|
||||
BIO_R_CONNECT_TIMEOUT:147:connect timeout
|
||||
BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET:107:gethostbyname addr is not af inet
|
||||
BIO_R_GETSOCKNAME_ERROR:132:getsockname error
|
||||
BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS:133:getsockname truncated address
|
||||
@@ -2041,8 +2043,6 @@ BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED:144:no hostname or service specified
|
||||
BIO_R_NO_PORT_DEFINED:113:no port defined
|
||||
BIO_R_NO_SUCH_FILE:128:no such file
|
||||
BIO_R_NULL_PARAMETER:115:null parameter
|
||||
BIO_R_TRANSFER_ERROR:104:transfer error
|
||||
BIO_R_TRANSFER_TIMEOUT:105:transfer timeout
|
||||
BIO_R_UNABLE_TO_BIND_SOCKET:117:unable to bind socket
|
||||
BIO_R_UNABLE_TO_CREATE_SOCKET:118:unable to create socket
|
||||
BIO_R_UNABLE_TO_KEEPALIVE:137:unable to keepalive
|
||||
@@ -2113,6 +2113,7 @@ CMP_R_ERROR_PROTECTING_MESSAGE:127:error protecting message
|
||||
CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash
|
||||
CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf
|
||||
CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection
|
||||
CMP_R_ERROR_VALIDATING_SIGNATURE:171:error validating signature
|
||||
CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey
|
||||
CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random
|
||||
CMP_R_FAIL_INFO_OUT_OF_RANGE:129:fail info out of range
|
||||
@@ -2134,7 +2135,6 @@ CMP_R_NULL_ARGUMENT:103:null argument
|
||||
CMP_R_PKIBODY_ERROR:146:pkibody error
|
||||
CMP_R_PKISTATUSINFO_NOT_FOUND:132:pkistatusinfo not found
|
||||
CMP_R_POLLING_FAILED:172:polling failed
|
||||
CMP_R_POTENTIALLY_INVALID_CERTIFICATE:147:potentially invalid certificate
|
||||
CMP_R_RECEIVED_ERROR:180:received error
|
||||
CMP_R_RECIPNONCE_UNMATCHED:148:recipnonce unmatched
|
||||
CMP_R_REQUEST_NOT_ACCEPTED:149:request not accepted
|
||||
@@ -2185,6 +2185,8 @@ CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE:114:\
|
||||
error reading messagedigest attribute
|
||||
CMS_R_ERROR_SETTING_KEY:115:error setting key
|
||||
CMS_R_ERROR_SETTING_RECIPIENTINFO:116:error setting recipientinfo
|
||||
CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE:182:ess no signing certid attribute
|
||||
CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR:183:ess signing certid mismatch error
|
||||
CMS_R_INVALID_ENCRYPTED_KEY_LENGTH:117:invalid encrypted key length
|
||||
CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER:176:invalid key encryption parameter
|
||||
CMS_R_INVALID_KEY_LENGTH:118:invalid key length
|
||||
@@ -2334,6 +2336,7 @@ CT_R_SCT_UNSUPPORTED_VERSION:115:sct unsupported version
|
||||
CT_R_UNRECOGNIZED_SIGNATURE_NID:101:unrecognized signature nid
|
||||
CT_R_UNSUPPORTED_ENTRY_TYPE:102:unsupported entry type
|
||||
CT_R_UNSUPPORTED_VERSION:103:unsupported version
|
||||
DH_R_BAD_FFC_PARAMETERS:127:bad ffc parameters
|
||||
DH_R_BAD_GENERATOR:101:bad generator
|
||||
DH_R_BN_DECODE_ERROR:109:bn decode error
|
||||
DH_R_BN_ERROR:106:bn error
|
||||
@@ -2361,6 +2364,7 @@ DH_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error
|
||||
DH_R_PEER_KEY_ERROR:111:peer key error
|
||||
DH_R_SHARED_INFO_ERROR:113:shared info error
|
||||
DH_R_UNABLE_TO_CHECK_GENERATOR:121:unable to check generator
|
||||
DSA_R_BAD_FFC_PARAMETERS:114:bad ffc parameters
|
||||
DSA_R_BAD_Q_VALUE:102:bad q value
|
||||
DSA_R_BN_DECODE_ERROR:108:bn decode error
|
||||
DSA_R_BN_ERROR:109:bn error
|
||||
@@ -2559,6 +2563,7 @@ EVP_R_NO_KEYMGMT_AVAILABLE:199:no keymgmt available
|
||||
EVP_R_NO_KEYMGMT_PRESENT:196:no keymgmt present
|
||||
EVP_R_NO_KEY_SET:154:no key set
|
||||
EVP_R_NO_OPERATION_SET:149:no operation set
|
||||
EVP_R_NULL_MAC_PKEY_CTX:208:null mac pkey ctx
|
||||
EVP_R_ONLY_ONESHOT_SUPPORTED:177:only oneshot supported
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:150:\
|
||||
operation not supported for this keytype
|
||||
@@ -2571,6 +2576,7 @@ EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED:179:\
|
||||
EVP_R_PRIVATE_KEY_DECODE_ERROR:145:private key decode error
|
||||
EVP_R_PRIVATE_KEY_ENCODE_ERROR:146:private key encode error
|
||||
EVP_R_PUBLIC_KEY_NOT_RSA:106:public key not rsa
|
||||
EVP_R_SET_DEFAULT_PROPERTY_FAILURE:209:set default property failure
|
||||
EVP_R_TOO_MANY_RECORDS:183:too many records
|
||||
EVP_R_UNKNOWN_CIPHER:160:unknown cipher
|
||||
EVP_R_UNKNOWN_DIGEST:161:unknown digest
|
||||
@@ -2592,29 +2598,6 @@ EVP_R_WRAP_MODE_NOT_ALLOWED:170:wrap mode not allowed
|
||||
EVP_R_WRONG_FINAL_BLOCK_LENGTH:109:wrong final block length
|
||||
EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE:191:xts data unit is too large
|
||||
EVP_R_XTS_DUPLICATED_KEYS:192:xts duplicated keys
|
||||
HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN:108:asn1 len exceeds max resp len
|
||||
HTTP_R_CONNECT_FAILURE:100:connect failure
|
||||
HTTP_R_ERROR_PARSING_ASN1_LENGTH:109:error parsing asn1 length
|
||||
HTTP_R_ERROR_PARSING_CONTENT_LENGTH:119:error parsing content length
|
||||
HTTP_R_ERROR_PARSING_URL:101:error parsing url
|
||||
HTTP_R_ERROR_RECEIVING:103:error receiving
|
||||
HTTP_R_ERROR_SENDING:102:error sending
|
||||
HTTP_R_INCONSISTENT_CONTENT_LENGTH:120:inconsistent content length
|
||||
HTTP_R_MAX_RESP_LEN_EXCEEDED:117:max resp len exceeded
|
||||
HTTP_R_MISSING_ASN1_ENCODING:110:missing asn1 encoding
|
||||
HTTP_R_MISSING_CONTENT_TYPE:121:missing content type
|
||||
HTTP_R_MISSING_REDIRECT_LOCATION:111:missing redirect location
|
||||
HTTP_R_RECEIVED_ERROR:105:received error
|
||||
HTTP_R_RECEIVED_WRONG_HTTP_VERSION:106:received wrong http version
|
||||
HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP:112:redirection from https to http
|
||||
HTTP_R_REDIRECTION_NOT_ENABLED:116:redirection not enabled
|
||||
HTTP_R_RESPONSE_LINE_TOO_LONG:113:response line too long
|
||||
HTTP_R_RESPONSE_PARSE_ERROR:104:response parse error
|
||||
HTTP_R_SOCK_NOT_SUPPORTED:122:sock not supported
|
||||
HTTP_R_STATUS_CODE_UNSUPPORTED:114:status code unsupported
|
||||
HTTP_R_TLS_NOT_ENABLED:107:tls not enabled
|
||||
HTTP_R_TOO_MANY_REDIRECTIONS:115:too many redirections
|
||||
HTTP_R_UNEXPECTED_CONTENT_TYPE:118:unexpected content type
|
||||
KDF_R_BAD_ENCODING:122:bad encoding
|
||||
KDF_R_BAD_LENGTH:123:bad length
|
||||
KDF_R_BOTH_MODE_AND_MODE_INT:127:both mode and mode int
|
||||
@@ -2649,6 +2632,7 @@ OCSP_R_CERTIFICATE_VERIFY_ERROR:101:certificate verify error
|
||||
OCSP_R_DIGEST_ERR:102:digest err
|
||||
OCSP_R_ERROR_IN_NEXTUPDATE_FIELD:122:error in nextupdate field
|
||||
OCSP_R_ERROR_IN_THISUPDATE_FIELD:123:error in thisupdate field
|
||||
OCSP_R_ERROR_PARSING_URL:121:error parsing url
|
||||
OCSP_R_MISSING_OCSPSIGNING_USAGE:103:missing ocspsigning usage
|
||||
OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE:124:nextupdate before thisupdate
|
||||
OCSP_R_NOT_BASIC_RESPONSE:104:not basic response
|
||||
@@ -2662,6 +2646,8 @@ OCSP_R_REQUEST_NOT_SIGNED:128:request not signed
|
||||
OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA:111:\
|
||||
response contains no revocation data
|
||||
OCSP_R_ROOT_CA_NOT_TRUSTED:112:root ca not trusted
|
||||
OCSP_R_SERVER_RESPONSE_ERROR:114:server response error
|
||||
OCSP_R_SERVER_RESPONSE_PARSE_ERROR:115:server response parse error
|
||||
OCSP_R_SIGNATURE_FAILURE:117:signature failure
|
||||
OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND:118:signer certificate not found
|
||||
OCSP_R_STATUS_EXPIRED:125:status expired
|
||||
@@ -2841,6 +2827,7 @@ PROV_R_INVALID_PADDING_MODE:168:invalid padding mode
|
||||
PROV_R_INVALID_PSS_SALTLEN:169:invalid pss saltlen
|
||||
PROV_R_INVALID_SALT_LENGTH:112:invalid salt length
|
||||
PROV_R_INVALID_SEED_LENGTH:154:invalid seed length
|
||||
PROV_R_INVALID_SIGNATURE_SIZE:179:invalid signature size
|
||||
PROV_R_INVALID_TAG:110:invalid tag
|
||||
PROV_R_INVALID_TAGLEN:118:invalid taglen
|
||||
PROV_R_INVALID_X931_DIGEST:170:invalid x931 digest
|
||||
@@ -2862,6 +2849,8 @@ PROV_R_NOT_SUPPORTED:136:not supported
|
||||
PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length
|
||||
PROV_R_NO_KEY_SET:114:no key set
|
||||
PROV_R_NO_PARAMETERS_SET:177:no parameters set
|
||||
PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:178:\
|
||||
operation not supported for this keytype
|
||||
PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small
|
||||
PROV_R_PSS_SALTLEN_TOO_SMALL:172:pss saltlen too small
|
||||
PROV_R_READ_KEY:159:read key
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]= \
|
||||
ess_lib.c ess_asn1.c ess_err.c
|
||||
|
||||
IF[{- !$disabled{'cms'} and !$disabled{'ts'} -}]
|
||||
SOURCE[../../libcrypto]= ess_lib.c
|
||||
ENDIF
|
||||
|
||||
SOURCE[../../libcrypto]= ess_asn1.c ess_err.c
|
||||
|
||||
+61
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -9,9 +9,11 @@
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/ess.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include "crypto/ess.h"
|
||||
#include "crypto/cms.h"
|
||||
|
||||
/* ASN1 stuff for ESS Structure */
|
||||
|
||||
@@ -55,3 +57,61 @@ ASN1_SEQUENCE(ESS_SIGNING_CERT_V2) = {
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(ESS_SIGNING_CERT_V2)
|
||||
IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT_V2)
|
||||
|
||||
/* No cms support means no CMS_SignerInfo* definitions */
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
|
||||
/*
|
||||
* Returns < 0 if attribute is not found, 1 if found, or
|
||||
* -1 on attribute parsing failure.
|
||||
*/
|
||||
int cms_signerinfo_get_signing_cert_v2(CMS_SignerInfo *si,
|
||||
ESS_SIGNING_CERT_V2 **psc)
|
||||
{
|
||||
ASN1_STRING *str;
|
||||
ESS_SIGNING_CERT_V2 *sc;
|
||||
ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_signingCertificateV2);
|
||||
|
||||
if (psc != NULL)
|
||||
*psc = NULL;
|
||||
str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE);
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
sc = ASN1_item_unpack(str, ASN1_ITEM_rptr(ESS_SIGNING_CERT_V2));
|
||||
if (sc == NULL)
|
||||
return -1;
|
||||
if (psc != NULL)
|
||||
*psc = sc;
|
||||
else
|
||||
ESS_SIGNING_CERT_V2_free(sc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns < 0 if attribute is not found, 1 if found, or
|
||||
* -1 on attribute parsing failure.
|
||||
*/
|
||||
int cms_signerinfo_get_signing_cert(CMS_SignerInfo *si,
|
||||
ESS_SIGNING_CERT **psc)
|
||||
{
|
||||
ASN1_STRING *str;
|
||||
ESS_SIGNING_CERT *sc;
|
||||
ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_signingCertificate);
|
||||
|
||||
if (psc != NULL)
|
||||
*psc = NULL;
|
||||
str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE);
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
sc = ASN1_item_unpack(str, ASN1_ITEM_rptr(ESS_SIGNING_CERT));
|
||||
if (sc == NULL)
|
||||
return -1;
|
||||
if (psc != NULL)
|
||||
*psc = sc;
|
||||
else
|
||||
ESS_SIGNING_CERT_free(sc);
|
||||
return 1;
|
||||
}
|
||||
#endif /* !OPENSSL_NO_CMS */
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
||||
+93
-5
@@ -15,8 +15,8 @@
|
||||
|
||||
DEFINE_STACK_OF(ESS_CERT_ID)
|
||||
DEFINE_STACK_OF(ESS_CERT_ID_V2)
|
||||
DEFINE_STACK_OF(X509)
|
||||
DEFINE_STACK_OF(GENERAL_NAME)
|
||||
DEFINE_STACK_OF(X509)
|
||||
|
||||
static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed);
|
||||
static ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new_init(const EVP_MD *hash_alg,
|
||||
@@ -61,9 +61,12 @@ static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed)
|
||||
unsigned char cert_sha1[SHA_DIGEST_LENGTH];
|
||||
|
||||
/* Call for side-effect of computing hash and caching extensions */
|
||||
X509_check_purpose(cert, -1, 0);
|
||||
if (!X509v3_cache_extensions(cert, NULL, NULL))
|
||||
return NULL;
|
||||
|
||||
if ((cid = ESS_CERT_ID_new()) == NULL)
|
||||
goto err;
|
||||
/* TODO(3.0): fetch sha1 algorithm from providers */
|
||||
if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL))
|
||||
goto err;
|
||||
if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH))
|
||||
@@ -85,8 +88,8 @@ static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed)
|
||||
goto err;
|
||||
name = NULL; /* Ownership is lost. */
|
||||
ASN1_INTEGER_free(cid->issuer_serial->serial);
|
||||
if (!(cid->issuer_serial->serial =
|
||||
ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
|
||||
if ((cid->issuer_serial->serial =
|
||||
ASN1_INTEGER_dup(X509_get_serialNumber(cert))) == NULL)
|
||||
goto err;
|
||||
|
||||
return cid;
|
||||
@@ -159,6 +162,7 @@ static ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new_init(const EVP_MD *hash_alg,
|
||||
cid->hash_alg = NULL;
|
||||
}
|
||||
|
||||
/* TODO(3.0): fetch sha1 algorithm from providers */
|
||||
if (!X509_digest(cert, hash_alg, hash, &hash_len))
|
||||
goto err;
|
||||
|
||||
@@ -196,8 +200,9 @@ ESS_SIGNING_CERT *ESS_SIGNING_CERT_get(PKCS7_SIGNER_INFO *si)
|
||||
{
|
||||
ASN1_TYPE *attr;
|
||||
const unsigned char *p;
|
||||
|
||||
attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate);
|
||||
if (!attr)
|
||||
if (attr == NULL)
|
||||
return NULL;
|
||||
p = attr->value.sequence->data;
|
||||
return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
|
||||
@@ -273,3 +278,86 @@ int ESS_SIGNING_CERT_V2_add(PKCS7_SIGNER_INFO *si,
|
||||
OPENSSL_free(pp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ess_issuer_serial_cmp(const ESS_ISSUER_SERIAL *is, const X509 *cert)
|
||||
{
|
||||
GENERAL_NAME *issuer;
|
||||
|
||||
if (is == NULL || cert == NULL || sk_GENERAL_NAME_num(is->issuer) != 1)
|
||||
return -1;
|
||||
|
||||
issuer = sk_GENERAL_NAME_value(is->issuer, 0);
|
||||
if (issuer->type != GEN_DIRNAME
|
||||
|| X509_NAME_cmp(issuer->d.dirn, X509_get_issuer_name(cert)) != 0)
|
||||
return -1;
|
||||
|
||||
return ASN1_INTEGER_cmp(is->serial, X509_get0_serialNumber(cert));
|
||||
}
|
||||
|
||||
/* Returns < 0 if certificate is not found, certificate index otherwise. */
|
||||
int ess_find_cert(const STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
|
||||
{
|
||||
int i;
|
||||
unsigned char cert_sha1[SHA_DIGEST_LENGTH];
|
||||
|
||||
if (cert_ids == NULL || cert == NULL)
|
||||
return -1;
|
||||
|
||||
/* Recompute SHA1 hash of certificate if necessary (side effect). */
|
||||
if (!X509v3_cache_extensions(cert, NULL, NULL))
|
||||
return -1;
|
||||
|
||||
/* TODO(3.0): fetch sha1 algorithm from providers */
|
||||
if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL))
|
||||
return -1;
|
||||
|
||||
/* Look for cert in the cert_ids vector. */
|
||||
for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) {
|
||||
const ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i);
|
||||
|
||||
if (cid->hash->length == SHA_DIGEST_LENGTH
|
||||
&& memcmp(cid->hash->data, cert_sha1, SHA_DIGEST_LENGTH) == 0) {
|
||||
const ESS_ISSUER_SERIAL *is = cid->issuer_serial;
|
||||
|
||||
if (is == NULL || ess_issuer_serial_cmp(is, cert) == 0)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns < 0 if certificate is not found, certificate index otherwise. */
|
||||
int ess_find_cert_v2(const STACK_OF(ESS_CERT_ID_V2) *cert_ids, const X509 *cert)
|
||||
{
|
||||
int i;
|
||||
unsigned char cert_digest[EVP_MAX_MD_SIZE];
|
||||
unsigned int len;
|
||||
|
||||
/* Look for cert in the cert_ids vector. */
|
||||
for (i = 0; i < sk_ESS_CERT_ID_V2_num(cert_ids); ++i) {
|
||||
const ESS_CERT_ID_V2 *cid = sk_ESS_CERT_ID_V2_value(cert_ids, i);
|
||||
const EVP_MD *md;
|
||||
|
||||
if (cid != NULL && cid->hash_alg != NULL)
|
||||
md = EVP_get_digestbyobj(cid->hash_alg->algorithm);
|
||||
else
|
||||
md = EVP_sha256();
|
||||
|
||||
/* TODO(3.0): fetch sha1 algorithm from providers */
|
||||
if (!X509_digest(cert, md, cert_digest, &len))
|
||||
return -1;
|
||||
|
||||
if (cid->hash->length != (int)len)
|
||||
return -1;
|
||||
|
||||
if (memcmp(cid->hash->data, cert_digest, cid->hash->length) == 0) {
|
||||
const ESS_ISSUER_SERIAL *is = cid->issuer_serial;
|
||||
|
||||
if (is == NULL || ess_issuer_serial_cmp(is, cert) == 0)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
+1
-1
@@ -423,7 +423,7 @@ static int evp_decodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
|
||||
table = data_ascii2bin;
|
||||
|
||||
/* trim white space from the start of the line. */
|
||||
while ((conv_ascii2bin(*f, table) == B64_WS) && (n > 0)) {
|
||||
while ((n > 0) && (conv_ascii2bin(*f, table) == B64_WS)) {
|
||||
f++;
|
||||
n--;
|
||||
}
|
||||
|
||||
@@ -444,7 +444,13 @@ void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id,
|
||||
data.free_method = free_method;
|
||||
data.user_fn = user_fn;
|
||||
data.user_arg = user_arg;
|
||||
ossl_algorithm_do_all(libctx, operation_id, NULL, do_one, &data);
|
||||
|
||||
/*
|
||||
* No pre- or post-condition for this call, as this only creates methods
|
||||
* temporarly and then promptly destroys them.
|
||||
*/
|
||||
ossl_algorithm_do_all(libctx, operation_id, NULL, NULL, do_one, NULL,
|
||||
&data);
|
||||
}
|
||||
|
||||
const char *evp_first_name(const OSSL_PROVIDER *prov, int name_id)
|
||||
|
||||
@@ -368,13 +368,13 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
|
||||
|
||||
/*
|
||||
* For clarity. The error is if parameters in peer are
|
||||
* present (!missing) but don't match. EVP_PKEY_cmp_parameters may return
|
||||
* present (!missing) but don't match. EVP_PKEY_parameters_eq 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)) {
|
||||
!EVP_PKEY_parameters_eq(ctx->pkey, peer)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
+10
-10
@@ -23,7 +23,7 @@
|
||||
#include "internal/provider.h"
|
||||
#include "evp_local.h"
|
||||
|
||||
EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf)
|
||||
EVP_KDF_CTX *EVP_KDF_new_ctx(EVP_KDF *kdf)
|
||||
{
|
||||
EVP_KDF_CTX *ctx = NULL;
|
||||
|
||||
@@ -34,7 +34,7 @@ EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf)
|
||||
if (ctx == NULL
|
||||
|| (ctx->data = kdf->newctx(ossl_provider_ctx(kdf->prov))) == NULL
|
||||
|| !EVP_KDF_up_ref(kdf)) {
|
||||
EVPerr(EVP_F_EVP_KDF_CTX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
EVPerr(0, ERR_R_MALLOC_FAILURE);
|
||||
if (ctx != NULL)
|
||||
kdf->freectx(ctx->data);
|
||||
OPENSSL_free(ctx);
|
||||
@@ -45,7 +45,7 @@ EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx)
|
||||
void EVP_KDF_free_ctx(EVP_KDF_CTX *ctx)
|
||||
{
|
||||
if (ctx != NULL) {
|
||||
ctx->meth->freectx(ctx->data);
|
||||
@@ -55,7 +55,7 @@ void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src)
|
||||
EVP_KDF_CTX *EVP_KDF_dup_ctx(const EVP_KDF_CTX *src)
|
||||
{
|
||||
EVP_KDF_CTX *dst;
|
||||
|
||||
@@ -64,20 +64,20 @@ EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src)
|
||||
|
||||
dst = OPENSSL_malloc(sizeof(*dst));
|
||||
if (dst == NULL) {
|
||||
EVPerr(EVP_F_EVP_KDF_CTX_DUP, ERR_R_MALLOC_FAILURE);
|
||||
EVPerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(dst, src, sizeof(*dst));
|
||||
if (!EVP_KDF_up_ref(dst->meth)) {
|
||||
EVPerr(EVP_F_EVP_KDF_CTX_DUP, ERR_R_MALLOC_FAILURE);
|
||||
EVPerr(0, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dst->data = src->meth->dupctx(src->data);
|
||||
if (dst->data == NULL) {
|
||||
EVP_KDF_CTX_free(dst);
|
||||
EVP_KDF_free_ctx(dst);
|
||||
return NULL;
|
||||
}
|
||||
return dst;
|
||||
@@ -98,7 +98,7 @@ const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf)
|
||||
return kdf->prov;
|
||||
}
|
||||
|
||||
const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx)
|
||||
const EVP_KDF *EVP_KDF_get_ctx_kdf(EVP_KDF_CTX *ctx)
|
||||
{
|
||||
return ctx->meth;
|
||||
}
|
||||
@@ -151,14 +151,14 @@ int EVP_KDF_get_params(EVP_KDF *kdf, OSSL_PARAM params[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_KDF_CTX_get_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[])
|
||||
int EVP_KDF_get_ctx_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[])
|
||||
{
|
||||
if (ctx->meth->get_ctx_params != NULL)
|
||||
return ctx->meth->get_ctx_params(ctx->data, params);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_KDF_CTX_set_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[])
|
||||
int EVP_KDF_set_ctx_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[])
|
||||
{
|
||||
if (ctx->meth->set_ctx_params != NULL)
|
||||
return ctx->meth->set_ctx_params(ctx->data, params);
|
||||
|
||||
@@ -39,6 +39,13 @@ static int try_import(const OSSL_PARAM params[], void *arg)
|
||||
{
|
||||
struct import_data_st *data = arg;
|
||||
|
||||
/* Just in time creation of keydata */
|
||||
if (data->keydata == NULL
|
||||
&& (data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* It's fine if there was no data to transfer, we just end up with an
|
||||
* empty destination key.
|
||||
@@ -46,13 +53,6 @@ static int try_import(const OSSL_PARAM params[], void *arg)
|
||||
if (params[0].key == NULL)
|
||||
return 1;
|
||||
|
||||
/* Just in time creation of keydata, if needed */
|
||||
if (data->keydata == NULL
|
||||
&& (data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return evp_keymgmt_import(data->keymgmt, data->keydata, data->selection,
|
||||
params);
|
||||
}
|
||||
@@ -236,8 +236,8 @@ int evp_keymgmt_util_has(EVP_PKEY *pk, int selection)
|
||||
* but also in the operation cache to see if there's any common keymgmt that
|
||||
* supplies OP_keymgmt_match.
|
||||
*
|
||||
* evp_keymgmt_util_match() adheres to the return values that EVP_PKEY_cmp()
|
||||
* and EVP_PKEY_cmp_parameters() return, i.e.:
|
||||
* evp_keymgmt_util_match() adheres to the return values that EVP_PKEY_eq()
|
||||
* and EVP_PKEY_parameters_eq() return, i.e.:
|
||||
*
|
||||
* 1 same key
|
||||
* 0 not same key
|
||||
|
||||
+10
-10
@@ -19,14 +19,14 @@
|
||||
#include "internal/provider.h"
|
||||
#include "evp_local.h"
|
||||
|
||||
EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac)
|
||||
EVP_MAC_CTX *EVP_MAC_new_ctx(EVP_MAC *mac)
|
||||
{
|
||||
EVP_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(EVP_MAC_CTX));
|
||||
|
||||
if (ctx == NULL
|
||||
|| (ctx->data = mac->newctx(ossl_provider_ctx(mac->prov))) == NULL
|
||||
|| !EVP_MAC_up_ref(mac)) {
|
||||
EVPerr(EVP_F_EVP_MAC_CTX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
EVPerr(0, ERR_R_MALLOC_FAILURE);
|
||||
if (ctx != NULL)
|
||||
mac->freectx(ctx->data);
|
||||
OPENSSL_free(ctx);
|
||||
@@ -37,7 +37,7 @@ EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx)
|
||||
void EVP_MAC_free_ctx(EVP_MAC_CTX *ctx)
|
||||
{
|
||||
if (ctx != NULL) {
|
||||
ctx->meth->freectx(ctx->data);
|
||||
@@ -48,7 +48,7 @@ void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx)
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src)
|
||||
EVP_MAC_CTX *EVP_MAC_dup_ctx(const EVP_MAC_CTX *src)
|
||||
{
|
||||
EVP_MAC_CTX *dst;
|
||||
|
||||
@@ -57,27 +57,27 @@ EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src)
|
||||
|
||||
dst = OPENSSL_malloc(sizeof(*dst));
|
||||
if (dst == NULL) {
|
||||
EVPerr(EVP_F_EVP_MAC_CTX_DUP, ERR_R_MALLOC_FAILURE);
|
||||
EVPerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*dst = *src;
|
||||
if (!EVP_MAC_up_ref(dst->meth)) {
|
||||
EVPerr(EVP_F_EVP_MAC_CTX_DUP, ERR_R_MALLOC_FAILURE);
|
||||
EVPerr(0, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dst->data = src->meth->dupctx(src->data);
|
||||
if (dst->data == NULL) {
|
||||
EVP_MAC_CTX_free(dst);
|
||||
EVP_MAC_free_ctx(dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx)
|
||||
EVP_MAC *EVP_MAC_get_ctx_mac(EVP_MAC_CTX *ctx)
|
||||
{
|
||||
return ctx->meth;
|
||||
}
|
||||
@@ -144,14 +144,14 @@ int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[])
|
||||
int EVP_MAC_get_ctx_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[])
|
||||
{
|
||||
if (ctx->meth->get_ctx_params != NULL)
|
||||
return ctx->meth->get_ctx_params(ctx->data, params);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[])
|
||||
int EVP_MAC_set_ctx_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[])
|
||||
{
|
||||
if (ctx->meth->set_ctx_params != NULL)
|
||||
return ctx->meth->set_ctx_params(ctx->data, params);
|
||||
|
||||
@@ -41,7 +41,7 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
|
||||
salt = (unsigned char *)empty;
|
||||
|
||||
kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_PBKDF2, NULL);
|
||||
kctx = EVP_KDF_CTX_new(kdf);
|
||||
kctx = EVP_KDF_new_ctx(kdf);
|
||||
EVP_KDF_free(kdf);
|
||||
if (kctx == NULL)
|
||||
return 0;
|
||||
@@ -54,11 +54,11 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
|
||||
(char *)mdname, 0);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
if (EVP_KDF_CTX_set_params(kctx, params) != 1
|
||||
if (EVP_KDF_set_ctx_params(kctx, params) != 1
|
||||
|| EVP_KDF_derive(kctx, out, keylen) != 1)
|
||||
rv = 0;
|
||||
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
|
||||
OSSL_TRACE_BEGIN(PKCS5V2) {
|
||||
BIO_printf(trc_out, "Password:\n");
|
||||
|
||||
+87
-35
@@ -119,7 +119,7 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
* If |to| is a legacy key and |from| isn't, we must downgrade |from|.
|
||||
* If that fails, this function fails.
|
||||
*/
|
||||
if (to->type != EVP_PKEY_NONE && from->keymgmt != NULL)
|
||||
if (evp_pkey_is_legacy(to) && evp_pkey_is_provided(from))
|
||||
if (!evp_pkey_downgrade((EVP_PKEY *)from))
|
||||
return 0;
|
||||
|
||||
@@ -135,15 +135,15 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
* like evp_keymgmt_util_copy() and evp_pkey_export_to_provider() called
|
||||
* further down help us find out if they are the same or not.
|
||||
*/
|
||||
if (to->type == EVP_PKEY_NONE && to->keymgmt == NULL) {
|
||||
if (from->type != EVP_PKEY_NONE) {
|
||||
if (evp_pkey_is_blank(to)) {
|
||||
if (evp_pkey_is_legacy(from)) {
|
||||
if (EVP_PKEY_set_type(to, from->type) == 0)
|
||||
return 0;
|
||||
} else {
|
||||
if (EVP_PKEY_set_type_by_keymgmt(to, from->keymgmt) == 0)
|
||||
return 0;
|
||||
}
|
||||
} else if (to->type != EVP_PKEY_NONE) {
|
||||
} else if (evp_pkey_is_legacy(to)) {
|
||||
if (to->type != from->type) {
|
||||
EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES);
|
||||
goto err;
|
||||
@@ -156,7 +156,7 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
}
|
||||
|
||||
if (!EVP_PKEY_missing_parameters(to)) {
|
||||
if (EVP_PKEY_cmp_parameters(to, from) == 1)
|
||||
if (EVP_PKEY_parameters_eq(to, from) == 1)
|
||||
return 1;
|
||||
EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_PARAMETERS);
|
||||
return 0;
|
||||
@@ -272,7 +272,14 @@ static int evp_pkey_cmp_any(const EVP_PKEY *a, const EVP_PKEY *b,
|
||||
return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
return EVP_PKEY_parameters_eq(a, b);
|
||||
}
|
||||
#endif
|
||||
|
||||
int EVP_PKEY_parameters_eq(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
/*
|
||||
* TODO: clean up legacy stuff from this function when legacy support
|
||||
@@ -290,7 +297,14 @@ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
return -2;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
return EVP_PKEY_eq(a, b);
|
||||
}
|
||||
#endif
|
||||
|
||||
int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
/*
|
||||
* TODO: clean up legacy stuff from this function when legacy support
|
||||
@@ -581,7 +595,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
prov == NULL ? NULL : ossl_provider_library_context(prov);
|
||||
EVP_PKEY *ret = EVP_PKEY_new();
|
||||
EVP_MAC *cmac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, NULL);
|
||||
EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_CTX_new(cmac) : NULL;
|
||||
EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_new_ctx(cmac) : NULL;
|
||||
OSSL_PARAM params[4];
|
||||
size_t paramsn = 0;
|
||||
|
||||
@@ -606,7 +620,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
(char *)priv, len);
|
||||
params[paramsn] = OSSL_PARAM_construct_end();
|
||||
|
||||
if (!EVP_MAC_CTX_set_params(cmctx, params)) {
|
||||
if (!EVP_MAC_set_ctx_params(cmctx, params)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED);
|
||||
goto err;
|
||||
}
|
||||
@@ -616,7 +630,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
|
||||
err:
|
||||
EVP_PKEY_free(ret);
|
||||
EVP_MAC_CTX_free(cmctx);
|
||||
EVP_MAC_free_ctx(cmctx);
|
||||
EVP_MAC_free(cmac);
|
||||
return NULL;
|
||||
# else
|
||||
@@ -1201,6 +1215,18 @@ int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid)
|
||||
int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
|
||||
const unsigned char *pt, size_t ptlen)
|
||||
{
|
||||
if (pkey->ameth == NULL) {
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
if (pkey->keymgmt == NULL || pkey->keydata == NULL)
|
||||
return 0;
|
||||
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT,
|
||||
(unsigned char *)pt, ptlen);
|
||||
return evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params);
|
||||
}
|
||||
|
||||
if (ptlen > INT_MAX)
|
||||
return 0;
|
||||
if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, ptlen,
|
||||
@@ -1212,6 +1238,33 @@ int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
|
||||
size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if (pkey->ameth == NULL) {
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
if (pkey->keymgmt == NULL || pkey->keydata == NULL)
|
||||
return 0;
|
||||
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT,
|
||||
NULL, 0);
|
||||
if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
|
||||
return 0;
|
||||
|
||||
*ppt = OPENSSL_malloc(params[0].return_size);
|
||||
if (*ppt == NULL)
|
||||
return 0;
|
||||
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT,
|
||||
*ppt, params[0].return_size);
|
||||
if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
|
||||
return 0;
|
||||
|
||||
return params[0].return_size;
|
||||
}
|
||||
|
||||
|
||||
rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppt);
|
||||
if (rv <= 0)
|
||||
return 0;
|
||||
@@ -1357,19 +1410,17 @@ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
|
||||
pkey->engine = e;
|
||||
|
||||
/*
|
||||
* The EVP_PKEY_ASN1_METHOD |pkey_id| serves different purposes,
|
||||
* depending on if we're setting this key to contain a legacy or
|
||||
* a provider side "origin" key. For a legacy key, we assign it
|
||||
* to the |type| field, but for a provider side key, we assign it
|
||||
* to the |save_type| field, because |type| is supposed to be set
|
||||
* to EVP_PKEY_NONE in that case.
|
||||
* The EVP_PKEY_ASN1_METHOD |pkey_id| retains its legacy key purpose
|
||||
* for any key type that has a legacy implementation, regardless of
|
||||
* if the internal key is a legacy or a provider side one. When
|
||||
* there is no legacy implementation for the key, the type becomes
|
||||
* EVP_PKEY_KEYMGMT, which indicates that one should be cautious
|
||||
* with functions that expect legacy internal keys.
|
||||
*/
|
||||
if (ameth != NULL) {
|
||||
if (keymgmt != NULL)
|
||||
pkey->save_type = ameth->pkey_id;
|
||||
else if (pkey->ameth != NULL)
|
||||
pkey->type = ameth->pkey_id;
|
||||
}
|
||||
if (ameth != NULL)
|
||||
pkey->type = ameth->pkey_id;
|
||||
else
|
||||
pkey->type = EVP_PKEY_KEYMGMT;
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
@@ -1453,7 +1504,6 @@ void evp_pkey_free_legacy(EVP_PKEY *x)
|
||||
ENGINE_finish(x->pmeth_engine);
|
||||
x->pmeth_engine = NULL;
|
||||
# endif
|
||||
x->type = EVP_PKEY_NONE;
|
||||
}
|
||||
#endif /* FIPS_MODULE */
|
||||
|
||||
@@ -1472,6 +1522,7 @@ static void evp_pkey_free_it(EVP_PKEY *x)
|
||||
x->keymgmt = NULL;
|
||||
x->keydata = NULL;
|
||||
}
|
||||
x->type = EVP_PKEY_NONE;
|
||||
}
|
||||
|
||||
void EVP_PKEY_free(EVP_PKEY *x)
|
||||
@@ -1661,32 +1712,33 @@ int evp_pkey_downgrade(EVP_PKEY *pk)
|
||||
{
|
||||
EVP_KEYMGMT *keymgmt = pk->keymgmt;
|
||||
void *keydata = pk->keydata;
|
||||
int type = pk->save_type;
|
||||
int type = pk->type;
|
||||
const char *keytype = NULL;
|
||||
|
||||
/* If this isn't a provider side key, we're done */
|
||||
if (keymgmt == NULL)
|
||||
return 1;
|
||||
|
||||
/* Get the key type name for error reporting */
|
||||
if (type != EVP_PKEY_NONE)
|
||||
keytype = OBJ_nid2sn(type);
|
||||
else
|
||||
keytype =
|
||||
evp_first_name(EVP_KEYMGMT_provider(keymgmt), keymgmt->name_id);
|
||||
keytype = evp_first_name(EVP_KEYMGMT_provider(keymgmt), keymgmt->name_id);
|
||||
|
||||
/*
|
||||
* |save_type| was set when any of the EVP_PKEY_set_type functions
|
||||
* was called. It was set to EVP_PKEY_NONE if the key type wasn't
|
||||
* recognised to be any of the legacy key types, and the downgrade
|
||||
* isn't possible.
|
||||
* If the type is EVP_PKEY_NONE, then we have a problem somewhere else
|
||||
* in our code. If it's not one of the well known EVP_PKEY_xxx values,
|
||||
* it should at least be EVP_PKEY_KEYMGMT at this point.
|
||||
* TODO(3.0) remove this check when we're confident that the rest of the
|
||||
* code treats this correctly.
|
||||
*/
|
||||
if (type == EVP_PKEY_NONE) {
|
||||
ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_KEY_TYPE,
|
||||
"key type = %s, can't downgrade", keytype);
|
||||
if (!ossl_assert(type != EVP_PKEY_NONE)) {
|
||||
ERR_raise_data(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR,
|
||||
"keymgmt key type = %s but legacy type = EVP_PKEY_NONE",
|
||||
keytype);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Prefer the legacy key type name for error reporting */
|
||||
if (type != EVP_PKEY_KEYMGMT)
|
||||
keytype = OBJ_nid2sn(type);
|
||||
|
||||
/*
|
||||
* To be able to downgrade, we steal the provider side "origin" keymgmt
|
||||
* and keydata. We've already grabbed the pointers, so all we need to
|
||||
|
||||
@@ -63,7 +63,7 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen,
|
||||
maxmem = SCRYPT_MAX_MEM;
|
||||
|
||||
kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_SCRYPT, NULL);
|
||||
kctx = EVP_KDF_CTX_new(kdf);
|
||||
kctx = EVP_KDF_new_ctx(kdf);
|
||||
EVP_KDF_free(kdf);
|
||||
if (kctx == NULL)
|
||||
return 0;
|
||||
@@ -78,11 +78,11 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen,
|
||||
*z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_P, &p);
|
||||
*z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_MAXMEM, &maxmem);
|
||||
*z = OSSL_PARAM_construct_end();
|
||||
if (EVP_KDF_CTX_set_params(kctx, params) != 1
|
||||
if (EVP_KDF_set_ctx_params(kctx, params) != 1
|
||||
|| EVP_KDF_derive(kctx, key, keylen) != 1)
|
||||
rv = 0;
|
||||
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_free_ctx(kctx);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ static int pkey_kdf_init(EVP_PKEY_CTX *ctx)
|
||||
return 0;
|
||||
|
||||
kdf = EVP_KDF_fetch(NULL, kdf_name, NULL);
|
||||
kctx = EVP_KDF_CTX_new(kdf);
|
||||
kctx = EVP_KDF_new_ctx(kdf);
|
||||
EVP_KDF_free(kdf);
|
||||
if (kctx == NULL) {
|
||||
OPENSSL_free(pkctx);
|
||||
@@ -66,7 +66,7 @@ static void pkey_kdf_cleanup(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
EVP_PKEY_KDF_CTX *pkctx = ctx->data;
|
||||
|
||||
EVP_KDF_CTX_free(pkctx->kctx);
|
||||
EVP_KDF_free_ctx(pkctx->kctx);
|
||||
pkey_kdf_free_collected(pkctx);
|
||||
OPENSSL_free(pkctx);
|
||||
}
|
||||
@@ -202,7 +202,7 @@ static int pkey_kdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
break;
|
||||
}
|
||||
|
||||
return EVP_KDF_CTX_set_params(kctx, params);
|
||||
return EVP_KDF_set_ctx_params(kctx, params);
|
||||
}
|
||||
|
||||
static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
|
||||
@@ -210,7 +210,7 @@ static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
|
||||
{
|
||||
EVP_PKEY_KDF_CTX *pkctx = ctx->data;
|
||||
EVP_KDF_CTX *kctx = pkctx->kctx;
|
||||
const EVP_KDF *kdf = EVP_KDF_CTX_kdf(kctx);
|
||||
const EVP_KDF *kdf = EVP_KDF_get_ctx_kdf(kctx);
|
||||
BUF_MEM **collector = NULL;
|
||||
const OSSL_PARAM *defs = EVP_KDF_settable_ctx_params(kdf);
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
@@ -239,7 +239,7 @@ static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
|
||||
if (collector != NULL)
|
||||
ok = collect(collector, params[0].data, params[0].data_size);
|
||||
else
|
||||
ok = EVP_KDF_CTX_set_params(kctx, params);
|
||||
ok = EVP_KDF_set_ctx_params(kctx, params);
|
||||
OPENSSL_free(params[0].data);
|
||||
return ok;
|
||||
}
|
||||
@@ -274,7 +274,7 @@ static int pkey_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||
pkctx->collected_seed->data,
|
||||
pkctx->collected_seed->length);
|
||||
|
||||
r = EVP_KDF_CTX_set_params(kctx, params);
|
||||
r = EVP_KDF_set_ctx_params(kctx, params);
|
||||
pkey_kdf_free_collected(pkctx);
|
||||
if (!r)
|
||||
return 0;
|
||||
@@ -287,7 +287,7 @@ static int pkey_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||
pkctx->collected_info->data,
|
||||
pkctx->collected_info->length);
|
||||
|
||||
r = EVP_KDF_CTX_set_params(kctx, params);
|
||||
r = EVP_KDF_set_ctx_params(kctx, params);
|
||||
pkey_kdf_free_collected(pkctx);
|
||||
if (!r)
|
||||
return 0;
|
||||
|
||||
+20
-19
@@ -71,7 +71,7 @@ static int pkey_mac_init(EVP_PKEY_CTX *ctx)
|
||||
}
|
||||
|
||||
if (mac != NULL) {
|
||||
hctx->ctx = EVP_MAC_CTX_new(mac);
|
||||
hctx->ctx = EVP_MAC_new_ctx(mac);
|
||||
if (hctx->ctx == NULL) {
|
||||
OPENSSL_free(hctx);
|
||||
return 0;
|
||||
@@ -116,7 +116,7 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
|
||||
EVP_PKEY_CTX_set_data(dst, dctx);
|
||||
dst->keygen_info_count = 0;
|
||||
|
||||
dctx->ctx = EVP_MAC_CTX_dup(sctx->ctx);
|
||||
dctx->ctx = EVP_MAC_dup_ctx(sctx->ctx);
|
||||
if (dctx->ctx == NULL)
|
||||
goto err;
|
||||
|
||||
@@ -128,7 +128,7 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
|
||||
* fetches the MAC method anew in this case. Therefore, its reference
|
||||
* count must be adjusted here.
|
||||
*/
|
||||
if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(dctx->ctx)))
|
||||
if (!EVP_MAC_up_ref(EVP_MAC_get_ctx_mac(dctx->ctx)))
|
||||
goto err;
|
||||
|
||||
dctx->type = sctx->type;
|
||||
@@ -163,7 +163,8 @@ static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
|
||||
MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx);
|
||||
|
||||
if (hctx != NULL) {
|
||||
EVP_MAC *mac = hctx->ctx != NULL ? EVP_MAC_CTX_mac(hctx->ctx) : NULL;
|
||||
EVP_MAC *mac = hctx->ctx != NULL ? EVP_MAC_get_ctx_mac(hctx->ctx)
|
||||
: NULL;
|
||||
|
||||
switch (hctx->type) {
|
||||
case MAC_TYPE_RAW:
|
||||
@@ -171,7 +172,7 @@ static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
|
||||
hctx->raw_data.ktmp.length);
|
||||
break;
|
||||
}
|
||||
EVP_MAC_CTX_free(hctx->ctx);
|
||||
EVP_MAC_free_ctx(hctx->ctx);
|
||||
EVP_MAC_free(mac);
|
||||
OPENSSL_free(hctx);
|
||||
EVP_PKEY_CTX_set_data(ctx, NULL);
|
||||
@@ -206,10 +207,10 @@ static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmkey = EVP_MAC_CTX_dup(hctx->ctx);
|
||||
cmkey = EVP_MAC_dup_ctx(hctx->ctx);
|
||||
if (cmkey == NULL)
|
||||
return 0;
|
||||
if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx)))
|
||||
if (!EVP_MAC_up_ref(EVP_MAC_get_ctx_mac(hctx->ctx)))
|
||||
return 0;
|
||||
EVP_PKEY_assign(pkey, nid, cmkey);
|
||||
}
|
||||
@@ -255,7 +256,7 @@ static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
|
||||
}
|
||||
|
||||
if (set_key) {
|
||||
if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx),
|
||||
if (!EVP_MAC_is_a(EVP_MAC_get_ctx_mac(hctx->ctx),
|
||||
OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)))))
|
||||
return 0;
|
||||
key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
|
||||
@@ -280,7 +281,7 @@ static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
|
||||
OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
|
||||
key->data, key->length);
|
||||
params[params_n++] = OSSL_PARAM_construct_end();
|
||||
rv = EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||
rv = EVP_MAC_set_ctx_params(hctx->ctx, params);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@@ -330,7 +331,7 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!EVP_MAC_CTX_set_params(hctx->ctx, params)
|
||||
if (!EVP_MAC_set_ctx_params(hctx->ctx, params)
|
||||
|| !EVP_MAC_init(hctx->ctx))
|
||||
return 0;
|
||||
}
|
||||
@@ -351,10 +352,10 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
|
||||
if (ctx->pkey == NULL)
|
||||
return 0;
|
||||
new_mac_ctx = EVP_MAC_CTX_dup(ctx->pkey->pkey.ptr);
|
||||
new_mac_ctx = EVP_MAC_dup_ctx(ctx->pkey->pkey.ptr);
|
||||
if (new_mac_ctx == NULL)
|
||||
return 0;
|
||||
EVP_MAC_CTX_free(hctx->ctx);
|
||||
EVP_MAC_free_ctx(hctx->ctx);
|
||||
hctx->ctx = new_mac_ctx;
|
||||
}
|
||||
break;
|
||||
@@ -389,17 +390,17 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!EVP_MAC_CTX_set_params(hctx->ctx, params))
|
||||
if (!EVP_MAC_set_ctx_params(hctx->ctx, params))
|
||||
return 0;
|
||||
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &verify);
|
||||
|
||||
if (!EVP_MAC_CTX_get_params(hctx->ctx, params))
|
||||
if (!EVP_MAC_get_ctx_params(hctx->ctx, params))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Since EVP_MAC_CTX_{get,set}_params() returned successfully,
|
||||
* Since EVP_MAC_{get,set}_ctx_params() returned successfully,
|
||||
* we can only assume that the size was ignored, i.e. this
|
||||
* control is unsupported.
|
||||
*/
|
||||
@@ -433,7 +434,7 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||
return EVP_MAC_set_ctx_params(hctx->ctx, params);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -478,7 +479,7 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
key->data, key->length);
|
||||
params[params_n] = OSSL_PARAM_construct_end();
|
||||
|
||||
return EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||
return EVP_MAC_set_ctx_params(hctx->ctx, params);
|
||||
}
|
||||
break;
|
||||
case MAC_TYPE_MAC:
|
||||
@@ -513,7 +514,7 @@ static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
mac = EVP_MAC_CTX_mac(hctx->ctx);
|
||||
mac = EVP_MAC_get_ctx_mac(hctx->ctx);
|
||||
|
||||
/*
|
||||
* Translation of some control names that are equivalent to a single
|
||||
@@ -535,7 +536,7 @@ static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
return 0;
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||
ok = EVP_MAC_set_ctx_params(hctx->ctx, params);
|
||||
OPENSSL_free(params[0].data);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -144,6 +144,8 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
|
||||
int ret = 0;
|
||||
OSSL_CALLBACK cb;
|
||||
EVP_PKEY *allocated_pkey = NULL;
|
||||
/* Legacy compatible keygen callback info, only used with provider impls */
|
||||
int gentmp[2];
|
||||
|
||||
if (ppkey == NULL)
|
||||
return -1;
|
||||
@@ -165,6 +167,18 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
|
||||
if (ctx->op.keymgmt.genctx == NULL)
|
||||
goto legacy;
|
||||
|
||||
/*
|
||||
* Asssigning gentmp to ctx->keygen_info is something our legacy
|
||||
* implementations do. Because the provider implementations aren't
|
||||
* allowed to reach into our EVP_PKEY_CTX, we need to provide similar
|
||||
* space for backward compatibility. It's ok that we attach a local
|
||||
* variable, as it should only be useful in the calls down from here.
|
||||
* This is cleared as soon as it isn't useful any more, i.e. directly
|
||||
* after the evp_keymgmt_util_gen() call.
|
||||
*/
|
||||
ctx->keygen_info = gentmp;
|
||||
ctx->keygen_info_count = 2;
|
||||
|
||||
ret = 1;
|
||||
if (ctx->pkey != NULL) {
|
||||
EVP_KEYMGMT *tmp_keymgmt = ctx->keymgmt;
|
||||
@@ -191,6 +205,8 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
|
||||
ossl_callback_to_pkey_gencb, ctx)
|
||||
!= NULL);
|
||||
|
||||
ctx->keygen_info = NULL;
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
/* In case |*ppkey| was originally a legacy key */
|
||||
if (ret)
|
||||
|
||||
+59
-46
@@ -137,6 +137,40 @@ EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
|
||||
}
|
||||
#endif /* FIPS_MODULE */
|
||||
|
||||
static int is_legacy_alg(int id, const char *keytype)
|
||||
{
|
||||
#ifndef FIPS_MODULE
|
||||
/* Certain EVP_PKEY keytypes are only available in legacy form */
|
||||
if (id == -1) {
|
||||
id = OBJ_sn2nid(keytype);
|
||||
if (id == NID_undef)
|
||||
id = OBJ_ln2nid(keytype);
|
||||
if (id == NID_undef)
|
||||
return 0;
|
||||
}
|
||||
switch (id) {
|
||||
/*
|
||||
* TODO(3.0): Remove SM2 and DHX when they are converted to have provider
|
||||
* support
|
||||
*/
|
||||
case EVP_PKEY_SM2:
|
||||
case EVP_PKEY_DHX:
|
||||
case EVP_PKEY_SCRYPT:
|
||||
case EVP_PKEY_TLS1_PRF:
|
||||
case EVP_PKEY_HKDF:
|
||||
case EVP_PKEY_CMAC:
|
||||
case EVP_PKEY_HMAC:
|
||||
case EVP_PKEY_SIPHASH:
|
||||
case EVP_PKEY_POLY1305:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
|
||||
EVP_PKEY *pkey, ENGINE *e,
|
||||
const char *keytype, const char *propquery,
|
||||
@@ -155,10 +189,10 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
|
||||
goto common;
|
||||
|
||||
/*
|
||||
* If the key doesn't contain anything legacy, then it must be provided,
|
||||
* so we extract the necessary information and use that.
|
||||
* If the internal key is provided, we extract the keytype from its
|
||||
* keymgmt and skip over the legacy code.
|
||||
*/
|
||||
if (pkey != NULL && pkey->type == EVP_PKEY_NONE) {
|
||||
if (pkey != NULL && evp_pkey_is_provided(pkey)) {
|
||||
/* If we have an engine, something went wrong somewhere... */
|
||||
if (!ossl_assert(e == NULL))
|
||||
return NULL;
|
||||
@@ -228,10 +262,20 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
|
||||
* implementation.
|
||||
*/
|
||||
if (e == NULL && keytype != NULL) {
|
||||
/* This could fail so ignore errors */
|
||||
ERR_set_mark();
|
||||
int legacy = is_legacy_alg(id, keytype);
|
||||
|
||||
if (legacy) {
|
||||
/* This could fail so ignore errors */
|
||||
ERR_set_mark();
|
||||
}
|
||||
|
||||
keymgmt = EVP_KEYMGMT_fetch(libctx, keytype, propquery);
|
||||
ERR_pop_to_mark();
|
||||
if (legacy) {
|
||||
ERR_pop_to_mark();
|
||||
} else if (keymgmt == NULL) {
|
||||
EVPerr(EVP_F_INT_CTX_NEW, EVP_R_FETCH_FAILED);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
@@ -341,45 +385,14 @@ void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
|
||||
|
||||
void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
|
||||
{
|
||||
int pkey_id = dst->pkey_id;
|
||||
int flags = dst->flags;
|
||||
|
||||
dst->init = src->init;
|
||||
dst->copy = src->copy;
|
||||
dst->cleanup = src->cleanup;
|
||||
*dst = *src;
|
||||
|
||||
dst->paramgen_init = src->paramgen_init;
|
||||
dst->paramgen = src->paramgen;
|
||||
|
||||
dst->keygen_init = src->keygen_init;
|
||||
dst->keygen = src->keygen;
|
||||
|
||||
dst->sign_init = src->sign_init;
|
||||
dst->sign = src->sign;
|
||||
|
||||
dst->verify_init = src->verify_init;
|
||||
dst->verify = src->verify;
|
||||
|
||||
dst->verify_recover_init = src->verify_recover_init;
|
||||
dst->verify_recover = src->verify_recover;
|
||||
|
||||
dst->signctx_init = src->signctx_init;
|
||||
dst->signctx = src->signctx;
|
||||
|
||||
dst->verifyctx_init = src->verifyctx_init;
|
||||
dst->verifyctx = src->verifyctx;
|
||||
|
||||
dst->encrypt_init = src->encrypt_init;
|
||||
dst->encrypt = src->encrypt;
|
||||
|
||||
dst->decrypt_init = src->decrypt_init;
|
||||
dst->decrypt = src->decrypt;
|
||||
|
||||
dst->derive_init = src->derive_init;
|
||||
dst->derive = src->derive;
|
||||
|
||||
dst->ctrl = src->ctrl;
|
||||
dst->ctrl_str = src->ctrl_str;
|
||||
|
||||
dst->check = src->check;
|
||||
/* We only copy the function pointers so restore the other values */
|
||||
dst->pkey_id = pkey_id;
|
||||
dst->flags = flags;
|
||||
}
|
||||
|
||||
void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
|
||||
@@ -1033,7 +1046,7 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_DH
|
||||
else if (strcmp(name, "dh_paramgen_generator") == 0)
|
||||
name = OSSL_PKEY_PARAM_FFC_GENERATOR;
|
||||
name = OSSL_PKEY_PARAM_DH_GENERATOR;
|
||||
else if (strcmp(name, "dh_paramgen_prime_len") == 0)
|
||||
name = OSSL_PKEY_PARAM_FFC_PBITS;
|
||||
else if (strcmp(name, "dh_paramgen_subprime_len") == 0)
|
||||
@@ -1042,9 +1055,9 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
|
||||
name = OSSL_PKEY_PARAM_FFC_TYPE;
|
||||
value = dh_gen_type_id2name(atoi(value));
|
||||
} else if (strcmp(name, "dh_param") == 0)
|
||||
name = OSSL_PKEY_PARAM_FFC_GROUP;
|
||||
name = OSSL_PKEY_PARAM_DH_GROUP;
|
||||
else if (strcmp(name, "dh_rfc5114") == 0) {
|
||||
name = OSSL_PKEY_PARAM_FFC_GROUP;
|
||||
name = OSSL_PKEY_PARAM_DH_GROUP;
|
||||
value = ffc_named_group_from_uid(atoi(value));
|
||||
} else if (strcmp(name, "dh_pad") == 0)
|
||||
name = OSSL_EXCHANGE_PARAM_PAD;
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ static void dummy_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx,
|
||||
}
|
||||
|
||||
static int dummy_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
|
||||
void *from_d, int idx,
|
||||
void **from_d, int idx,
|
||||
long argl, void *argp)
|
||||
{
|
||||
return 1;
|
||||
|
||||
@@ -27,7 +27,7 @@ int ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[])
|
||||
if (ffc == NULL)
|
||||
return 0;
|
||||
|
||||
prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GROUP);
|
||||
prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_GROUP);
|
||||
if (prm != NULL) {
|
||||
if (prm->data_type != OSSL_PARAM_UTF8_STRING)
|
||||
goto err;
|
||||
|
||||
@@ -220,7 +220,7 @@ int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld,
|
||||
|
||||
if (name == NULL
|
||||
|| !ossl_param_build_set_utf8_string(bld, params,
|
||||
OSSL_PKEY_PARAM_FFC_GROUP,
|
||||
OSSL_PKEY_PARAM_DH_GROUP,
|
||||
name))
|
||||
return 0;
|
||||
#else
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
#include <string.h> /* memset */
|
||||
#include <openssl/sha.h> /* SHA_DIGEST_LENGTH */
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/dherr.h>
|
||||
#include <openssl/dsaerr.h>
|
||||
#include "crypto/bn.h"
|
||||
#include "internal/ffc.h"
|
||||
|
||||
@@ -40,6 +43,9 @@ static int ffc_validate_LN(size_t L, size_t N, int type)
|
||||
/* Valid DH L,N parameters from SP800-56Ar3 5.5.1 Table 1 */
|
||||
if (L == 2048 && (N == 224 || N == 256))
|
||||
return 112;
|
||||
#ifndef OPENSSL_NO_DH
|
||||
DHerr(0, DH_R_BAD_FFC_PARAMETERS);
|
||||
#endif
|
||||
} else if (type == FFC_PARAM_TYPE_DSA) {
|
||||
/* Valid DSA L,N parameters from FIPS 186-4 Section 4.2 */
|
||||
if (L == 1024 && N == 160)
|
||||
@@ -48,6 +54,9 @@ static int ffc_validate_LN(size_t L, size_t N, int type)
|
||||
return 112;
|
||||
if (L == 3072 && N == 256)
|
||||
return 128;
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
DSAerr(0, DSA_R_BAD_FFC_PARAMETERS);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=http_client.c http_err.c http_lib.c
|
||||
@@ -1,1271 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright Siemens AG 2018-2020
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "e_os.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "crypto/ctype.h"
|
||||
#include <string.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/httperr.h>
|
||||
#include <openssl/cmperr.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/http.h>
|
||||
#include "internal/sockets.h"
|
||||
#include "internal/cryptlib.h" /* for ossl_assert() */
|
||||
|
||||
#include "http_local.h"
|
||||
|
||||
DEFINE_STACK_OF(CONF_VALUE)
|
||||
|
||||
#define HTTP_PREFIX "HTTP/"
|
||||
#define HTTP_VERSION_PATT "1." /* allow 1.x */
|
||||
#define HTTP_VERSION_STR_LEN 3
|
||||
#define HTTP_LINE1_MINLEN ((int)strlen(HTTP_PREFIX HTTP_VERSION_PATT "x 200\n"))
|
||||
#define HTTP_VERSION_MAX_REDIRECTIONS 50
|
||||
|
||||
#define HTTP_STATUS_CODE_OK 200
|
||||
#define HTTP_STATUS_CODE_MOVED_PERMANENTLY 301
|
||||
#define HTTP_STATUS_CODE_FOUND 302
|
||||
|
||||
|
||||
/* Stateful HTTP request code, supporting blocking and non-blocking I/O */
|
||||
|
||||
/* Opaque HTTP request status structure */
|
||||
|
||||
struct ossl_http_req_ctx_st {
|
||||
int state; /* Current I/O state */
|
||||
unsigned char *iobuf; /* Line buffer */
|
||||
int iobuflen; /* Line buffer length */
|
||||
BIO *wbio; /* BIO to send request to */
|
||||
BIO *rbio; /* BIO to read response from */
|
||||
BIO *mem; /* Memory BIO response is built into */
|
||||
int method_GET; /* HTTP method "GET" or "POST" */
|
||||
const char *expected_ct; /* expected Content-Type, or NULL */
|
||||
int expect_asn1; /* response must be ASN.1-encoded */
|
||||
unsigned long resp_len; /* length of response */
|
||||
unsigned long max_resp_len; /* Maximum length of response */
|
||||
time_t max_time; /* Maximum end time of the transfer, or 0 */
|
||||
char *redirection_url; /* Location given with HTTP status 301/302 */
|
||||
};
|
||||
|
||||
#define HTTP_DEFAULT_MAX_LINE_LENGTH (4 * 1024)
|
||||
#define HTTP_DEFAULT_MAX_RESP_LEN (100 * 1024)
|
||||
|
||||
/* HTTP states */
|
||||
|
||||
#define OHS_NOREAD 0x1000 /* If set no reading should be performed */
|
||||
#define OHS_ERROR (0 | OHS_NOREAD) /* Error condition */
|
||||
#define OHS_FIRSTLINE 1 /* First line being read */
|
||||
#define OHS_REDIRECT 0xa /* Looking for redirection location */
|
||||
#define OHS_HEADERS 2 /* MIME headers being read */
|
||||
#define OHS_ASN1_HEADER 3 /* HTTP initial header (tag+length) being read */
|
||||
#define OHS_CONTENT 4 /* HTTP content octets being read */
|
||||
#define OHS_WRITE_INIT (5 | OHS_NOREAD) /* 1st call: ready to start I/O */
|
||||
#define OHS_WRITE (6 | OHS_NOREAD) /* Request being sent */
|
||||
#define OHS_FLUSH (7 | OHS_NOREAD) /* Request being flushed */
|
||||
#define OHS_DONE (8 | OHS_NOREAD) /* Completed */
|
||||
#define OHS_HTTP_HEADER (9 | OHS_NOREAD) /* Headers set, w/o final \r\n */
|
||||
|
||||
OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio,
|
||||
int method_GET, int maxline,
|
||||
unsigned long max_resp_len,
|
||||
int timeout,
|
||||
const char *expected_content_type,
|
||||
int expect_asn1)
|
||||
{
|
||||
OSSL_HTTP_REQ_CTX *rctx;
|
||||
|
||||
if (wbio == NULL || rbio == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((rctx = OPENSSL_zalloc(sizeof(*rctx))) == NULL)
|
||||
return NULL;
|
||||
rctx->state = OHS_ERROR;
|
||||
rctx->iobuflen = maxline > 0 ? maxline : HTTP_DEFAULT_MAX_LINE_LENGTH;
|
||||
rctx->iobuf = OPENSSL_malloc(rctx->iobuflen);
|
||||
rctx->wbio = wbio;
|
||||
rctx->rbio = rbio;
|
||||
rctx->mem = BIO_new(BIO_s_mem());
|
||||
if (rctx->iobuf == NULL || rctx->mem == NULL) {
|
||||
OSSL_HTTP_REQ_CTX_free(rctx);
|
||||
return NULL;
|
||||
}
|
||||
rctx->method_GET = method_GET;
|
||||
rctx->expected_ct = expected_content_type;
|
||||
rctx->expect_asn1 = expect_asn1;
|
||||
rctx->resp_len = 0;
|
||||
OSSL_HTTP_REQ_CTX_set_max_response_length(rctx, max_resp_len);
|
||||
rctx->max_time = timeout > 0 ? time(NULL) + timeout : 0;
|
||||
return rctx;
|
||||
}
|
||||
|
||||
void OSSL_HTTP_REQ_CTX_free(OSSL_HTTP_REQ_CTX *rctx)
|
||||
{
|
||||
if (rctx == NULL)
|
||||
return;
|
||||
BIO_free(rctx->mem); /* this may indirectly call ERR_clear_error() */
|
||||
OPENSSL_free(rctx->iobuf);
|
||||
OPENSSL_free(rctx);
|
||||
}
|
||||
|
||||
BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(OSSL_HTTP_REQ_CTX *rctx)
|
||||
{
|
||||
if (rctx == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
return rctx->mem;
|
||||
}
|
||||
|
||||
void OSSL_HTTP_REQ_CTX_set_max_response_length(OSSL_HTTP_REQ_CTX *rctx,
|
||||
unsigned long len)
|
||||
{
|
||||
if (rctx == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return;
|
||||
}
|
||||
rctx->max_resp_len = len != 0 ? len : HTTP_DEFAULT_MAX_RESP_LEN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create HTTP header using given op and path (or "/" in case path is NULL).
|
||||
* Server name (and port) must be given if and only if plain HTTP proxy is used.
|
||||
*/
|
||||
int OSSL_HTTP_REQ_CTX_header(OSSL_HTTP_REQ_CTX *rctx, const char *server,
|
||||
const char *port, const char *path)
|
||||
{
|
||||
if (rctx == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (BIO_printf(rctx->mem, "%s ", rctx->method_GET ? "GET" : "POST") <= 0)
|
||||
return 0;
|
||||
|
||||
if (server != NULL) { /* HTTP (but not HTTPS) proxy is used */
|
||||
/*
|
||||
* Section 5.1.2 of RFC 1945 states that the absoluteURI form is only
|
||||
* allowed when using a proxy
|
||||
*/
|
||||
if (BIO_printf(rctx->mem, OSSL_HTTP_PREFIX"%s", server) <= 0)
|
||||
return 0;
|
||||
if (port != NULL && BIO_printf(rctx->mem, ":%s", port) <= 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Make sure path includes a forward slash */
|
||||
if (path == NULL)
|
||||
path = "/";
|
||||
if (path[0] != '/' && BIO_printf(rctx->mem, "/") <= 0)
|
||||
return 0;
|
||||
|
||||
if (BIO_printf(rctx->mem, "%s "HTTP_PREFIX"1.0\r\n", path) <= 0)
|
||||
return 0;
|
||||
rctx->state = OHS_HTTP_HEADER;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int OSSL_HTTP_REQ_CTX_add1_header(OSSL_HTTP_REQ_CTX *rctx,
|
||||
const char *name, const char *value)
|
||||
{
|
||||
if (rctx == NULL || name == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (BIO_puts(rctx->mem, name) <= 0)
|
||||
return 0;
|
||||
if (value != NULL) {
|
||||
if (BIO_write(rctx->mem, ": ", 2) != 2)
|
||||
return 0;
|
||||
if (BIO_puts(rctx->mem, value) <= 0)
|
||||
return 0;
|
||||
}
|
||||
if (BIO_write(rctx->mem, "\r\n", 2) != 2)
|
||||
return 0;
|
||||
rctx->state = OHS_HTTP_HEADER;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int OSSL_HTTP_REQ_CTX_content(OSSL_HTTP_REQ_CTX *rctx,
|
||||
const char *content_type, BIO *req_mem)
|
||||
{
|
||||
const unsigned char *req;
|
||||
long req_len;
|
||||
|
||||
if (rctx == NULL || req_mem == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (content_type != NULL
|
||||
&& BIO_printf(rctx->mem, "Content-Type: %s\r\n", content_type) <= 0)
|
||||
return 0;
|
||||
|
||||
if ((req_len = BIO_get_mem_data(req_mem, &req)) <= 0)
|
||||
return 0;
|
||||
rctx->state = OHS_WRITE_INIT;
|
||||
|
||||
return BIO_printf(rctx->mem, "Content-Length: %ld\r\n\r\n", req_len) > 0
|
||||
&& BIO_write(rctx->mem, req, req_len) == (int)req_len;
|
||||
}
|
||||
|
||||
BIO *HTTP_asn1_item2bio(const ASN1_ITEM *it, const ASN1_VALUE *val)
|
||||
{
|
||||
BIO *res;
|
||||
|
||||
if (it == NULL || val == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((res = BIO_new(BIO_s_mem())) == NULL)
|
||||
return NULL;
|
||||
if (ASN1_item_i2d_bio(it, res, val) <= 0) {
|
||||
BIO_free(res);
|
||||
res = NULL;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int OSSL_HTTP_REQ_CTX_i2d(OSSL_HTTP_REQ_CTX *rctx, const char *content_type,
|
||||
const ASN1_ITEM *it, ASN1_VALUE *req)
|
||||
{
|
||||
BIO *mem;
|
||||
int res;
|
||||
|
||||
if (rctx == NULL || it == NULL || req == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = (mem = HTTP_asn1_item2bio(it, req)) != NULL
|
||||
&& OSSL_HTTP_REQ_CTX_content(rctx, content_type, mem);
|
||||
BIO_free(mem);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int OSSL_HTTP_REQ_CTX_add1_headers(OSSL_HTTP_REQ_CTX *rctx,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
const char *host)
|
||||
{
|
||||
int i;
|
||||
int add_host = 1;
|
||||
CONF_VALUE *hdr;
|
||||
|
||||
for (i = 0; i < sk_CONF_VALUE_num(headers); i++) {
|
||||
hdr = sk_CONF_VALUE_value(headers, i);
|
||||
if (add_host && strcasecmp("host", hdr->name) == 0)
|
||||
add_host = 0;
|
||||
if (!OSSL_HTTP_REQ_CTX_add1_header(rctx, hdr->name, hdr->value))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (add_host && !OSSL_HTTP_REQ_CTX_add1_header(rctx, "Host", host))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Create OSSL_HTTP_REQ_CTX structure using the values provided.
|
||||
* If !use_http_proxy then the 'server' and 'port' parameters are ignored.
|
||||
* If req_mem == NULL then use GET and ignore content_type, else POST.
|
||||
*/
|
||||
OSSL_HTTP_REQ_CTX *HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int use_http_proxy,
|
||||
const char *server, const char *port,
|
||||
const char *path,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
const char *content_type, BIO *req_mem,
|
||||
int maxline, unsigned long max_resp_len,
|
||||
int timeout,
|
||||
const char *expected_content_type,
|
||||
int expect_asn1)
|
||||
{
|
||||
OSSL_HTTP_REQ_CTX *rctx;
|
||||
|
||||
if (use_http_proxy && (server == NULL || port == NULL)) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
/* remaining parameters are checked indirectly by the functions called */
|
||||
|
||||
if ((rctx = OSSL_HTTP_REQ_CTX_new(wbio, rbio, req_mem == NULL, maxline,
|
||||
max_resp_len, timeout,
|
||||
expected_content_type, expect_asn1))
|
||||
== NULL)
|
||||
return NULL;
|
||||
|
||||
if (OSSL_HTTP_REQ_CTX_header(rctx, use_http_proxy ? server : NULL,
|
||||
port, path)
|
||||
&& OSSL_HTTP_REQ_CTX_add1_headers(rctx, headers, server)
|
||||
&& (req_mem == NULL
|
||||
|| OSSL_HTTP_REQ_CTX_content(rctx, content_type, req_mem)))
|
||||
return rctx;
|
||||
|
||||
OSSL_HTTP_REQ_CTX_free(rctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse first HTTP response line. This should be like this: "HTTP/1.0 200 OK".
|
||||
* We need to obtain the numeric code and (optional) informational message.
|
||||
*/
|
||||
|
||||
static int parse_http_line1(char *line)
|
||||
{
|
||||
int retcode;
|
||||
char *code, *reason, *end;
|
||||
|
||||
/* Skip to first whitespace (past protocol info) */
|
||||
for (code = line; *code != '\0' && !ossl_isspace(*code); code++)
|
||||
continue;
|
||||
if (*code == '\0') {
|
||||
HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Skip past whitespace to start of response code */
|
||||
while (*code != '\0' && ossl_isspace(*code))
|
||||
code++;
|
||||
|
||||
if (*code == '\0') {
|
||||
HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find end of response code: first whitespace after start of code */
|
||||
for (reason = code; *reason != '\0' && !ossl_isspace(*reason); reason++)
|
||||
continue;
|
||||
|
||||
if (*reason == '\0') {
|
||||
HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set end of response code and start of message */
|
||||
*reason++ = '\0';
|
||||
|
||||
/* Attempt to parse numeric code */
|
||||
retcode = strtoul(code, &end, 10);
|
||||
|
||||
if (*end != '\0')
|
||||
return 0;
|
||||
|
||||
/* Skip over any leading whitespace in message */
|
||||
while (*reason != '\0' && ossl_isspace(*reason))
|
||||
reason++;
|
||||
|
||||
if (*reason != '\0') {
|
||||
/*
|
||||
* Finally zap any trailing whitespace in message (include CRLF)
|
||||
*/
|
||||
|
||||
/* chop any trailing whitespace from reason */
|
||||
/* We know reason has a non-whitespace character so this is OK */
|
||||
for (end = reason + strlen(reason) - 1; ossl_isspace(*end); end--)
|
||||
*end = '\0';
|
||||
}
|
||||
|
||||
switch (retcode) {
|
||||
case HTTP_STATUS_CODE_OK:
|
||||
case HTTP_STATUS_CODE_MOVED_PERMANENTLY:
|
||||
case HTTP_STATUS_CODE_FOUND:
|
||||
return retcode;
|
||||
default:
|
||||
if (retcode < 400)
|
||||
HTTPerr(0, HTTP_R_STATUS_CODE_UNSUPPORTED);
|
||||
else
|
||||
HTTPerr(0, HTTP_R_RECEIVED_ERROR);
|
||||
if (*reason == '\0')
|
||||
ERR_add_error_data(2, "Code=", code);
|
||||
else
|
||||
ERR_add_error_data(4, "Code=", code, ",Reason=", reason);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int check_set_resp_len(OSSL_HTTP_REQ_CTX *rctx, unsigned long len)
|
||||
{
|
||||
const char *tag = NULL;
|
||||
unsigned long val = 0;
|
||||
|
||||
if (len > rctx->max_resp_len) {
|
||||
HTTPerr(0, HTTP_R_MAX_RESP_LEN_EXCEEDED);
|
||||
tag = ",max=";
|
||||
val = rctx->max_resp_len;
|
||||
}
|
||||
if (rctx->resp_len != 0 && rctx->resp_len != len) {
|
||||
HTTPerr(0, HTTP_R_INCONSISTENT_CONTENT_LENGTH);
|
||||
tag = ",before=";
|
||||
val = rctx->resp_len;
|
||||
}
|
||||
if (tag != NULL) {
|
||||
char len_str[32];
|
||||
char str[32];
|
||||
|
||||
BIO_snprintf(len_str, sizeof(len_str), "%lu", len);
|
||||
BIO_snprintf(str, sizeof(str), "%lu", val);
|
||||
ERR_add_error_data(4, "length=", len_str, tag, str);
|
||||
return 0;
|
||||
}
|
||||
rctx->resp_len = len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try exchanging request and response via HTTP on (non-)blocking BIO in rctx.
|
||||
* Returns 1 on success, 0 on error or redirection, -1 on BIO_should_retry.
|
||||
*/
|
||||
int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
|
||||
{
|
||||
int i;
|
||||
long n, n_to_send = 0;
|
||||
unsigned long resp_len;
|
||||
const unsigned char *p;
|
||||
char *key, *value, *line_end = NULL;
|
||||
|
||||
if (rctx == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rctx->redirection_url = NULL;
|
||||
next_io:
|
||||
if ((rctx->state & OHS_NOREAD) == 0) {
|
||||
n = BIO_read(rctx->rbio, rctx->iobuf, rctx->iobuflen);
|
||||
if (n <= 0) {
|
||||
if (BIO_should_retry(rctx->rbio))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write data to memory BIO */
|
||||
if (BIO_write(rctx->mem, rctx->iobuf, n) != n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (rctx->state) {
|
||||
case OHS_HTTP_HEADER:
|
||||
/* Last operation was adding headers: need a final \r\n */
|
||||
if (BIO_write(rctx->mem, "\r\n", 2) != 2) {
|
||||
rctx->state = OHS_ERROR;
|
||||
return 0;
|
||||
}
|
||||
rctx->state = OHS_WRITE_INIT;
|
||||
|
||||
/* fall thru */
|
||||
case OHS_WRITE_INIT:
|
||||
n_to_send = BIO_get_mem_data(rctx->mem, NULL);
|
||||
rctx->state = OHS_WRITE;
|
||||
|
||||
/* fall thru */
|
||||
case OHS_WRITE:
|
||||
n = BIO_get_mem_data(rctx->mem, &p);
|
||||
|
||||
i = BIO_write(rctx->wbio, p + (n - n_to_send), n_to_send);
|
||||
|
||||
if (i <= 0) {
|
||||
if (BIO_should_retry(rctx->wbio))
|
||||
return -1;
|
||||
rctx->state = OHS_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
n_to_send -= i;
|
||||
|
||||
if (n_to_send > 0)
|
||||
goto next_io;
|
||||
|
||||
rctx->state = OHS_FLUSH;
|
||||
|
||||
(void)BIO_reset(rctx->mem);
|
||||
|
||||
/* fall thru */
|
||||
case OHS_FLUSH:
|
||||
|
||||
i = BIO_flush(rctx->wbio);
|
||||
|
||||
if (i > 0) {
|
||||
rctx->state = OHS_FIRSTLINE;
|
||||
goto next_io;
|
||||
}
|
||||
|
||||
if (BIO_should_retry(rctx->wbio))
|
||||
return -1;
|
||||
|
||||
rctx->state = OHS_ERROR;
|
||||
return 0;
|
||||
|
||||
case OHS_ERROR:
|
||||
return 0;
|
||||
|
||||
case OHS_FIRSTLINE:
|
||||
case OHS_HEADERS:
|
||||
case OHS_REDIRECT:
|
||||
|
||||
/* Attempt to read a line in */
|
||||
next_line:
|
||||
/*
|
||||
* Due to strange memory BIO behavior with BIO_gets we have to check
|
||||
* there's a complete line in there before calling BIO_gets or we'll
|
||||
* just get a partial read.
|
||||
*/
|
||||
n = BIO_get_mem_data(rctx->mem, &p);
|
||||
if (n <= 0 || memchr(p, '\n', n) == 0) {
|
||||
if (n >= rctx->iobuflen) {
|
||||
rctx->state = OHS_ERROR;
|
||||
return 0;
|
||||
}
|
||||
goto next_io;
|
||||
}
|
||||
n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen);
|
||||
|
||||
if (n <= 0) {
|
||||
if (BIO_should_retry(rctx->mem))
|
||||
goto next_io;
|
||||
rctx->state = OHS_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Don't allow excessive lines */
|
||||
if (n == rctx->iobuflen) {
|
||||
HTTPerr(0, HTTP_R_RESPONSE_LINE_TOO_LONG);
|
||||
rctx->state = OHS_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* First line */
|
||||
if (rctx->state == OHS_FIRSTLINE) {
|
||||
switch (parse_http_line1((char *)rctx->iobuf)) {
|
||||
case HTTP_STATUS_CODE_OK:
|
||||
rctx->state = OHS_HEADERS;
|
||||
goto next_line;
|
||||
case HTTP_STATUS_CODE_MOVED_PERMANENTLY:
|
||||
case HTTP_STATUS_CODE_FOUND: /* i.e., moved temporarily */
|
||||
if (rctx->method_GET) {
|
||||
rctx->state = OHS_REDIRECT;
|
||||
goto next_line;
|
||||
}
|
||||
HTTPerr(0, HTTP_R_REDIRECTION_NOT_ENABLED);
|
||||
/* redirection is not supported/recommended for POST */
|
||||
/* fall through */
|
||||
default:
|
||||
rctx->state = OHS_ERROR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
key = (char *)rctx->iobuf;
|
||||
value = strchr(key, ':');
|
||||
if (value != NULL) {
|
||||
*(value++) = '\0';
|
||||
while (ossl_isspace(*value))
|
||||
value++;
|
||||
line_end = strchr(value, '\r');
|
||||
if (line_end == NULL)
|
||||
line_end = strchr(value, '\n');
|
||||
if (line_end != NULL)
|
||||
*line_end = '\0';
|
||||
}
|
||||
if (value != NULL && line_end != NULL) {
|
||||
if (rctx->state == OHS_REDIRECT
|
||||
&& strcasecmp(key, "Location") == 0) {
|
||||
rctx->redirection_url = value;
|
||||
return 0;
|
||||
}
|
||||
if (rctx->expected_ct != NULL
|
||||
&& strcasecmp(key, "Content-Type") == 0) {
|
||||
if (strcasecmp(rctx->expected_ct, value) != 0) {
|
||||
HTTPerr(0, HTTP_R_UNEXPECTED_CONTENT_TYPE);
|
||||
ERR_add_error_data(4, "expected=", rctx->expected_ct,
|
||||
",actual=", value);
|
||||
return 0;
|
||||
}
|
||||
rctx->expected_ct = NULL; /* content-type has been found */
|
||||
}
|
||||
if (strcasecmp(key, "Content-Length") == 0) {
|
||||
resp_len = strtoul(value, &line_end, 10);
|
||||
if (line_end == value || *line_end != '\0') {
|
||||
HTTPerr(0, HTTP_R_ERROR_PARSING_CONTENT_LENGTH);
|
||||
ERR_add_error_data(2, "input=", value);
|
||||
return 0;
|
||||
}
|
||||
if (!check_set_resp_len(rctx, resp_len))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for blank line: end of headers */
|
||||
for (p = rctx->iobuf; *p != '\0'; p++) {
|
||||
if (*p != '\r' && *p != '\n')
|
||||
break;
|
||||
}
|
||||
if (*p != '\0') /* not end of headers */
|
||||
goto next_line;
|
||||
|
||||
if (rctx->expected_ct != NULL) {
|
||||
HTTPerr(0, HTTP_R_MISSING_CONTENT_TYPE);
|
||||
ERR_add_error_data(2, "expected=", rctx->expected_ct);
|
||||
return 0;
|
||||
}
|
||||
if (rctx->state == OHS_REDIRECT) {
|
||||
/* http status code indicated redirect but there was no Location */
|
||||
HTTPerr(0, HTTP_R_MISSING_REDIRECT_LOCATION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!rctx->expect_asn1) {
|
||||
rctx->state = OHS_CONTENT;
|
||||
goto content;
|
||||
}
|
||||
|
||||
rctx->state = OHS_ASN1_HEADER;
|
||||
|
||||
/* Fall thru */
|
||||
case OHS_ASN1_HEADER:
|
||||
/*
|
||||
* Now reading ASN1 header: can read at least 2 bytes which is enough
|
||||
* for ASN1 SEQUENCE header and either length field or at least the
|
||||
* length of the length field.
|
||||
*/
|
||||
n = BIO_get_mem_data(rctx->mem, &p);
|
||||
if (n < 2)
|
||||
goto next_io;
|
||||
|
||||
/* Check it is an ASN1 SEQUENCE */
|
||||
if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) {
|
||||
HTTPerr(0, HTTP_R_MISSING_ASN1_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check out length field */
|
||||
if ((*p & 0x80) != 0) {
|
||||
/*
|
||||
* If MSB set on initial length octet we can now always read 6
|
||||
* octets: make sure we have them.
|
||||
*/
|
||||
if (n < 6)
|
||||
goto next_io;
|
||||
n = *p & 0x7F;
|
||||
/* Not NDEF or excessive length */
|
||||
if (n == 0 || (n > 4)) {
|
||||
HTTPerr(0, HTTP_R_ERROR_PARSING_ASN1_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
p++;
|
||||
resp_len = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
resp_len <<= 8;
|
||||
resp_len |= *p++;
|
||||
}
|
||||
resp_len += n + 2;
|
||||
} else {
|
||||
resp_len = *p + 2;
|
||||
}
|
||||
if (!check_set_resp_len(rctx, resp_len))
|
||||
return 0;
|
||||
|
||||
content:
|
||||
rctx->state = OHS_CONTENT;
|
||||
|
||||
/* Fall thru */
|
||||
case OHS_CONTENT:
|
||||
default:
|
||||
n = BIO_get_mem_data(rctx->mem, NULL);
|
||||
if (n < (long)rctx->resp_len /* may be 0 if no Content-Type or ASN.1 */)
|
||||
goto next_io;
|
||||
|
||||
rctx->state = OHS_DONE;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
|
||||
/* set up a new connection BIO, to HTTP server or to HTTP(S) proxy if given */
|
||||
static BIO *HTTP_new_bio(const char *server /* optionally includes ":port" */,
|
||||
const char *server_port /* explicit server port */,
|
||||
const char *proxy /* optionally includes ":port" */)
|
||||
{
|
||||
const char *host = server, *host_end;
|
||||
char host_name[100];
|
||||
const char *port = server_port;
|
||||
BIO *cbio;
|
||||
|
||||
if (!ossl_assert(server != NULL))
|
||||
return NULL;
|
||||
|
||||
if (proxy != NULL) {
|
||||
host = proxy;
|
||||
port = NULL;
|
||||
}
|
||||
|
||||
host_end = strchr(host, '/');
|
||||
if (host_end != NULL && (size_t)(host_end - host) < sizeof(host_name)) {
|
||||
/* chop trailing string starting with '/' */
|
||||
strncpy(host_name, host, host_end - host + 1);
|
||||
host = host_name;
|
||||
}
|
||||
|
||||
cbio = BIO_new_connect(host /* optionally includes ":port" */);
|
||||
if (cbio == NULL)
|
||||
goto end;
|
||||
if (port != NULL)
|
||||
(void)BIO_set_conn_port(cbio, port);
|
||||
|
||||
end:
|
||||
return cbio;
|
||||
}
|
||||
#endif /* OPENSSL_NO_SOCK */
|
||||
|
||||
static ASN1_VALUE *BIO_mem_d2i(BIO *mem, const ASN1_ITEM *it)
|
||||
{
|
||||
const unsigned char *p;
|
||||
long len = BIO_get_mem_data(mem, &p);
|
||||
ASN1_VALUE *resp = ASN1_item_d2i(NULL, &p, len, it);
|
||||
|
||||
if (resp == NULL)
|
||||
HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR);
|
||||
return resp;
|
||||
}
|
||||
|
||||
static BIO *OSSL_HTTP_REQ_CTX_transfer(OSSL_HTTP_REQ_CTX *rctx)
|
||||
{
|
||||
int sending = 1;
|
||||
int rv;
|
||||
|
||||
if (rctx == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
rv = OSSL_HTTP_REQ_CTX_nbio(rctx);
|
||||
if (rv != -1)
|
||||
break;
|
||||
/* BIO_should_retry was true */
|
||||
sending = 0;
|
||||
/* will not actually wait if rctx->max_time == 0 */
|
||||
if (BIO_wait(rctx->rbio, rctx->max_time, 100 /* milliseconds */) <= 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (rv == 0) {
|
||||
if (rctx->redirection_url == NULL) { /* an error occurred */
|
||||
if (sending && (rctx->state & OHS_NOREAD) != 0)
|
||||
HTTPerr(0, HTTP_R_ERROR_SENDING);
|
||||
else
|
||||
HTTPerr(0, HTTP_R_ERROR_RECEIVING);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (!BIO_up_ref(rctx->mem))
|
||||
return NULL;
|
||||
return rctx->mem;
|
||||
}
|
||||
|
||||
/* Exchange ASN.1-encoded request and response via HTTP on (non-)blocking BIO */
|
||||
ASN1_VALUE *OSSL_HTTP_REQ_CTX_sendreq_d2i(OSSL_HTTP_REQ_CTX *rctx,
|
||||
const ASN1_ITEM *it)
|
||||
{
|
||||
if (rctx == NULL || it == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
return BIO_mem_d2i(OSSL_HTTP_REQ_CTX_transfer(rctx), it);
|
||||
}
|
||||
|
||||
static int update_timeout(int timeout, time_t start_time)
|
||||
{
|
||||
long elapsed_time;
|
||||
|
||||
if (timeout == 0)
|
||||
return 0;
|
||||
elapsed_time = (long)(time(NULL) - start_time); /* this might overflow */
|
||||
return timeout <= elapsed_time ? -1 : timeout - elapsed_time;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Exchange HTTP request and response with the given server.
|
||||
* If req_mem == NULL then use GET and ignore content_type, else POST.
|
||||
* The redirection_url output (freed by caller) parameter is used only for GET.
|
||||
*
|
||||
* Typically the bio and rbio parameters are NULL and a network BIO is created
|
||||
* internally for connecting to the given server and port, optionally via a
|
||||
* proxy and its port, and is then used for exchanging the request and response.
|
||||
* If bio is given and rbio is NULL then this BIO is used instead.
|
||||
* If both bio and rbio are given (which may be memory BIOs for instance)
|
||||
* then no explicit connection is attempted,
|
||||
* bio is used for writing the request, and rbio for reading the response.
|
||||
*
|
||||
* bio_update_fn is an optional BIO connect/disconnect callback function,
|
||||
* which has the prototype
|
||||
* BIO *(*OSSL_HTTP_bio_cb_t) (BIO *bio, void *arg, int conn, int detail);
|
||||
* The callback may modify the HTTP BIO provided in the bio argument,
|
||||
* whereby it may make use of any custom defined argument 'arg'.
|
||||
* During connection establishment, just after BIO_connect_retry(),
|
||||
* the callback function is invoked with the 'conn' argument being 1
|
||||
* 'detail' indicating whether a HTTPS (i.e., TLS) connection is requested.
|
||||
* On disconnect 'conn' is 0 and 'detail' indicates that no error occurred.
|
||||
* For instance, on connect the funct may prepend a TLS BIO to implement HTTPS;
|
||||
* after disconnect it may do some error diagnostics and/or specific cleanup.
|
||||
* The function should return NULL to indicate failure.
|
||||
* After disconnect the modified BIO will be deallocated using BIO_free_all().
|
||||
*/
|
||||
BIO *OSSL_HTTP_transfer(const char *server, const char *port, const char *path,
|
||||
int use_ssl, const char *proxy, const char *no_proxy,
|
||||
BIO *bio, BIO *rbio,
|
||||
OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
const char *content_type, BIO *req_mem,
|
||||
int maxline, unsigned long max_resp_len, int timeout,
|
||||
const char *expected_ct, int expect_asn1,
|
||||
char **redirection_url)
|
||||
{
|
||||
time_t start_time = timeout > 0 ? time(NULL) : 0;
|
||||
BIO *cbio; /* = bio if present, used as connection BIO if rbio is NULL */
|
||||
OSSL_HTTP_REQ_CTX *rctx;
|
||||
BIO *resp = NULL;
|
||||
|
||||
if (redirection_url != NULL)
|
||||
*redirection_url = NULL; /* do this beforehand to prevent dbl free */
|
||||
|
||||
if (use_ssl && bio_update_fn == NULL) {
|
||||
HTTPerr(0, HTTP_R_TLS_NOT_ENABLED);
|
||||
return NULL;
|
||||
}
|
||||
if (rbio != NULL && (bio == NULL || bio_update_fn != NULL)) {
|
||||
HTTPerr(0, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bio != NULL) {
|
||||
cbio = bio;
|
||||
} else {
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
if (server == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
if (*port == '\0')
|
||||
port = NULL;
|
||||
if (port == NULL && strchr(server, ':') == NULL)
|
||||
port = use_ssl ? OSSL_HTTPS_PORT : OSSL_HTTP_PORT;
|
||||
proxy = http_adapt_proxy(proxy, no_proxy, server, use_ssl);
|
||||
if ((cbio = HTTP_new_bio(server, port, proxy)) == NULL)
|
||||
return NULL;
|
||||
#else
|
||||
HTTPerr(0, HTTP_R_SOCK_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
/* remaining parameters are checked indirectly by the functions called */
|
||||
|
||||
(void)ERR_set_mark(); /* prepare removing any spurious libssl errors */
|
||||
if (rbio == NULL && BIO_connect_retry(cbio, timeout) <= 0)
|
||||
goto end;
|
||||
/* now timeout is guaranteed to be >= 0 */
|
||||
|
||||
/* callback can be used to wrap or prepend TLS session */
|
||||
if (bio_update_fn != NULL) {
|
||||
BIO *orig_bio = cbio;
|
||||
cbio = (*bio_update_fn)(cbio, arg, 1 /* connect */, use_ssl);
|
||||
if (cbio == NULL) {
|
||||
cbio = orig_bio;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
rctx = HTTP_REQ_CTX_new(cbio, rbio != NULL ? rbio : cbio,
|
||||
!use_ssl && proxy != NULL, server, port, path,
|
||||
headers, content_type, req_mem, maxline,
|
||||
max_resp_len, update_timeout(timeout, start_time),
|
||||
expected_ct, expect_asn1);
|
||||
if (rctx == NULL)
|
||||
goto end;
|
||||
|
||||
resp = OSSL_HTTP_REQ_CTX_transfer(rctx);
|
||||
if (resp == NULL) {
|
||||
if (rctx->redirection_url != NULL) {
|
||||
if (redirection_url == NULL)
|
||||
HTTPerr(0, HTTP_R_REDIRECTION_NOT_ENABLED);
|
||||
else
|
||||
/* may be NULL if out of memory: */
|
||||
*redirection_url = OPENSSL_strdup(rctx->redirection_url);
|
||||
} else {
|
||||
char buf[200];
|
||||
unsigned long err = ERR_peek_error();
|
||||
int lib = ERR_GET_LIB(err);
|
||||
int reason = ERR_GET_REASON(err);
|
||||
|
||||
if (lib == ERR_LIB_SSL || lib == ERR_LIB_HTTP
|
||||
|| (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_TIMEOUT)
|
||||
|| (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_ERROR)
|
||||
#ifndef OPENSSL_NO_CMP
|
||||
|| (lib == ERR_LIB_CMP
|
||||
&& reason == CMP_R_POTENTIALLY_INVALID_CERTIFICATE)
|
||||
#endif
|
||||
) {
|
||||
BIO_snprintf(buf, 200, "server=%s:%s", server, port);
|
||||
ERR_add_error_data(1, buf);
|
||||
if (proxy != NULL)
|
||||
ERR_add_error_data(2, " proxy=", proxy);
|
||||
if (err == 0) {
|
||||
BIO_snprintf(buf, 200, " peer has disconnected%s",
|
||||
use_ssl ? " violating the protocol" :
|
||||
", likely because it requires the use of TLS");
|
||||
ERR_add_error_data(1, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
OSSL_HTTP_REQ_CTX_free(rctx);
|
||||
|
||||
/* callback can be used to clean up TLS session */
|
||||
if (bio_update_fn != NULL
|
||||
&& (*bio_update_fn)(cbio, arg, 0, resp != NULL) == NULL) {
|
||||
BIO_free(resp);
|
||||
resp = NULL;
|
||||
}
|
||||
|
||||
end:
|
||||
/*
|
||||
* Use BIO_free_all() because bio_update_fn may prepend or append to cbio.
|
||||
* This also frees any (e.g., SSL/TLS) BIOs linked with bio and,
|
||||
* like BIO_reset(bio), calls SSL_shutdown() to notify/alert the peer.
|
||||
*/
|
||||
if (bio == NULL) /* cbio was not provided by caller */
|
||||
BIO_free_all(cbio);
|
||||
|
||||
if (resp != NULL)
|
||||
/* remove any spurious error queue entries by ssl_add_cert_chain() */
|
||||
(void)ERR_pop_to_mark();
|
||||
else
|
||||
(void)ERR_clear_last_mark();
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
static int redirection_ok(int n_redir, const char *old_url, const char *new_url)
|
||||
{
|
||||
size_t https_len = strlen(OSSL_HTTPS_NAME":");
|
||||
|
||||
if (n_redir >= HTTP_VERSION_MAX_REDIRECTIONS) {
|
||||
HTTPerr(0, HTTP_R_TOO_MANY_REDIRECTIONS);
|
||||
return 0;
|
||||
}
|
||||
if (*new_url == '/') /* redirection to same server => same protocol */
|
||||
return 1;
|
||||
if (strncmp(old_url, OSSL_HTTPS_NAME":", https_len) == 0 &&
|
||||
strncmp(new_url, OSSL_HTTPS_NAME":", https_len) != 0) {
|
||||
HTTPerr(0, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get data via HTTP from server at given URL, potentially with redirection */
|
||||
BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,
|
||||
BIO *bio, BIO *rbio,
|
||||
OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
int maxline, unsigned long max_resp_len, int timeout,
|
||||
const char *expected_content_type, int expect_asn1)
|
||||
{
|
||||
time_t start_time = timeout > 0 ? time(NULL) : 0;
|
||||
char *current_url, *redirection_url;
|
||||
int n_redirs = 0;
|
||||
char *host;
|
||||
char *port;
|
||||
char *path;
|
||||
int use_ssl;
|
||||
BIO *resp = NULL;
|
||||
|
||||
if (url == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
if ((current_url = OPENSSL_strdup(url)) == NULL)
|
||||
return NULL;
|
||||
|
||||
for (;;) {
|
||||
if (!OSSL_HTTP_parse_url(current_url, &host, &port, &path, &use_ssl))
|
||||
break;
|
||||
|
||||
new_rpath:
|
||||
resp = OSSL_HTTP_transfer(host, port, path, use_ssl, proxy, no_proxy,
|
||||
bio, rbio,
|
||||
bio_update_fn, arg, headers, NULL, NULL,
|
||||
maxline, max_resp_len,
|
||||
update_timeout(timeout, start_time),
|
||||
expected_content_type, expect_asn1,
|
||||
&redirection_url);
|
||||
OPENSSL_free(path);
|
||||
if (resp == NULL && redirection_url != NULL) {
|
||||
if (redirection_ok(++n_redirs, current_url, redirection_url)) {
|
||||
(void)BIO_reset(bio);
|
||||
OPENSSL_free(current_url);
|
||||
current_url = redirection_url;
|
||||
if (*redirection_url == '/') { /* redirection to same server */
|
||||
path = OPENSSL_strdup(redirection_url);
|
||||
goto new_rpath;
|
||||
}
|
||||
OPENSSL_free(host);
|
||||
OPENSSL_free(port);
|
||||
continue;
|
||||
}
|
||||
OPENSSL_free(redirection_url);
|
||||
}
|
||||
OPENSSL_free(host);
|
||||
OPENSSL_free(port);
|
||||
break;
|
||||
}
|
||||
OPENSSL_free(current_url);
|
||||
return resp;
|
||||
}
|
||||
|
||||
/* Get ASN.1-encoded data via HTTP from server at given URL */
|
||||
ASN1_VALUE *OSSL_HTTP_get_asn1(const char *url,
|
||||
const char *proxy, const char *no_proxy,
|
||||
BIO *bio, BIO *rbio,
|
||||
OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
int maxline, unsigned long max_resp_len,
|
||||
int timeout, const char *expected_content_type,
|
||||
const ASN1_ITEM *it)
|
||||
{
|
||||
BIO *mem;
|
||||
ASN1_VALUE *resp = NULL;
|
||||
|
||||
if (url == NULL || it == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
if ((mem = OSSL_HTTP_get(url, proxy, no_proxy, bio, rbio, bio_update_fn,
|
||||
arg, headers, maxline, max_resp_len, timeout,
|
||||
expected_content_type, 1 /* expect_asn1 */))
|
||||
!= NULL)
|
||||
resp = BIO_mem_d2i(mem, it);
|
||||
BIO_free(mem);
|
||||
return resp;
|
||||
}
|
||||
|
||||
/* Post ASN.1-encoded request via HTTP to server return ASN.1 response */
|
||||
ASN1_VALUE *OSSL_HTTP_post_asn1(const char *server, const char *port,
|
||||
const char *path, int use_ssl,
|
||||
const char *proxy, const char *no_proxy,
|
||||
BIO *bio, BIO *rbio,
|
||||
OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
const char *content_type,
|
||||
const ASN1_VALUE *req, const ASN1_ITEM *req_it,
|
||||
int maxline, unsigned long max_resp_len,
|
||||
int timeout, const char *expected_ct,
|
||||
const ASN1_ITEM *rsp_it)
|
||||
{
|
||||
BIO *req_mem;
|
||||
BIO *res_mem;
|
||||
ASN1_VALUE *resp = NULL;
|
||||
|
||||
if (req == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
/* remaining parameters are checked indirectly */
|
||||
|
||||
req_mem = HTTP_asn1_item2bio(req_it, req);
|
||||
res_mem = OSSL_HTTP_transfer(server, port, path, use_ssl, proxy, no_proxy,
|
||||
bio, rbio,
|
||||
bio_update_fn, arg, headers, content_type,
|
||||
req_mem /* may be NULL */, maxline,
|
||||
max_resp_len, timeout,
|
||||
expected_ct, 1 /* expect_asn1 */, NULL);
|
||||
BIO_free(req_mem);
|
||||
if (res_mem != NULL)
|
||||
resp = BIO_mem_d2i(res_mem, rsp_it);
|
||||
BIO_free(res_mem);
|
||||
return resp;
|
||||
}
|
||||
|
||||
/* BASE64 encoder used for encoding basic proxy authentication credentials */
|
||||
static char *base64encode(const void *buf, size_t len)
|
||||
{
|
||||
int i;
|
||||
size_t outl;
|
||||
char *out;
|
||||
|
||||
/* Calculate size of encoded data */
|
||||
outl = (len / 3);
|
||||
if (len % 3 > 0)
|
||||
outl++;
|
||||
outl <<= 2;
|
||||
out = OPENSSL_malloc(outl + 1);
|
||||
if (out == NULL)
|
||||
return 0;
|
||||
|
||||
i = EVP_EncodeBlock((unsigned char *)out, buf, len);
|
||||
if (!ossl_assert(0 <= i && (size_t)i <= outl)) {
|
||||
OPENSSL_free(out);
|
||||
return NULL;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Promote the given connection BIO using the CONNECT method for a TLS proxy.
|
||||
* This is typically called by an app, so bio_err and prog are used unless NULL
|
||||
* to print additional diagnostic information in a user-oriented way.
|
||||
*/
|
||||
int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
|
||||
const char *proxyuser, const char *proxypass,
|
||||
int timeout, BIO *bio_err, const char *prog)
|
||||
{
|
||||
#undef BUF_SIZE
|
||||
#define BUF_SIZE (8 * 1024)
|
||||
char *mbuf = OPENSSL_malloc(BUF_SIZE);
|
||||
char *mbufp;
|
||||
int read_len = 0;
|
||||
int ret = 0;
|
||||
BIO *fbio = BIO_new(BIO_f_buffer());
|
||||
int rv;
|
||||
time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
|
||||
|
||||
if (bio == NULL || server == NULL
|
||||
|| (bio_err != NULL && prog == NULL)) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
goto end;
|
||||
}
|
||||
if (port == NULL || *port == '\0')
|
||||
port = OSSL_HTTPS_PORT;
|
||||
|
||||
if (mbuf == NULL || fbio == NULL) {
|
||||
BIO_printf(bio_err /* may be NULL */, "%s: out of memory", prog);
|
||||
goto end;
|
||||
}
|
||||
BIO_push(fbio, bio);
|
||||
|
||||
BIO_printf(fbio, "CONNECT %s:%s "HTTP_PREFIX"1.0\r\n", server, port);
|
||||
|
||||
/*
|
||||
* Workaround for broken proxies which would otherwise close
|
||||
* the connection when entering tunnel mode (e.g., Squid 2.6)
|
||||
*/
|
||||
BIO_printf(fbio, "Proxy-Connection: Keep-Alive\r\n");
|
||||
|
||||
/* Support for basic (base64) proxy authentication */
|
||||
if (proxyuser != NULL) {
|
||||
size_t len = strlen(proxyuser) + 1;
|
||||
char *proxyauth, *proxyauthenc = NULL;
|
||||
|
||||
if (proxypass != NULL)
|
||||
len += strlen(proxypass);
|
||||
proxyauth = OPENSSL_malloc(len + 1);
|
||||
if (proxyauth == NULL)
|
||||
goto end;
|
||||
if (BIO_snprintf(proxyauth, len + 1, "%s:%s", proxyuser,
|
||||
proxypass != NULL ? proxypass : "") != (int)len)
|
||||
goto proxy_end;
|
||||
proxyauthenc = base64encode(proxyauth, len);
|
||||
if (proxyauthenc != NULL) {
|
||||
BIO_printf(fbio, "Proxy-Authorization: Basic %s\r\n", proxyauthenc);
|
||||
OPENSSL_clear_free(proxyauthenc, strlen(proxyauthenc));
|
||||
}
|
||||
proxy_end:
|
||||
OPENSSL_clear_free(proxyauth, len);
|
||||
if (proxyauthenc == NULL)
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Terminate the HTTP CONNECT request */
|
||||
BIO_printf(fbio, "\r\n");
|
||||
|
||||
for (;;) {
|
||||
if (BIO_flush(fbio) != 0)
|
||||
break;
|
||||
/* potentially needs to be retried if BIO is non-blocking */
|
||||
if (!BIO_should_retry(fbio))
|
||||
break;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
/* will not actually wait if timeout == 0 */
|
||||
rv = BIO_wait(fbio, max_time, 100 /* milliseconds */);
|
||||
if (rv <= 0) {
|
||||
BIO_printf(bio_err, "%s: HTTP CONNECT %s\n", prog,
|
||||
rv == 0 ? "timed out" : "failed waiting for data");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*-
|
||||
* The first line is the HTTP response.
|
||||
* According to RFC 7230, it is formatted exactly like this:
|
||||
* HTTP/d.d ddd Reason text\r\n
|
||||
*/
|
||||
read_len = BIO_gets(fbio, mbuf, BUF_SIZE);
|
||||
/* the BIO may not block, so we must wait for the 1st line to come in */
|
||||
if (read_len < HTTP_LINE1_MINLEN)
|
||||
continue;
|
||||
|
||||
/* RFC 7231 4.3.6: any 2xx status code is valid */
|
||||
if (strncmp(mbuf, HTTP_PREFIX, strlen(HTTP_PREFIX)) != 0) {
|
||||
HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR);
|
||||
BIO_printf(bio_err, "%s: HTTP CONNECT failed, non-HTTP response\n",
|
||||
prog);
|
||||
/* Wrong protocol, not even HTTP, so stop reading headers */
|
||||
goto end;
|
||||
}
|
||||
mbufp = mbuf + strlen(HTTP_PREFIX);
|
||||
if (strncmp(mbufp, HTTP_VERSION_PATT, strlen(HTTP_VERSION_PATT)) != 0) {
|
||||
HTTPerr(0, HTTP_R_RECEIVED_WRONG_HTTP_VERSION);
|
||||
BIO_printf(bio_err,
|
||||
"%s: HTTP CONNECT failed, bad HTTP version %.*s\n",
|
||||
prog, HTTP_VERSION_STR_LEN, mbufp);
|
||||
goto end;
|
||||
}
|
||||
mbufp += HTTP_VERSION_STR_LEN;
|
||||
if (strncmp(mbufp, " 2", strlen(" 2")) != 0) {
|
||||
mbufp += 1;
|
||||
/* chop any trailing whitespace */
|
||||
while (read_len > 0 && ossl_isspace(mbuf[read_len - 1]))
|
||||
read_len--;
|
||||
mbuf[read_len] = '\0';
|
||||
HTTPerr(0, HTTP_R_CONNECT_FAILURE);
|
||||
ERR_add_error_data(2, "Reason=", mbufp);
|
||||
BIO_printf(bio_err, "%s: HTTP CONNECT failed, Reason=%s\n",
|
||||
prog, mbufp);
|
||||
goto end;
|
||||
}
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read past all following headers */
|
||||
do {
|
||||
/*
|
||||
* TODO: This does not necessarily catch the case when the full
|
||||
* HTTP response came in in more than a single TCP message.
|
||||
*/
|
||||
read_len = BIO_gets(fbio, mbuf, BUF_SIZE);
|
||||
} while (read_len > 2);
|
||||
|
||||
end:
|
||||
if (fbio != NULL) {
|
||||
(void)BIO_flush(fbio);
|
||||
BIO_pop(fbio);
|
||||
BIO_free(fbio);
|
||||
}
|
||||
OPENSSL_free(mbuf);
|
||||
return ret;
|
||||
#undef BUF_SIZE
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/httperr.h>
|
||||
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
static const ERR_STRING_DATA HTTP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN),
|
||||
"asn1 len exceeds max resp len"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_CONNECT_FAILURE), "connect failure"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_PARSING_ASN1_LENGTH),
|
||||
"error parsing asn1 length"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_PARSING_CONTENT_LENGTH),
|
||||
"error parsing content length"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_PARSING_URL), "error parsing url"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_RECEIVING), "error receiving"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_SENDING), "error sending"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INCONSISTENT_CONTENT_LENGTH),
|
||||
"inconsistent content length"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MAX_RESP_LEN_EXCEEDED),
|
||||
"max resp len exceeded"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_ASN1_ENCODING),
|
||||
"missing asn1 encoding"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_CONTENT_TYPE),
|
||||
"missing content type"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_REDIRECT_LOCATION),
|
||||
"missing redirect location"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RECEIVED_ERROR), "received error"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RECEIVED_WRONG_HTTP_VERSION),
|
||||
"received wrong http version"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP),
|
||||
"redirection from https to http"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_REDIRECTION_NOT_ENABLED),
|
||||
"redirection not enabled"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_LINE_TOO_LONG),
|
||||
"response line too long"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_PARSE_ERROR),
|
||||
"response parse error"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SOCK_NOT_SUPPORTED),
|
||||
"sock not supported"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_STATUS_CODE_UNSUPPORTED),
|
||||
"status code unsupported"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_TLS_NOT_ENABLED), "tls not enabled"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_TOO_MANY_REDIRECTIONS),
|
||||
"too many redirections"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_UNEXPECTED_CONTENT_TYPE),
|
||||
"unexpected content type"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
int ERR_load_HTTP_strings(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
if (ERR_reason_error_string(HTTP_str_reasons[0].error) == NULL)
|
||||
ERR_load_strings_const(HTTP_str_reasons);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/http.h>
|
||||
#include <openssl/httperr.h>
|
||||
#include <openssl/err.h>
|
||||
#include <string.h>
|
||||
#include "internal/cryptlib.h" /* for ossl_assert() */
|
||||
|
||||
#include "http_local.h"
|
||||
|
||||
/*
|
||||
* Parse a URL and split it up into host, port and path components and
|
||||
* whether it indicates SSL/TLS. Return 1 on success, 0 on error.
|
||||
*/
|
||||
|
||||
int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport,
|
||||
char **ppath, int *pssl)
|
||||
{
|
||||
char *p, *buf;
|
||||
char *host;
|
||||
const char *port = OSSL_HTTP_PORT;
|
||||
size_t https_len = strlen(OSSL_HTTPS_NAME);
|
||||
|
||||
if (!ossl_assert(https_len >= strlen(OSSL_HTTP_NAME)))
|
||||
return 0;
|
||||
if (url == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (phost != NULL)
|
||||
*phost = NULL;
|
||||
if (pport != NULL)
|
||||
*pport = NULL;
|
||||
if (ppath != NULL)
|
||||
*ppath = NULL;
|
||||
if (pssl != NULL)
|
||||
*pssl = 0;
|
||||
|
||||
/* dup the buffer since we are going to mess with it */
|
||||
if ((buf = OPENSSL_strdup(url)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* Check for initial colon */
|
||||
p = strchr(buf, ':');
|
||||
if (p == NULL || (size_t)(p - buf) > https_len) {
|
||||
p = buf;
|
||||
} else {
|
||||
*(p++) = '\0';
|
||||
|
||||
if (strcmp(buf, OSSL_HTTPS_NAME) == 0) {
|
||||
if (pssl != NULL)
|
||||
*pssl = 1;
|
||||
port = OSSL_HTTPS_PORT;
|
||||
} else if (strcmp(buf, OSSL_HTTP_NAME) != 0) {
|
||||
goto parse_err;
|
||||
}
|
||||
|
||||
/* Check for double slash */
|
||||
if ((p[0] != '/') || (p[1] != '/'))
|
||||
goto parse_err;
|
||||
p += 2;
|
||||
}
|
||||
host = p;
|
||||
|
||||
/* Check for trailing part of path */
|
||||
p = strchr(p, '/');
|
||||
if (ppath != NULL && (*ppath = OPENSSL_strdup(p == NULL ? "/" : p)) == NULL)
|
||||
goto err;
|
||||
if (p != NULL)
|
||||
*p = '\0'; /* Set start of path to 0 so hostname[:port] is valid */
|
||||
|
||||
p = host;
|
||||
if (host[0] == '[') {
|
||||
/* ipv6 literal */
|
||||
host++;
|
||||
p = strchr(host, ']');
|
||||
if (p == NULL)
|
||||
goto parse_err;
|
||||
*p = '\0';
|
||||
p++;
|
||||
}
|
||||
|
||||
/* Look for optional ':' for port number */
|
||||
if ((p = strchr(p, ':'))) {
|
||||
*p = '\0';
|
||||
port = p + 1;
|
||||
}
|
||||
if (phost != NULL && (*phost = OPENSSL_strdup(host)) == NULL)
|
||||
goto err;
|
||||
if (pport != NULL && (*pport = OPENSSL_strdup(port)) == NULL)
|
||||
goto err;
|
||||
|
||||
OPENSSL_free(buf);
|
||||
return 1;
|
||||
|
||||
parse_err:
|
||||
HTTPerr(0, HTTP_R_ERROR_PARSING_URL);
|
||||
|
||||
err:
|
||||
if (ppath != NULL) {
|
||||
OPENSSL_free(*ppath);
|
||||
*ppath = NULL;
|
||||
}
|
||||
if (pport != NULL) {
|
||||
OPENSSL_free(*pport);
|
||||
*pport = NULL;
|
||||
}
|
||||
if (phost != NULL) {
|
||||
OPENSSL_free(*phost);
|
||||
*phost = NULL;
|
||||
}
|
||||
OPENSSL_free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int http_use_proxy(const char *no_proxy, const char *server)
|
||||
{
|
||||
size_t sl;
|
||||
const char *found = NULL;
|
||||
|
||||
if (!ossl_assert(server != NULL))
|
||||
return 0;
|
||||
sl = strlen(server);
|
||||
|
||||
/*
|
||||
* using environment variable names, both lowercase and uppercase variants,
|
||||
* compatible with other HTTP client implementations like wget, curl and git
|
||||
*/
|
||||
if (no_proxy == NULL)
|
||||
no_proxy = getenv("no_proxy");
|
||||
if (no_proxy == NULL)
|
||||
no_proxy = getenv(OPENSSL_NO_PROXY);
|
||||
if (no_proxy != NULL)
|
||||
found = strstr(no_proxy, server);
|
||||
while (found != NULL
|
||||
&& ((found != no_proxy && found[-1] != ' ' && found[-1] != ',')
|
||||
|| (found[sl] != '\0' && found[sl] != ' ' && found[sl] != ',')))
|
||||
found = strstr(found + 1, server);
|
||||
return found == NULL;
|
||||
}
|
||||
|
||||
const char *http_adapt_proxy(const char *proxy, const char *no_proxy,
|
||||
const char *server, int use_ssl)
|
||||
{
|
||||
const int http_len = strlen(OSSL_HTTP_PREFIX);
|
||||
const int https_len = strlen(OSSL_HTTPS_PREFIX);
|
||||
|
||||
/*
|
||||
* using environment variable names, both lowercase and uppercase variants,
|
||||
* compatible with other HTTP client implementations like wget, curl and git
|
||||
*/
|
||||
if (proxy == NULL)
|
||||
proxy = getenv(use_ssl ? "https_proxy" : "http_proxy");
|
||||
if (proxy == NULL)
|
||||
proxy = getenv(use_ssl ? OPENSSL_HTTP_PROXY :
|
||||
OPENSSL_HTTPS_PROXY);
|
||||
if (proxy == NULL)
|
||||
return NULL;
|
||||
|
||||
/* skip any leading "http://" or "https://" */
|
||||
if (strncmp(proxy, OSSL_HTTP_PREFIX, http_len) == 0)
|
||||
proxy += http_len;
|
||||
else if (strncmp(proxy, OSSL_HTTPS_PREFIX, https_len) == 0)
|
||||
proxy += https_len;
|
||||
|
||||
if (*proxy == '\0' || !http_use_proxy(no_proxy, server))
|
||||
return NULL;
|
||||
return proxy;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright Siemens AG 2018-2020
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#ifndef OSSL_CRYPTO_HTTP_LOCAL_H
|
||||
# define OSSL_CRYPTO_HTTP_LOCAL_H
|
||||
|
||||
# include <openssl/ocsp.h>
|
||||
|
||||
/* name aliases for legacy names with name prefix "OCSP_" */
|
||||
typedef OCSP_REQ_CTX OSSL_HTTP_REQ_CTX;
|
||||
/* functions meanwhile only used internally */
|
||||
# define OSSL_HTTP_REQ_CTX_new OCSP_REQ_CTX_new
|
||||
# define OSSL_HTTP_REQ_CTX_free OCSP_REQ_CTX_free
|
||||
# define OSSL_HTTP_REQ_CTX_header OCSP_REQ_CTX_http
|
||||
# define OSSL_HTTP_REQ_CTX_add1_header OCSP_REQ_CTX_add1_header
|
||||
# define OSSL_HTTP_REQ_CTX_i2d OCSP_REQ_CTX_i2d
|
||||
# define OSSL_HTTP_REQ_CTX_nbio OCSP_REQ_CTX_nbio
|
||||
# define OSSL_HTTP_REQ_CTX_sendreq_d2i OCSP_REQ_CTX_nbio_d2i
|
||||
/* functions that are meanwhile unused */
|
||||
# define OSSL_HTTP_REQ_CTX_get0_mem_bio OCSP_REQ_CTX_get0_mem_bio /* undoc'd */
|
||||
# define OSSL_HTTP_REQ_CTX_set_max_response_length OCSP_set_max_response_length
|
||||
|
||||
BIO *HTTP_asn1_item2bio(const ASN1_ITEM *it, const ASN1_VALUE *val);
|
||||
OSSL_HTTP_REQ_CTX *HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int use_http_proxy,
|
||||
const char *server, const char *port,
|
||||
const char *path,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
const char *content_type, BIO *req_mem,
|
||||
int maxline, unsigned long max_resp_len,
|
||||
int timeout,
|
||||
const char *expected_content_type,
|
||||
int expect_asn1);
|
||||
ASN1_VALUE *HTTP_sendreq_bio(BIO *bio, OSSL_HTTP_bio_cb_t bio_update_fn,
|
||||
void *arg, const char *server, const char *port,
|
||||
const char *path, int use_ssl, int use_proxy,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
const char *content_type,
|
||||
ASN1_VALUE *req, const ASN1_ITEM *req_it,
|
||||
int maxline, unsigned long max_resp_len,
|
||||
int timeout, const ASN1_ITEM *rsp_it);
|
||||
int http_use_proxy(const char *no_proxy, const char *server);
|
||||
const char *http_adapt_proxy(const char *proxy, const char *no_proxy,
|
||||
const char *server, int use_ssl);
|
||||
|
||||
#endif /* !defined(OSSL_CRYPTO_HTTP_LOCAL_H) */
|
||||
+15
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -15,6 +15,12 @@
|
||||
# define STRICT_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !STRICT_ALIGNMENT
|
||||
typedef size_t size_t_aX __attribute((__aligned__(1)));
|
||||
#else
|
||||
typedef size_t size_t_aX;
|
||||
#endif
|
||||
|
||||
void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
unsigned char ivec[16], block128_f block)
|
||||
@@ -40,8 +46,8 @@ void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
} else {
|
||||
while (len >= 16) {
|
||||
for (n = 0; n < 16; n += sizeof(size_t))
|
||||
*(size_t *)(out + n) =
|
||||
*(size_t *)(in + n) ^ *(size_t *)(iv + n);
|
||||
*(size_t_aX *)(out + n) =
|
||||
*(size_t_aX *)(in + n) ^ *(size_t_aX *)(iv + n);
|
||||
(*block) (out, out, key);
|
||||
iv = out;
|
||||
len -= 16;
|
||||
@@ -96,7 +102,8 @@ void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
|
||||
}
|
||||
} else if (16 % sizeof(size_t) == 0) { /* always true */
|
||||
while (len >= 16) {
|
||||
size_t *out_t = (size_t *)out, *iv_t = (size_t *)iv;
|
||||
size_t_aX *out_t = (size_t_aX *)out;
|
||||
size_t_aX *iv_t = (size_t_aX *)iv;
|
||||
|
||||
(*block) (in, out, key);
|
||||
for (n = 0; n < 16 / sizeof(size_t); n++)
|
||||
@@ -125,8 +132,10 @@ void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
|
||||
}
|
||||
} else if (16 % sizeof(size_t) == 0) { /* always true */
|
||||
while (len >= 16) {
|
||||
size_t c, *out_t = (size_t *)out, *ivec_t = (size_t *)ivec;
|
||||
const size_t *in_t = (const size_t *)in;
|
||||
size_t c;
|
||||
size_t_aX *out_t = (size_t_aX *)out;
|
||||
size_t_aX *ivec_t = (size_t_aX *)ivec;
|
||||
const size_t_aX *in_t = (const size_t_aX *)in;
|
||||
|
||||
(*block) (in, tmp.c, key);
|
||||
for (n = 0; n < 16 / sizeof(size_t); n++) {
|
||||
|
||||
+17
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,14 @@
|
||||
#include <openssl/crypto.h>
|
||||
#include "crypto/modes.h"
|
||||
|
||||
#ifndef STRICT_ALIGNMENT
|
||||
# ifdef __GNUC__
|
||||
typedef u64 u64_a1 __attribute((__aligned__(1)));
|
||||
# else
|
||||
typedef u64 u64_a1;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* First you setup M and L parameters and pass the key schedule. This is
|
||||
* called once per session setup...
|
||||
@@ -170,8 +178,8 @@ int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
|
||||
ctx->cmac.u[0] ^= temp.u[0];
|
||||
ctx->cmac.u[1] ^= temp.u[1];
|
||||
#else
|
||||
ctx->cmac.u[0] ^= ((u64 *)inp)[0];
|
||||
ctx->cmac.u[1] ^= ((u64 *)inp)[1];
|
||||
ctx->cmac.u[0] ^= ((u64_a1 *)inp)[0];
|
||||
ctx->cmac.u[1] ^= ((u64_a1 *)inp)[1];
|
||||
#endif
|
||||
(*block) (ctx->cmac.c, ctx->cmac.c, key);
|
||||
(*block) (ctx->nonce.c, scratch.c, key);
|
||||
@@ -181,8 +189,8 @@ int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
|
||||
temp.u[1] ^= scratch.u[1];
|
||||
memcpy(out, temp.c, 16);
|
||||
#else
|
||||
((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0];
|
||||
((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1];
|
||||
((u64_a1 *)out)[0] = scratch.u[0] ^ ((u64_a1 *)inp)[0];
|
||||
((u64_a1 *)out)[1] = scratch.u[1] ^ ((u64_a1 *)inp)[1];
|
||||
#endif
|
||||
inp += 16;
|
||||
out += 16;
|
||||
@@ -254,8 +262,10 @@ int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
|
||||
ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]);
|
||||
memcpy(out, scratch.c, 16);
|
||||
#else
|
||||
ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]);
|
||||
ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]);
|
||||
ctx->cmac.u[0] ^= (((u64_a1 *)out)[0]
|
||||
= scratch.u[0] ^ ((u64_a1 *)inp)[0]);
|
||||
ctx->cmac.u[1] ^= (((u64_a1 *)out)[1]
|
||||
= scratch.u[1] ^ ((u64_a1 *)inp)[1]);
|
||||
#endif
|
||||
(*block) (ctx->cmac.c, ctx->cmac.c, key);
|
||||
|
||||
|
||||
+14
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,12 @@
|
||||
#include <openssl/crypto.h>
|
||||
#include "crypto/modes.h"
|
||||
|
||||
#if defined(__GNUC__) && !defined(STRICT_ALIGNMENT)
|
||||
typedef size_t size_t_aX __attribute((__aligned__(1)));
|
||||
#else
|
||||
typedef size_t size_t_aX;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The input and output encrypted as though 128bit cfb mode is being used.
|
||||
* The extra state information to record how much of the 128bit block we have
|
||||
@@ -43,8 +49,9 @@ void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
while (len >= 16) {
|
||||
(*block) (ivec, ivec, key);
|
||||
for (; n < 16; n += sizeof(size_t)) {
|
||||
*(size_t *)(out + n) =
|
||||
*(size_t *)(ivec + n) ^= *(size_t *)(in + n);
|
||||
*(size_t_aX *)(out + n) =
|
||||
*(size_t_aX *)(ivec + n)
|
||||
^= *(size_t_aX *)(in + n);
|
||||
}
|
||||
len -= 16;
|
||||
out += 16;
|
||||
@@ -92,9 +99,10 @@ void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
while (len >= 16) {
|
||||
(*block) (ivec, ivec, key);
|
||||
for (; n < 16; n += sizeof(size_t)) {
|
||||
size_t t = *(size_t *)(in + n);
|
||||
*(size_t *)(out + n) = *(size_t *)(ivec + n) ^ t;
|
||||
*(size_t *)(ivec + n) = t;
|
||||
size_t t = *(size_t_aX *)(in + n);
|
||||
*(size_t_aX *)(out + n)
|
||||
= *(size_t_aX *)(ivec + n) ^ t;
|
||||
*(size_t_aX *)(ivec + n) = t;
|
||||
}
|
||||
len -= 16;
|
||||
out += 16;
|
||||
|
||||
+10
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,12 @@
|
||||
#include <openssl/crypto.h>
|
||||
#include "crypto/modes.h"
|
||||
|
||||
#if defined(__GNUC__) && !defined(STRICT_ALIGNMENT)
|
||||
typedef size_t size_t_aX __attribute((__aligned__(1)));
|
||||
#else
|
||||
typedef size_t size_t_aX;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NOTE: the IV/counter CTR mode is big-endian. The code itself is
|
||||
* endian-neutral.
|
||||
@@ -97,8 +103,9 @@ void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
(*block) (ivec, ecount_buf, key);
|
||||
ctr128_inc_aligned(ivec);
|
||||
for (n = 0; n < 16; n += sizeof(size_t))
|
||||
*(size_t *)(out + n) =
|
||||
*(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n);
|
||||
*(size_t_aX *)(out + n) =
|
||||
*(size_t_aX *)(in + n)
|
||||
^ *(size_t_aX *)(ecount_buf + n);
|
||||
len -= 16;
|
||||
out += 16;
|
||||
in += 16;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user