, 's', "string to generate ASN1 structure from"}, {OPT_MORE_STR, 0, 0, "into multiple ASN1 blob wrappings"}, + {"genstr", OPT_GENSTR, 's', "string to generate ASN1 structure from"}, {"genconf", OPT_GENCONF, 's', "file to generate ASN1 structure from"}, {"strictpem", OPT_STRICTPEM, 0, "equivalent to '-inform pem' (obsolete)"}, diff --git a/crypto/openssl/apps/cms.c b/crypto/openssl/apps/cms.c index 919d306ff687..6f19414880c9 100644 --- a/crypto/openssl/apps/cms.c +++ b/crypto/openssl/apps/cms.c @@ -1280,6 +1280,7 @@ int cms_main(int argc, char **argv) goto end; } if (ret <= 0) { + BIO_printf(bio_err, "Error writing CMS output\n"); ret = 6; goto end; } diff --git a/crypto/openssl/apps/enc.c b/crypto/openssl/apps/enc.c index 3f45ba15e576..33949d402dd7 100644 --- a/crypto/openssl/apps/enc.c +++ b/crypto/openssl/apps/enc.c @@ -260,6 +260,8 @@ int enc_main(int argc, char **argv) goto opthelp; if (k) n *= 1024; + if (n > INT_MAX) + goto opthelp; bsize = (int)n; break; case OPT_K: diff --git a/crypto/openssl/apps/include/apps.h b/crypto/openssl/apps/include/apps.h index ceebfde72786..11381ea7da8c 100644 --- a/crypto/openssl/apps/include/apps.h +++ b/crypto/openssl/apps/include/apps.h @@ -103,7 +103,6 @@ int wrap_password_callback(char *buf, int bufsiz, int verify, void *cb_data); /* progress callback for dsaparam, dhparam, req, genpkey, etc. */ int progress_cb(EVP_PKEY_CTX *ctx); -int chopup_args(ARGS *arg, char *buf); void dump_cert_text(BIO *out, X509 *x); void print_name(BIO *out, const char *title, const X509_NAME *nm); void print_bignum_var(BIO *, const BIGNUM *, const char *, diff --git a/crypto/openssl/apps/lib/apps.c b/crypto/openssl/apps/lib/apps.c index d4e72307de58..1b9c9e3e9a19 100644 --- a/crypto/openssl/apps/lib/apps.c +++ b/crypto/openssl/apps/lib/apps.c @@ -83,55 +83,6 @@ static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl); int app_init(long mesgwin); -int chopup_args(ARGS *arg, char *buf) -{ - int quoted; - char c = '\0', *p = NULL; - - arg->argc = 0; - if (arg->size == 0) { - arg->size = 20; - arg->argv = app_malloc(sizeof(*arg->argv) * arg->size, "argv space"); - } - - for (p = buf;;) { - /* Skip whitespace. */ - while (*p && isspace(_UC(*p))) - p++; - if (*p == '\0') - break; - - /* The start of something good :-) */ - if (arg->argc >= arg->size) { - char **tmp; - - arg->size += 20; - tmp = OPENSSL_realloc(arg->argv, sizeof(*arg->argv) * arg->size); - if (tmp == NULL) - return 0; - arg->argv = tmp; - } - quoted = *p == '\'' || *p == '"'; - if (quoted) - c = *p++; - arg->argv[arg->argc++] = p; - - /* now look for the end of this */ - if (quoted) { - while (*p && *p != c) - p++; - *p++ = '\0'; - } else { - while (*p && !isspace(_UC(*p))) - p++; - if (*p) - *p++ = '\0'; - } - } - arg->argv[arg->argc] = NULL; - return 1; -} - #ifndef APP_INIT int app_init(long mesgwin) { diff --git a/crypto/openssl/apps/ocsp.c b/crypto/openssl/apps/ocsp.c index 79b76a2ca747..95a95f56cb99 100644 --- a/crypto/openssl/apps/ocsp.c +++ b/crypto/openssl/apps/ocsp.c @@ -662,7 +662,8 @@ redo_accept: resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); - send_ocsp_response(cbio, resp); + if (resp != NULL) + send_ocsp_response(cbio, resp); } goto done_resp; } @@ -764,16 +765,18 @@ redo_accept: BIO_free(derbio); } - i = OCSP_response_status(resp); - if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { - BIO_printf(out, "Responder Error: %s (%d)\n", - OCSP_response_status_str(i), i); - if (!ignore_err) + if (resp != NULL) { + i = OCSP_response_status(resp); + if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { + BIO_printf(out, "Responder Error: %s (%d)\n", + OCSP_response_status_str(i), i); + if (!ignore_err) goto end; - } + } - if (resp_text) - OCSP_RESPONSE_print(out, resp, 0); + if (resp_text) + OCSP_RESPONSE_print(out, resp, 0); + } /* If running as responder don't verify our own response */ if (cbio != NULL) { diff --git a/crypto/openssl/apps/rand.c b/crypto/openssl/apps/rand.c index b123a151ea74..da747c1783e4 100644 --- a/crypto/openssl/apps/rand.c +++ b/crypto/openssl/apps/rand.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2025 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 @@ -199,7 +199,7 @@ int rand_main(int argc, char **argv) int chunk; chunk = scaled_num > buflen ? (int)buflen : (int)scaled_num; - r = RAND_bytes(buf, chunk); + r = RAND_bytes_ex(app_get0_libctx(), buf, chunk, 0); if (r <= 0) goto end; if (format != FORMAT_TEXT) { diff --git a/crypto/openssl/crypto/aes/asm/aes-s390x.pl b/crypto/openssl/crypto/aes/asm/aes-s390x.pl index 5d1283f57690..2345d4574a41 100755 --- a/crypto/openssl/crypto/aes/asm/aes-s390x.pl +++ b/crypto/openssl/crypto/aes/asm/aes-s390x.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2025 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 @@ -1431,6 +1431,9 @@ $code.=<<___ if (!$softonly); st${g} $s3,0($sp) # backchain la %r1,$stdframe($sp) + xc $stdframe+0(64,$sp),$stdframe+0($sp) # clear reserved/unused + # in parameter block + lmg $s2,$s3,0($key) # copy key stg $s2,$stdframe+80($sp) stg $s3,$stdframe+88($sp) diff --git a/crypto/openssl/crypto/asn1/asn_mime.c b/crypto/openssl/crypto/asn1/asn_mime.c index 806adade7ffc..9afe249965e9 100644 --- a/crypto/openssl/crypto/asn1/asn_mime.c +++ b/crypto/openssl/crypto/asn1/asn_mime.c @@ -168,6 +168,19 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) BIO_write(out, ",", 1); write_comma = 1; md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm); + + /* RFC 8702 does not define a micalg for SHAKE, assuming "shake-" */ + if (md_nid == NID_shake128) { + if (BIO_puts(out, "shake-128") < 0) + goto err; + continue; + } + if (md_nid == NID_shake256) { + if (BIO_puts(out, "shake-256") < 0) + goto err; + continue; + } + md = EVP_get_digestbynid(md_nid); if (md && md->md_ctrl) { int rv; @@ -204,15 +217,15 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) case NID_id_GostR3411_94: BIO_puts(out, "gostr3411-94"); - goto err; + break; case NID_id_GostR3411_2012_256: BIO_puts(out, "gostr3411-2012-256"); - goto err; + break; case NID_id_GostR3411_2012_512: BIO_puts(out, "gostr3411-2012-512"); - goto err; + break; default: if (have_unknown) { @@ -272,7 +285,8 @@ int SMIME_write_ASN1_ex(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, BIO_printf(bio, "Content-Type: multipart/signed;"); BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix); BIO_puts(bio, " micalg=\""); - asn1_write_micalg(bio, mdalgs); + if (!asn1_write_micalg(bio, mdalgs)) + return 0; BIO_printf(bio, "\"; boundary=\"----%s\"%s%s", bound, mime_eol, mime_eol); BIO_printf(bio, "This is an S/MIME signed message%s%s", diff --git a/crypto/openssl/crypto/bio/bss_dgram.c b/crypto/openssl/crypto/bio/bss_dgram.c index ea2550859ccd..784a1abb00bb 100644 --- a/crypto/openssl/crypto/bio/bss_dgram.c +++ b/crypto/openssl/crypto/bio/bss_dgram.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2025 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 @@ -464,11 +464,11 @@ static int dgram_write(BIO *b, const char *in, int inl) return ret; } -static long dgram_get_mtu_overhead(bio_dgram_data *data) +static long dgram_get_mtu_overhead(BIO_ADDR *addr) { long ret; - switch (BIO_ADDR_family(&data->peer)) { + switch (BIO_ADDR_family(addr)) { case AF_INET: /* * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP @@ -480,7 +480,8 @@ static long dgram_get_mtu_overhead(bio_dgram_data *data) { # ifdef IN6_IS_ADDR_V4MAPPED struct in6_addr tmp_addr; - if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL) + + if (BIO_ADDR_rawaddress(addr, &tmp_addr, NULL) && IN6_IS_ADDR_V4MAPPED(&tmp_addr)) /* * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP @@ -666,11 +667,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) &sockopt_len)) < 0 || sockopt_val < 0) { ret = 0; } else { - /* - * we assume that the transport protocol is UDP and no IP - * options are used. - */ - data->mtu = sockopt_val - 8 - 20; + data->mtu = sockopt_val - dgram_get_mtu_overhead(&addr); ret = data->mtu; } break; @@ -682,11 +679,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) || sockopt_val < 0) { ret = 0; } else { - /* - * we assume that the transport protocol is UDP and no IPV6 - * options are used. - */ - data->mtu = sockopt_val - 8 - 40; + data->mtu = sockopt_val - dgram_get_mtu_overhead(&addr); ret = data->mtu; } break; @@ -700,7 +693,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) # endif break; case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: - ret = -dgram_get_mtu_overhead(data); + ret = -dgram_get_mtu_overhead(&data->peer); switch (BIO_ADDR_family(&data->peer)) { case AF_INET: ret += 576; @@ -956,7 +949,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) } break; case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: - ret = dgram_get_mtu_overhead(data); + ret = dgram_get_mtu_overhead(&data->peer); break; /* diff --git a/crypto/openssl/crypto/dh/dh_check.c b/crypto/openssl/crypto/dh/dh_check.c index ae23f61839ea..2d899dc96f67 100644 --- a/crypto/openssl/crypto/dh/dh_check.c +++ b/crypto/openssl/crypto/dh/dh_check.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 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,6 +16,7 @@ #include #include "internal/cryptlib.h" #include +#include #include "dh_local.h" #include "crypto/dh.h" @@ -329,17 +330,27 @@ end: * FFC pairwise check from SP800-56A R3. * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency */ -int ossl_dh_check_pairwise(const DH *dh) +int ossl_dh_check_pairwise(const DH *dh, int return_on_null_numbers) { int ret = 0; BN_CTX *ctx = NULL; BIGNUM *pub_key = NULL; + OSSL_SELF_TEST *st = NULL; + OSSL_CALLBACK *stcb = NULL; + void *stcbarg = NULL; if (dh->params.p == NULL || dh->params.g == NULL || dh->priv_key == NULL || dh->pub_key == NULL) - return 0; + return return_on_null_numbers; + + OSSL_SELF_TEST_get_callback(dh->libctx, &stcb, &stcbarg); + st = OSSL_SELF_TEST_new(stcb, stcbarg); + if (st == NULL) + goto err; + OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, + OSSL_SELF_TEST_DESC_PCT_DH); ctx = BN_CTX_new_ex(dh->libctx); if (ctx == NULL) @@ -351,10 +362,27 @@ int ossl_dh_check_pairwise(const DH *dh) /* recalculate the public key = (g ^ priv) mod p */ if (!ossl_dh_generate_public_key(ctx, dh, dh->priv_key, pub_key)) goto err; + +#ifdef FIPS_MODULE + { + int len; + unsigned char bytes[1024] = {0}; /* Max key size of 8192 bits */ + + if (BN_num_bytes(pub_key) > (int)sizeof(bytes)) + goto err; + len = BN_bn2bin(pub_key, bytes); + OSSL_SELF_TEST_oncorrupt_byte(st, bytes); + if (BN_bin2bn(bytes, len, pub_key) == NULL) + goto err; + } +#endif /* check it matches the existing public_key */ ret = BN_cmp(pub_key, dh->pub_key) == 0; -err: + err: BN_free(pub_key); BN_CTX_free(ctx); + + OSSL_SELF_TEST_onend(st, ret); + OSSL_SELF_TEST_free(st); return ret; } diff --git a/crypto/openssl/crypto/dh/dh_key.c b/crypto/openssl/crypto/dh/dh_key.c index 7132b9b68e53..052d4d29ed22 100644 --- a/crypto/openssl/crypto/dh/dh_key.c +++ b/crypto/openssl/crypto/dh/dh_key.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 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 @@ -267,7 +267,7 @@ static int generate_key(DH *dh) int ok = 0; int generate_new_key = 0; #ifndef FIPS_MODULE - unsigned l; + int l; #endif BN_CTX *ctx = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; @@ -327,11 +327,13 @@ static int generate_key(DH *dh) goto err; #else if (dh->params.q == NULL) { - /* secret exponent length, must satisfy 2^(l-1) <= p */ - if (dh->length != 0 - && dh->length >= BN_num_bits(dh->params.p)) + /* secret exponent length, must satisfy 2^l < (p-1)/2 */ + l = BN_num_bits(dh->params.p); + if (dh->length >= l) goto err; - l = dh->length ? dh->length : BN_num_bits(dh->params.p) - 1; + l -= 2; + if (dh->length != 0 && dh->length < l) + l = dh->length; if (!BN_priv_rand_ex(priv_key, l, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY, 0, ctx)) goto err; diff --git a/crypto/openssl/crypto/dh/dh_pmeth.c b/crypto/openssl/crypto/dh/dh_pmeth.c index 3b75a537b3e0..74bef9370d3a 100644 --- a/crypto/openssl/crypto/dh/dh_pmeth.c +++ b/crypto/openssl/crypto/dh/dh_pmeth.c @@ -408,7 +408,7 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, } dh = (DH *)EVP_PKEY_get0_DH(ctx->pkey); dhpub = EVP_PKEY_get0_DH(ctx->peerkey); - if (dhpub == NULL) { + if (dhpub == NULL || dh == NULL) { ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET); return 0; } diff --git a/crypto/openssl/crypto/encode_decode/decoder_lib.c b/crypto/openssl/crypto/encode_decode/decoder_lib.c index ffcf3cde1155..dedfb24e569e 100644 --- a/crypto/openssl/crypto/encode_decode/decoder_lib.c +++ b/crypto/openssl/crypto/encode_decode/decoder_lib.c @@ -537,6 +537,14 @@ static void collect_extra_decoder(OSSL_DECODER *decoder, void *arg) } } +static int decoder_sk_cmp(const OSSL_DECODER_INSTANCE *const *a, + const OSSL_DECODER_INSTANCE *const *b) +{ + if ((*a)->score == (*b)->score) + return (*a)->order - (*b)->order; + return (*a)->score - (*b)->score; +} + int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, OSSL_LIB_CTX *libctx, const char *propq) { @@ -595,6 +603,26 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, OSSL_DECODER_do_all_provided(libctx, collect_all_decoders, skdecoders); numdecoders = sk_OSSL_DECODER_num(skdecoders); + /* + * If there are provided or default properties, sort the initial decoder list + * by property matching score so that the highest scored provider is selected + * first. + */ + if (propq != NULL || ossl_ctx_global_properties(libctx, 0) != NULL) { + int num_decoder_insts = sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts); + int i; + OSSL_DECODER_INSTANCE *di; + sk_OSSL_DECODER_INSTANCE_compfunc old_cmp = + sk_OSSL_DECODER_INSTANCE_set_cmp_func(ctx->decoder_insts, decoder_sk_cmp); + + for (i = 0; i < num_decoder_insts; i++) { + di = sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i); + di->order = i; + } + sk_OSSL_DECODER_INSTANCE_sort(ctx->decoder_insts); + sk_OSSL_DECODER_INSTANCE_set_cmp_func(ctx->decoder_insts, old_cmp); + } + memset(&data, 0, sizeof(data)); data.ctx = ctx; data.w_prev_start = 0; diff --git a/crypto/openssl/crypto/encode_decode/decoder_pkey.c b/crypto/openssl/crypto/encode_decode/decoder_pkey.c index f99566bde744..9fc4e2312331 100644 --- a/crypto/openssl/crypto/encode_decode/decoder_pkey.c +++ b/crypto/openssl/crypto/encode_decode/decoder_pkey.c @@ -222,15 +222,21 @@ struct collect_data_st { int total; /* number of matching results */ char error_occurred; char keytype_resolved; + OSSL_PROPERTY_LIST *pq; STACK_OF(EVP_KEYMGMT) *keymgmts; }; -static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder, - void *provctx, struct collect_data_st *data) +/* + * Add decoder instance to the decoder context if it is compatible. Returns 1 + * if a decoder was added, 0 otherwise. + */ +static int collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder, + void *provctx, struct collect_data_st *data) { void *decoderctx = NULL; OSSL_DECODER_INSTANCE *di = NULL; + const OSSL_PROPERTY_LIST *props; /* * We already checked the EVP_KEYMGMT is applicable in check_keymgmt so we @@ -239,17 +245,17 @@ static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder, if (keymgmt->name_id != decoder->base.id) /* Mismatch is not an error, continue. */ - return; + return 0; if ((decoderctx = decoder->newctx(provctx)) == NULL) { data->error_occurred = 1; - return; + return 0; } if ((di = ossl_decoder_instance_new(decoder, decoderctx)) == NULL) { decoder->freectx(decoderctx); data->error_occurred = 1; - return; + return 0; } /* @@ -263,7 +269,7 @@ static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder, || OPENSSL_strcasecmp(data->ctx->start_input_type, "PEM") != 0)) { /* Mismatch is not an error, continue. */ ossl_decoder_instance_free(di); - return; + return 0; } OSSL_TRACE_BEGIN(DECODER) { @@ -275,13 +281,30 @@ static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder, OSSL_DECODER_get0_properties(decoder)); } OSSL_TRACE_END(DECODER); + /* + * Get the property match score so the decoders can be prioritized later. + */ + props = ossl_decoder_parsed_properties(decoder); + if (data->pq != NULL && props != NULL) { + di->score = ossl_property_match_count(data->pq, props); + /* + * Mismatch of mandatory properties is not an error, the decoder is just + * ignored, continue. *** 6151 LINES SKIPPED ***