Latest update (add quic)

This commit is contained in:
2020-07-12 19:52:18 +09:00
parent 3a6d64bb68
commit e85ee33eee
501 changed files with 19166 additions and 10232 deletions
+9 -5
View File
@@ -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)
+1 -1
View File
@@ -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,
+6 -2
View File
@@ -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
View File
@@ -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
-3
View File
@@ -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),
-99
View File
@@ -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
View File
@@ -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);
+6 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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
+3 -3
View File
@@ -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
View File
@@ -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;
+2
View File
@@ -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
View File
@@ -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;
-68
View File
@@ -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;
}
+7 -7
View File
@@ -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 */
+7 -3
View File
@@ -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)
+6 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+4
View File
@@ -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
View File
@@ -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;
+3
View File
@@ -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
View File
@@ -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);
+6 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
-1
View File
@@ -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 {
+3 -3
View File
@@ -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);
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
-3
View File
@@ -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);
+1 -1
View File
@@ -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;
+2 -1
View File
@@ -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"},
+1 -1
View File
@@ -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);
-2082
View File
@@ -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: $!";
+2 -1
View File
@@ -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);
}
+1 -1
View File
@@ -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
View File
@@ -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);
+7 -8
View File
@@ -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;
}
+3 -7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+13
View File
@@ -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
View File
@@ -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;
+3 -3
View File
@@ -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
View File
@@ -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;
+5 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+6
View File
@@ -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>
+1 -1
View File
@@ -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;
+2 -1
View File
@@ -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 */
-1
View File
@@ -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},
};
-2
View File
@@ -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
+3 -2
View File
@@ -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);
-1
View File
@@ -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
View File
@@ -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
View File
@@ -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
+7 -2
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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--;
}
+7 -1
View File
@@ -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)
+2 -2
View File
@@ -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
View File
@@ -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);
+9 -9
View File
@@ -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
View File
@@ -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);
+3 -3
View File
@@ -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
View File
@@ -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
+3 -3
View File
@@ -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;
}
+7 -7
View File
@@ -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
View File
@@ -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;
}
+16
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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
+9
View File
@@ -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;
}
-2
View File
@@ -1,2 +0,0 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=http_client.c http_err.c http_lib.c
-1271
View File
@@ -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
}
-69
View File
@@ -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;
}
-177
View File
@@ -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;
}
-52
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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