The branch master has been updated via f6c024c2e7f33e9d26c62cf19d519e5ef7fa4a09 (commit) via 75a8f1eff03a1c91c22683b022e2145628962157 (commit) via 0b020b14882173918b9cc3e8e3bd85fb9ffac948 (commit) via 273f7fe16a6e4b2a443fb16846beaffd70461750 (commit) via 4cabbb9f485ba7d1edcfbbd2aa8610159f94543e (commit) from faec5c4a8aa3943d835bdad26800a103426b0eda (commit)
- Log ----------------------------------------------------------------- commit f6c024c2e7f33e9d26c62cf19d519e5ef7fa4a09 Author: Matt Caswell <m...@openssl.org> Date: Tue Mar 27 10:58:34 2018 +0100 Update CHANGES and NEWS for the new release Reviewed-by: Richard Levitte <levi...@openssl.org> commit 75a8f1eff03a1c91c22683b022e2145628962157 Author: Andy Polyakov <ap...@openssl.org> Date: Mon Mar 26 10:55:35 2018 +0200 test/test_test.c: add CRYPTO_memcmp regression test. Reviewed-by: Matt Caswell <m...@openssl.org> commit 0b020b14882173918b9cc3e8e3bd85fb9ffac948 Author: Andy Polyakov <ap...@openssl.org> Date: Wed Mar 21 23:48:10 2018 +0100 pariscid.pl: fix nasty typo in CRYPTO_memcmp. Comparison was effectively reduced to least significant bits. CVE-2018-0733 Reviewed-by: Matt Caswell <m...@openssl.org> commit 273f7fe16a6e4b2a443fb16846beaffd70461750 Author: Matt Caswell <m...@openssl.org> Date: Fri Jan 26 16:23:03 2018 +0000 Add fuzz corpora file that found the ASN.1 stack depth issue Reviewed-by: Rich Salz <rs...@openssl.org> commit 4cabbb9f485ba7d1edcfbbd2aa8610159f94543e Author: Matt Caswell <m...@openssl.org> Date: Thu Mar 22 09:39:53 2018 +0000 Limit ASN.1 constructed types recursive definition depth Constructed types with a recursive definition (such as can be found in PKCS7) could eventually exceed the stack given malicious input with excessive recursion. Therefore we limit the stack depth. CVE-2018-0739 Credit to OSSFuzz for finding this issue. Reviewed-by: Rich Salz <rs...@openssl.org> ----------------------------------------------------------------------- Summary of changes: CHANGES | 46 ++++++++++++++++++++ NEWS | 5 ++- crypto/asn1/asn1_err.c | 3 +- crypto/asn1/tasn_dec.c | 48 ++++++++++++++------- crypto/err/openssl.txt | 1 + crypto/pariscid.pl | 2 +- .../asn1/eba5151118ff75ce6a86438a3a6f819c41d8be40 | Bin 0 -> 73846 bytes include/openssl/asn1err.h | 1 + test/test_test.c | 5 +++ 9 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 fuzz/corpora/asn1/eba5151118ff75ce6a86438a3a6f819c41d8be40 diff --git a/CHANGES b/CHANGES index 3f6c8de..462394c 100644 --- a/CHANGES +++ b/CHANGES @@ -292,6 +292,52 @@ Changes between 1.1.0g and 1.1.0h [xx XXX xxxx] + *) Constructed ASN.1 types with a recursive definition could exceed the stack + + Constructed ASN.1 types with a recursive definition (such as can be found + in PKCS7) could eventually exceed the stack given malicious input with + excessive recursion. This could result in a Denial Of Service attack. There + are no such structures used within SSL/TLS that come from untrusted sources + so this is considered safe. + + This issue was reported to OpenSSL on 4th January 2018 by the OSS-fuzz + project. + (CVE-2018-0739) + [Matt Caswell] + + *) Incorrect CRYPTO_memcmp on HP-UX PA-RISC + + Because of an implementation bug the PA-RISC CRYPTO_memcmp function is + effectively reduced to only comparing the least significant bit of each + byte. This allows an attacker to forge messages that would be considered as + authenticated in an amount of tries lower than that guaranteed by the + security claims of the scheme. The module can only be compiled by the + HP-UX assembler, so that only HP-UX PA-RISC targets are affected. + + This issue was reported to OpenSSL on 2nd March 2018 by Peter Waltenberg + (IBM). + (CVE-2018-0733) + [Andy Polyakov] + + *) Add a build target 'build_all_generated', to build all generated files + and only that. This can be used to prepare everything that requires + things like perl for a system that lacks perl and then move everything + to that system and do the rest of the build there. + [Richard Levitte] + + *) Backport SSL_OP_NO_RENGOTIATION + + OpenSSL 1.0.2 and below had the ability to disable renegotiation using the + (undocumented) SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS flag. Due to the opacity + changes this is no longer possible in 1.1.0. Therefore the new + SSL_OP_NO_RENEGOTIATION option from 1.1.1-dev has been backported to + 1.1.0 to provide equivalent functionality. + + Note that if an application built against 1.1.0h headers (or above) is run + using an older version of 1.1.0 (prior to 1.1.0h) then the option will be + accepted but nothing will happen, i.e. renegotiation will not be prevented. + [Matt Caswell] + *) Removed the OS390-Unix config target. It relied on a script that doesn't exist. [Rich Salz] diff --git a/NEWS b/NEWS index c60da87..60c841f 100644 --- a/NEWS +++ b/NEWS @@ -5,7 +5,7 @@ This file gives a brief overview of the major changes between each OpenSSL release. For more details please read the CHANGES file. - Major changes between OpenSSL 1.1.0g and OpenSSL 1.1.1 [in pre-release] + Major changes between OpenSSL 1.1.0h and OpenSSL 1.1.1 [in pre-release] o Support for TLSv1.3 added o Move the display of configuration data to configdata.pm. @@ -24,6 +24,9 @@ Major changes between OpenSSL 1.1.0g and OpenSSL 1.1.0h [under development] + o Constructed ASN.1 types with a recursive definition could exceed the + stack (CVE-2018-0739) + o Incorrect CRYPTO_memcmp on HP-UX PA-RISC (CVE-2018-0733) o rsaz_1024_mul_avx2 overflow bug on x86_64 (CVE-2017-3738) Major changes between OpenSSL 1.1.0f and OpenSSL 1.1.0g [2 Nov 2017] diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c index da856b2..de92adc 100644 --- a/crypto/asn1/asn1_err.c +++ b/crypto/asn1/asn1_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-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 @@ -246,6 +246,7 @@ static const ERR_STRING_DATA ASN1_str_reasons[] = { {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NESTED_ASN1_STRING), "nested asn1 string"}, + {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NESTED_TOO_DEEP), "nested too deep"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NON_HEX_CHARACTERS), "non hex characters"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NOT_ASCII_FORMAT), "not ascii format"}, diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c index 8667bec..9cdee2d 100644 --- a/crypto/asn1/tasn_dec.c +++ b/crypto/asn1/tasn_dec.c @@ -17,9 +17,19 @@ #include "internal/numbers.h" #include "asn1_locl.h" + +/* + * Constructed types with a recursive definition (such as can be found in PKCS7) + * could eventually exceed the stack given malicious input with excessive + * recursion. Therefore we limit the stack depth. This is the maximum number of + * recursive invocations of asn1_item_embed_d2i(). + */ +#define ASN1_MAX_CONSTRUCTED_NEST 30 + static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx); + int tag, int aclass, char opt, ASN1_TLC *ctx, + int depth); static int asn1_check_eoc(const unsigned char **in, long len); static int asn1_find_end(const unsigned char **in, long len, char inf); @@ -37,11 +47,11 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx); + ASN1_TLC *ctx, int depth); static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx); + ASN1_TLC *ctx, int depth); static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, @@ -111,7 +121,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, int tag, int aclass, char opt, ASN1_TLC *ctx) { int rv; - rv = asn1_item_embed_d2i(pval, in, len, it, tag, aclass, opt, ctx); + rv = asn1_item_embed_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); if (rv <= 0) ASN1_item_ex_free(pval, it); return rv; @@ -124,7 +134,8 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx) + int tag, int aclass, char opt, ASN1_TLC *ctx, + int depth) { const ASN1_TEMPLATE *tt, *errtt = NULL; const ASN1_EXTERN_FUNCS *ef; @@ -145,6 +156,11 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, else asn1_cb = 0; + if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { + ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_NESTED_TOO_DEEP); + goto err; + } + switch (it->itype) { case ASN1_ITYPE_PRIMITIVE: if (it->templates) { @@ -160,7 +176,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, goto err; } return asn1_template_ex_d2i(pval, in, len, - it->templates, opt, ctx); + it->templates, opt, ctx, depth); } return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt, ctx); @@ -221,7 +237,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, /* * We mark field as OPTIONAL so its absence can be recognised. */ - ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); + ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth); /* If field not present, try the next one */ if (ret == -1) continue; @@ -344,7 +360,8 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, * attempt to read in field, allowing each to be OPTIONAL */ - ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx); + ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx, + depth); if (!ret) { errtt = seqtt; goto err; @@ -420,7 +437,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx) + ASN1_TLC *ctx, int depth) { int flags, aclass; int ret; @@ -455,7 +472,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, return 0; } /* We've found the field so it can't be OPTIONAL now */ - ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx); + ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth); if (!ret) { ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); return 0; @@ -479,7 +496,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, } } } else - return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx); + return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth); *in = p; return 1; @@ -491,7 +508,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx) + ASN1_TLC *ctx, int depth) { int flags, aclass; int ret; @@ -573,7 +590,8 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, } skfield = NULL; if (!asn1_item_embed_d2i(&skfield, &p, len, - ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) { + ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx, + depth)) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); /* |skfield| may be partially allocated despite failure. */ @@ -595,7 +613,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, /* IMPLICIT tagging */ ret = asn1_item_embed_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, - ctx); + ctx, depth); if (!ret) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); goto err; @@ -604,7 +622,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, } else { /* Nothing special */ ret = asn1_item_embed_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), - -1, 0, opt, ctx); + -1, 0, opt, ctx, depth); if (!ret) { ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); goto err; diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index bb8c157..4fa56fd 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -1680,6 +1680,7 @@ ASN1_R_MISSING_VALUE:189:missing value ASN1_R_MSTRING_NOT_UNIVERSAL:139:mstring not universal ASN1_R_MSTRING_WRONG_TAG:140:mstring wrong tag ASN1_R_NESTED_ASN1_STRING:197:nested asn1 string +ASN1_R_NESTED_TOO_DEEP:201:nested too deep ASN1_R_NON_HEX_CHARACTERS:141:non hex characters ASN1_R_NOT_ASCII_FORMAT:190:not ascii format ASN1_R_NOT_ENOUGH_DATA:142:not enough data diff --git a/crypto/pariscid.pl b/crypto/pariscid.pl index f82e27a..3e26f8e 100644 --- a/crypto/pariscid.pl +++ b/crypto/pariscid.pl @@ -160,7 +160,7 @@ L\$oop_cmp or %r29,$rv,$rv sub %r0,$rv,%r29 - extru %r29,31,1,$rv + extru %r29,0,1,$rv L\$no_data bv ($rp) .EXIT diff --git a/fuzz/corpora/asn1/eba5151118ff75ce6a86438a3a6f819c41d8be40 b/fuzz/corpora/asn1/eba5151118ff75ce6a86438a3a6f819c41d8be40 new file mode 100644 index 0000000..030b710 Binary files /dev/null and b/fuzz/corpora/asn1/eba5151118ff75ce6a86438a3a6f819c41d8be40 differ diff --git a/include/openssl/asn1err.h b/include/openssl/asn1err.h index 7da927f..a53bc4a 100644 --- a/include/openssl/asn1err.h +++ b/include/openssl/asn1err.h @@ -191,6 +191,7 @@ int ERR_load_ASN1_strings(void); # define ASN1_R_MSTRING_NOT_UNIVERSAL 139 # define ASN1_R_MSTRING_WRONG_TAG 140 # define ASN1_R_NESTED_ASN1_STRING 197 +# define ASN1_R_NESTED_TOO_DEEP 201 # define ASN1_R_NON_HEX_CHARACTERS 141 # define ASN1_R_NOT_ASCII_FORMAT 190 # define ASN1_R_NOT_ENOUGH_DATA 142 diff --git a/test/test_test.c b/test/test_test.c index c45bf8d..76b61f8 100644 --- a/test/test_test.c +++ b/test/test_test.c @@ -531,6 +531,10 @@ static int test_bn_output(int n) return 1; } +static int test_memcmp(void) +{ + return CRYPTO_memcmp("ab","cd",2); +} int setup_tests(void) { @@ -553,6 +557,7 @@ 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; } _____ openssl-commits mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-commits