Latest update - pre9

This commit is contained in:
2018-08-10 09:36:18 +09:00
parent 0961fd12de
commit f78925a4b7
63 changed files with 863 additions and 279 deletions
+10
View File
@@ -9,6 +9,16 @@
Changes between 1.1.0h and 1.1.1 [xx XXX xxxx]
*) s390x assembly pack: add (improved) hardware-support for the following
cryptographic primitives: sha3, shake, aes-gcm, aes-ccm, aes-ctr, aes-ofb,
aes-cfb/cfb8, aes-ecb.
[Patrick Steuer]
*) Make EVP_PKEY_asn1_new() a bit stricter about its input. A NULL pem_str
parameter is no longer accepted, as it leads to a corrupt table. NULL
pem_str is reserved for alias entries only.
[Richard Levitte]
*) Use the new ec_scalar_mul_ladder scaffold to implement a specialized ladder
step for prime curves. The new implementation is based on formulae from
differential addition-and-doubling in homogeneous projective coordinates
+2 -2
View File
@@ -93,8 +93,8 @@ GENERATED={- # common0.tmpl provides @generated
@generated) -}
INSTALL_LIBS={- join(" ", map { quotify1(lib($_)) } @{$unified_info{install}->{libraries}}) -}
INSTALL_SHLIBS={- join(" ", map { quotify1(shlib($_)) } @{$unified_info{install}->{libraries}}) -}
INSTALL_SHLIBPDBS={- join(" ", map { local $shlibext = ".pdb"; quotify1(shlib($_)) } @{$unified_info{install}->{libraries}}) -}
INSTALL_SHLIBS={- join(" ", map { quotify_l(shlib($_)) } @{$unified_info{install}->{libraries}}) -}
INSTALL_SHLIBPDBS={- join(" ", map { local $shlibext = ".pdb"; quotify_l(shlib($_)) } @{$unified_info{install}->{libraries}}) -}
INSTALL_ENGINES={- join(" ", map { quotify1(dso($_)) } @{$unified_info{install}->{engines}}) -}
INSTALL_ENGINEPDBS={- join(" ", map { local $dsoext = ".pdb"; quotify1(dso($_)) } @{$unified_info{install}->{engines}}) -}
INSTALL_PROGRAMS={- join(" ", map { quotify1($_.$exeext) } grep { !m|^test\\| } @{$unified_info{install}->{programs}}) -}
+3 -2
View File
@@ -1034,11 +1034,12 @@ if ($d) {
$target = $t;
}
}
&usage if !$table{$target} || $table{$target}->{template};
$config{target} = $target;
my %target = resolve_config($target);
&usage if (!%target || $target{template});
foreach (keys %target_attr_translate) {
$target{$target_attr_translate{$_}} = $target{$_}
if $target{$_};
+6 -4
View File
@@ -145,8 +145,8 @@
put together one-size-fits-all instructions. You might
have to pass more flags or set up environment variables
to actually make it work. Android and iOS cases are
discussed in corresponding Configurations/10-main.cf
sections. But there are cases when this option alone is
discussed in corresponding Configurations/15-*.conf
files. But there are cases when this option alone is
sufficient. For example to build the mingw64 target on
Linux "--cross-compile-prefix=x86_64-w64-mingw32-"
works. Naturally provided that mingw packages are
@@ -157,10 +157,12 @@
"--cross-compile-prefix=mipsel-linux-gnu-" suffices
in such case. Needless to mention that you have to
invoke ./Configure, not ./config, and pass your target
name explicitly.
name explicitly. Also, note that --openssldir refers
to target's file system, not one you are building on.
--debug
Build OpenSSL with debugging symbols.
Build OpenSSL with debugging symbols and zero optimization
level.
--libdir=DIR
The name of the directory under the top of the installation
+2 -2
View File
@@ -46,8 +46,8 @@
One can engage clang by adjusting PATH to cover NDK's clang. Just keep
in mind that if you miss it, Configure will try to use gcc... Also,
PATH would need even further adjustment to cover unprefixed, yet
target-specific, ar and ranlib (or not, if you use binutils-multiarch
on your Linux).
target-specific, ar and ranlib. It's possible that you don't need to
bother, if binutils-multiarch is installed on your Linux system.
Running tests (on Linux)
------------------------
+12
View File
@@ -216,6 +216,18 @@ EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
goto err;
}
/*
* One of the following must be true:
*
* pem_str == NULL AND ASN1_PKEY_ALIAS is set
* pem_str != NULL AND ASN1_PKEY_ALIAS is clear
*
* Anything else is an error and may lead to a corrupt ASN1 method table
*/
if (!((pem_str == NULL && (flags & ASN1_PKEY_ALIAS) != 0)
|| (pem_str != NULL && (flags & ASN1_PKEY_ALIAS) == 0)))
goto err;
if (pem_str) {
ameth->pem_str = OPENSSL_strdup(pem_str);
if (!ameth->pem_str)
-4
View File
@@ -883,8 +883,6 @@ static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, const char *name)
htmp.params = NULL;
idx = sk_MIME_HEADER_find(hdrs, &htmp);
if (idx < 0)
return NULL;
return sk_MIME_HEADER_value(hdrs, idx);
}
@@ -896,8 +894,6 @@ static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, const char *name)
param.param_name = (char *)name;
param.param_value = NULL;
idx = sk_MIME_PARAM_find(hdr->params, &param);
if (idx < 0)
return NULL;
return sk_MIME_PARAM_value(hdr->params, idx);
}
+18 -7
View File
@@ -58,8 +58,10 @@ int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
{
const ASN1_AUX *aux;
int *lck, ret;
CRYPTO_REF_COUNT *lck;
CRYPTO_RWLOCK **lock;
int ret = -1;
if ((it->itype != ASN1_ITYPE_SEQUENCE)
&& (it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
return 0;
@@ -68,25 +70,34 @@ int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
return 0;
lck = offset2ptr(*pval, aux->ref_offset);
lock = offset2ptr(*pval, aux->ref_lock);
if (op == 0) {
*lck = 1;
switch (op) {
case 0:
*lck = ret = 1;
*lock = CRYPTO_THREAD_lock_new();
if (*lock == NULL) {
ASN1err(ASN1_F_ASN1_DO_LOCK, ERR_R_MALLOC_FAILURE);
return -1;
}
return 1;
}
if (CRYPTO_atomic_add(lck, op, &ret, *lock) < 0)
break;
case 1:
if (!CRYPTO_UP_REF(lck, &ret, *lock))
return -1;
break;
case -1:
if (!CRYPTO_DOWN_REF(lck, &ret, *lock))
return -1; /* failed */
#ifdef REF_PRINT
fprintf(stderr, "%p:%4d:%s\n", it, *lck, it->sname);
fprintf(stderr, "%p:%4d:%s\n", it, ret, it->sname);
#endif
REF_ASSERT_ISNT(ret < 0);
if (ret == 0) {
CRYPTO_THREAD_lock_free(*lock);
*lock = NULL;
}
break;
}
return ret;
}
+3 -6
View File
@@ -63,8 +63,7 @@ static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed,
if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL)
|| !EVP_DigestUpdate(hashctx, dom_s, strlen(dom_s))
|| !EVP_DigestUpdate(hashctx, dom, sizeof(dom))
|| (context_len > 0
&& !EVP_DigestUpdate(hashctx, context, context_len)))
|| !EVP_DigestUpdate(hashctx, context, context_len))
return C448_FAILURE;
return C448_SUCCESS;
@@ -161,8 +160,7 @@ c448_error_t c448_ed448_sign(
|| !EVP_DigestUpdate(hashctx,
expanded + EDDSA_448_PRIVATE_BYTES,
EDDSA_448_PRIVATE_BYTES)
|| (message_len > 0
&& !EVP_DigestUpdate(hashctx, message, message_len))) {
|| !EVP_DigestUpdate(hashctx, message, message_len)) {
OPENSSL_cleanse(expanded, sizeof(expanded));
goto err;
}
@@ -202,8 +200,7 @@ c448_error_t c448_ed448_sign(
if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len)
|| !EVP_DigestUpdate(hashctx, nonce_point, sizeof(nonce_point))
|| !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES)
|| (message_len > 0
&& !EVP_DigestUpdate(hashctx, message, message_len))
|| !EVP_DigestUpdate(hashctx, message, message_len)
|| !EVP_DigestFinalXOF(hashctx, challenge, sizeof(challenge)))
goto err;
+1 -5
View File
@@ -75,14 +75,10 @@ int engine_free_util(ENGINE *e, int not_locked)
if (e == NULL)
return 1;
#ifdef HAVE_ATOMICS
CRYPTO_DOWN_REF(&e->struct_ref, &i, global_engine_lock);
#else
if (not_locked)
CRYPTO_atomic_add(&e->struct_ref, -1, &i, global_engine_lock);
CRYPTO_DOWN_REF(&e->struct_ref, &i, global_engine_lock);
else
i = --e->struct_ref;
#endif
engine_ref_debug(e, 0, -1);
if (i > 0)
return 1;
+1
View File
@@ -22,3 +22,4 @@ INCLUDE[e_camellia.o]=.. ../modes
INCLUDE[e_sm4.o]=.. ../modes
INCLUDE[e_des.o]=..
INCLUDE[e_des3.o]=..
INCLUDE[m_sha3.o]=..
+1 -2
View File
@@ -217,9 +217,8 @@ int EVP_PBE_find(int type, int pbe_nid,
pbelu.pbe_type = type;
pbelu.pbe_nid = pbe_nid;
if (pbe_algs) {
if (pbe_algs != NULL) {
i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
if (i != -1)
pbetmp = sk_EVP_PBE_CTL_value(pbe_algs, i);
}
if (pbetmp == NULL) {
+229 -5
View File
@@ -66,6 +66,9 @@ static int sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len)
size_t bsz = ctx->block_size;
size_t num, rem;
if (len == 0)
return 1;
if ((num = ctx->num) != 0) { /* process intermediate buffer? */
rem = bsz - num;
@@ -134,6 +137,226 @@ static int shake_ctrl(EVP_MD_CTX *evp_ctx, int cmd, int p1, void *p2)
}
}
#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM)
/*
* IBM S390X support
*/
# include "s390x_arch.h"
# define S390X_SHA3_FC(ctx) ((ctx)->pad)
# define S390X_sha3_224_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \
S390X_CAPBIT(S390X_SHA3_224)) && \
(OPENSSL_s390xcap_P.klmd[0] & \
S390X_CAPBIT(S390X_SHA3_224)))
# define S390X_sha3_256_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \
S390X_CAPBIT(S390X_SHA3_256)) && \
(OPENSSL_s390xcap_P.klmd[0] & \
S390X_CAPBIT(S390X_SHA3_256)))
# define S390X_sha3_384_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \
S390X_CAPBIT(S390X_SHA3_384)) && \
(OPENSSL_s390xcap_P.klmd[0] & \
S390X_CAPBIT(S390X_SHA3_384)))
# define S390X_sha3_512_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \
S390X_CAPBIT(S390X_SHA3_512)) && \
(OPENSSL_s390xcap_P.klmd[0] & \
S390X_CAPBIT(S390X_SHA3_512)))
# define S390X_shake128_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \
S390X_CAPBIT(S390X_SHAKE_128)) && \
(OPENSSL_s390xcap_P.klmd[0] & \
S390X_CAPBIT(S390X_SHAKE_128)))
# define S390X_shake256_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] & \
S390X_CAPBIT(S390X_SHAKE_256)) && \
(OPENSSL_s390xcap_P.klmd[0] & \
S390X_CAPBIT(S390X_SHAKE_256)))
/* Convert md-size to block-size. */
# define S390X_KECCAK1600_BSZ(n) ((KECCAK1600_WIDTH - ((n) << 1)) >> 3)
static int s390x_sha3_init(EVP_MD_CTX *evp_ctx)
{
KECCAK1600_CTX *ctx = evp_ctx->md_data;
const size_t bsz = evp_ctx->digest->block_size;
/*-
* KECCAK1600_CTX structure's pad field is used to store the KIMD/KLMD
* function code.
*/
switch (bsz) {
case S390X_KECCAK1600_BSZ(224):
ctx->pad = S390X_SHA3_224;
break;
case S390X_KECCAK1600_BSZ(256):
ctx->pad = S390X_SHA3_256;
break;
case S390X_KECCAK1600_BSZ(384):
ctx->pad = S390X_SHA3_384;
break;
case S390X_KECCAK1600_BSZ(512):
ctx->pad = S390X_SHA3_512;
break;
default:
return 0;
}
memset(ctx->A, 0, sizeof(ctx->A));
ctx->num = 0;
ctx->block_size = bsz;
ctx->md_size = evp_ctx->digest->md_size;
return 1;
}
static int s390x_shake_init(EVP_MD_CTX *evp_ctx)
{
KECCAK1600_CTX *ctx = evp_ctx->md_data;
const size_t bsz = evp_ctx->digest->block_size;
/*-
* KECCAK1600_CTX structure's pad field is used to store the KIMD/KLMD
* function code.
*/
switch (bsz) {
case S390X_KECCAK1600_BSZ(128):
ctx->pad = S390X_SHAKE_128;
break;
case S390X_KECCAK1600_BSZ(256):
ctx->pad = S390X_SHAKE_256;
break;
default:
return 0;
}
memset(ctx->A, 0, sizeof(ctx->A));
ctx->num = 0;
ctx->block_size = bsz;
ctx->md_size = evp_ctx->digest->md_size;
return 1;
}
static int s390x_sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len)
{
KECCAK1600_CTX *ctx = evp_ctx->md_data;
const unsigned char *inp = _inp;
const size_t bsz = ctx->block_size;
size_t num, rem;
if (len == 0)
return 1;
if ((num = ctx->num) != 0) {
rem = bsz - num;
if (len < rem) {
memcpy(ctx->buf + num, inp, len);
ctx->num += len;
return 1;
}
memcpy(ctx->buf + num, inp, rem);
inp += rem;
len -= rem;
s390x_kimd(ctx->buf, bsz, ctx->pad, ctx->A);
ctx->num = 0;
}
rem = len % bsz;
s390x_kimd(inp, len - rem, ctx->pad, ctx->A);
if (rem) {
memcpy(ctx->buf, inp + len - rem, rem);
ctx->num = rem;
}
return 1;
}
static int s390x_sha3_final(EVP_MD_CTX *evp_ctx, unsigned char *md)
{
KECCAK1600_CTX *ctx = evp_ctx->md_data;
s390x_klmd(ctx->buf, ctx->num, NULL, 0, ctx->pad, ctx->A);
memcpy(md, ctx->A, ctx->md_size);
return 1;
}
static int s390x_shake_final(EVP_MD_CTX *evp_ctx, unsigned char *md)
{
KECCAK1600_CTX *ctx = evp_ctx->md_data;
s390x_klmd(ctx->buf, ctx->num, md, ctx->md_size, ctx->pad, ctx->A);
return 1;
}
# define EVP_MD_SHA3(bitlen) \
const EVP_MD *EVP_sha3_##bitlen(void) \
{ \
static const EVP_MD s390x_sha3_##bitlen##_md = { \
NID_sha3_##bitlen, \
NID_RSA_SHA3_##bitlen, \
bitlen / 8, \
EVP_MD_FLAG_DIGALGID_ABSENT, \
s390x_sha3_init, \
s390x_sha3_update, \
s390x_sha3_final, \
NULL, \
NULL, \
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
sizeof(KECCAK1600_CTX), \
}; \
static const EVP_MD sha3_##bitlen##_md = { \
NID_sha3_##bitlen, \
NID_RSA_SHA3_##bitlen, \
bitlen / 8, \
EVP_MD_FLAG_DIGALGID_ABSENT, \
sha3_init, \
sha3_update, \
sha3_final, \
NULL, \
NULL, \
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
sizeof(KECCAK1600_CTX), \
}; \
return S390X_sha3_##bitlen##_CAPABLE ? \
&s390x_sha3_##bitlen##_md : \
&sha3_##bitlen##_md; \
}
# define EVP_MD_SHAKE(bitlen) \
const EVP_MD *EVP_shake##bitlen(void) \
{ \
static const EVP_MD s390x_shake##bitlen##_md = { \
NID_shake##bitlen, \
0, \
bitlen / 8, \
EVP_MD_FLAG_XOF, \
s390x_shake_init, \
s390x_sha3_update, \
s390x_shake_final, \
NULL, \
NULL, \
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
sizeof(KECCAK1600_CTX), \
shake_ctrl \
}; \
static const EVP_MD shake##bitlen##_md = { \
NID_shake##bitlen, \
0, \
bitlen / 8, \
EVP_MD_FLAG_XOF, \
shake_init, \
sha3_update, \
sha3_final, \
NULL, \
NULL, \
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
sizeof(KECCAK1600_CTX), \
shake_ctrl \
}; \
return S390X_shake##bitlen##_CAPABLE ? \
&s390x_shake##bitlen##_md : \
&shake##bitlen##_md; \
}
#else
# define EVP_MD_SHA3(bitlen) \
const EVP_MD *EVP_sha3_##bitlen(void) \
{ \
@@ -153,11 +376,6 @@ const EVP_MD *EVP_sha3_##bitlen(void) \
return &sha3_##bitlen##_md; \
}
EVP_MD_SHA3(224)
EVP_MD_SHA3(256)
EVP_MD_SHA3(384)
EVP_MD_SHA3(512)
# define EVP_MD_SHAKE(bitlen) \
const EVP_MD *EVP_shake##bitlen(void) \
{ \
@@ -177,6 +395,12 @@ const EVP_MD *EVP_shake##bitlen(void) \
}; \
return &shake##bitlen##_md; \
}
#endif
EVP_MD_SHA3(224)
EVP_MD_SHA3(256)
EVP_MD_SHA3(384)
EVP_MD_SHA3(512)
EVP_MD_SHAKE(128)
EVP_MD_SHAKE(256)
+1
View File
@@ -182,6 +182,7 @@ struct x509_st {
unsigned char sha1_hash[SHA_DIGEST_LENGTH];
X509_CERT_AUX *aux;
CRYPTO_RWLOCK *lock;
volatile int ex_cached;
} /* X509 */ ;
/*
+8 -6
View File
@@ -157,16 +157,18 @@ void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data)
OPENSSL_LH_NODE **rn;
void *ret;
lh->error = 0;
tsan_store((TSAN_QUALIFIER int *)&lh->error, 0);
rn = getrn(lh, data, &hash);
if (*rn == NULL) {
lh->num_retrieve_miss++;
tsan_counter(&lh->num_retrieve_miss);
return NULL;
} else {
ret = (*rn)->data;
lh->num_retrieve++;
tsan_counter(&lh->num_retrieve);
}
return ret;
}
@@ -296,7 +298,7 @@ static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh,
OPENSSL_LH_COMPFUNC cf;
hash = (*(lh->hash)) (data);
lh->num_hash_calls++;
tsan_counter(&lh->num_hash_calls);
*rhash = hash;
nn = hash % lh->pmax;
@@ -306,12 +308,12 @@ static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh,
cf = lh->comp;
ret = &(lh->b[(int)nn]);
for (n1 = *ret; n1 != NULL; n1 = n1->next) {
lh->num_hash_comps++;
tsan_counter(&lh->num_hash_comps);
if (n1->hash != hash) {
ret = &(n1->next);
continue;
}
lh->num_comp_calls++;
tsan_counter(&lh->num_comp_calls);
if (cf(n1->data, data) == 0)
break;
ret = &(n1->next);
+7 -5
View File
@@ -8,6 +8,8 @@
*/
#include <openssl/crypto.h>
#include "internal/tsan_assist.h"
struct lhash_node_st {
void *data;
struct lhash_node_st *next;
@@ -29,14 +31,14 @@ struct lhash_st {
unsigned long num_expand_reallocs;
unsigned long num_contracts;
unsigned long num_contract_reallocs;
unsigned long num_hash_calls;
unsigned long num_comp_calls;
TSAN_QUALIFIER unsigned long num_hash_calls;
TSAN_QUALIFIER unsigned long num_comp_calls;
unsigned long num_insert;
unsigned long num_replace;
unsigned long num_delete;
unsigned long num_no_delete;
unsigned long num_retrieve;
unsigned long num_retrieve_miss;
unsigned long num_hash_comps;
TSAN_QUALIFIER unsigned long num_retrieve;
TSAN_QUALIFIER unsigned long num_retrieve_miss;
TSAN_QUALIFIER unsigned long num_hash_comps;
int error;
};
+9 -9
View File
@@ -31,13 +31,13 @@ static void (*free_impl)(void *, const char *, int)
= CRYPTO_free;
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
static int malloc_count;
static int realloc_count;
static int free_count;
static int dummy;
# include "internal/tsan_assist.h"
# define INCREMENT(x) CRYPTO_atomic_add(&x, 1, &dummy, memdbg_lock)
# define GET(ret, val) CRYPTO_atomic_read(&val, ret, memdbg_lock)
static TSAN_QUALIFIER int malloc_count;
static TSAN_QUALIFIER int realloc_count;
static TSAN_QUALIFIER int free_count;
# define INCREMENT(x) tsan_counter(&(x))
static char *md_failstring;
static long md_count;
@@ -98,11 +98,11 @@ void CRYPTO_get_mem_functions(
void CRYPTO_get_alloc_counts(int *mcount, int *rcount, int *fcount)
{
if (mcount != NULL)
GET(mcount, malloc_count);
*mcount = tsan_load(&malloc_count);
if (rcount != NULL)
GET(rcount, realloc_count);
*rcount = tsan_load(&realloc_count);
if (fcount != NULL)
GET(fcount, free_count);
*fcount = tsan_load(&free_count);
}
/*
+1 -2
View File
@@ -46,9 +46,8 @@ int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid)
const nid_triple *rv = NULL;
tmp.sign_id = signid;
if (sig_app) {
if (sig_app != NULL) {
int idx = sk_nid_triple_find(sig_app, &tmp);
if (idx >= 0)
rv = sk_nid_triple_value(sig_app, idx);
}
#ifndef OBJ_XREF_TEST2
+1 -1
View File
@@ -1605,7 +1605,7 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme
id-pkinit 4 : pkInitClientAuth : PKINIT Client Auth
id-pkinit 5 : pkInitKDC : Signing KDC Response
# New algorithms from draft-ietf-curdle-pkix-04
# From RFC8410
1 3 101 110 : X25519
1 3 101 111 : X448
1 3 101 112 : ED25519
+4
View File
@@ -12,6 +12,10 @@
# ifndef __ASSEMBLER__
void s390x_kimd(const unsigned char *in, size_t len, unsigned int fc,
void *param);
void s390x_klmd(const unsigned char *in, size_t inlen, unsigned char *out,
size_t outlen, unsigned int fc, void *param);
void s390x_km(const unsigned char *in, size_t len, unsigned char *out,
unsigned int fc, void *param);
void s390x_kmac(const unsigned char *in, size_t len, unsigned int fc,
+42
View File
@@ -262,6 +262,48 @@ OPENSSL_vx_probe:
.size OPENSSL_vx_probe,.-OPENSSL_vx_probe
___
{
################
# void s390x_kimd(const unsigned char *in, size_t len, unsigned int fc,
# void *param)
my ($in,$len,$fc,$param) = map("%r$_",(2..5));
$code.=<<___;
.globl s390x_kimd
.type s390x_kimd,\@function
.align 16
s390x_kimd:
llgfr %r0,$fc
lgr %r1,$param
.long 0xb93e0002 # kimd %r0,%r2
brc 1,.-4 # pay attention to "partial completion"
br $ra
.size s390x_kimd,.-s390x_kimd
___
}
{
################
# void s390x_klmd(const unsigned char *in, size_t inlen, unsigned char *out,
# size_t outlen, unsigned int fc, void *param)
my ($in,$inlen,$out,$outlen,$fc) = map("%r$_",(2..6));
$code.=<<___;
.globl s390x_klmd
.type s390x_klmd,\@function
.align 32
s390x_klmd:
llgfr %r0,$fc
l${g} %r1,$stdframe($sp)
.long 0xb93f0042 # klmd %r4,%r2
brc 1,.-4 # pay attention to "partial completion"
br $ra
.size s390x_klmd,.-s390x_klmd
___
}
################
# void s390x_km(const unsigned char *in, size_t len, unsigned char *out,
# unsigned int fc, void *param)
+1 -5
View File
@@ -329,10 +329,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type,
*/
CRYPTO_THREAD_write_lock(ctx->lock);
j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp);
if (j != -1)
tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j);
else
tmp = NULL;
CRYPTO_THREAD_unlock(ctx->lock);
/* If a CRL, update the last file suffix added for this */
@@ -343,10 +340,9 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type,
* Look for entry again in case another thread added an entry
* first.
*/
if (!hent) {
if (hent == NULL) {
htmp.hash = h;
idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
if (idx >= 0)
hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
}
if (hent == NULL) {
+6 -5
View File
@@ -619,17 +619,18 @@ STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
X509_OBJECT *x)
{
int idx, i;
int idx, i, num;
X509_OBJECT *obj;
idx = sk_X509_OBJECT_find(h, x);
if (idx == -1)
if (idx < 0)
return NULL;
if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
return sk_X509_OBJECT_value(h, idx);
for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
for (i = idx, num = sk_X509_OBJECT_num(h); i < num; i++) {
obj = sk_X509_OBJECT_value(h, i);
if (x509_object_cmp
((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
if (x509_object_cmp((const X509_OBJECT **)&obj,
(const X509_OBJECT **)&x))
return NULL;
if (x->type == X509_LU_X509) {
if (!X509_cmp(obj->data.x509, x->data.x509))
+4 -3
View File
@@ -98,13 +98,14 @@ int X509_TRUST_get_by_id(int id)
{
X509_TRUST tmp;
int idx;
if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
return id - X509_TRUST_MIN;
tmp.trust = id;
if (!trtable)
if (trtable == NULL)
return -1;
tmp.trust = id;
idx = sk_X509_TRUST_find(trtable, &tmp);
if (idx == -1)
if (idx < 0)
return -1;
return idx + X509_TRUST_COUNT;
}
+4 -5
View File
@@ -555,10 +555,9 @@ int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
return 0;
} else {
idx = sk_X509_VERIFY_PARAM_find(param_table, param);
if (idx != -1) {
ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
if (idx >= 0) {
ptmp = sk_X509_VERIFY_PARAM_delete(param_table, idx);
X509_VERIFY_PARAM_free(ptmp);
(void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
}
}
if (!sk_X509_VERIFY_PARAM_push(param_table, param))
@@ -588,9 +587,9 @@ const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
X509_VERIFY_PARAM pm;
pm.name = (char *)name;
if (param_table) {
if (param_table != NULL) {
idx = sk_X509_VERIFY_PARAM_find(param_table, &pm);
if (idx != -1)
if (idx >= 0)
return sk_X509_VERIFY_PARAM_value(param_table, idx);
}
return OBJ_bsearch_table(&pm, default_table, OSSL_NELEM(default_table));
+5 -3
View File
@@ -26,8 +26,8 @@ int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
return X509_NAME_get_text_by_OBJ(name, obj, buf, len);
}
int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf,
int len)
int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
char *buf, int len)
{
int i;
const ASN1_STRING *data;
@@ -36,9 +36,11 @@ int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf
if (i < 0)
return -1;
data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
i = (data->length > (len - 1)) ? (len - 1) : data->length;
if (buf == NULL)
return data->length;
if (len <= 0)
return 0;
i = (data->length > (len - 1)) ? (len - 1) : data->length;
memcpy(buf, data->data, i);
buf[i] = '\0';
return i;
+7 -3
View File
@@ -383,8 +383,11 @@ static int def_crl_lookup(X509_CRL *crl,
X509_NAME *issuer)
{
X509_REVOKED rtmp, *rev;
int idx;
rtmp.serialNumber = *serial;
int idx, num;
if (crl->crl.revoked == NULL)
return 0;
/*
* Sort revoked into serial number order if not already sorted. Do this
* under a lock to avoid race condition.
@@ -394,11 +397,12 @@ static int def_crl_lookup(X509_CRL *crl,
sk_X509_REVOKED_sort(crl->crl.revoked);
CRYPTO_THREAD_unlock(crl->lock);
}
rtmp.serialNumber = *serial;
idx = sk_X509_REVOKED_find(crl->crl.revoked, &rtmp);
if (idx < 0)
return 0;
/* Need to look for matching name */
for (; idx < sk_X509_REVOKED_num(crl->crl.revoked); idx++) {
for (num = sk_X509_REVOKED_num(crl->crl.revoked); idx < num; idx++) {
rev = sk_X509_REVOKED_value(crl->crl.revoked, idx);
if (ASN1_INTEGER_cmp(&rev->serialNumber, serial))
return 0;
+4 -6
View File
@@ -26,19 +26,19 @@ static int policy_cache_set_int(long *out, ASN1_INTEGER *value);
static int policy_cache_create(X509 *x,
CERTIFICATEPOLICIES *policies, int crit)
{
int i, ret = 0;
int i, num, ret = 0;
X509_POLICY_CACHE *cache = x->policy_cache;
X509_POLICY_DATA *data = NULL;
POLICYINFO *policy;
if (sk_POLICYINFO_num(policies) == 0)
if ((num = sk_POLICYINFO_num(policies)) <= 0)
goto bad_policy;
cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
if (cache->data == NULL) {
X509V3err(X509V3_F_POLICY_CACHE_CREATE, ERR_R_MALLOC_FAILURE);
goto just_cleanup;
}
for (i = 0; i < sk_POLICYINFO_num(policies); i++) {
for (i = 0; i < num; i++) {
policy = sk_POLICYINFO_value(policies, i);
data = policy_data_new(policy, NULL, crit);
if (data == NULL) {
@@ -54,7 +54,7 @@ static int policy_cache_create(X509 *x,
goto bad_policy;
}
cache->anyPolicy = data;
} else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1) {
} else if (sk_X509_POLICY_DATA_find(cache->data, data) >=0 ) {
ret = -1;
goto bad_policy;
} else if (!sk_X509_POLICY_DATA_push(cache->data, data)) {
@@ -204,8 +204,6 @@ X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
X509_POLICY_DATA tmp;
tmp.valid_policy = (ASN1_OBJECT *)id;
idx = sk_X509_POLICY_DATA_find(cache->data, &tmp);
if (idx == -1)
return NULL;
return sk_X509_POLICY_DATA_value(cache->data, idx);
}
-3
View File
@@ -36,9 +36,6 @@ X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
l.data = &n;
idx = sk_X509_POLICY_NODE_find(nodes, &l);
if (idx == -1)
return NULL;
return sk_X509_POLICY_NODE_value(nodes, idx);
}
+1 -1
View File
@@ -442,7 +442,7 @@ static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
if (*pnodes == NULL &&
(*pnodes = policy_node_cmp_new()) == NULL)
return 0;
if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
if (sk_X509_POLICY_NODE_find(*pnodes, pcy) >= 0)
return 1;
return sk_X509_POLICY_NODE_push(*pnodes, pcy) != 0;
}
-2
View File
@@ -64,8 +64,6 @@ const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
if (!ext_list)
return NULL;
idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp);
if (idx == -1)
return NULL;
return sk_X509V3_EXT_METHOD_value(ext_list, idx);
}
+13 -5
View File
@@ -13,6 +13,7 @@
#include <openssl/x509v3.h>
#include <openssl/x509_vfy.h>
#include "internal/x509_int.h"
#include "internal/tsan_assist.h"
static void x509v3_cache_extensions(X509 *x);
@@ -133,13 +134,14 @@ int X509_PURPOSE_get_by_id(int purpose)
{
X509_PURPOSE tmp;
int idx;
if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
return purpose - X509_PURPOSE_MIN;
tmp.purpose = purpose;
if (!xptable)
if (xptable == NULL)
return -1;
tmp.purpose = purpose;
idx = sk_X509_PURPOSE_find(xptable, &tmp);
if (idx == -1)
if (idx < 0)
return -1;
return idx + X509_PURPOSE_COUNT;
}
@@ -350,10 +352,10 @@ static void x509v3_cache_extensions(X509 *x)
ASN1_BIT_STRING *ns;
EXTENDED_KEY_USAGE *extusage;
X509_EXTENSION *ex;
int i;
if (x->ex_flags & EXFLAG_SET)
/* fast lock-free check, see end of the function for details. */
if (tsan_load((TSAN_QUALIFIER int *)&x->ex_cached))
return;
CRYPTO_THREAD_write_lock(x->lock);
@@ -497,6 +499,12 @@ static void x509v3_cache_extensions(X509 *x)
x509_init_sig_info(x);
x->ex_flags |= EXFLAG_SET;
CRYPTO_THREAD_unlock(x->lock);
/*
* It has to be placed after memory barrier, which is implied by unlock.
* Worst thing that can happen is that another thread proceeds to lock
* and checks x->ex_flags & EXFLAGS_SET. See beginning of the function.
*/
tsan_store((TSAN_QUALIFIER int *)&x->ex_cached, 1);
}
/*-
+9 -16
View File
@@ -18,7 +18,7 @@ lh_TYPE_doall, lh_TYPE_doall_arg, lh_TYPE_error - dynamic hash table
DECLARE_LHASH_OF(TYPE);
LHASH *lh_TYPE_new();
LHASH *lh_TYPE_new(OPENSSL_LH_HASHFUNC hash, OPENSSL_LH_COMPFUNC compare);
void lh_TYPE_free(LHASH_OF(TYPE) *table);
TYPE *lh_TYPE_insert(LHASH_OF(TYPE) *table, TYPE *data);
@@ -27,7 +27,7 @@ lh_TYPE_doall, lh_TYPE_doall_arg, lh_TYPE_error - dynamic hash table
void lh_TYPE_doall(LHASH_OF(TYPE) *table, OPENSSL_LH_DOALL_FUNC func);
void lh_TYPE_doall_arg(LHASH_OF(TYPE) *table, OPENSSL_LH_DOALL_FUNCARG func,
TYPE, TYPE *arg);
TYPE *arg);
int lh_TYPE_error(LHASH_OF(TYPE) *table);
@@ -171,25 +171,18 @@ lh_TYPE_retrieve() returns the hash table entry if it has been found,
B<NULL> otherwise.
lh_TYPE_error() returns 1 if an error occurred in the last operation, 0
otherwise.
otherwise. It's meaningful only after non-retrieve operations.
lh_TYPE_free(), lh_TYPE_doall() and lh_TYPE_doall_arg() return no values.
=head1 NOTE
The various LHASH macros and callback types exist to make it possible
to write type-checked code without resorting to function-prototype
casting - an evil that makes application code much harder to
audit/verify and also opens the window of opportunity for stack
corruption and other hard-to-find bugs. It also, apparently, violates
ANSI-C.
The LHASH code is not thread safe. All updating operations must be
performed under a write lock. All retrieve operations should be performed
under a read lock, I<unless> accurate usage statistics are desired.
In which case, a write lock should be used for retrieve operations
as well. For output of the usage statistics, using the functions from
L<OPENSSL_LH_stats(3)>, a read lock suffices.
The LHASH code is not thread safe. All updating operations, as well as
lh_TYPE_error call must be performed under a write lock. All retrieve
operations should be performed under a read lock, I<unless> accurate
usage statistics are desired. In which case, a write lock should be used
for retrieve operations as well. For output of the usage statistics,
using the functions from L<OPENSSL_LH_stats(3)>, a read lock suffices.
The LHASH code regards table entries as constant data. As such, it
internally represents lh_insert()'d items with a "const void *"
+1 -1
View File
@@ -49,9 +49,9 @@ int FuzzerInitialize(int *argc, char ***argv)
idx = SSL_get_ex_data_X509_STORE_CTX_idx();
FuzzerSetRand();
comp_methods = SSL_COMP_get_compression_methods();
if (comp_methods != NULL)
sk_SSL_COMP_sort(comp_methods);
return 1;
}
+1 -1
View File
@@ -496,9 +496,9 @@ int FuzzerInitialize(int *argc, char ***argv)
idx = SSL_get_ex_data_X509_STORE_CTX_idx();
FuzzerSetRand();
comp_methods = SSL_COMP_get_compression_methods();
if (comp_methods != NULL)
sk_SSL_COMP_sort(comp_methods);
return 1;
}
+84
View File
@@ -0,0 +1,84 @@
/*
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
/*
* Goal here is to facilitate writing "thread-opportunistic" code that
* withstands Thread Sanitizer's scrutiny. "Thread-opportunistic" is when
* exact result is not required, e.g. some statistics, or execution flow
* doesn't have to be unambiguous. Simplest example is lazy "constant"
* initialization when one can synchronize on variable itself, e.g.
*
* if (var == NOT_YET_INITIALIZED)
* var = function_returning_same_value();
*
* This does work provided that loads and stores are single-instuction
* operations (and integer ones are on *all* supported platforms), but
* it upsets Thread Sanitizer. Suggested solution is
*
* if (tsan_load(&var) == NOT_YET_INITIALIZED)
* tsan_store(&var, function_returning_same_value());
*
* Production machine code would be the same, so one can wonder why
* bother. Having Thread Sanitizer accept "thread-opportunistic" code
* allows to move on trouble-shooting real bugs.
*
* We utilize the fact that compilers that implement Thread Sanitizer
* implement even atomic operations. Then it's assumed that
* ATOMIC_{LONG|INT}_LOCK_FREE are assigned same value as
* ATOMIC_POINTER_LOCK_FREE. And check for >= 2 ensures that correspodning
* code is inlined. It should be noted that statistics counters become
* accurate in such case.
*/
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L \
&& !defined(__STDC_NO_ATOMICS__)
# include <stdatomic.h>
# if defined(ATOMIC_POINTER_LOCK_FREE) \
&& ATOMIC_POINTER_LOCK_FREE >= 2
# define TSAN_QUALIFIER _Atomic
# define tsan_load(ptr) atomic_load_explicit((ptr), memory_order_relaxed)
# define tsan_store(ptr, val) atomic_store_explicit((ptr), (val), memory_order_relaxed)
# define tsan_counter(ptr) atomic_fetch_add_explicit((ptr), 1, memory_order_relaxed)
# endif
#elif defined(__GNUC__) && defined(__ATOMIC_RELAXED)
# if defined(__GCC_ATOMIC_POINTER_LOCK_FREE) \
&& __GCC_ATOMIC_POINTER_LOCK_FREE >= 2
# define TSAN_QUALIFIER volatile
# define tsan_load(ptr) __atomic_load_n((ptr), __ATOMIC_RELAXED)
# define tsan_store(ptr, val) __atomic_store_n((ptr), (val), __ATOMIC_RELAXED)
# define tsan_counter(ptr) __atomic_fetch_add((ptr), 1, __ATOMIC_RELAXED)
# endif
#elif defined(_MSC_VER) && _MSC_VER>=1200
# define TSAN_QUALIFIER volatile
# define tsan_load(ptr) (*(ptr))
# define tsan_store(ptr, val) (*(ptr) = (val))
# pragma intrinsic(_InterlockedExchangeAdd)
# ifdef _WIN64
# pragma intrinsic(_InterlockedExchangeAdd64)
# define tsan_counter(ptr) (sizeof(*ptr) == 8 ? _InterlockedExchangeAdd64((ptr), 1) \
: _InterlockedExchangeAdd((ptr), 1))
# else
# define tsan_counter(ptr) _InterlockedExchangeAdd((ptr), 1)
# endif
#endif
#ifndef TSAN_QUALIFIER
# define TSAN_QUALIFIER volatile
# define tsan_load(ptr) (*(ptr))
# define tsan_store(ptr, val) (*(ptr) = (val))
# define tsan_counter(ptr) ((*(ptr))++)
#endif
+8 -2
View File
@@ -263,9 +263,15 @@ extern "C" {
# define SSL3_CT_FORTEZZA_DMS 20
/*
* SSL3_CT_NUMBER is used to size arrays and it must be large enough to
* contain all of the cert types defined either for SSLv3 and TLSv1.
* contain all of the cert types defined for *either* SSLv3 and TLSv1.
*/
# define SSL3_CT_NUMBER 9
# define SSL3_CT_NUMBER 10
# if defined(TLS_CT_NUMBER)
# if TLS_CT_NUMBER != SSL3_CT_NUMBER
# error "SSL/TLS CT_NUMBER values do not match"
# endif
# endif
/* No longer used as of OpenSSL 1.1.1 */
# define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001
+7 -1
View File
@@ -1151,7 +1151,13 @@ __owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
* when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see
* comment there)
*/
# define TLS_CT_NUMBER 9
# define TLS_CT_NUMBER 10
# if defined(SSL3_CT_NUMBER)
# if TLS_CT_NUMBER != SSL3_CT_NUMBER
# error "SSL/TLS CT_NUMBER values do not match"
# endif
# endif
# define TLS1_FINISH_MAC_LENGTH 12
+10 -5
View File
@@ -816,7 +816,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
/* Clear our SSL3_RECORD structures */
memset(wr, 0, sizeof(wr));
for (j = 0; j < numpipes; j++) {
unsigned int version = SSL_TREAT_AS_TLS13(s) ? TLS1_2_VERSION
unsigned int version = (s->version == TLS1_3_VERSION) ? TLS1_2_VERSION
: s->version;
unsigned char *compressdata = NULL;
size_t maxcomplen;
@@ -829,7 +829,10 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
* In TLSv1.3, once encrypting, we always use application data for the
* record type
*/
if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL)
if (SSL_TREAT_AS_TLS13(s)
&& s->enc_write_ctx != NULL
&& (s->statem.enc_write_state != ENC_WRITE_STATE_WRITE_PLAIN_ALERTS
|| type != SSL3_RT_ALERT))
rectype = SSL3_RT_APPLICATION_DATA;
else
rectype = type;
@@ -892,7 +895,10 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
SSL3_RECORD_reset_input(&wr[j]);
}
if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL) {
if (SSL_TREAT_AS_TLS13(s)
&& s->enc_write_ctx != NULL
&& (s->statem.enc_write_state != ENC_WRITE_STATE_WRITE_PLAIN_ALERTS
|| type != SSL3_RT_ALERT)) {
size_t rlen, max_send_fragment;
if (!WPACKET_put_bytes_u8(thispkt, type)) {
@@ -981,8 +987,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
SSL3_RECORD_set_length(thiswr, len);
}
if (s->early_data_state == SSL_EARLY_DATA_WRITING
|| s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) {
if (s->statem.enc_write_state == ENC_WRITE_STATE_WRITE_PLAIN_ALERTS) {
/*
* We haven't actually negotiated the version yet, but we're trying to
* send early data - so we need to use the tls13enc function.
+7 -2
View File
@@ -342,7 +342,10 @@ int ssl3_get_record(SSL *s)
if (SSL_IS_TLS13(s) && s->enc_read_ctx != NULL) {
if (thisrr->type != SSL3_RT_APPLICATION_DATA
&& (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC
|| !SSL_IS_FIRST_HANDSHAKE(s))) {
|| !SSL_IS_FIRST_HANDSHAKE(s))
&& (thisrr->type != SSL3_RT_ALERT
|| s->statem.enc_read_state
!= ENC_READ_STATE_ALLOW_PLAIN_ALERTS)) {
SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE,
SSL_F_SSL3_GET_RECORD, SSL_R_BAD_RECORD_TYPE);
return -1;
@@ -692,7 +695,9 @@ int ssl3_get_record(SSL *s)
}
}
if (SSL_IS_TLS13(s) && s->enc_read_ctx != NULL) {
if (SSL_IS_TLS13(s)
&& s->enc_read_ctx != NULL
&& thisrr->type != SSL3_RT_ALERT) {
size_t end;
if (thisrr->length == 0
+7 -1
View File
@@ -52,7 +52,13 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending)
seq = RECORD_LAYER_get_read_sequence(&s->rlayer);
}
if (ctx == NULL) {
/*
* If we're sending an alert and ctx != NULL then we must be forcing
* plaintext alerts. If we're reading and ctx != NULL then we allow
* plaintext alerts at certain points in the handshake. If we've got this
* far then we have already validated that a plaintext alert is ok here.
*/
if (ctx == NULL || rec->type == SSL3_RT_ALERT) {
memmove(rec->data, rec->input, rec->length);
rec->input = rec->data;
return 1;
+2 -2
View File
@@ -155,7 +155,7 @@ int ssl3_change_cipher_state(SSL *s, int which)
RECORD_LAYER_reset_read_sequence(&s->rlayer);
mac_secret = &(s->s3->read_mac_secret[0]);
} else {
s->statem.invalid_enc_write_ctx = 1;
s->statem.enc_write_state = ENC_WRITE_STATE_INVALID;
if (s->enc_write_ctx != NULL) {
reuse_dd = 1;
} else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) {
@@ -238,7 +238,7 @@ int ssl3_change_cipher_state(SSL *s, int which)
goto err;
}
s->statem.invalid_enc_write_ctx = 0;
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
OPENSSL_cleanse(exp_key, sizeof(exp_key));
OPENSSL_cleanse(exp_iv, sizeof(exp_iv));
return 1;
-3
View File
@@ -507,10 +507,7 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
ctmp.id = s->compress_meth;
if (ssl_comp_methods != NULL) {
i = sk_SSL_COMP_find(ssl_comp_methods, &ctmp);
if (i >= 0)
*comp = sk_SSL_COMP_value(ssl_comp_methods, i);
else
*comp = NULL;
}
/* If were only interested in comp then return success */
if ((enc == NULL) && (md == NULL))
+1 -1
View File
@@ -129,8 +129,8 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_load_ssl_strings)
"ERR_load_SSL_strings()\n");
# endif
ERR_load_SSL_strings();
#endif
ssl_strings_inited = 1;
#endif
return 1;
}
+13 -28
View File
@@ -2330,7 +2330,6 @@ LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx)
long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
{
long l;
int i;
/* For some cases with ctx == NULL perform syntax checks */
if (ctx == NULL) {
switch (cmd) {
@@ -2385,40 +2384,27 @@ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
case SSL_CTRL_SESS_NUMBER:
return lh_SSL_SESSION_num_items(ctx->sessions);
case SSL_CTRL_SESS_CONNECT:
return CRYPTO_atomic_read(&ctx->stats.sess_connect, &i, ctx->lock)
? i : 0;
return tsan_load(&ctx->stats.sess_connect);
case SSL_CTRL_SESS_CONNECT_GOOD:
return CRYPTO_atomic_read(&ctx->stats.sess_connect_good, &i, ctx->lock)
? i : 0;
return tsan_load(&ctx->stats.sess_connect_good);
case SSL_CTRL_SESS_CONNECT_RENEGOTIATE:
return CRYPTO_atomic_read(&ctx->stats.sess_connect_renegotiate, &i,
ctx->lock)
? i : 0;
return tsan_load(&ctx->stats.sess_connect_renegotiate);
case SSL_CTRL_SESS_ACCEPT:
return CRYPTO_atomic_read(&ctx->stats.sess_accept, &i, ctx->lock)
? i : 0;
return tsan_load(&ctx->stats.sess_accept);
case SSL_CTRL_SESS_ACCEPT_GOOD:
return CRYPTO_atomic_read(&ctx->stats.sess_accept_good, &i, ctx->lock)
? i : 0;
return tsan_load(&ctx->stats.sess_accept_good);
case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE:
return CRYPTO_atomic_read(&ctx->stats.sess_accept_renegotiate, &i,
ctx->lock)
? i : 0;
return tsan_load(&ctx->stats.sess_accept_renegotiate);
case SSL_CTRL_SESS_HIT:
return CRYPTO_atomic_read(&ctx->stats.sess_hit, &i, ctx->lock)
? i : 0;
return tsan_load(&ctx->stats.sess_hit);
case SSL_CTRL_SESS_CB_HIT:
return CRYPTO_atomic_read(&ctx->stats.sess_cb_hit, &i, ctx->lock)
? i : 0;
return tsan_load(&ctx->stats.sess_cb_hit);
case SSL_CTRL_SESS_MISSES:
return CRYPTO_atomic_read(&ctx->stats.sess_miss, &i, ctx->lock)
? i : 0;
return tsan_load(&ctx->stats.sess_miss);
case SSL_CTRL_SESS_TIMEOUTS:
return CRYPTO_atomic_read(&ctx->stats.sess_timeout, &i, ctx->lock)
? i : 0;
return tsan_load(&ctx->stats.sess_timeout);
case SSL_CTRL_SESS_CACHE_FULL:
return CRYPTO_atomic_read(&ctx->stats.sess_cache_full, &i, ctx->lock)
? i : 0;
return tsan_load(&ctx->stats.sess_cache_full);
case SSL_CTRL_MODE:
return (ctx->mode |= larg);
case SSL_CTRL_CLEAR_MODE:
@@ -3492,13 +3478,12 @@ void ssl_update_cache(SSL *s, int mode)
/* auto flush every 255 connections */
if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && ((i & mode) == mode)) {
int *stat, val;
TSAN_QUALIFIER int *stat;
if (mode & SSL_SESS_CACHE_CLIENT)
stat = &s->session_ctx->stats.sess_connect_good;
else
stat = &s->session_ctx->stats.sess_accept_good;
if (CRYPTO_atomic_read(stat, &val, s->session_ctx->lock)
&& (val & 0xff) == 0xff)
if ((tsan_load(stat) & 0xff) == 0xff)
SSL_CTX_flush_sessions(s->session_ctx, (unsigned long)time(NULL));
}
}
+17 -14
View File
@@ -33,6 +33,7 @@
# include "packet_locl.h"
# include "internal/dane.h"
# include "internal/refcount.h"
# include "internal/tsan_assist.h"
# ifdef OPENSSL_BUILD_SHLIBSSL
# undef OPENSSL_EXTERN
@@ -816,20 +817,22 @@ struct ssl_ctx_st {
const unsigned char *data, int len,
int *copy);
struct {
int sess_connect; /* SSL new conn - started */
int sess_connect_renegotiate; /* SSL reneg - requested */
int sess_connect_good; /* SSL new conne/reneg - finished */
int sess_accept; /* SSL new accept - started */
int sess_accept_renegotiate; /* SSL reneg - requested */
int sess_accept_good; /* SSL accept/reneg - finished */
int sess_miss; /* session lookup misses */
int sess_timeout; /* reuse attempt on timeouted session */
int sess_cache_full; /* session removed due to full cache */
int sess_hit; /* session reuse actually done */
int sess_cb_hit; /* session-id that was not in the cache was
* passed back via the callback. This
* indicates that the application is supplying
* session-id's from other processes - spooky
TSAN_QUALIFIER int sess_connect; /* SSL new conn - started */
TSAN_QUALIFIER int sess_connect_renegotiate; /* SSL reneg - requested */
TSAN_QUALIFIER int sess_connect_good; /* SSL new conne/reneg - finished */
TSAN_QUALIFIER int sess_accept; /* SSL new accept - started */
TSAN_QUALIFIER int sess_accept_renegotiate; /* SSL reneg - requested */
TSAN_QUALIFIER int sess_accept_good; /* SSL accept/reneg - finished */
TSAN_QUALIFIER int sess_miss; /* session lookup misses */
TSAN_QUALIFIER int sess_timeout; /* reuse attempt on timeouted session */
TSAN_QUALIFIER int sess_cache_full; /* session removed due to full cache */
TSAN_QUALIFIER int sess_hit; /* session reuse actually done */
TSAN_QUALIFIER int sess_cb_hit; /* session-id that was not in
* the cache was passed back via
* the callback. This indicates
* that the application is
* supplying session-id's from
* other processes - spooky
* :-) */
} stats;
+7 -13
View File
@@ -448,7 +448,6 @@ SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id,
size_t sess_id_len)
{
SSL_SESSION *ret = NULL;
int discard;
if ((s->session_ctx->session_cache_mode
& SSL_SESS_CACHE_NO_INTERNAL_LOOKUP) == 0) {
@@ -469,8 +468,7 @@ SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id,
}
CRYPTO_THREAD_unlock(s->session_ctx->lock);
if (ret == NULL)
CRYPTO_atomic_add(&s->session_ctx->stats.sess_miss, 1, &discard,
s->session_ctx->lock);
tsan_counter(&s->session_ctx->stats.sess_miss);
}
if (ret == NULL && s->session_ctx->get_session_cb != NULL) {
@@ -479,8 +477,7 @@ SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id,
ret = s->session_ctx->get_session_cb(s, sess_id, sess_id_len, &copy);
if (ret != NULL) {
CRYPTO_atomic_add(&s->session_ctx->stats.sess_cb_hit, 1, &discard,
s->session_ctx->lock);
tsan_counter(&s->session_ctx->stats.sess_cb_hit);
/*
* Increment reference count now if the session callback asks us
@@ -533,7 +530,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello)
/* This is used only by servers. */
SSL_SESSION *ret = NULL;
int fatal = 0, discard;
int fatal = 0;
int try_session_cache = 0;
SSL_TICKET_STATUS r;
@@ -612,8 +609,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello)
}
if (ret->timeout < (long)(time(NULL) - ret->time)) { /* timeout */
CRYPTO_atomic_add(&s->session_ctx->stats.sess_timeout, 1, &discard,
s->session_ctx->lock);
tsan_counter(&s->session_ctx->stats.sess_timeout);
if (try_session_cache) {
/* session was from the cache, so remove it */
SSL_CTX_remove_session(s->session_ctx, ret);
@@ -641,8 +637,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello)
s->session = ret;
}
CRYPTO_atomic_add(&s->session_ctx->stats.sess_hit, 1, &discard,
s->session_ctx->lock);
tsan_counter(&s->session_ctx->stats.sess_hit);
s->verify_result = s->session->verify_result;
return 1;
@@ -669,7 +664,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello)
int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
{
int ret = 0, discard;
int ret = 0;
SSL_SESSION *s;
/*
@@ -736,8 +731,7 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
if (!remove_session_lock(ctx, ctx->session_cache_tail, 0))
break;
else
CRYPTO_atomic_add(&ctx->stats.sess_cache_full, 1, &discard,
ctx->lock);
tsan_counter(&ctx->stats.sess_cache_full);
}
}
}
+3 -5
View File
@@ -912,7 +912,7 @@ static int init_server_name(SSL *s, unsigned int context)
static int final_server_name(SSL *s, unsigned int context, int sent)
{
int ret = SSL_TLSEXT_ERR_NOACK, discard;
int ret = SSL_TLSEXT_ERR_NOACK;
int altmp = SSL_AD_UNRECOGNIZED_NAME;
int was_ticket = (SSL_get_options(s) & SSL_OP_NO_TICKET) == 0;
@@ -960,10 +960,8 @@ static int final_server_name(SSL *s, unsigned int context, int sent)
* exceed sess_accept (zero) for the new context.
*/
if (SSL_IS_FIRST_HANDSHAKE(s) && s->ctx != s->session_ctx) {
CRYPTO_atomic_add(&s->ctx->stats.sess_accept, 1, &discard,
s->ctx->lock);
CRYPTO_atomic_add(&s->session_ctx->stats.sess_accept, -1, &discard,
s->session_ctx->lock);
tsan_counter(&s->ctx->stats.sess_accept);
tsan_counter(&s->session_ctx->stats.sess_accept);
}
/*
+2 -1
View File
@@ -123,7 +123,8 @@ void ossl_statem_fatal(SSL *s, int al, int func, int reason, const char *file,
s->statem.in_init = 1;
s->statem.state = MSG_FLOW_ERROR;
ERR_put_error(ERR_LIB_SSL, func, reason, file, line);
if (al != SSL_AD_NO_ALERT && !s->statem.invalid_enc_write_ctx)
if (al != SSL_AD_NO_ALERT
&& s->statem.enc_write_state != ENC_WRITE_STATE_INVALID)
ssl3_send_alert(s, SSL3_AL_FATAL, al);
}
+18 -1
View File
@@ -71,6 +71,22 @@ typedef enum {
WRITE_STATE_POST_WORK
} WRITE_STATE;
typedef enum {
/* The enc_write_ctx can be used normally */
ENC_WRITE_STATE_VALID,
/* The enc_write_ctx cannot be used */
ENC_WRITE_STATE_INVALID,
/* Write alerts in plaintext, but otherwise use the enc_write_ctx */
ENC_WRITE_STATE_WRITE_PLAIN_ALERTS
} ENC_WRITE_STATES;
typedef enum {
/* The enc_read_ctx can be used normally */
ENC_READ_STATE_VALID,
/* We may receive encrypted or plaintext alerts */
ENC_READ_STATE_ALLOW_PLAIN_ALERTS
} ENC_READ_STATES;
/*****************************************************************************
* *
* This structure should be considered "opaque" to anything outside of the *
@@ -100,7 +116,8 @@ struct ossl_statem_st {
/* Should we skip the CertificateVerify message? */
unsigned int no_cert_verify;
int use_timer;
int invalid_enc_write_ctx;
ENC_WRITE_STATES enc_write_state;
ENC_READ_STATES enc_read_state;
};
typedef struct ossl_statem_st OSSL_STATEM;
+11 -7
View File
@@ -1409,7 +1409,6 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt)
unsigned int compression;
unsigned int sversion;
unsigned int context;
int discard;
RAW_EXTENSION *extensions = NULL;
#ifndef OPENSSL_NO_COMP
SSL_COMP *comp;
@@ -1616,8 +1615,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt)
|| (SSL_IS_TLS13(s)
&& s->session->ext.tick_identity
!= TLSEXT_PSK_BAD_IDENTITY)) {
CRYPTO_atomic_add(&s->session_ctx->stats.sess_miss, 1, &discard,
s->session_ctx->lock);
tsan_counter(&s->session_ctx->stats.sess_miss);
if (!ssl_get_new_session(s, 0)) {
/* SSLfatal() already called */
goto err;
@@ -2647,10 +2645,16 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt)
PACKET extpkt;
if (!PACKET_as_length_prefixed_2(pkt, &extpkt)
|| PACKET_remaining(pkt) != 0
|| !tls_collect_extensions(s, &extpkt,
SSL_EXT_TLS1_3_NEW_SESSION_TICKET,
&exts, NULL, 1)
|| PACKET_remaining(pkt) != 0) {
SSLfatal(s, SSL_AD_DECODE_ERROR,
SSL_F_TLS_PROCESS_NEW_SESSION_TICKET,
SSL_R_LENGTH_MISMATCH);
goto err;
}
if (!tls_collect_extensions(s, &extpkt,
SSL_EXT_TLS1_3_NEW_SESSION_TICKET, &exts,
NULL, 1)
|| !tls_parse_all_extensions(s,
SSL_EXT_TLS1_3_NEW_SESSION_TICKET,
exts, NULL, 0, 1)) {
+16 -16
View File
@@ -132,23 +132,18 @@ int tls_setup_handshake(SSL *s)
}
if (SSL_IS_FIRST_HANDSHAKE(s)) {
/* N.B. s->session_ctx == s->ctx here */
CRYPTO_atomic_add(&s->session_ctx->stats.sess_accept, 1, &i,
s->session_ctx->lock);
tsan_counter(&s->session_ctx->stats.sess_accept);
} else {
/* N.B. s->ctx may not equal s->session_ctx */
CRYPTO_atomic_add(&s->ctx->stats.sess_accept_renegotiate, 1, &i,
s->ctx->lock);
tsan_counter(&s->ctx->stats.sess_accept_renegotiate);
s->s3->tmp.cert_request = 0;
}
} else {
int discard;
if (SSL_IS_FIRST_HANDSHAKE(s))
CRYPTO_atomic_add(&s->session_ctx->stats.sess_connect, 1, &discard,
s->session_ctx->lock);
tsan_counter(&s->session_ctx->stats.sess_connect);
else
CRYPTO_atomic_add(&s->session_ctx->stats.sess_connect_renegotiate,
1, &discard, s->session_ctx->lock);
tsan_counter(&s->session_ctx->stats.sess_connect_renegotiate);
/* mark client_random uninitialized */
memset(s->s3->client_random, 0, sizeof(s->s3->client_random));
@@ -752,6 +747,12 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt)
/* This is a real handshake so make sure we clean it up at the end */
if (s->server) {
/*
* To get this far we must have read encrypted data from the client. We
* no longer tolerate unencrypted alerts. This value is ignored if less
* than TLSv1.3
*/
s->statem.enc_read_state = ENC_READ_STATE_VALID;
if (s->post_handshake_auth != SSL_PHA_REQUESTED)
s->statem.cleanuphand = 1;
if (SSL_IS_TLS13(s) && !tls13_save_handshake_digest_for_pha(s)) {
@@ -1009,7 +1010,6 @@ unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk)
*/
WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop)
{
int discard;
void (*cb) (const SSL *ssl, int type, int val) = NULL;
if (clearbufs) {
@@ -1055,8 +1055,7 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop)
ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
/* N.B. s->ctx may not equal s->session_ctx */
CRYPTO_atomic_add(&s->ctx->stats.sess_accept_good, 1, &discard,
s->ctx->lock);
tsan_counter(&s->ctx->stats.sess_accept_good);
s->handshake_func = ossl_statem_accept;
if (SSL_IS_DTLS(s) && !s->hit) {
@@ -1084,12 +1083,10 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop)
ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
}
if (s->hit)
CRYPTO_atomic_add(&s->session_ctx->stats.sess_hit, 1, &discard,
s->session_ctx->lock);
tsan_counter(&s->session_ctx->stats.sess_hit);
s->handshake_func = ossl_statem_connect;
CRYPTO_atomic_add(&s->session_ctx->stats.sess_connect_good, 1,
&discard, s->session_ctx->lock);
tsan_counter(&s->session_ctx->stats.sess_connect_good);
if (SSL_IS_DTLS(s) && s->hit) {
/*
@@ -1917,6 +1914,9 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions)
if (highver != 0 && s->version != vent->version)
continue;
if (highver == 0 && (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) != 0)
highver = vent->version;
method = vent->cmeth();
err = ssl_method_error(s, method);
if (err != 0) {
+22 -10
View File
@@ -848,12 +848,7 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
return WORK_MORE_A;
break;
}
/*
* TODO(TLS1.3): This actually causes a problem. We don't yet know
* whether the next record we are going to receive is an unencrypted
* alert, or an encrypted handshake message. We're going to need
* something clever in the record layer for this.
*/
if (SSL_IS_TLS13(s)) {
if (!s->method->ssl3_enc->setup_key_block(s)
|| !s->method->ssl3_enc->change_cipher_state(s,
@@ -868,6 +863,12 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
/* SSLfatal() already called */
return WORK_ERROR;
}
/*
* We don't yet know whether the next record we are going to receive
* is an unencrypted alert, an encrypted alert, or an encrypted
* handshake message. We temporarily tolerate unencrypted alerts.
*/
s->statem.enc_read_state = ENC_READ_STATE_ALLOW_PLAIN_ALERTS;
break;
}
@@ -2371,10 +2372,14 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt)
if (!WPACKET_sub_memcpy_u8(pkt, session_id, sl)
|| !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, pkt, &len)
|| !WPACKET_put_bytes_u8(pkt, compm)
|| !tls_construct_extensions(s, pkt,
s->hello_retry_request
== SSL_HRR_PENDING
|| !WPACKET_put_bytes_u8(pkt, compm)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_SERVER_HELLO,
ERR_R_INTERNAL_ERROR);
return 0;
}
if (!tls_construct_extensions(s, pkt,
s->hello_retry_request == SSL_HRR_PENDING
? SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST
: (SSL_IS_TLS13(s)
? SSL_EXT_TLS1_3_SERVER_HELLO
@@ -3520,6 +3525,13 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
size_t chainidx;
SSL_SESSION *new_sess = NULL;
/*
* To get this far we must have read encrypted data from the client. We no
* longer tolerate unencrypted alerts. This value is ignored if less than
* TLSv1.3
*/
s->statem.enc_read_state = ENC_READ_STATE_VALID;
if ((sk = sk_X509_new_null()) == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
ERR_R_MALLOC_FAILURE);
+2 -2
View File
@@ -154,7 +154,7 @@ int tls1_change_cipher_state(SSL *s, int which)
mac_secret = &(s->s3->read_mac_secret[0]);
mac_secret_size = &(s->s3->read_mac_secret_size);
} else {
s->statem.invalid_enc_write_ctx = 1;
s->statem.enc_write_state = ENC_WRITE_STATE_INVALID;
if (s->ext.use_etm)
s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE;
else
@@ -316,7 +316,7 @@ int tls1_change_cipher_state(SSL *s, int which)
ERR_R_INTERNAL_ERROR);
goto err;
}
s->statem.invalid_enc_write_ctx = 0;
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
#ifdef SSL_DEBUG
printf("which = %04X\nkey=", which);
+7 -4
View File
@@ -425,7 +425,7 @@ int tls13_change_cipher_state(SSL *s, int which)
RECORD_LAYER_reset_read_sequence(&s->rlayer);
} else {
s->statem.invalid_enc_write_ctx = 1;
s->statem.enc_write_state = ENC_WRITE_STATE_INVALID;
if (s->enc_write_ctx != NULL) {
EVP_CIPHER_CTX_reset(s->enc_write_ctx);
} else {
@@ -648,7 +648,10 @@ int tls13_change_cipher_state(SSL *s, int which)
goto err;
}
s->statem.invalid_enc_write_ctx = 0;
if (!s->server && label == client_early_traffic)
s->statem.enc_write_state = ENC_WRITE_STATE_WRITE_PLAIN_ALERTS;
else
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
ret = 1;
err:
OPENSSL_cleanse(secret, sizeof(secret));
@@ -671,7 +674,7 @@ int tls13_update_key(SSL *s, int sending)
insecret = s->client_app_traffic_secret;
if (sending) {
s->statem.invalid_enc_write_ctx = 1;
s->statem.enc_write_state = ENC_WRITE_STATE_INVALID;
iv = s->write_iv;
ciph_ctx = s->enc_write_ctx;
RECORD_LAYER_reset_write_sequence(&s->rlayer);
@@ -692,7 +695,7 @@ int tls13_update_key(SSL *s, int sending)
memcpy(insecret, secret, hashlen);
s->statem.invalid_enc_write_ctx = 0;
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
ret = 1;
err:
OPENSSL_cleanse(secret, sizeof(secret));
+17 -1
View File
@@ -67,6 +67,7 @@ static int test_standard_methods(void)
const EVP_PKEY_ASN1_METHOD **tmp;
int last_pkey_id = -1;
size_t i;
int ok = 1;
for (tmp = standard_methods, i = 0; i < OSSL_NELEM(standard_methods);
i++, tmp++) {
@@ -75,11 +76,26 @@ static int test_standard_methods(void)
break;
}
last_pkey_id = (*tmp)->pkey_id;
/*
* One of the following must be true:
*
* pem_str == NULL AND ASN1_PKEY_ALIAS is set
* pem_str != NULL AND ASN1_PKEY_ALIAS is clear
*
* Anything else is an error and may lead to a corrupt ASN1 method table
*/
if (!TEST_true(((*tmp)->pem_str == NULL && ((*tmp)->pkey_flags & ASN1_PKEY_ALIAS) != 0)
|| ((*tmp)->pem_str != NULL && ((*tmp)->pkey_flags & ASN1_PKEY_ALIAS) == 0))) {
TEST_note("asn1 standard methods: Index %zu, pkey ID %d, Name=%s",
i, (*tmp)->pkey_id, OBJ_nid2sn((*tmp)->pkey_id));
ok = 0;
}
}
if (TEST_int_ne(last_pkey_id, 0)) {
TEST_info("asn1 standard methods: Table order OK");
return 1;
return ok;
}
TEST_note("asn1 standard methods: out of order");
+56
View File
@@ -0,0 +1,56 @@
#! /usr/bin/env perl
# Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the OpenSSL license (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
use strict;
use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/;
use OpenSSL::Test::Utils;
use TLSProxy::Proxy;
my $test_name = "test_tls13alerts";
setup($test_name);
plan skip_all => "TLSProxy isn't usable on $^O"
if $^O =~ /^(VMS)$/;
plan skip_all => "$test_name needs the dynamic engine feature enabled"
if disabled("engine") || disabled("dynamic-engine");
plan skip_all => "$test_name needs the sock feature enabled"
if disabled("sock");
plan skip_all => "$test_name needs TLS1.3 enabled"
if disabled("tls1_3");
$ENV{OPENSSL_ia32cap} = '~0x200000200000000';
my $proxy = TLSProxy::Proxy->new(
undef,
cmdstr(app(["openssl"]), display => 1),
srctop_file("apps", "server.pem"),
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
#Test 1: We test that a server can handle an unencrypted alert when normally the
# next message is encrypted
$proxy->filter(\&alert_filter);
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
plan tests => 1;
my $alert = TLSProxy::Message->alert();
ok(TLSProxy::Message->fail() && !$alert->server() && !$alert->encrypted(), "Client sends an unecrypted alert");
sub alert_filter
{
my $proxy = shift;
if ($proxy->flight != 1) {
return;
}
${$proxy->message_list}[1]->session_id_len(1);
${$proxy->message_list}[1]->repack();
}
+22 -2
View File
@@ -41,14 +41,15 @@ my $proxy = TLSProxy::Proxy->new(
use constant {
DOWNGRADE_TO_TLS_1_2 => 0,
DOWNGRADE_TO_TLS_1_1 => 1
DOWNGRADE_TO_TLS_1_1 => 1,
FALLBACK_FROM_TLS_1_3 => 2,
};
#Test 1: Downgrade from TLSv1.3 to TLSv1.2
$proxy->filter(\&downgrade_filter);
my $testtype = DOWNGRADE_TO_TLS_1_2;
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
plan tests => 3;
plan tests => 4;
ok(TLSProxy::Message->fail(), "Downgrade TLSv1.3 to TLSv1.2");
#Test 2: Downgrade from TLSv1.3 to TLSv1.1
@@ -64,6 +65,18 @@ $proxy->serverflags("-no_tls1_3");
$proxy->start();
ok(TLSProxy::Message->fail(), "Downgrade TLSv1.2 to TLSv1.1");
#Test 4: Client falls back from TLSv1.3 (server does not support the fallback
# SCSV)
$proxy->clear();
$testtype = FALLBACK_FROM_TLS_1_3;
$proxy->clientflags("-fallback_scsv -no_tls1_3");
$proxy->start();
my $alert = TLSProxy::Message->alert();
ok(TLSProxy::Message->fail()
&& !$alert->server()
&& $alert->description() == TLSProxy::Message::AL_DESC_ILLEGAL_PARAMETER,
"Fallback from TLSv1.3");
sub downgrade_filter
{
my $proxy = shift;
@@ -76,6 +89,12 @@ sub downgrade_filter
my $message = ${$proxy->message_list}[0];
my $ext;
if ($testtype == FALLBACK_FROM_TLS_1_3) {
#The default ciphersuite we use for TLSv1.2 without any SCSV
my @ciphersuites = (TLSProxy::Message::CIPHER_RSA_WITH_AES_128_CBC_SHA);
$message->ciphersuite_len(2 * scalar @ciphersuites);
$message->ciphersuites(\@ciphersuites);
} else {
if ($testtype == DOWNGRADE_TO_TLS_1_2) {
$ext = pack "C3",
0x02, # Length
@@ -87,6 +106,7 @@ sub downgrade_filter
}
$message->set_extension(TLSProxy::Message::EXT_SUPPORTED_VERSIONS, $ext);
}
$message->repack();
}
+6
View File
@@ -84,6 +84,11 @@ static int test_sanity_range(void)
return 1;
}
static int test_sanity_memcmp(void)
{
return CRYPTO_memcmp("ab","cd",2);
}
int setup_tests(void)
{
ADD_TEST(test_sanity_null_zero);
@@ -92,6 +97,7 @@ int setup_tests(void)
ADD_TEST(test_sanity_sign);
ADD_TEST(test_sanity_unsigned_conversion);
ADD_TEST(test_sanity_range);
ADD_TEST(test_sanity_memcmp);
return 1;
}
-6
View File
@@ -531,11 +531,6 @@ static int test_bn_output(int n)
return 1;
}
static int test_memcmp(void)
{
return CRYPTO_memcmp("ab","cd",2);
}
int setup_tests(void)
{
ADD_TEST(test_int);
@@ -557,7 +552,6 @@ int setup_tests(void)
ADD_TEST(test_messages);
ADD_TEST(test_single_eval);
ADD_TEST(test_output);
ADD_TEST(test_memcmp);
ADD_ALL_TESTS(test_bn_output, OSSL_NELEM(bn_output_tests));
return 1;
}
+51
View File
@@ -0,0 +1,51 @@
# Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the OpenSSL license (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
use strict;
package TLSProxy::Alert;
sub new
{
my $class = shift;
my ($server,
$encrypted,
$level,
$description) = @_;
my $self = {
server => $server,
encrypted => $encrypted,
level => $level,
description => $description
};
return bless $self, $class;
}
#Read only accessors
sub server
{
my $self = shift;
return $self->{server};
}
sub encrypted
{
my $self = shift;
return $self->{encrypted};
}
sub level
{
my $self = shift;
return $self->{level};
}
sub description
{
my $self = shift;
return $self->{description};
}
1;
+17
View File
@@ -9,6 +9,8 @@ use strict;
package TLSProxy::Message;
use TLSProxy::Alert;
use constant TLS_MESSAGE_HEADER_LENGTH => 4;
#Message types
@@ -39,6 +41,7 @@ use constant {
use constant {
AL_DESC_CLOSE_NOTIFY => 0,
AL_DESC_UNEXPECTED_MESSAGE => 10,
AL_DESC_ILLEGAL_PARAMETER => 47,
AL_DESC_NO_RENEGOTIATION => 100
};
@@ -123,6 +126,7 @@ use constant {
};
use constant {
CIPHER_RSA_WITH_AES_128_CBC_SHA => 0x002f,
CIPHER_DHE_RSA_AES_128_SHA => 0x0033,
CIPHER_ADH_AES_128_SHA => 0x0034,
CIPHER_TLS13_AES_128_GCM_SHA256 => 0x1301,
@@ -140,6 +144,7 @@ my @message_rec_list = ();
my @message_frag_lens = ();
my $ciphersuite = 0;
my $successondata = 0;
my $alert;
sub clear
{
@@ -152,6 +157,7 @@ sub clear
$successondata = 0;
@message_rec_list = ();
@message_frag_lens = ();
$alert = undef;
}
#Class method to extract messages from a record
@@ -281,6 +287,11 @@ sub get_messages
if ($alertlev == AL_LEVEL_FATAL || $alertdesc == AL_DESC_CLOSE_NOTIFY) {
$end = 1;
}
$alert = TLSProxy::Alert->new(
$server,
$record->encrypted,
$alertlev,
$alertdesc);
}
return @messages;
@@ -388,6 +399,12 @@ sub fail
my $class = shift;
return !$success && $end;
}
sub alert
{
return $alert;
}
sub new
{
my $class = shift;
+3 -1
View File
@@ -97,7 +97,9 @@ sub get_records
$data # decrypt_data
);
if ($content_type != RT_CCS) {
if ($content_type != RT_CCS
&& (!TLSProxy::Proxy->is_tls13()
|| $content_type != RT_ALERT)) {
if (($server && $server_encrypting)
|| (!$server && $client_encrypting)) {
if (!TLSProxy::Proxy->is_tls13() && $etm) {