aboutsummaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2024-02-02 04:39:16 +0000
committerCy Schubert <cy@FreeBSD.org>2024-02-02 09:48:38 +0000
commit9dd13e84fa8eca8f3462bd55485aa3da8c37f54a (patch)
tree588240aeb9a7363618b8a687c72588bd74948634 /crypto
parent825caf7e12445fa4818413cc37c8b45bebb6c3a9 (diff)
downloadsrc-9dd13e84fa8eca8f3462bd55485aa3da8c37f54a.tar.gz
src-9dd13e84fa8eca8f3462bd55485aa3da8c37f54a.zip
OpenSSL: Vendor import of OpenSSL 3.0.13vendor/openssl-3.0
* Fixed PKCS12 Decoding crashes ([CVE-2024-0727]) * Fixed Excessive time spent checking invalid RSA public keys ([CVE-2023-6237]) * Fixed POLY1305 MAC implementation corrupting vector registers on PowerPC CPUs which support PowerISA 2.07 ([CVE-2023-6129]) * Fix excessive time spent in DH check / generation with large Q parameter value ([CVE-2023-5678]) Release notes can be found at https://www.openssl.org/news/openssl-3.0-notes.html.
Diffstat (limited to 'crypto')
-rw-r--r--crypto/LPdir_nyi.c56
-rw-r--r--crypto/LPdir_vms.c207
-rw-r--r--crypto/LPdir_win.c214
-rw-r--r--crypto/LPdir_win32.c41
-rw-r--r--crypto/LPdir_wince.c44
-rw-r--r--crypto/alphacpuid.pl256
-rw-r--r--crypto/asn1/asn_moid.c4
-rw-r--r--crypto/asn1/asn_mstbl.c8
-rw-r--r--crypto/asn1/x_algor.c6
-rw-r--r--crypto/async/arch/async_win.c59
-rw-r--r--crypto/bn/asm/alpha-mont.pl327
-rw-r--r--crypto/bn/bn_exp.c21
-rw-r--r--crypto/bn/bn_gf2m.c8
-rw-r--r--crypto/bn/bn_mod.c10
-rw-r--r--crypto/bn/bn_nist.c126
-rw-r--r--crypto/build.info4
-rw-r--r--crypto/cms/cms_att.c24
-rw-r--r--crypto/cms/cms_dh.c8
-rw-r--r--crypto/cms/cms_rsa.c35
-rw-r--r--crypto/cms/cms_sd.c31
-rw-r--r--crypto/cms/cms_smime.c3
-rw-r--r--crypto/conf/conf_err.c2
-rw-r--r--crypto/dh/dh_check.c12
-rw-r--r--crypto/dh/dh_err.c3
-rw-r--r--crypto/dh/dh_key.c12
-rw-r--r--crypto/dso/dso_vms.c489
-rw-r--r--crypto/dso/dso_win32.c671
-rw-r--r--crypto/ec/ecx_backend.c9
-rw-r--r--crypto/err/openssl.ec81
-rw-r--r--crypto/err/openssl.txt2
-rw-r--r--crypto/evp/e_aes.c16
-rw-r--r--crypto/evp/evp_fetch.c23
-rw-r--r--crypto/http/http_client.c8
-rw-r--r--crypto/http/http_lib.c2
-rw-r--r--crypto/mem_sec.c12
-rw-r--r--crypto/modes/asm/ghash-alpha.pl467
-rw-r--r--crypto/objects/obj_dat.c4
-rw-r--r--crypto/param_build.c8
-rw-r--r--crypto/params_from_text.c10
-rwxr-xr-xcrypto/perlasm/x86_64-xlate.pl7
-rw-r--r--crypto/pkcs12/p12_add.c20
-rw-r--r--crypto/pkcs12/p12_mutl.c7
-rw-r--r--crypto/pkcs12/p12_npas.c7
-rw-r--r--crypto/pkcs7/pk7_attr.c20
-rw-r--r--crypto/pkcs7/pk7_mime.c9
-rwxr-xr-xcrypto/poly1305/asm/poly1305-ppc.pl44
-rw-r--r--crypto/property/property_parse.c50
-rw-r--r--crypto/provider_conf.c104
-rw-r--r--crypto/provider_core.c70
-rw-r--r--crypto/rsa/rsa_lib.c8
-rw-r--r--crypto/rsa/rsa_sp800_56b_check.c10
-rw-r--r--crypto/sha/asm/sha1-alpha.pl329
-rw-r--r--crypto/threads_win.c263
-rw-r--r--crypto/x509/t_req.c8
-rw-r--r--crypto/x509/t_x509.c4
-rw-r--r--crypto/x509/v3_addr.c6
-rw-r--r--crypto/x509/v3_asid.c24
-rw-r--r--crypto/x509/v3_crld.c7
-rw-r--r--crypto/x509/v3_ist.c18
-rw-r--r--crypto/x509/v3_san.c13
-rw-r--r--crypto/x509/v3_sxnet.c20
-rw-r--r--crypto/x509/x509_att.c92
-rw-r--r--crypto/x509/x509_req.c4
63 files changed, 4185 insertions, 282 deletions
diff --git a/crypto/LPdir_nyi.c b/crypto/LPdir_nyi.c
new file mode 100644
index 000000000000..a1540785f87d
--- /dev/null
+++ b/crypto/LPdir_nyi.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * This file is dual-licensed and is also available under the following
+ * terms:
+ *
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LPDIR_H
+# include "LPdir.h"
+#endif
+
+struct LP_dir_context_st {
+ void *dummy;
+};
+const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
+{
+ errno = EINVAL;
+ return 0;
+}
+
+int LP_find_file_end(LP_DIR_CTX **ctx)
+{
+ errno = EINVAL;
+ return 0;
+}
diff --git a/crypto/LPdir_vms.c b/crypto/LPdir_vms.c
new file mode 100644
index 000000000000..51043263ae67
--- /dev/null
+++ b/crypto/LPdir_vms.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * This file is dual-licensed and is also available under the following
+ * terms:
+ *
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <descrip.h>
+#include <namdef.h>
+#include <rmsdef.h>
+#include <libfildef.h>
+#include <lib$routines.h>
+#include <strdef.h>
+#include <str$routines.h>
+#include <stsdef.h>
+#ifndef LPDIR_H
+# include "LPdir.h"
+#endif
+#include "vms_rms.h"
+
+/* Some compiler options hide EVMSERR. */
+#ifndef EVMSERR
+# define EVMSERR 65535 /* error for non-translatable VMS errors */
+#endif
+
+struct LP_dir_context_st {
+ unsigned long VMS_context;
+ char filespec[NAMX_MAXRSS + 1];
+ char result[NAMX_MAXRSS + 1];
+ struct dsc$descriptor_d filespec_dsc;
+ struct dsc$descriptor_d result_dsc;
+};
+
+const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
+{
+ int status;
+ char *p, *r;
+ size_t l;
+ unsigned long flags = 0;
+
+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
+#if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size save
+# pragma pointer_size 32
+ char *ctx_filespec_32p;
+# pragma pointer_size restore
+ char ctx_filespec_32[NAMX_MAXRSS + 1];
+#endif /* __INITIAL_POINTER_SIZE == 64 */
+
+#ifdef NAML$C_MAXRSS
+ flags |= LIB$M_FIL_LONG_NAMES;
+#endif
+
+ if (ctx == NULL || directory == NULL) {
+ errno = EINVAL;
+ return 0;
+ }
+
+ errno = 0;
+ if (*ctx == NULL) {
+ size_t filespeclen = strlen(directory);
+ char *filespec = NULL;
+
+ if (filespeclen == 0) {
+ errno = ENOENT;
+ return 0;
+ }
+
+ /* MUST be a VMS directory specification! Let's estimate if it is. */
+ if (directory[filespeclen - 1] != ']'
+ && directory[filespeclen - 1] != '>'
+ && directory[filespeclen - 1] != ':') {
+ errno = EINVAL;
+ return 0;
+ }
+
+ filespeclen += 4; /* "*.*;" */
+
+ if (filespeclen > NAMX_MAXRSS) {
+ errno = ENAMETOOLONG;
+ return 0;
+ }
+
+ *ctx = malloc(sizeof(**ctx));
+ if (*ctx == NULL) {
+ errno = ENOMEM;
+ return 0;
+ }
+ memset(*ctx, 0, sizeof(**ctx));
+
+ strcpy((*ctx)->filespec, directory);
+ strcat((*ctx)->filespec, "*.*;");
+
+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
+#if __INITIAL_POINTER_SIZE == 64
+# define CTX_FILESPEC ctx_filespec_32p
+ /* Copy the file name to storage with a 32-bit pointer. */
+ ctx_filespec_32p = ctx_filespec_32;
+ strcpy(ctx_filespec_32p, (*ctx)->filespec);
+#else /* __INITIAL_POINTER_SIZE == 64 */
+# define CTX_FILESPEC (*ctx)->filespec
+#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+ (*ctx)->filespec_dsc.dsc$w_length = filespeclen;
+ (*ctx)->filespec_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ (*ctx)->filespec_dsc.dsc$b_class = DSC$K_CLASS_S;
+ (*ctx)->filespec_dsc.dsc$a_pointer = CTX_FILESPEC;
+ }
+
+ (*ctx)->result_dsc.dsc$w_length = 0;
+ (*ctx)->result_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ (*ctx)->result_dsc.dsc$b_class = DSC$K_CLASS_D;
+ (*ctx)->result_dsc.dsc$a_pointer = 0;
+
+ status = lib$find_file(&(*ctx)->filespec_dsc, &(*ctx)->result_dsc,
+ &(*ctx)->VMS_context, 0, 0, 0, &flags);
+
+ if (status == RMS$_NMF) {
+ errno = 0;
+ vaxc$errno = status;
+ return NULL;
+ }
+
+ if (!$VMS_STATUS_SUCCESS(status)) {
+ errno = EVMSERR;
+ vaxc$errno = status;
+ return NULL;
+ }
+
+ /*
+ * Quick, cheap and dirty way to discard any device and directory, since
+ * we only want file names
+ */
+ l = (*ctx)->result_dsc.dsc$w_length;
+ p = (*ctx)->result_dsc.dsc$a_pointer;
+ r = p;
+ for (; *p; p++) {
+ if (*p == '^' && p[1] != '\0') { /* Take care of ODS-5 escapes */
+ p++;
+ } else if (*p == ':' || *p == '>' || *p == ']') {
+ l -= p + 1 - r;
+ r = p + 1;
+ } else if (*p == ';') {
+ l = p - r;
+ break;
+ }
+ }
+
+ strncpy((*ctx)->result, r, l);
+ (*ctx)->result[l] = '\0';
+ str$free1_dx(&(*ctx)->result_dsc);
+
+ return (*ctx)->result;
+}
+
+int LP_find_file_end(LP_DIR_CTX **ctx)
+{
+ if (ctx != NULL && *ctx != NULL) {
+ int status = lib$find_file_end(&(*ctx)->VMS_context);
+
+ free(*ctx);
+
+ if (!$VMS_STATUS_SUCCESS(status)) {
+ errno = EVMSERR;
+ vaxc$errno = status;
+ return 0;
+ }
+ return 1;
+ }
+ errno = EINVAL;
+ return 0;
+}
diff --git a/crypto/LPdir_win.c b/crypto/LPdir_win.c
new file mode 100644
index 000000000000..83cbe1fc0907
--- /dev/null
+++ b/crypto/LPdir_win.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * This file is dual-licensed and is also available under the following
+ * terms:
+ *
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <windows.h>
+#include <tchar.h>
+#include "internal/numbers.h"
+#ifndef LPDIR_H
+# include "LPdir.h"
+#endif
+
+/*
+ * We're most likely overcautious here, but let's reserve for broken WinCE
+ * headers and explicitly opt for UNICODE call. Keep in mind that our WinCE
+ * builds are compiled with -DUNICODE [as well as -D_UNICODE].
+ */
+#if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
+# define FindFirstFile FindFirstFileW
+#endif
+#if defined(LP_SYS_WINCE) && !defined(FindNextFile)
+# define FindNextFile FindNextFileW
+#endif
+
+#ifndef NAME_MAX
+# define NAME_MAX 255
+#endif
+
+#ifdef CP_UTF8
+# define CP_DEFAULT CP_UTF8
+#else
+# define CP_DEFAULT CP_ACP
+#endif
+
+struct LP_dir_context_st {
+ WIN32_FIND_DATA ctx;
+ HANDLE handle;
+ char entry_name[NAME_MAX + 1];
+};
+
+const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
+{
+ if (ctx == NULL || directory == NULL) {
+ errno = EINVAL;
+ return 0;
+ }
+
+ errno = 0;
+ if (*ctx == NULL) {
+ size_t dirlen = strlen(directory);
+
+ if (dirlen == 0 || dirlen > INT_MAX - 3) {
+ errno = ENOENT;
+ return 0;
+ }
+
+ *ctx = malloc(sizeof(**ctx));
+ if (*ctx == NULL) {
+ errno = ENOMEM;
+ return 0;
+ }
+ memset(*ctx, 0, sizeof(**ctx));
+
+ if (sizeof(TCHAR) != sizeof(char)) {
+ TCHAR *wdir = NULL;
+ /* len_0 denotes string length *with* trailing 0 */
+ size_t index = 0, len_0 = dirlen + 1;
+#ifdef LP_MULTIBYTE_AVAILABLE
+ int sz = 0;
+ UINT cp;
+
+ do {
+# ifdef CP_UTF8
+ if ((sz = MultiByteToWideChar((cp = CP_UTF8), 0,
+ directory, len_0,
+ NULL, 0)) > 0 ||
+ GetLastError() != ERROR_NO_UNICODE_TRANSLATION)
+ break;
+# endif
+ sz = MultiByteToWideChar((cp = CP_ACP), 0,
+ directory, len_0,
+ NULL, 0);
+ } while (0);
+
+ if (sz > 0) {
+ /*
+ * allocate two additional characters in case we need to
+ * concatenate asterisk, |sz| covers trailing '\0'!
+ */
+ wdir = _alloca((sz + 2) * sizeof(TCHAR));
+ if (!MultiByteToWideChar(cp, 0, directory, len_0,
+ (WCHAR *)wdir, sz)) {
+ free(*ctx);
+ *ctx = NULL;
+ errno = EINVAL;
+ return 0;
+ }
+ } else
+#endif
+ {
+ sz = len_0;
+ /*
+ * allocate two additional characters in case we need to
+ * concatenate asterisk, |sz| covers trailing '\0'!
+ */
+ wdir = _alloca((sz + 2) * sizeof(TCHAR));
+ for (index = 0; index < len_0; index++)
+ wdir[index] = (TCHAR)directory[index];
+ }
+
+ sz--; /* wdir[sz] is trailing '\0' now */
+ if (wdir[sz - 1] != TEXT('*')) {
+ if (wdir[sz - 1] != TEXT('/') && wdir[sz - 1] != TEXT('\\'))
+ _tcscpy(wdir + sz, TEXT("/*"));
+ else
+ _tcscpy(wdir + sz, TEXT("*"));
+ }
+
+ (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
+ } else {
+ if (directory[dirlen - 1] != '*') {
+ char *buf = _alloca(dirlen + 3);
+
+ strcpy(buf, directory);
+ if (buf[dirlen - 1] != '/' && buf[dirlen - 1] != '\\')
+ strcpy(buf + dirlen, "/*");
+ else
+ strcpy(buf + dirlen, "*");
+
+ directory = buf;
+ }
+
+ (*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx);
+ }
+
+ if ((*ctx)->handle == INVALID_HANDLE_VALUE) {
+ free(*ctx);
+ *ctx = NULL;
+ errno = EINVAL;
+ return 0;
+ }
+ } else {
+ if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) {
+ return 0;
+ }
+ }
+ if (sizeof(TCHAR) != sizeof(char)) {
+ TCHAR *wdir = (*ctx)->ctx.cFileName;
+ size_t index, len_0 = 0;
+
+ while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1))
+ len_0++;
+ len_0++;
+
+#ifdef LP_MULTIBYTE_AVAILABLE
+ if (!WideCharToMultiByte(CP_DEFAULT, 0, (WCHAR *)wdir, len_0,
+ (*ctx)->entry_name,
+ sizeof((*ctx)->entry_name), NULL, 0))
+#endif
+ for (index = 0; index < len_0; index++)
+ (*ctx)->entry_name[index] = (char)wdir[index];
+ } else
+ strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName,
+ sizeof((*ctx)->entry_name) - 1);
+
+ (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
+
+ return (*ctx)->entry_name;
+}
+
+int LP_find_file_end(LP_DIR_CTX **ctx)
+{
+ if (ctx != NULL && *ctx != NULL) {
+ FindClose((*ctx)->handle);
+ free(*ctx);
+ *ctx = NULL;
+ return 1;
+ }
+ errno = EINVAL;
+ return 0;
+}
diff --git a/crypto/LPdir_win32.c b/crypto/LPdir_win32.c
new file mode 100644
index 000000000000..b29e096ff30f
--- /dev/null
+++ b/crypto/LPdir_win32.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * This file is dual-licensed and is also available under the following
+ * terms:
+ *
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LP_SYS_WIN32
+#define LP_MULTIBYTE_AVAILABLE
+#include "LPdir_win.c"
diff --git a/crypto/LPdir_wince.c b/crypto/LPdir_wince.c
new file mode 100644
index 000000000000..ebf89628272a
--- /dev/null
+++ b/crypto/LPdir_wince.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * This file is dual-licensed and is also available under the following
+ * terms:
+ *
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LP_SYS_WINCE
+/*
+ * We might want to define LP_MULTIBYTE_AVAILABLE here. It's currently under
+ * investigation what the exact conditions would be
+ */
+#include "LPdir_win.c"
diff --git a/crypto/alphacpuid.pl b/crypto/alphacpuid.pl
new file mode 100644
index 000000000000..b96975038060
--- /dev/null
+++ b/crypto/alphacpuid.pl
@@ -0,0 +1,256 @@
+#! /usr/bin/env perl
+# Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+
+$output = pop and open STDOUT,">$output";
+
+print <<'___';
+.text
+
+.set noat
+
+.globl OPENSSL_cpuid_setup
+.ent OPENSSL_cpuid_setup
+OPENSSL_cpuid_setup:
+ .frame $30,0,$26
+ .prologue 0
+ ret ($26)
+.end OPENSSL_cpuid_setup
+
+.globl OPENSSL_wipe_cpu
+.ent OPENSSL_wipe_cpu
+OPENSSL_wipe_cpu:
+ .frame $30,0,$26
+ .prologue 0
+ clr $1
+ clr $2
+ clr $3
+ clr $4
+ clr $5
+ clr $6
+ clr $7
+ clr $8
+ clr $16
+ clr $17
+ clr $18
+ clr $19
+ clr $20
+ clr $21
+ clr $22
+ clr $23
+ clr $24
+ clr $25
+ clr $27
+ clr $at
+ clr $29
+ fclr $f0
+ fclr $f1
+ fclr $f10
+ fclr $f11
+ fclr $f12
+ fclr $f13
+ fclr $f14
+ fclr $f15
+ fclr $f16
+ fclr $f17
+ fclr $f18
+ fclr $f19
+ fclr $f20
+ fclr $f21
+ fclr $f22
+ fclr $f23
+ fclr $f24
+ fclr $f25
+ fclr $f26
+ fclr $f27
+ fclr $f28
+ fclr $f29
+ fclr $f30
+ mov $sp,$0
+ ret ($26)
+.end OPENSSL_wipe_cpu
+
+.globl OPENSSL_atomic_add
+.ent OPENSSL_atomic_add
+OPENSSL_atomic_add:
+ .frame $30,0,$26
+ .prologue 0
+1: ldl_l $0,0($16)
+ addl $0,$17,$1
+ stl_c $1,0($16)
+ beq $1,1b
+ addl $0,$17,$0
+ ret ($26)
+.end OPENSSL_atomic_add
+
+.globl OPENSSL_rdtsc
+.ent OPENSSL_rdtsc
+OPENSSL_rdtsc:
+ .frame $30,0,$26
+ .prologue 0
+ rpcc $0
+ ret ($26)
+.end OPENSSL_rdtsc
+
+.globl OPENSSL_cleanse
+.ent OPENSSL_cleanse
+OPENSSL_cleanse:
+ .frame $30,0,$26
+ .prologue 0
+ beq $17,.Ldone
+ and $16,7,$0
+ bic $17,7,$at
+ beq $at,.Little
+ beq $0,.Laligned
+
+.Little:
+ subq $0,8,$0
+ ldq_u $1,0($16)
+ mov $16,$2
+.Lalign:
+ mskbl $1,$16,$1
+ lda $16,1($16)
+ subq $17,1,$17
+ addq $0,1,$0
+ beq $17,.Lout
+ bne $0,.Lalign
+.Lout: stq_u $1,0($2)
+ beq $17,.Ldone
+ bic $17,7,$at
+ beq $at,.Little
+
+.Laligned:
+ stq $31,0($16)
+ subq $17,8,$17
+ lda $16,8($16)
+ bic $17,7,$at
+ bne $at,.Laligned
+ bne $17,.Little
+.Ldone: ret ($26)
+.end OPENSSL_cleanse
+
+.globl CRYPTO_memcmp
+.ent CRYPTO_memcmp
+CRYPTO_memcmp:
+ .frame $30,0,$26
+ .prologue 0
+ xor $0,$0,$0
+ beq $18,.Lno_data
+
+ xor $1,$1,$1
+ nop
+.Loop_cmp:
+ ldq_u $2,0($16)
+ subq $18,1,$18
+ ldq_u $3,0($17)
+ extbl $2,$16,$2
+ lda $16,1($16)
+ extbl $3,$17,$3
+ lda $17,1($17)
+ xor $3,$2,$2
+ or $2,$0,$0
+ bne $18,.Loop_cmp
+
+ subq $31,$0,$0
+ srl $0,63,$0
+.Lno_data:
+ ret ($26)
+.end CRYPTO_memcmp
+___
+{
+my ($out,$cnt,$max)=("\$16","\$17","\$18");
+my ($tick,$lasttick)=("\$19","\$20");
+my ($diff,$lastdiff)=("\$21","\$22");
+my ($v0,$ra,$sp,$zero)=("\$0","\$26","\$30","\$31");
+
+print <<___;
+.globl OPENSSL_instrument_bus
+.ent OPENSSL_instrument_bus
+OPENSSL_instrument_bus:
+ .frame $sp,0,$ra
+ .prologue 0
+ mov $cnt,$v0
+
+ rpcc $lasttick
+ mov 0,$diff
+
+ ecb ($out)
+ ldl_l $tick,0($out)
+ addl $diff,$tick,$tick
+ mov $tick,$diff
+ stl_c $tick,0($out)
+ stl $diff,0($out)
+
+.Loop: rpcc $tick
+ subq $tick,$lasttick,$diff
+ mov $tick,$lasttick
+
+ ecb ($out)
+ ldl_l $tick,0($out)
+ addl $diff,$tick,$tick
+ mov $tick,$diff
+ stl_c $tick,0($out)
+ stl $diff,0($out)
+
+ subl $cnt,1,$cnt
+ lda $out,4($out)
+ bne $cnt,.Loop
+
+ ret ($ra)
+.end OPENSSL_instrument_bus
+
+.globl OPENSSL_instrument_bus2
+.ent OPENSSL_instrument_bus2
+OPENSSL_instrument_bus2:
+ .frame $sp,0,$ra
+ .prologue 0
+ mov $cnt,$v0
+
+ rpcc $lasttick
+ mov 0,$diff
+
+ ecb ($out)
+ ldl_l $tick,0($out)
+ addl $diff,$tick,$tick
+ mov $tick,$diff
+ stl_c $tick,0($out)
+ stl $diff,0($out)
+
+ rpcc $tick
+ subq $tick,$lasttick,$diff
+ mov $tick,$lasttick
+ mov $diff,$lastdiff
+.Loop2:
+ ecb ($out)
+ ldl_l $tick,0($out)
+ addl $diff,$tick,$tick
+ mov $tick,$diff
+ stl_c $tick,0($out)
+ stl $diff,0($out)
+
+ subl $max,1,$max
+ beq $max,.Ldone2
+
+ rpcc $tick
+ subq $tick,$lasttick,$diff
+ mov $tick,$lasttick
+ subq $lastdiff,$diff,$tick
+ mov $diff,$lastdiff
+ cmovne $tick,1,$tick
+ subl $cnt,$tick,$cnt
+ s4addq $tick,$out,$out
+ bne $cnt,.Loop2
+
+.Ldone2:
+ subl $v0,$cnt,$v0
+ ret ($ra)
+.end OPENSSL_instrument_bus2
+___
+}
+
+close STDOUT or die "error closing STDOUT: $!";
diff --git a/crypto/asn1/asn_moid.c b/crypto/asn1/asn_moid.c
index 526219c1a723..9aaab8a269d3 100644
--- a/crypto/asn1/asn_moid.c
+++ b/crypto/asn1/asn_moid.c
@@ -67,6 +67,10 @@ static int do_create(const char *value, const char *name)
if (p == NULL) {
ln = name;
ostr = value;
+ } else if (p == value) {
+ /* we started with a leading comma */
+ ln = name;
+ ostr = p + 1;
} else {
ln = value;
ostr = p + 1;
diff --git a/crypto/asn1/asn_mstbl.c b/crypto/asn1/asn_mstbl.c
index 3543cd22568f..1208d5663d25 100644
--- a/crypto/asn1/asn_mstbl.c
+++ b/crypto/asn1/asn_mstbl.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2012-2024 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
@@ -72,6 +72,8 @@ static int do_tcreate(const char *value, const char *name)
goto err;
for (i = 0; i < sk_CONF_VALUE_num(lst); i++) {
cnf = sk_CONF_VALUE_value(lst, i);
+ if (cnf->value == NULL)
+ goto err;
if (strcmp(cnf->name, "min") == 0) {
tbl_min = strtoul(cnf->value, &eptr, 0);
if (*eptr)
@@ -98,7 +100,9 @@ static int do_tcreate(const char *value, const char *name)
if (rv == 0) {
if (cnf)
ERR_raise_data(ERR_LIB_ASN1, ASN1_R_INVALID_STRING_TABLE_VALUE,
- "field=%s, value=%s", cnf->name, cnf->value);
+ "field=%s, value=%s", cnf->name,
+ cnf->value != NULL ? cnf->value
+ : value);
else
ERR_raise_data(ERR_LIB_ASN1, ASN1_R_INVALID_STRING_TABLE_VALUE,
"name=%s, value=%s", name, value);
diff --git a/crypto/asn1/x_algor.c b/crypto/asn1/x_algor.c
index c0a5f76803ee..2c4a8d4b4ee8 100644
--- a/crypto/asn1/x_algor.c
+++ b/crypto/asn1/x_algor.c
@@ -179,7 +179,11 @@ int ossl_x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md)
*palg = X509_ALGOR_new();
if (*palg == NULL)
goto err;
- X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp);
+ if (!X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp)) {
+ X509_ALGOR_free(*palg);
+ *palg = NULL;
+ goto err;
+ }
stmp = NULL;
err:
ASN1_STRING_free(stmp);
diff --git a/crypto/async/arch/async_win.c b/crypto/async/arch/async_win.c
new file mode 100644
index 000000000000..0b276fd504d8
--- /dev/null
+++ b/crypto/async/arch/async_win.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* This must be the first #include file */
+#include "../async_local.h"
+
+#ifdef ASYNC_WIN
+
+# include <windows.h>
+# include "internal/cryptlib.h"
+
+int ASYNC_is_capable(void)
+{
+ return 1;
+}
+
+void async_local_cleanup(void)
+{
+ async_ctx *ctx = async_get_ctx();
+ if (ctx != NULL) {
+ async_fibre *fibre = &ctx->dispatcher;
+ if (fibre != NULL && fibre->fibre != NULL && fibre->converted) {
+ ConvertFiberToThread();
+ fibre->fibre = NULL;
+ }
+ }
+}
+
+int async_fibre_init_dispatcher(async_fibre *fibre)
+{
+# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600
+ fibre->fibre = ConvertThreadToFiberEx(NULL, FIBER_FLAG_FLOAT_SWITCH);
+# else
+ fibre->fibre = ConvertThreadToFiber(NULL);
+# endif
+ if (fibre->fibre == NULL) {
+ fibre->converted = 0;
+ fibre->fibre = GetCurrentFiber();
+ if (fibre->fibre == NULL)
+ return 0;
+ } else {
+ fibre->converted = 1;
+ }
+
+ return 1;
+}
+
+VOID CALLBACK async_start_func_win(PVOID unused)
+{
+ async_start_func();
+}
+
+#endif
diff --git a/crypto/bn/asm/alpha-mont.pl b/crypto/bn/asm/alpha-mont.pl
new file mode 100644
index 000000000000..9d362a6f65ed
--- /dev/null
+++ b/crypto/bn/asm/alpha-mont.pl
@@ -0,0 +1,327 @@
+#! /usr/bin/env perl
+# Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# On 21264 RSA sign performance improves by 70/35/20/15 percent for
+# 512/1024/2048/4096 bit key lengths. This is against vendor compiler
+# instructed to '-tune host' code with in-line assembler. Other
+# benchmarks improve by 15-20%. To anchor it to something else, the
+# code provides approximately the same performance per GHz as AMD64.
+# I.e. if you compare 1GHz 21264 and 2GHz Opteron, you'll observe ~2x
+# difference.
+
+$output=pop and open STDOUT,">$output";
+
+# int bn_mul_mont(
+$rp="a0"; # BN_ULONG *rp,
+$ap="a1"; # const BN_ULONG *ap,
+$bp="a2"; # const BN_ULONG *bp,
+$np="a3"; # const BN_ULONG *np,
+$n0="a4"; # const BN_ULONG *n0,
+$num="a5"; # int num);
+
+$lo0="t0";
+$hi0="t1";
+$lo1="t2";
+$hi1="t3";
+$aj="t4";
+$bi="t5";
+$nj="t6";
+$tp="t7";
+$alo="t8";
+$ahi="t9";
+$nlo="t10";
+$nhi="t11";
+$tj="t12";
+$i="s3";
+$j="s4";
+$m1="s5";
+
+$code=<<___;
+#ifdef __linux__
+#include <asm/regdef.h>
+#else
+#include <asm.h>
+#include <regdef.h>
+#endif
+
+.text
+
+.set noat
+.set noreorder
+
+.globl bn_mul_mont
+.align 5
+.ent bn_mul_mont
+bn_mul_mont:
+ lda sp,-48(sp)
+ stq ra,0(sp)
+ stq s3,8(sp)
+ stq s4,16(sp)
+ stq s5,24(sp)
+ stq fp,32(sp)
+ mov sp,fp
+ .mask 0x0400f000,-48
+ .frame fp,48,ra
+ .prologue 0
+
+ .align 4
+ .set reorder
+ sextl $num,$num
+ mov 0,v0
+ cmplt $num,4,AT
+ bne AT,.Lexit
+
+ ldq $hi0,0($ap) # ap[0]
+ s8addq $num,16,AT
+ ldq $aj,8($ap)
+ subq sp,AT,sp
+ ldq $bi,0($bp) # bp[0]
+ lda AT,-4096(zero) # mov -4096,AT
+ ldq $n0,0($n0)
+ and sp,AT,sp
+
+ mulq $hi0,$bi,$lo0
+ ldq $hi1,0($np) # np[0]
+ umulh $hi0,$bi,$hi0
+ ldq $nj,8($np)
+
+ mulq $lo0,$n0,$m1
+
+ mulq $hi1,$m1,$lo1
+ umulh $hi1,$m1,$hi1
+
+ addq $lo1,$lo0,$lo1
+ cmpult $lo1,$lo0,AT
+ addq $hi1,AT,$hi1
+
+ mulq $aj,$bi,$alo
+ mov 2,$j
+ umulh $aj,$bi,$ahi
+ mov sp,$tp
+
+ mulq $nj,$m1,$nlo
+ s8addq $j,$ap,$aj
+ umulh $nj,$m1,$nhi
+ s8addq $j,$np,$nj
+.align 4
+.L1st:
+ .set noreorder
+ ldq $aj,0($aj)
+ addl $j,1,$j
+ ldq $nj,0($nj)
+ lda $tp,8($tp)
+
+ addq $alo,$hi0,$lo0
+ mulq $aj,$bi,$alo
+ cmpult $lo0,$hi0,AT
+ addq $nlo,$hi1,$lo1
+
+ mulq $nj,$m1,$nlo
+ addq $ahi,AT,$hi0
+ cmpult $lo1,$hi1,v0
+ cmplt $j,$num,$tj
+
+ umulh $aj,$bi,$ahi
+ addq $nhi,v0,$hi1
+ addq $lo1,$lo0,$lo1
+ s8addq $j,$ap,$aj
+
+ umulh $nj,$m1,$nhi
+ cmpult $lo1,$lo0,v0
+ addq $hi1,v0,$hi1
+ s8addq $j,$np,$nj
+
+ stq $lo1,-8($tp)
+ nop
+ unop
+ bne $tj,.L1st
+ .set reorder
+
+ addq $alo,$hi0,$lo0
+ addq $nlo,$hi1,$lo1
+ cmpult $lo0,$hi0,AT
+ cmpult $lo1,$hi1,v0
+ addq $ahi,AT,$hi0
+ addq $nhi,v0,$hi1
+
+ addq $lo1,$lo0,$lo1
+ cmpult $lo1,$lo0,v0
+ addq $hi1,v0,$hi1
+
+ stq $lo1,0($tp)
+
+ addq $hi1,$hi0,$hi1
+ cmpult $hi1,$hi0,AT
+ stq $hi1,8($tp)
+ stq AT,16($tp)
+
+ mov 1,$i
+.align 4
+.Louter:
+ s8addq $i,$bp,$bi
+ ldq $hi0,0($ap)
+ ldq $aj,8($ap)
+ ldq $bi,0($bi)
+ ldq $hi1,0($np)
+ ldq $nj,8($np)
+ ldq $tj,0(sp)
+
+ mulq $hi0,$bi,$lo0
+ umulh $hi0,$bi,$hi0
+
+ addq $lo0,$tj,$lo0
+ cmpult $lo0,$tj,AT
+ addq $hi0,AT,$hi0
+
+ mulq $lo0,$n0,$m1
+
+ mulq $hi1,$m1,$lo1
+ umulh $hi1,$m1,$hi1
+
+ addq $lo1,$lo0,$lo1
+ cmpult $lo1,$lo0,AT
+ mov 2,$j
+ addq $hi1,AT,$hi1
+
+ mulq $aj,$bi,$alo
+ mov sp,$tp
+ umulh $aj,$bi,$ahi
+
+ mulq $nj,$m1,$nlo
+ s8addq $j,$ap,$aj
+ umulh $nj,$m1,$nhi
+.align 4
+.Linner:
+ .set noreorder
+ ldq $tj,8($tp) #L0
+ nop #U1
+ ldq $aj,0($aj) #L1
+ s8addq $j,$np,$nj #U0
+
+ ldq $nj,0($nj) #L0
+ nop #U1
+ addq $alo,$hi0,$lo0 #L1
+ lda $tp,8($tp)
+
+ mulq $aj,$bi,$alo #U1
+ cmpult $lo0,$hi0,AT #L0
+ addq $nlo,$hi1,$lo1 #L1
+ addl $j,1,$j
+
+ mulq $nj,$m1,$nlo #U1
+ addq $ahi,AT,$hi0 #L0
+ addq $lo0,$tj,$lo0 #L1
+ cmpult $lo1,$hi1,v0 #U0
+
+ umulh $aj,$bi,$ahi #U1
+ cmpult $lo0,$tj,AT #L0
+ addq $lo1,$lo0,$lo1 #L1
+ addq $nhi,v0,$hi1 #U0
+
+ umulh $nj,$m1,$nhi #U1
+ s8addq $j,$ap,$aj #L0
+ cmpult $lo1,$lo0,v0 #L1
+ cmplt $j,$num,$tj #U0 # borrow $tj
+
+ addq $hi0,AT,$hi0 #L0
+ addq $hi1,v0,$hi1 #U1
+ stq $lo1,-8($tp) #L1
+ bne $tj,.Linner #U0
+ .set reorder
+
+ ldq $tj,8($tp)
+ addq $alo,$hi0,$lo0
+ addq $nlo,$hi1,$lo1
+ cmpult $lo0,$hi0,AT
+ cmpult $lo1,$hi1,v0
+ addq $ahi,AT,$hi0
+ addq $nhi,v0,$hi1
+
+ addq $lo0,$tj,$lo0
+ cmpult $lo0,$tj,AT
+ addq $hi0,AT,$hi0
+
+ ldq $tj,16($tp)
+ addq $lo1,$lo0,$j
+ cmpult $j,$lo0,v0
+ addq $hi1,v0,$hi1
+
+ addq $hi1,$hi0,$lo1
+ stq $j,0($tp)
+ cmpult $lo1,$hi0,$hi1
+ addq $lo1,$tj,$lo1
+ cmpult $lo1,$tj,AT
+ addl $i,1,$i
+ addq $hi1,AT,$hi1
+ stq $lo1,8($tp)
+ cmplt $i,$num,$tj # borrow $tj
+ stq $hi1,16($tp)
+ bne $tj,.Louter
+
+ s8addq $num,sp,$tj # &tp[num]
+ mov $rp,$bp # put rp aside
+ mov sp,$tp
+ mov sp,$ap
+ mov 0,$hi0 # clear borrow bit
+
+.align 4
+.Lsub: ldq $lo0,0($tp)
+ ldq $lo1,0($np)
+ lda $tp,8($tp)
+ lda $np,8($np)
+ subq $lo0,$lo1,$lo1 # tp[i]-np[i]
+ cmpult $lo0,$lo1,AT
+ subq $lo1,$hi0,$lo0
+ cmpult $lo1,$lo0,$hi0
+ or $hi0,AT,$hi0
+ stq $lo0,0($rp)
+ cmpult $tp,$tj,v0
+ lda $rp,8($rp)
+ bne v0,.Lsub
+
+ subq $hi1,$hi0,$hi0 # handle upmost overflow bit
+ mov sp,$tp
+ mov $bp,$rp # restore rp
+
+.align 4
+.Lcopy: ldq $aj,0($tp) # conditional copy
+ ldq $nj,0($rp)
+ lda $tp,8($tp)
+ lda $rp,8($rp)
+ cmoveq $hi0,$nj,$aj
+ stq zero,-8($tp) # zap tp
+ cmpult $tp,$tj,AT
+ stq $aj,-8($rp)
+ bne AT,.Lcopy
+ mov 1,v0
+
+.Lexit:
+ .set noreorder
+ mov fp,sp
+ /*ldq ra,0(sp)*/
+ ldq s3,8(sp)
+ ldq s4,16(sp)
+ ldq s5,24(sp)
+ ldq fp,32(sp)
+ lda sp,48(sp)
+ ret (ra)
+.end bn_mul_mont
+.ascii "Montgomery Multiplication for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
+.align 2
+___
+
+print $code;
+close STDOUT or die "error closing STDOUT: $!";
diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c
index 4e169ae1f9a4..598a592ca139 100644
--- a/crypto/bn/bn_exp.c
+++ b/crypto/bn/bn_exp.c
@@ -243,6 +243,14 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
wstart = bits - 1; /* The top bit of the window */
wend = 0; /* The bottom bit of the window */
+ if (r == p) {
+ BIGNUM *p_dup = BN_CTX_get(ctx);
+
+ if (p_dup == NULL || BN_copy(p_dup, p) == NULL)
+ goto err;
+ p = p_dup;
+ }
+
if (!BN_one(r))
goto err;
@@ -1317,6 +1325,11 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
return 0;
}
+ if (r == m) {
+ ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT);
+ return 0;
+ }
+
bits = BN_num_bits(p);
if (bits == 0) {
/* x**0 mod 1, or x**0 mod -1 is still zero. */
@@ -1362,6 +1375,14 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
wstart = bits - 1; /* The top bit of the window */
wend = 0; /* The bottom bit of the window */
+ if (r == p) {
+ BIGNUM *p_dup = BN_CTX_get(ctx);
+
+ if (p_dup == NULL || BN_copy(p_dup, p) == NULL)
+ goto err;
+ p = p_dup;
+ }
+
if (!BN_one(r))
goto err;
diff --git a/crypto/bn/bn_gf2m.c b/crypto/bn/bn_gf2m.c
index 304c2ea08d0e..c811ae82d6b1 100644
--- a/crypto/bn/bn_gf2m.c
+++ b/crypto/bn/bn_gf2m.c
@@ -734,14 +734,20 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
{
BIGNUM *b = NULL;
int ret = 0;
+ int numbits;
BN_CTX_start(ctx);
if ((b = BN_CTX_get(ctx)) == NULL)
goto err;
+ /* Fail on a non-sensical input p value */
+ numbits = BN_num_bits(p);
+ if (numbits <= 1)
+ goto err;
+
/* generate blinding value */
do {
- if (!BN_priv_rand_ex(b, BN_num_bits(p) - 1,
+ if (!BN_priv_rand_ex(b, numbits - 1,
BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, 0, ctx))
goto err;
} while (BN_is_zero(b));
diff --git a/crypto/bn/bn_mod.c b/crypto/bn/bn_mod.c
index 7f5afa25ecc8..2dda2e3442ed 100644
--- a/crypto/bn/bn_mod.c
+++ b/crypto/bn/bn_mod.c
@@ -17,6 +17,11 @@ int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
* always holds)
*/
+ if (r == d) {
+ ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT);
+ return 0;
+ }
+
if (!(BN_mod(r, m, d, ctx)))
return 0;
if (!r->neg)
@@ -186,6 +191,11 @@ int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BIGNUM *m)
{
+ if (r == m) {
+ ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT);
+ return 0;
+ }
+
if (!BN_sub(r, a, b))
return 0;
if (r->neg)
diff --git a/crypto/bn/bn_nist.c b/crypto/bn/bn_nist.c
index 3d4d9a2fb2df..d761e5702da2 100644
--- a/crypto/bn/bn_nist.c
+++ b/crypto/bn/bn_nist.c
@@ -319,6 +319,28 @@ static void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top)
# endif
#endif /* BN_BITS2 != 64 */
+#ifdef NIST_INT64
+/* Helpers to load/store a 32-bit word (uint32_t) from/into a memory
+ * location and avoid potential aliasing issue. */
+static ossl_inline uint32_t load_u32(const void *ptr)
+{
+ uint32_t tmp;
+
+ memcpy(&tmp, ptr, sizeof(tmp));
+ return tmp;
+}
+
+static ossl_inline void store_lo32(void *ptr, NIST_INT64 val)
+{
+ /* A cast is needed for big-endian system: on a 32-bit BE system
+ * NIST_INT64 may be defined as well if the compiler supports 64-bit
+ * long long. */
+ uint32_t tmp = (uint32_t)val;
+
+ memcpy(ptr, &tmp, sizeof(tmp));
+}
+#endif /* NIST_INT64 */
+
#define nist_set_192(to, from, a1, a2, a3) \
{ \
bn_cp_64(to, 0, from, (a3) - 3) \
@@ -374,42 +396,42 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
unsigned int *rp = (unsigned int *)r_d;
const unsigned int *bp = (const unsigned int *)buf.ui;
- acc = rp[0];
+ acc = load_u32(&rp[0]);
acc += bp[3 * 2 - 6];
acc += bp[5 * 2 - 6];
- rp[0] = (unsigned int)acc;
+ store_lo32(&rp[0], acc);
acc >>= 32;
- acc += rp[1];
+ acc += load_u32(&rp[1]);
acc += bp[3 * 2 - 5];
acc += bp[5 * 2 - 5];
- rp[1] = (unsigned int)acc;
+ store_lo32(&rp[1], acc);
acc >>= 32;
- acc += rp[2];
+ acc += load_u32(&rp[2]);
acc += bp[3 * 2 - 6];
acc += bp[4 * 2 - 6];
acc += bp[5 * 2 - 6];
- rp[2] = (unsigned int)acc;
+ store_lo32(&rp[2], acc);
acc >>= 32;
- acc += rp[3];
+ acc += load_u32(&rp[3]);
acc += bp[3 * 2 - 5];
acc += bp[4 * 2 - 5];
acc += bp[5 * 2 - 5];
- rp[3] = (unsigned int)acc;
+ store_lo32(&rp[3], acc);
acc >>= 32;
- acc += rp[4];
+ acc += load_u32(&rp[4]);
acc += bp[4 * 2 - 6];
acc += bp[5 * 2 - 6];
- rp[4] = (unsigned int)acc;
+ store_lo32(&rp[4], acc);
acc >>= 32;
- acc += rp[5];
+ acc += load_u32(&rp[5]);
acc += bp[4 * 2 - 5];
acc += bp[5 * 2 - 5];
- rp[5] = (unsigned int)acc;
+ store_lo32(&rp[5], acc);
carry = (int)(acc >> 32);
}
@@ -683,36 +705,36 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
unsigned int *rp = (unsigned int *)r_d;
const unsigned int *bp = (const unsigned int *)buf.ui;
- acc = rp[0];
+ acc = load_u32(&rp[0]);
acc += bp[8 - 8];
acc += bp[9 - 8];
acc -= bp[11 - 8];
acc -= bp[12 - 8];
acc -= bp[13 - 8];
acc -= bp[14 - 8];
- rp[0] = (unsigned int)acc;
+ store_lo32(&rp[0], acc);
acc >>= 32;
- acc += rp[1];
+ acc += load_u32(&rp[1]);
acc += bp[9 - 8];
acc += bp[10 - 8];
acc -= bp[12 - 8];
acc -= bp[13 - 8];
acc -= bp[14 - 8];
acc -= bp[15 - 8];
- rp[1] = (unsigned int)acc;
+ store_lo32(&rp[1], acc);
acc >>= 32;
- acc += rp[2];
+ acc += load_u32(&rp[2]);
acc += bp[10 - 8];
acc += bp[11 - 8];
acc -= bp[13 - 8];
acc -= bp[14 - 8];
acc -= bp[15 - 8];
- rp[2] = (unsigned int)acc;
+ store_lo32(&rp[2], acc);
acc >>= 32;
- acc += rp[3];
+ acc += load_u32(&rp[3]);
acc += bp[11 - 8];
acc += bp[11 - 8];
acc += bp[12 - 8];
@@ -721,10 +743,10 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
acc -= bp[15 - 8];
acc -= bp[8 - 8];
acc -= bp[9 - 8];
- rp[3] = (unsigned int)acc;
+ store_lo32(&rp[3], acc);
acc >>= 32;
- acc += rp[4];
+ acc += load_u32(&rp[4]);
acc += bp[12 - 8];
acc += bp[12 - 8];
acc += bp[13 - 8];
@@ -732,10 +754,10 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
acc += bp[14 - 8];
acc -= bp[9 - 8];
acc -= bp[10 - 8];
- rp[4] = (unsigned int)acc;
+ store_lo32(&rp[4], acc);
acc >>= 32;
- acc += rp[5];
+ acc += load_u32(&rp[5]);
acc += bp[13 - 8];
acc += bp[13 - 8];
acc += bp[14 - 8];
@@ -743,10 +765,10 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
acc += bp[15 - 8];
acc -= bp[10 - 8];
acc -= bp[11 - 8];
- rp[5] = (unsigned int)acc;
+ store_lo32(&rp[5], acc);
acc >>= 32;
- acc += rp[6];
+ acc += load_u32(&rp[6]);
acc += bp[14 - 8];
acc += bp[14 - 8];
acc += bp[15 - 8];
@@ -755,10 +777,10 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
acc += bp[13 - 8];
acc -= bp[8 - 8];
acc -= bp[9 - 8];
- rp[6] = (unsigned int)acc;
+ store_lo32(&rp[6], acc);
acc >>= 32;
- acc += rp[7];
+ acc += load_u32(&rp[7]);
acc += bp[15 - 8];
acc += bp[15 - 8];
acc += bp[15 - 8];
@@ -767,7 +789,7 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
acc -= bp[11 - 8];
acc -= bp[12 - 8];
acc -= bp[13 - 8];
- rp[7] = (unsigned int)acc;
+ store_lo32(&rp[7], acc);
carry = (int)(acc >> 32);
}
@@ -920,32 +942,32 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
unsigned int *rp = (unsigned int *)r_d;
const unsigned int *bp = (const unsigned int *)buf.ui;
- acc = rp[0];
+ acc = load_u32(&rp[0]);
acc += bp[12 - 12];
acc += bp[21 - 12];
acc += bp[20 - 12];
acc -= bp[23 - 12];
- rp[0] = (unsigned int)acc;
+ store_lo32(&rp[0], acc);
acc >>= 32;
- acc += rp[1];
+ acc += load_u32(&rp[1]);
acc += bp[13 - 12];
acc += bp[22 - 12];
acc += bp[23 - 12];
acc -= bp[12 - 12];
acc -= bp[20 - 12];
- rp[1] = (unsigned int)acc;
+ store_lo32(&rp[1], acc);
acc >>= 32;
- acc += rp[2];
+ acc += load_u32(&rp[2]);
acc += bp[14 - 12];
acc += bp[23 - 12];
acc -= bp[13 - 12];
acc -= bp[21 - 12];
- rp[2] = (unsigned int)acc;
+ store_lo32(&rp[2], acc);
acc >>= 32;
- acc += rp[3];
+ acc += load_u32(&rp[3]);
acc += bp[15 - 12];
acc += bp[12 - 12];
acc += bp[20 - 12];
@@ -953,10 +975,10 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
acc -= bp[14 - 12];
acc -= bp[22 - 12];
acc -= bp[23 - 12];
- rp[3] = (unsigned int)acc;
+ store_lo32(&rp[3], acc);
acc >>= 32;
- acc += rp[4];
+ acc += load_u32(&rp[4]);
acc += bp[21 - 12];
acc += bp[21 - 12];
acc += bp[16 - 12];
@@ -967,10 +989,10 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
acc -= bp[15 - 12];
acc -= bp[23 - 12];
acc -= bp[23 - 12];
- rp[4] = (unsigned int)acc;
+ store_lo32(&rp[4], acc);
acc >>= 32;
- acc += rp[5];
+ acc += load_u32(&rp[5]);
acc += bp[22 - 12];
acc += bp[22 - 12];
acc += bp[17 - 12];
@@ -979,10 +1001,10 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
acc += bp[21 - 12];
acc += bp[23 - 12];
acc -= bp[16 - 12];
- rp[5] = (unsigned int)acc;
+ store_lo32(&rp[5], acc);
acc >>= 32;
- acc += rp[6];
+ acc += load_u32(&rp[6]);
acc += bp[23 - 12];
acc += bp[23 - 12];
acc += bp[18 - 12];
@@ -990,48 +1012,48 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
acc += bp[14 - 12];
acc += bp[22 - 12];
acc -= bp[17 - 12];
- rp[6] = (unsigned int)acc;
+ store_lo32(&rp[6], acc);
acc >>= 32;
- acc += rp[7];
+ acc += load_u32(&rp[7]);
acc += bp[19 - 12];
acc += bp[16 - 12];
acc += bp[15 - 12];
acc += bp[23 - 12];
acc -= bp[18 - 12];
- rp[7] = (unsigned int)acc;
+ store_lo32(&rp[7], acc);
acc >>= 32;
- acc += rp[8];
+ acc += load_u32(&rp[8]);
acc += bp[20 - 12];
acc += bp[17 - 12];
acc += bp[16 - 12];
acc -= bp[19 - 12];
- rp[8] = (unsigned int)acc;
+ store_lo32(&rp[8], acc);
acc >>= 32;
- acc += rp[9];
+ acc += load_u32(&rp[9]);
acc += bp[21 - 12];
acc += bp[18 - 12];
acc += bp[17 - 12];
acc -= bp[20 - 12];
- rp[9] = (unsigned int)acc;
+ store_lo32(&rp[9], acc);
acc >>= 32;
- acc += rp[10];
+ acc += load_u32(&rp[10]);
acc += bp[22 - 12];
acc += bp[19 - 12];
acc += bp[18 - 12];
acc -= bp[21 - 12];
- rp[10] = (unsigned int)acc;
+ store_lo32(&rp[10], acc);
acc >>= 32;
- acc += rp[11];
+ acc += load_u32(&rp[11]);
acc += bp[23 - 12];
acc += bp[20 - 12];
acc += bp[19 - 12];
acc -= bp[22 - 12];
- rp[11] = (unsigned int)acc;
+ store_lo32(&rp[11], acc);
carry = (int)(acc >> 32);
}
diff --git a/crypto/build.info b/crypto/build.info
index c04db5591120..a45bf8deefd5 100644
--- a/crypto/build.info
+++ b/crypto/build.info
@@ -74,8 +74,8 @@ DEFINE[../providers/libfips.a]=$CPUIDDEF
# already gets everything that the static libcrypto.a has, and doesn't need it
# added again.
IF[{- !$disabled{module} && !$disabled{shared} -}]
- SOURCE[../providers/liblegacy.a]=$CPUID_COMMON
- DEFINE[../providers/liblegacy.a]=$CPUIDDEF
+ SOURCE[../providers/legacy]=$CPUID_COMMON
+ DEFINE[../providers/legacy]=$CPUIDDEF
ENDIF
# Implementations are now spread across several libraries, so the CPUID define
diff --git a/crypto/cms/cms_att.c b/crypto/cms/cms_att.c
index 5b99516b29a1..64acda72630a 100644
--- a/crypto/cms/cms_att.c
+++ b/crypto/cms/cms_att.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2024 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
@@ -12,8 +12,9 @@
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/cms.h>
-#include "cms_local.h"
#include "internal/nelem.h"
+#include "crypto/x509.h"
+#include "cms_local.h"
/*-
* Attribute flags.
@@ -94,7 +95,7 @@ X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc)
int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
{
- if (X509at_add1_attr(&si->signedAttrs, attr))
+ if (ossl_x509at_add1_attr(&si->signedAttrs, attr))
return 1;
return 0;
}
@@ -103,7 +104,7 @@ int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
const ASN1_OBJECT *obj, int type,
const void *bytes, int len)
{
- if (X509at_add1_attr_by_OBJ(&si->signedAttrs, obj, type, bytes, len))
+ if (ossl_x509at_add1_attr_by_OBJ(&si->signedAttrs, obj, type, bytes, len))
return 1;
return 0;
}
@@ -111,7 +112,7 @@ int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
int nid, int type, const void *bytes, int len)
{
- if (X509at_add1_attr_by_NID(&si->signedAttrs, nid, type, bytes, len))
+ if (ossl_x509at_add1_attr_by_NID(&si->signedAttrs, nid, type, bytes, len))
return 1;
return 0;
}
@@ -120,7 +121,8 @@ int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
const char *attrname, int type,
const void *bytes, int len)
{
- if (X509at_add1_attr_by_txt(&si->signedAttrs, attrname, type, bytes, len))
+ if (ossl_x509at_add1_attr_by_txt(&si->signedAttrs, attrname, type, bytes,
+ len))
return 1;
return 0;
}
@@ -161,7 +163,7 @@ X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc)
int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
{
- if (X509at_add1_attr(&si->unsignedAttrs, attr))
+ if (ossl_x509at_add1_attr(&si->unsignedAttrs, attr))
return 1;
return 0;
}
@@ -170,7 +172,7 @@ int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
const ASN1_OBJECT *obj, int type,
const void *bytes, int len)
{
- if (X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj, type, bytes, len))
+ if (ossl_x509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj, type, bytes, len))
return 1;
return 0;
}
@@ -179,7 +181,7 @@ int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
int nid, int type,
const void *bytes, int len)
{
- if (X509at_add1_attr_by_NID(&si->unsignedAttrs, nid, type, bytes, len))
+ if (ossl_x509at_add1_attr_by_NID(&si->unsignedAttrs, nid, type, bytes, len))
return 1;
return 0;
}
@@ -188,8 +190,8 @@ int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
const char *attrname, int type,
const void *bytes, int len)
{
- if (X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname,
- type, bytes, len))
+ if (ossl_x509at_add1_attr_by_txt(&si->unsignedAttrs, attrname,
+ type, bytes, len))
return 1;
return 0;
}
diff --git a/crypto/cms/cms_dh.c b/crypto/cms/cms_dh.c
index 9509796317b3..2f54ed2673a9 100644
--- a/crypto/cms/cms_dh.c
+++ b/crypto/cms/cms_dh.c
@@ -316,10 +316,10 @@ static int dh_cms_encrypt(CMS_RecipientInfo *ri)
goto err;
ASN1_STRING_set0(wrap_str, penc, penclen);
penc = NULL;
- X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
- V_ASN1_SEQUENCE, wrap_str);
-
- rv = 1;
+ rv = X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
+ V_ASN1_SEQUENCE, wrap_str);
+ if (!rv)
+ ASN1_STRING_free(wrap_str);
err:
OPENSSL_free(penc);
diff --git a/crypto/cms/cms_rsa.c b/crypto/cms/cms_rsa.c
index 61fd43fb54d0..12bc81843897 100644
--- a/crypto/cms/cms_rsa.c
+++ b/crypto/cms/cms_rsa.c
@@ -99,8 +99,10 @@ static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
goto err;
if (label != NULL
- && EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0)
+ && EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) {
+ OPENSSL_free(label);
goto err;
+ }
/* Carry on */
rv = 1;
@@ -114,6 +116,7 @@ static int rsa_cms_encrypt(CMS_RecipientInfo *ri)
const EVP_MD *md, *mgf1md;
RSA_OAEP_PARAMS *oaep = NULL;
ASN1_STRING *os = NULL;
+ ASN1_OCTET_STRING *los = NULL;
X509_ALGOR *alg;
EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen;
@@ -125,10 +128,10 @@ static int rsa_cms_encrypt(CMS_RecipientInfo *ri)
if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
return 0;
}
- if (pad_mode == RSA_PKCS1_PADDING) {
- X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
- return 1;
- }
+ if (pad_mode == RSA_PKCS1_PADDING)
+ return X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
+ V_ASN1_NULL, NULL);
+
/* Not supported */
if (pad_mode != RSA_PKCS1_OAEP_PADDING)
return 0;
@@ -147,30 +150,32 @@ static int rsa_cms_encrypt(CMS_RecipientInfo *ri)
if (!ossl_x509_algor_md_to_mgf1(&oaep->maskGenFunc, mgf1md))
goto err;
if (labellen > 0) {
- ASN1_OCTET_STRING *los;
-
oaep->pSourceFunc = X509_ALGOR_new();
if (oaep->pSourceFunc == NULL)
goto err;
los = ASN1_OCTET_STRING_new();
if (los == NULL)
goto err;
- if (!ASN1_OCTET_STRING_set(los, label, labellen)) {
- ASN1_OCTET_STRING_free(los);
+ if (!ASN1_OCTET_STRING_set(los, label, labellen))
goto err;
- }
- X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified),
- V_ASN1_OCTET_STRING, los);
+
+ if (!X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified),
+ V_ASN1_OCTET_STRING, los))
+ goto err;
+
+ los = NULL;
}
- /* create string with pss parameter encoding. */
+ /* create string with oaep parameter encoding. */
if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os))
- goto err;
- X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os);
+ goto err;
+ if (!X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os))
+ goto err;
os = NULL;
rv = 1;
err:
RSA_OAEP_PARAMS_free(oaep);
ASN1_STRING_free(os);
+ ASN1_OCTET_STRING_free(los);
return rv;
}
diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c
index 2093657a2a4a..3a21664e9da2 100644
--- a/crypto/cms/cms_sd.c
+++ b/crypto/cms/cms_sd.c
@@ -1037,31 +1037,32 @@ int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
int algnid, int keysize)
{
- X509_ALGOR *alg;
+ X509_ALGOR *alg = NULL;
ASN1_INTEGER *key = NULL;
if (keysize > 0) {
key = ASN1_INTEGER_new();
- if (key == NULL || !ASN1_INTEGER_set(key, keysize)) {
- ASN1_INTEGER_free(key);
- return 0;
- }
+ if (key == NULL || !ASN1_INTEGER_set(key, keysize))
+ goto err;
}
alg = X509_ALGOR_new();
- if (alg == NULL) {
- ASN1_INTEGER_free(key);
- return 0;
- }
+ if (alg == NULL)
+ goto err;
- X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
- key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
+ if (!X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
+ key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key))
+ goto err;
+ key = NULL;
if (*algs == NULL)
*algs = sk_X509_ALGOR_new_null();
- if (*algs == NULL || !sk_X509_ALGOR_push(*algs, alg)) {
- X509_ALGOR_free(alg);
- return 0;
- }
+ if (*algs == NULL || !sk_X509_ALGOR_push(*algs, alg))
+ goto err;
return 1;
+
+ err:
+ ASN1_INTEGER_free(key);
+ X509_ALGOR_free(alg);
+ return 0;
}
/* Check to see if a cipher exists and if so add S/MIME capabilities */
diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c
index 479038d5732f..d7719267c8c8 100644
--- a/crypto/cms/cms_smime.c
+++ b/crypto/cms/cms_smime.c
@@ -558,7 +558,7 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
{
CMS_SignerInfo *rct_si;
CMS_ContentInfo *cms = NULL;
- ASN1_OCTET_STRING **pos, *os;
+ ASN1_OCTET_STRING **pos, *os = NULL;
BIO *rct_cont = NULL;
int r = 0;
const CMS_CTX *ctx = si->cms_ctx;
@@ -620,6 +620,7 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
if (r)
return cms;
CMS_ContentInfo_free(cms);
+ ASN1_OCTET_STRING_free(os);
return NULL;
}
diff --git a/crypto/conf/conf_err.c b/crypto/conf/conf_err.c
index 68ee90b97055..fc0eee7d2f85 100644
--- a/crypto/conf/conf_err.c
+++ b/crypto/conf/conf_err.c
@@ -41,6 +41,8 @@ static const ERR_STRING_DATA CONF_str_reasons[] = {
"openssl conf references missing section"},
{ERR_PACK(ERR_LIB_CONF, 0, CONF_R_RECURSIVE_DIRECTORY_INCLUDE),
"recursive directory include"},
+ {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_RECURSIVE_SECTION_REFERENCE),
+ "recursive section reference"},
{ERR_PACK(ERR_LIB_CONF, 0, CONF_R_RELATIVE_PATH), "relative path"},
{ERR_PACK(ERR_LIB_CONF, 0, CONF_R_SSL_COMMAND_SECTION_EMPTY),
"ssl command section empty"},
diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c
index 7ba2beae7fd6..e20eb62081c5 100644
--- a/crypto/dh/dh_check.c
+++ b/crypto/dh/dh_check.c
@@ -249,6 +249,18 @@ int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key)
*/
int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
{
+ /* Don't do any checks at all with an excessively large modulus */
+ if (BN_num_bits(dh->params.p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) {
+ ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE);
+ *ret = DH_MODULUS_TOO_LARGE | DH_CHECK_PUBKEY_INVALID;
+ return 0;
+ }
+
+ if (dh->params.q != NULL && BN_ucmp(dh->params.p, dh->params.q) < 0) {
+ *ret |= DH_CHECK_INVALID_Q_VALUE | DH_CHECK_PUBKEY_INVALID;
+ return 1;
+ }
+
return ossl_ffc_validate_public_key(&dh->params, pub_key, ret);
}
diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c
index 4152397426cc..f76ac0dd1463 100644
--- a/crypto/dh/dh_err.c
+++ b/crypto/dh/dh_err.c
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 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
@@ -54,6 +54,7 @@ static const ERR_STRING_DATA DH_str_reasons[] = {
{ERR_PACK(ERR_LIB_DH, 0, DH_R_PARAMETER_ENCODING_ERROR),
"parameter encoding error"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_PEER_KEY_ERROR), "peer key error"},
+ {ERR_PACK(ERR_LIB_DH, 0, DH_R_Q_TOO_LARGE), "q too large"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_SHARED_INFO_ERROR), "shared info error"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_UNABLE_TO_CHECK_GENERATOR),
"unable to check generator"},
diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
index d84ea99241b9..afc49f5cdc87 100644
--- a/crypto/dh/dh_key.c
+++ b/crypto/dh/dh_key.c
@@ -49,6 +49,12 @@ int ossl_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
goto err;
}
+ if (dh->params.q != NULL
+ && BN_num_bits(dh->params.q) > OPENSSL_DH_MAX_MODULUS_BITS) {
+ ERR_raise(ERR_LIB_DH, DH_R_Q_TOO_LARGE);
+ goto err;
+ }
+
if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) {
ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL);
return 0;
@@ -267,6 +273,12 @@ static int generate_key(DH *dh)
return 0;
}
+ if (dh->params.q != NULL
+ && BN_num_bits(dh->params.q) > OPENSSL_DH_MAX_MODULUS_BITS) {
+ ERR_raise(ERR_LIB_DH, DH_R_Q_TOO_LARGE);
+ return 0;
+ }
+
if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) {
ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL);
return 0;
diff --git a/crypto/dso/dso_vms.c b/crypto/dso/dso_vms.c
new file mode 100644
index 000000000000..aa2dfaa4d15f
--- /dev/null
+++ b/crypto/dso/dso_vms.c
@@ -0,0 +1,489 @@
+/*
+ * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "dso_local.h"
+
+#ifdef OPENSSL_SYS_VMS
+
+# pragma message disable DOLLARID
+# include <errno.h>
+# include <rms.h>
+# include <lib$routines.h>
+# include <libfisdef.h>
+# include <stsdef.h>
+# include <descrip.h>
+# include <starlet.h>
+# include "../vms_rms.h"
+
+/* Some compiler options may mask the declaration of "_malloc32". */
+# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
+# if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size save
+# pragma pointer_size 32
+void *_malloc32(__size_t);
+# pragma pointer_size restore
+# endif /* __INITIAL_POINTER_SIZE == 64 */
+# endif /* __INITIAL_POINTER_SIZE && defined
+ * _ANSI_C_SOURCE */
+
+# pragma message disable DOLLARID
+
+static int vms_load(DSO *dso);
+static int vms_unload(DSO *dso);
+static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname);
+static char *vms_name_converter(DSO *dso, const char *filename);
+static char *vms_merger(DSO *dso, const char *filespec1,
+ const char *filespec2);
+
+static DSO_METHOD dso_meth_vms = {
+ "OpenSSL 'VMS' shared library method",
+ vms_load,
+ NULL, /* unload */
+ vms_bind_func,
+ NULL, /* ctrl */
+ vms_name_converter,
+ vms_merger,
+ NULL, /* init */
+ NULL, /* finish */
+ NULL, /* pathbyaddr */
+ NULL /* globallookup */
+};
+
+/*
+ * On VMS, the only "handle" is the file name. LIB$FIND_IMAGE_SYMBOL depends
+ * on the reference to the file name being the same for all calls regarding
+ * one shared image, so we'll just store it in an instance of the following
+ * structure and put a pointer to that instance in the meth_data stack.
+ */
+typedef struct dso_internal_st {
+ /*
+ * This should contain the name only, no directory, no extension, nothing
+ * but a name.
+ */
+ struct dsc$descriptor_s filename_dsc;
+ char filename[NAMX_MAXRSS + 1];
+ /*
+ * This contains whatever is not in filename, if needed. Normally not
+ * defined.
+ */
+ struct dsc$descriptor_s imagename_dsc;
+ char imagename[NAMX_MAXRSS + 1];
+} DSO_VMS_INTERNAL;
+
+DSO_METHOD *DSO_METHOD_openssl(void)
+{
+ return &dso_meth_vms;
+}
+
+static int vms_load(DSO *dso)
+{
+ void *ptr = NULL;
+ /* See applicable comments in dso_dl.c */
+ char *filename = DSO_convert_filename(dso, NULL);
+
+/* Ensure 32-bit pointer for "p", and appropriate malloc() function. */
+# if __INITIAL_POINTER_SIZE == 64
+# define DSO_MALLOC _malloc32
+# pragma pointer_size save
+# pragma pointer_size 32
+# else /* __INITIAL_POINTER_SIZE == 64 */
+# define DSO_MALLOC OPENSSL_malloc
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+ DSO_VMS_INTERNAL *p = NULL;
+
+# if __INITIAL_POINTER_SIZE == 64
+# pragma pointer_size restore
+# endif /* __INITIAL_POINTER_SIZE == 64 */
+
+ const char *sp1, *sp2; /* Search result */
+ const char *ext = NULL; /* possible extension to add */
+
+ if (filename == NULL) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_NO_FILENAME);
+ goto err;
+ }
+
+ /*-
+ * A file specification may look like this:
+ *
+ * node::dev:[dir-spec]name.type;ver
+ *
+ * or (for compatibility with TOPS-20):
+ *
+ * node::dev:<dir-spec>name.type;ver
+ *
+ * and the dir-spec uses '.' as separator. Also, a dir-spec
+ * may consist of several parts, with mixed use of [] and <>:
+ *
+ * [dir1.]<dir2>
+ *
+ * We need to split the file specification into the name and
+ * the rest (both before and after the name itself).
+ */
+ /*
+ * Start with trying to find the end of a dir-spec, and save the position
+ * of the byte after in sp1
+ */
+ sp1 = strrchr(filename, ']');
+ sp2 = strrchr(filename, '>');
+ if (sp1 == NULL)
+ sp1 = sp2;
+ if (sp2 != NULL && sp2 > sp1)
+ sp1 = sp2;
+ if (sp1 == NULL)
+ sp1 = strrchr(filename, ':');
+ if (sp1 == NULL)
+ sp1 = filename;
+ else
+ sp1++; /* The byte after the found character */
+ /* Now, let's see if there's a type, and save the position in sp2 */
+ sp2 = strchr(sp1, '.');
+ /*
+ * If there is a period and the next character is a semi-colon,
+ * we need to add an extension
+ */
+ if (sp2 != NULL && sp2[1] == ';')
+ ext = ".EXE";
+ /*
+ * If we found it, that's where we'll cut. Otherwise, look for a version
+ * number and save the position in sp2
+ */
+ if (sp2 == NULL) {
+ sp2 = strchr(sp1, ';');
+ ext = ".EXE";
+ }
+ /*
+ * If there was still nothing to find, set sp2 to point at the end of the
+ * string
+ */
+ if (sp2 == NULL)
+ sp2 = sp1 + strlen(sp1);
+
+ /* Check that we won't get buffer overflows */
+ if (sp2 - sp1 > FILENAME_MAX
+ || (sp1 - filename) + strlen(sp2) > FILENAME_MAX) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_FILENAME_TOO_BIG);
+ goto err;
+ }
+
+ p = DSO_MALLOC(sizeof(*p));
+ if (p == NULL) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ strncpy(p->filename, sp1, sp2 - sp1);
+ p->filename[sp2 - sp1] = '\0';
+
+ strncpy(p->imagename, filename, sp1 - filename);
+ p->imagename[sp1 - filename] = '\0';
+ if (ext) {
+ strcat(p->imagename, ext);
+ if (*sp2 == '.')
+ sp2++;
+ }
+ strcat(p->imagename, sp2);
+
+ p->filename_dsc.dsc$w_length = strlen(p->filename);
+ p->filename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ p->filename_dsc.dsc$b_class = DSC$K_CLASS_S;
+ p->filename_dsc.dsc$a_pointer = p->filename;
+ p->imagename_dsc.dsc$w_length = strlen(p->imagename);
+ p->imagename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S;
+ p->imagename_dsc.dsc$a_pointer = p->imagename;
+
+ if (!sk_void_push(dso->meth_data, (char *)p)) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_STACK_ERROR);
+ goto err;
+ }
+
+ /* Success (for now, we lie. We actually do not know...) */
+ dso->loaded_filename = filename;
+ return 1;
+ err:
+ /* Cleanup! */
+ OPENSSL_free(p);
+ OPENSSL_free(filename);
+ return 0;
+}
+
+/*
+ * Note that this doesn't actually unload the shared image, as there is no
+ * such thing in VMS. Next time it get loaded again, a new copy will
+ * actually be loaded.
+ */
+static int vms_unload(DSO *dso)
+{
+ DSO_VMS_INTERNAL *p;
+ if (dso == NULL) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if (sk_void_num(dso->meth_data) < 1)
+ return 1;
+ p = (DSO_VMS_INTERNAL *)sk_void_pop(dso->meth_data);
+ if (p == NULL) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_NULL_HANDLE);
+ return 0;
+ }
+ /* Cleanup */
+ OPENSSL_free(p);
+ return 1;
+}
+
+/*
+ * We must do this in a separate function because of the way the exception
+ * handler works (it makes this function return
+ */
+static int do_find_symbol(DSO_VMS_INTERNAL *ptr,
+ struct dsc$descriptor_s *symname_dsc, void **sym,
+ unsigned long flags)
+{
+ /*
+ * Make sure that signals are caught and returned instead of aborting the
+ * program. The exception handler gets unestablished automatically on
+ * return from this function.
+ */
+ lib$establish(lib$sig_to_ret);
+
+ if (ptr->imagename_dsc.dsc$w_length)
+ return lib$find_image_symbol(&ptr->filename_dsc,
+ symname_dsc, sym,
+ &ptr->imagename_dsc, flags);
+ else
+ return lib$find_image_symbol(&ptr->filename_dsc,
+ symname_dsc, sym, 0, flags);
+}
+
+# ifndef LIB$M_FIS_MIXEDCASE
+# define LIB$M_FIS_MIXEDCASE (1 << 4);
+# endif
+void vms_bind_sym(DSO *dso, const char *symname, void **sym)
+{
+ DSO_VMS_INTERNAL *ptr;
+ int status = 0;
+ struct dsc$descriptor_s symname_dsc;
+
+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
+# if __INITIAL_POINTER_SIZE == 64
+# define SYMNAME symname_32p
+# pragma pointer_size save
+# pragma pointer_size 32
+ char *symname_32p;
+# pragma pointer_size restore
+ char symname_32[NAMX_MAXRSS + 1];
+# else /* __INITIAL_POINTER_SIZE == 64 */
+# define SYMNAME ((char *) symname)
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+ *sym = NULL;
+
+ if ((dso == NULL) || (symname == NULL)) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER);
+ return;
+ }
+# if __INITIAL_POINTER_SIZE == 64
+ /* Copy the symbol name to storage with a 32-bit pointer. */
+ symname_32p = symname_32;
+ strcpy(symname_32p, symname);
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+ symname_dsc.dsc$w_length = strlen(SYMNAME);
+ symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ symname_dsc.dsc$b_class = DSC$K_CLASS_S;
+ symname_dsc.dsc$a_pointer = SYMNAME;
+
+ if (sk_void_num(dso->meth_data) < 1) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_STACK_ERROR);
+ return;
+ }
+ ptr = (DSO_VMS_INTERNAL *)sk_void_value(dso->meth_data,
+ sk_void_num(dso->meth_data) - 1);
+ if (ptr == NULL) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_NULL_HANDLE);
+ return;
+ }
+
+ status = do_find_symbol(ptr, &symname_dsc, sym, LIB$M_FIS_MIXEDCASE);
+
+ if (!$VMS_STATUS_SUCCESS(status))
+ status = do_find_symbol(ptr, &symname_dsc, sym, 0);
+
+ if (!$VMS_STATUS_SUCCESS(status)) {
+ unsigned short length;
+ char errstring[257];
+ struct dsc$descriptor_s errstring_dsc;
+
+ errstring_dsc.dsc$w_length = sizeof(errstring);
+ errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
+ errstring_dsc.dsc$a_pointer = errstring;
+
+ *sym = NULL;
+
+ status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
+
+ if (!$VMS_STATUS_SUCCESS(status))
+ lib$signal(status); /* This is really bad. Abort! */
+ else {
+ errstring[length] = '\0';
+
+ if (ptr->imagename_dsc.dsc$w_length)
+ ERR_raise_data(ERR_LIB_DSO, DSO_R_SYM_FAILURE,
+ "Symbol %s in %s (%s): %s",
+ symname, ptr->filename, ptr->imagename,
+ errstring);
+ else
+ ERR_raise_data(ERR_LIB_DSO, DSO_R_SYM_FAILURE,
+ "Symbol %s in %s: %s",
+ symname, ptr->filename, errstring);
+ }
+ return;
+ }
+ return;
+}
+
+static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname)
+{
+ DSO_FUNC_TYPE sym = 0;
+ vms_bind_sym(dso, symname, (void **)&sym);
+ return sym;
+}
+
+static char *vms_merger(DSO *dso, const char *filespec1,
+ const char *filespec2)
+{
+ int status;
+ int filespec1len, filespec2len;
+ struct FAB fab;
+ struct NAMX_STRUCT nam;
+ char esa[NAMX_MAXRSS + 1];
+ char *merged;
+
+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
+# if __INITIAL_POINTER_SIZE == 64
+# define FILESPEC1 filespec1_32p;
+# define FILESPEC2 filespec2_32p;
+# pragma pointer_size save
+# pragma pointer_size 32
+ char *filespec1_32p;
+ char *filespec2_32p;
+# pragma pointer_size restore
+ char filespec1_32[NAMX_MAXRSS + 1];
+ char filespec2_32[NAMX_MAXRSS + 1];
+# else /* __INITIAL_POINTER_SIZE == 64 */
+# define FILESPEC1 ((char *) filespec1)
+# define FILESPEC2 ((char *) filespec2)
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+ if (!filespec1)
+ filespec1 = "";
+ if (!filespec2)
+ filespec2 = "";
+ filespec1len = strlen(filespec1);
+ filespec2len = strlen(filespec2);
+
+# if __INITIAL_POINTER_SIZE == 64
+ /* Copy the file names to storage with a 32-bit pointer. */
+ filespec1_32p = filespec1_32;
+ filespec2_32p = filespec2_32;
+ strcpy(filespec1_32p, filespec1);
+ strcpy(filespec2_32p, filespec2);
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+ fab = cc$rms_fab;
+ nam = CC_RMS_NAMX;
+
+ FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNA = FILESPEC1;
+ FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNS = filespec1len;
+ FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNA = FILESPEC2;
+ FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNS = filespec2len;
+ NAMX_DNA_FNA_SET(fab)
+
+ nam.NAMX_ESA = esa;
+ nam.NAMX_ESS = NAMX_MAXRSS;
+ nam.NAMX_NOP = NAM$M_SYNCHK | NAM$M_PWD;
+ SET_NAMX_NO_SHORT_UPCASE(nam);
+
+ fab.FAB_NAMX = &nam;
+
+ status = sys$parse(&fab, 0, 0);
+
+ if (!$VMS_STATUS_SUCCESS(status)) {
+ unsigned short length;
+ char errstring[257];
+ struct dsc$descriptor_s errstring_dsc;
+
+ errstring_dsc.dsc$w_length = sizeof(errstring);
+ errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+ errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
+ errstring_dsc.dsc$a_pointer = errstring;
+
+ status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
+
+ if (!$VMS_STATUS_SUCCESS(status))
+ lib$signal(status); /* This is really bad. Abort! */
+ else {
+ errstring[length] = '\0';
+
+ ERR_raise_data(ERR_LIB_DSO, DSO_R_FAILURE,
+ "filespec \"%s\", default \"%s\": %s",
+ filespec1, filespec2, errstring);
+ }
+ return NULL;
+ }
+
+ merged = OPENSSL_malloc(nam.NAMX_ESL + 1);
+ if (merged == NULL)
+ goto malloc_err;
+ strncpy(merged, nam.NAMX_ESA, nam.NAMX_ESL);
+ merged[nam.NAMX_ESL] = '\0';
+ return merged;
+ malloc_err:
+ ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
+}
+
+static char *vms_name_converter(DSO *dso, const char *filename)
+{
+ char *translated;
+ int len, transform;
+ const char *p;
+
+ len = strlen(filename);
+
+ p = strchr(filename, ':');
+ if (p != NULL) {
+ transform = 0;
+ } else {
+ p = filename;
+ transform = (strrchr(p, '>') == NULL && strrchr(p, ']') == NULL);
+ }
+
+ if (transform) {
+ int rsize = len + sizeof(DSO_EXTENSION);
+
+ if ((translated = OPENSSL_malloc(rsize)) != NULL) {
+ p = strrchr(filename, ';');
+ if (p != NULL)
+ len = p - filename;
+ strncpy(translated, filename, len);
+ translated[len] = '\0';
+ strcat(translated, DSO_EXTENSION);
+ if (p != NULL)
+ strcat(translated, p);
+ }
+ } else {
+ translated = OPENSSL_strdup(filename);
+ }
+ return translated;
+}
+
+#endif /* OPENSSL_SYS_VMS */
diff --git a/crypto/dso/dso_win32.c b/crypto/dso/dso_win32.c
new file mode 100644
index 000000000000..4d3059d43879
--- /dev/null
+++ b/crypto/dso/dso_win32.c
@@ -0,0 +1,671 @@
+/*
+ * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "e_os.h"
+#include "dso_local.h"
+
+#if defined(DSO_WIN32)
+
+# ifdef _WIN32_WCE
+# if _WIN32_WCE < 300
+static FARPROC GetProcAddressA(HMODULE hModule, LPCSTR lpProcName)
+{
+ WCHAR lpProcNameW[64];
+ int i;
+
+ for (i = 0; lpProcName[i] && i < 64; i++)
+ lpProcNameW[i] = (WCHAR)lpProcName[i];
+ if (i == 64)
+ return NULL;
+ lpProcNameW[i] = 0;
+
+ return GetProcAddressW(hModule, lpProcNameW);
+}
+# endif
+# undef GetProcAddress
+# define GetProcAddress GetProcAddressA
+
+static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName)
+{
+ WCHAR *fnamw;
+ size_t len_0 = strlen(lpLibFileName) + 1, i;
+
+# ifdef _MSC_VER
+ fnamw = (WCHAR *)_alloca(len_0 * sizeof(WCHAR));
+# else
+ fnamw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
+# endif
+ if (fnamw == NULL) {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+# if defined(_WIN32_WCE) && _WIN32_WCE>=101
+ if (!MultiByteToWideChar(CP_ACP, 0, lpLibFileName, len_0, fnamw, len_0))
+# endif
+ for (i = 0; i < len_0; i++)
+ fnamw[i] = (WCHAR)lpLibFileName[i];
+
+ return LoadLibraryW(fnamw);
+}
+# endif
+
+/* Part of the hack in "win32_load" ... */
+# define DSO_MAX_TRANSLATED_SIZE 256
+
+static int win32_load(DSO *dso);
+static int win32_unload(DSO *dso);
+static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname);
+static char *win32_name_converter(DSO *dso, const char *filename);
+static char *win32_merger(DSO *dso, const char *filespec1,
+ const char *filespec2);
+static int win32_pathbyaddr(void *addr, char *path, int sz);
+static void *win32_globallookup(const char *name);
+
+static const char *openssl_strnchr(const char *string, int c, size_t len);
+
+static DSO_METHOD dso_meth_win32 = {
+ "OpenSSL 'win32' shared library method",
+ win32_load,
+ win32_unload,
+ win32_bind_func,
+ NULL, /* ctrl */
+ win32_name_converter,
+ win32_merger,
+ NULL, /* init */
+ NULL, /* finish */
+ win32_pathbyaddr, /* pathbyaddr */
+ win32_globallookup
+};
+
+DSO_METHOD *DSO_METHOD_openssl(void)
+{
+ return &dso_meth_win32;
+}
+
+/*
+ * For this DSO_METHOD, our meth_data STACK will contain; (i) a pointer to
+ * the handle (HINSTANCE) returned from LoadLibrary(), and copied.
+ */
+
+static int win32_load(DSO *dso)
+{
+ HINSTANCE h = NULL, *p = NULL;
+ /* See applicable comments from dso_dl.c */
+ char *filename = DSO_convert_filename(dso, NULL);
+
+ if (filename == NULL) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_NO_FILENAME);
+ goto err;
+ }
+ h = LoadLibraryA(filename);
+ if (h == NULL) {
+ ERR_raise_data(ERR_LIB_DSO, DSO_R_LOAD_FAILED,
+ "filename(%s)", filename);
+ goto err;
+ }
+ p = OPENSSL_malloc(sizeof(*p));
+ if (p == NULL) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ *p = h;
+ if (!sk_void_push(dso->meth_data, p)) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_STACK_ERROR);
+ goto err;
+ }
+ /* Success */
+ dso->loaded_filename = filename;
+ return 1;
+ err:
+ /* Cleanup ! */
+ OPENSSL_free(filename);
+ OPENSSL_free(p);
+ if (h != NULL)
+ FreeLibrary(h);
+ return 0;
+}
+
+static int win32_unload(DSO *dso)
+{
+ HINSTANCE *p;
+ if (dso == NULL) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if (sk_void_num(dso->meth_data) < 1)
+ return 1;
+ p = sk_void_pop(dso->meth_data);
+ if (p == NULL) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_NULL_HANDLE);
+ return 0;
+ }
+ if (!FreeLibrary(*p)) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_UNLOAD_FAILED);
+ /*
+ * We should push the value back onto the stack in case of a retry.
+ */
+ sk_void_push(dso->meth_data, p);
+ return 0;
+ }
+ /* Cleanup */
+ OPENSSL_free(p);
+ return 1;
+}
+
+static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname)
+{
+ HINSTANCE *ptr;
+ union {
+ void *p;
+ FARPROC f;
+ } sym;
+
+ if ((dso == NULL) || (symname == NULL)) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ if (sk_void_num(dso->meth_data) < 1) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_STACK_ERROR);
+ return NULL;
+ }
+ ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
+ if (ptr == NULL) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_NULL_HANDLE);
+ return NULL;
+ }
+ sym.f = GetProcAddress(*ptr, symname);
+ if (sym.p == NULL) {
+ ERR_raise_data(ERR_LIB_DSO, DSO_R_SYM_FAILURE, "symname(%s)", symname);
+ return NULL;
+ }
+ return (DSO_FUNC_TYPE)sym.f;
+}
+
+struct file_st {
+ const char *node;
+ int nodelen;
+ const char *device;
+ int devicelen;
+ const char *predir;
+ int predirlen;
+ const char *dir;
+ int dirlen;
+ const char *file;
+ int filelen;
+};
+
+static struct file_st *win32_splitter(DSO *dso, const char *filename,
+ int assume_last_is_dir)
+{
+ struct file_st *result = NULL;
+ enum { IN_NODE, IN_DEVICE, IN_FILE } position;
+ const char *start = filename;
+ char last;
+
+ if (!filename) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_NO_FILENAME);
+ return NULL;
+ }
+
+ result = OPENSSL_zalloc(sizeof(*result));
+ if (result == NULL) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ position = IN_DEVICE;
+
+ if ((filename[0] == '\\' && filename[1] == '\\')
+ || (filename[0] == '/' && filename[1] == '/')) {
+ position = IN_NODE;
+ filename += 2;
+ start = filename;
+ result->node = start;
+ }
+
+ do {
+ last = filename[0];
+ switch (last) {
+ case ':':
+ if (position != IN_DEVICE) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_INCORRECT_FILE_SYNTAX);
+ OPENSSL_free(result);
+ return NULL;
+ }
+ result->device = start;
+ result->devicelen = (int)(filename - start);
+ position = IN_FILE;
+ start = ++filename;
+ result->dir = start;
+ break;
+ case '\\':
+ case '/':
+ if (position == IN_NODE) {
+ result->nodelen = (int)(filename - start);
+ position = IN_FILE;
+ start = ++filename;
+ result->dir = start;
+ } else if (position == IN_DEVICE) {
+ position = IN_FILE;
+ filename++;
+ result->dir = start;
+ result->dirlen = (int)(filename - start);
+ start = filename;
+ } else {
+ filename++;
+ result->dirlen += (int)(filename - start);
+ start = filename;
+ }
+ break;
+ case '\0':
+ if (position == IN_NODE) {
+ result->nodelen = (int)(filename - start);
+ } else {
+ if (filename - start > 0) {
+ if (assume_last_is_dir) {
+ if (position == IN_DEVICE) {
+ result->dir = start;
+ result->dirlen = 0;
+ }
+ result->dirlen += (int)(filename - start);
+ } else {
+ result->file = start;
+ result->filelen = (int)(filename - start);
+ }
+ }
+ }
+ break;
+ default:
+ filename++;
+ break;
+ }
+ }
+ while (last);
+
+ if (!result->nodelen)
+ result->node = NULL;
+ if (!result->devicelen)
+ result->device = NULL;
+ if (!result->dirlen)
+ result->dir = NULL;
+ if (!result->filelen)
+ result->file = NULL;
+
+ return result;
+}
+
+static char *win32_joiner(DSO *dso, const struct file_st *file_split)
+{
+ int len = 0, offset = 0;
+ char *result = NULL;
+ const char *start;
+
+ if (!file_split) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ if (file_split->node) {
+ len += 2 + file_split->nodelen; /* 2 for starting \\ */
+ if (file_split->predir || file_split->dir || file_split->file)
+ len++; /* 1 for ending \ */
+ } else if (file_split->device) {
+ len += file_split->devicelen + 1; /* 1 for ending : */
+ }
+ len += file_split->predirlen;
+ if (file_split->predir && (file_split->dir || file_split->file)) {
+ len++; /* 1 for ending \ */
+ }
+ len += file_split->dirlen;
+ if (file_split->dir && file_split->file) {
+ len++; /* 1 for ending \ */
+ }
+ len += file_split->filelen;
+
+ if (!len) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_EMPTY_FILE_STRUCTURE);
+ return NULL;
+ }
+
+ result = OPENSSL_malloc(len + 1);
+ if (result == NULL) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (file_split->node) {
+ strcpy(&result[offset], "\\\\");
+ offset += 2;
+ strncpy(&result[offset], file_split->node, file_split->nodelen);
+ offset += file_split->nodelen;
+ if (file_split->predir || file_split->dir || file_split->file) {
+ result[offset] = '\\';
+ offset++;
+ }
+ } else if (file_split->device) {
+ strncpy(&result[offset], file_split->device, file_split->devicelen);
+ offset += file_split->devicelen;
+ result[offset] = ':';
+ offset++;
+ }
+ start = file_split->predir;
+ while (file_split->predirlen > (start - file_split->predir)) {
+ const char *end = openssl_strnchr(start, '/',
+ file_split->predirlen - (start -
+ file_split->predir));
+ if (!end)
+ end = start
+ + file_split->predirlen - (start - file_split->predir);
+ strncpy(&result[offset], start, end - start);
+ offset += (int)(end - start);
+ result[offset] = '\\';
+ offset++;
+ start = end + 1;
+ }
+ start = file_split->dir;
+ while (file_split->dirlen > (start - file_split->dir)) {
+ const char *end = openssl_strnchr(start, '/',
+ file_split->dirlen - (start -
+ file_split->dir));
+ if (!end)
+ end = start + file_split->dirlen - (start - file_split->dir);
+ strncpy(&result[offset], start, end - start);
+ offset += (int)(end - start);
+ result[offset] = '\\';
+ offset++;
+ start = end + 1;
+ }
+ strncpy(&result[offset], file_split->file, file_split->filelen);
+ offset += file_split->filelen;
+ result[offset] = '\0';
+ return result;
+}
+
+static char *win32_merger(DSO *dso, const char *filespec1,
+ const char *filespec2)
+{
+ char *merged = NULL;
+ struct file_st *filespec1_split = NULL;
+ struct file_st *filespec2_split = NULL;
+
+ if (!filespec1 && !filespec2) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ if (!filespec2) {
+ merged = OPENSSL_strdup(filespec1);
+ if (merged == NULL) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ } else if (!filespec1) {
+ merged = OPENSSL_strdup(filespec2);
+ if (merged == NULL) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ } else {
+ filespec1_split = win32_splitter(dso, filespec1, 0);
+ if (!filespec1_split) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ filespec2_split = win32_splitter(dso, filespec2, 1);
+ if (!filespec2_split) {
+ ERR_raise(ERR_LIB_DSO, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(filespec1_split);
+ return NULL;
+ }
+
+ /* Fill in into filespec1_split */
+ if (!filespec1_split->node && !filespec1_split->device) {
+ filespec1_split->node = filespec2_split->node;
+ filespec1_split->nodelen = filespec2_split->nodelen;
+ filespec1_split->device = filespec2_split->device;
+ filespec1_split->devicelen = filespec2_split->devicelen;
+ }
+ if (!filespec1_split->dir) {
+ filespec1_split->dir = filespec2_split->dir;
+ filespec1_split->dirlen = filespec2_split->dirlen;
+ } else if (filespec1_split->dir[0] != '\\'
+ && filespec1_split->dir[0] != '/') {
+ filespec1_split->predir = filespec2_split->dir;
+ filespec1_split->predirlen = filespec2_split->dirlen;
+ }
+ if (!filespec1_split->file) {
+ filespec1_split->file = filespec2_split->file;
+ filespec1_split->filelen = filespec2_split->filelen;
+ }
+
+ merged = win32_joiner(dso, filespec1_split);
+ }
+ OPENSSL_free(filespec1_split);
+ OPENSSL_free(filespec2_split);
+ return merged;
+}
+
+static char *win32_name_converter(DSO *dso, const char *filename)
+{
+ char *translated;
+ int len, transform;
+
+ len = strlen(filename);
+ transform = ((strstr(filename, "/") == NULL) &&
+ (strstr(filename, "\\") == NULL) &&
+ (strstr(filename, ":") == NULL));
+ if (transform)
+ /* We will convert this to "%s.dll" */
+ translated = OPENSSL_malloc(len + 5);
+ else
+ /* We will simply duplicate filename */
+ translated = OPENSSL_malloc(len + 1);
+ if (translated == NULL) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_NAME_TRANSLATION_FAILED);
+ return NULL;
+ }
+ if (transform)
+ sprintf(translated, "%s.dll", filename);
+ else
+ sprintf(translated, "%s", filename);
+ return translated;
+}
+
+static const char *openssl_strnchr(const char *string, int c, size_t len)
+{
+ size_t i;
+ const char *p;
+ for (i = 0, p = string; i < len && *p; i++, p++) {
+ if (*p == c)
+ return p;
+ }
+ return NULL;
+}
+
+# include <tlhelp32.h>
+# ifdef _WIN32_WCE
+# define DLLNAME "TOOLHELP.DLL"
+# else
+# ifdef MODULEENTRY32
+# undef MODULEENTRY32 /* unmask the ASCII version! */
+# endif
+# define DLLNAME "KERNEL32.DLL"
+# endif
+
+typedef HANDLE(WINAPI *CREATETOOLHELP32SNAPSHOT) (DWORD, DWORD);
+typedef BOOL(WINAPI *CLOSETOOLHELP32SNAPSHOT) (HANDLE);
+typedef BOOL(WINAPI *MODULE32) (HANDLE, MODULEENTRY32 *);
+
+static int win32_pathbyaddr(void *addr, char *path, int sz)
+{
+ HMODULE dll;
+ HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
+ MODULEENTRY32 me32;
+ CREATETOOLHELP32SNAPSHOT create_snap;
+ CLOSETOOLHELP32SNAPSHOT close_snap;
+ MODULE32 module_first, module_next;
+
+ if (addr == NULL) {
+ union {
+ int (*f) (void *, char *, int);
+ void *p;
+ } t = {
+ win32_pathbyaddr
+ };
+ addr = t.p;
+ }
+
+ dll = LoadLibrary(TEXT(DLLNAME));
+ if (dll == NULL) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
+ return -1;
+ }
+
+ create_snap = (CREATETOOLHELP32SNAPSHOT)
+ GetProcAddress(dll, "CreateToolhelp32Snapshot");
+ if (create_snap == NULL) {
+ FreeLibrary(dll);
+ ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
+ return -1;
+ }
+ /* We take the rest for granted... */
+# ifdef _WIN32_WCE
+ close_snap = (CLOSETOOLHELP32SNAPSHOT)
+ GetProcAddress(dll, "CloseToolhelp32Snapshot");
+# else
+ close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle;
+# endif
+ module_first = (MODULE32) GetProcAddress(dll, "Module32First");
+ module_next = (MODULE32) GetProcAddress(dll, "Module32Next");
+
+ /*
+ * Take a snapshot of current process which includes
+ * list of all involved modules.
+ */
+ hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0);
+ if (hModuleSnap == INVALID_HANDLE_VALUE) {
+ FreeLibrary(dll);
+ ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
+ return -1;
+ }
+
+ me32.dwSize = sizeof(me32);
+
+ if (!(*module_first) (hModuleSnap, &me32)) {
+ (*close_snap) (hModuleSnap);
+ FreeLibrary(dll);
+ ERR_raise(ERR_LIB_DSO, DSO_R_FAILURE);
+ return -1;
+ }
+
+ /* Enumerate the modules to find one which includes me. */
+ do {
+ if ((size_t) addr >= (size_t) me32.modBaseAddr &&
+ (size_t) addr < (size_t) (me32.modBaseAddr + me32.modBaseSize)) {
+ (*close_snap) (hModuleSnap);
+ FreeLibrary(dll);
+# ifdef _WIN32_WCE
+# if _WIN32_WCE >= 101
+ return WideCharToMultiByte(CP_ACP, 0, me32.szExePath, -1,
+ path, sz, NULL, NULL);
+# else
+ {
+ int i, len = (int)wcslen(me32.szExePath);
+ if (sz <= 0)
+ return len + 1;
+ if (len >= sz)
+ len = sz - 1;
+ for (i = 0; i < len; i++)
+ path[i] = (char)me32.szExePath[i];
+ path[len++] = '\0';
+ return len;
+ }
+# endif
+# else
+ {
+ int len = (int)strlen(me32.szExePath);
+ if (sz <= 0)
+ return len + 1;
+ if (len >= sz)
+ len = sz - 1;
+ memcpy(path, me32.szExePath, len);
+ path[len++] = '\0';
+ return len;
+ }
+# endif
+ }
+ } while ((*module_next) (hModuleSnap, &me32));
+
+ (*close_snap) (hModuleSnap);
+ FreeLibrary(dll);
+ return 0;
+}
+
+static void *win32_globallookup(const char *name)
+{
+ HMODULE dll;
+ HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
+ MODULEENTRY32 me32;
+ CREATETOOLHELP32SNAPSHOT create_snap;
+ CLOSETOOLHELP32SNAPSHOT close_snap;
+ MODULE32 module_first, module_next;
+ union {
+ void *p;
+ FARPROC f;
+ } ret = { NULL };
+
+ dll = LoadLibrary(TEXT(DLLNAME));
+ if (dll == NULL) {
+ ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
+ return NULL;
+ }
+
+ create_snap = (CREATETOOLHELP32SNAPSHOT)
+ GetProcAddress(dll, "CreateToolhelp32Snapshot");
+ if (create_snap == NULL) {
+ FreeLibrary(dll);
+ ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
+ return NULL;
+ }
+ /* We take the rest for granted... */
+# ifdef _WIN32_WCE
+ close_snap = (CLOSETOOLHELP32SNAPSHOT)
+ GetProcAddress(dll, "CloseToolhelp32Snapshot");
+# else
+ close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle;
+# endif
+ module_first = (MODULE32) GetProcAddress(dll, "Module32First");
+ module_next = (MODULE32) GetProcAddress(dll, "Module32Next");
+
+ hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0);
+ if (hModuleSnap == INVALID_HANDLE_VALUE) {
+ FreeLibrary(dll);
+ ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
+ return NULL;
+ }
+
+ me32.dwSize = sizeof(me32);
+
+ if (!(*module_first) (hModuleSnap, &me32)) {
+ (*close_snap) (hModuleSnap);
+ FreeLibrary(dll);
+ return NULL;
+ }
+
+ do {
+ if ((ret.f = GetProcAddress(me32.hModule, name))) {
+ (*close_snap) (hModuleSnap);
+ FreeLibrary(dll);
+ return ret.p;
+ }
+ } while ((*module_next) (hModuleSnap, &me32));
+
+ (*close_snap) (hModuleSnap);
+ FreeLibrary(dll);
+ return NULL;
+}
+#endif /* DSO_WIN32 */
diff --git a/crypto/ec/ecx_backend.c b/crypto/ec/ecx_backend.c
index 2ab7611be9af..e42767d6bf0f 100644
--- a/crypto/ec/ecx_backend.c
+++ b/crypto/ec/ecx_backend.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2024 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
@@ -122,7 +122,7 @@ ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key, int selection)
}
ret->libctx = key->libctx;
- ret->haspubkey = key->haspubkey;
+ ret->haspubkey = 0;
ret->keylen = key->keylen;
ret->type = key->type;
ret->references = 1;
@@ -133,8 +133,11 @@ ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key, int selection)
goto err;
}
- if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
+ if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0
+ && key->haspubkey == 1) {
memcpy(ret->pubkey, key->pubkey, sizeof(ret->pubkey));
+ ret->haspubkey = 1;
+ }
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
&& key->privkey != NULL) {
diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec
new file mode 100644
index 000000000000..3612c195f09f
--- /dev/null
+++ b/crypto/err/openssl.ec
@@ -0,0 +1,81 @@
+# configuration file for util/mkerr.pl
+
+# The INPUT HEADER is scanned for declarations
+# LIBNAME PUBLIC HEADER ERROR-TABLE FILE INTERNAL HEADER (if relevant)
+L ERR NONE NONE
+L FUNC NONE NONE
+L BN include/openssl/bnerr.h crypto/bn/bn_err.c include/crypto/bnerr.h
+L RSA include/openssl/rsaerr.h crypto/rsa/rsa_err.c include/crypto/rsaerr.h
+L DH include/openssl/dherr.h crypto/dh/dh_err.c include/crypto/dherr.h
+L EVP include/openssl/evperr.h crypto/evp/evp_err.c include/crypto/evperr.h
+L BUF include/openssl/buffererr.h crypto/buffer/buf_err.c include/crypto/buffererr.h
+L OBJ include/openssl/objectserr.h crypto/objects/obj_err.c include/crypto/objectserr.h
+L PEM include/openssl/pemerr.h crypto/pem/pem_err.c include/crypto/pemerr.h
+L DSA include/openssl/dsaerr.h crypto/dsa/dsa_err.c include/crypto/dsaerr.h
+L X509 include/openssl/x509err.h crypto/x509/x509_err.c include/crypto/x509err.h
+L ASN1 include/openssl/asn1err.h crypto/asn1/asn1_err.c include/crypto/asn1err.h
+L CONF include/openssl/conferr.h crypto/conf/conf_err.c include/crypto/conferr.h
+L CRYPTO include/openssl/cryptoerr.h crypto/cpt_err.c include/crypto/cryptoerr.h
+L EC include/openssl/ecerr.h crypto/ec/ec_err.c include/crypto/ecerr.h
+L SSL include/openssl/sslerr.h ssl/ssl_err.c ssl/sslerr.h
+L BIO include/openssl/bioerr.h crypto/bio/bio_err.c include/crypto/bioerr.h
+L PKCS7 include/openssl/pkcs7err.h crypto/pkcs7/pkcs7err.c include/crypto/pkcs7err.h
+L X509V3 include/openssl/x509v3err.h crypto/x509/v3err.c include/crypto/x509v3err.h
+L PKCS12 include/openssl/pkcs12err.h crypto/pkcs12/pk12err.c include/crypto/pkcs12err.h
+L RAND include/openssl/randerr.h crypto/rand/rand_err.c include/crypto/randerr.h
+L DSO NONE crypto/dso/dso_err.c include/internal/dsoerr.h
+L ENGINE include/openssl/engineerr.h crypto/engine/eng_err.c include/crypto/engineerr.h
+L OCSP include/openssl/ocsperr.h crypto/ocsp/ocsp_err.c include/crypto/ocsperr.h
+L UI include/openssl/uierr.h crypto/ui/ui_err.c include/crypto/uierr.h
+L COMP include/openssl/comperr.h crypto/comp/comp_err.c include/crypto/comperr.h
+L TS include/openssl/tserr.h crypto/ts/ts_err.c include/crypto/tserr.h
+L CMS include/openssl/cmserr.h crypto/cms/cms_err.c include/crypto/cmserr.h
+L CRMF include/openssl/crmferr.h crypto/crmf/crmf_err.c include/crypto/crmferr.h
+L CMP include/openssl/cmperr.h crypto/cmp/cmp_err.c include/crypto/cmperr.h
+L CT include/openssl/cterr.h crypto/ct/ct_err.c include/crypto/cterr.h
+L ASYNC include/openssl/asyncerr.h crypto/async/async_err.c include/crypto/asyncerr.h
+# KDF is only here for conservation purposes
+L KDF NONE NONE NONE
+L SM2 NONE crypto/sm2/sm2_err.c include/crypto/sm2err.h
+L OSSL_STORE include/openssl/storeerr.h crypto/store/store_err.c include/crypto/storeerr.h
+L ESS include/openssl/esserr.h crypto/ess/ess_err.c include/crypto/esserr.h
+L PROP NONE crypto/property/property_err.c include/internal/propertyerr.h
+L PROV include/openssl/proverr.h providers/common/provider_err.c providers/common/include/prov/proverr.h
+L OSSL_ENCODER include/openssl/encodererr.h crypto/encode_decode/encoder_err.c include/crypto/encodererr.h
+L OSSL_DECODER include/openssl/decodererr.h crypto/encode_decode/decoder_err.c include/crypto/decodererr.h
+L HTTP include/openssl/httperr.h crypto/http/http_err.c include/crypto/httperr.h
+
+# SSL/TLS alerts
+R SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
+R SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020
+R SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021
+R SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022
+R SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030
+R SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040
+R SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041
+R SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042
+R SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043
+R SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044
+R SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045
+R SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046
+R SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047
+R SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048
+R SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049
+R SSL_R_TLSV1_ALERT_DECODE_ERROR 1050
+R SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051
+R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060
+R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070
+R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071
+R SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080
+R SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086
+R SSL_R_TLSV1_ALERT_USER_CANCELLED 1090
+R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100
+R SSL_R_TLSV13_ALERT_MISSING_EXTENSION 1109
+R SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110
+R SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111
+R SSL_R_TLSV1_UNRECOGNIZED_NAME 1112
+R SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113
+R SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114
+R TLS1_AD_UNKNOWN_PSK_IDENTITY 1115
+R SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED 1116
+R TLS1_AD_NO_APPLICATION_PROTOCOL 1120
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index e51504b7abd5..36fe318baf7d 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -403,6 +403,7 @@ CONF_R_NUMBER_TOO_LARGE:121:number too large
CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION:124:\
openssl conf references missing section
CONF_R_RECURSIVE_DIRECTORY_INCLUDE:111:recursive directory include
+CONF_R_RECURSIVE_SECTION_REFERENCE:126:recursive section reference
CONF_R_RELATIVE_PATH:125:relative path
CONF_R_SSL_COMMAND_SECTION_EMPTY:117:ssl command section empty
CONF_R_SSL_COMMAND_SECTION_NOT_FOUND:118:ssl command section not found
@@ -500,6 +501,7 @@ DH_R_NO_PARAMETERS_SET:107:no parameters set
DH_R_NO_PRIVATE_VALUE:100:no private value
DH_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error
DH_R_PEER_KEY_ERROR:111:peer key error
+DH_R_Q_TOO_LARGE:130:q too large
DH_R_SHARED_INFO_ERROR:113:shared info error
DH_R_UNABLE_TO_CHECK_GENERATOR:121:unable to check generator
DSA_R_BAD_FFC_PARAMETERS:114:bad ffc parameters
diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c
index 52b9e87c1e2b..949de68077ec 100644
--- a/crypto/evp/e_aes.c
+++ b/crypto/evp/e_aes.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2024 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
@@ -831,8 +831,6 @@ typedef struct {
/* KMO-AES parameter block - end */
} kmo;
unsigned int fc;
-
- int res;
} S390X_AES_OFB_CTX;
typedef struct {
@@ -849,8 +847,6 @@ typedef struct {
/* KMF-AES parameter block - end */
} kmf;
unsigned int fc;
-
- int res;
} S390X_AES_CFB_CTX;
typedef struct {
@@ -1002,7 +998,6 @@ static int s390x_aes_ofb_init_key(EVP_CIPHER_CTX *ctx,
memcpy(cctx->kmo.param.cv, iv, ivlen);
memcpy(cctx->kmo.param.k, key, keylen);
cctx->fc = S390X_AES_FC(keylen);
- cctx->res = 0;
return 1;
}
@@ -1012,7 +1007,7 @@ static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
S390X_AES_OFB_CTX *cctx = EVP_C_DATA(S390X_AES_OFB_CTX, ctx);
const int ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);
unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
- int n = cctx->res;
+ int n = ctx->num;
int rem;
memcpy(cctx->kmo.param.cv, iv, ivlen);
@@ -1045,7 +1040,7 @@ static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
}
memcpy(iv, cctx->kmo.param.cv, ivlen);
- cctx->res = n;
+ ctx->num = n;
return 1;
}
@@ -1063,7 +1058,6 @@ static int s390x_aes_cfb_init_key(EVP_CIPHER_CTX *ctx,
if (!enc)
cctx->fc |= S390X_DECRYPT;
- cctx->res = 0;
memcpy(cctx->kmf.param.cv, iv, ivlen);
memcpy(cctx->kmf.param.k, key, keylen);
return 1;
@@ -1077,7 +1071,7 @@ static int s390x_aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const int enc = EVP_CIPHER_CTX_is_encrypting(ctx);
const int ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);
unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
- int n = cctx->res;
+ int n = ctx->num;
int rem;
unsigned char tmp;
@@ -1115,7 +1109,7 @@ static int s390x_aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
}
memcpy(iv, cctx->kmf.param.cv, ivlen);
- cctx->res = n;
+ ctx->num = n;
return 1;
}
diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c
index aafd927e63f9..6eeafd948ea1 100644
--- a/crypto/evp/evp_fetch.c
+++ b/crypto/evp/evp_fetch.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2024 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
@@ -349,13 +349,26 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata,
* there is a correct name_id and meth_id, since those have
* already been calculated in get_evp_method_from_store() and
* put_evp_method_in_store() above.
+ * Note that there is a corner case here, in which, if a user
+ * passes a name of the form name1:name2:..., then the construction
+ * will create a method against all names, but the lookup will fail
+ * as ossl_namemap_name2num treats the name string as a single name
+ * rather than introducing new features where in the EVP_<obj>_fetch
+ * parses the string and querys for each, return an error.
*/
if (name_id == 0)
name_id = ossl_namemap_name2num(namemap, name);
- meth_id = evp_method_id(name_id, operation_id);
- if (name_id != 0)
- ossl_method_store_cache_set(store, prov, meth_id, propq,
- method, up_ref_method, free_method);
+ if (name_id == 0) {
+ ERR_raise_data(ERR_LIB_EVP, ERR_R_FETCH_FAILED,
+ "Algorithm %s cannot be found", name);
+ free_method(method);
+ method = NULL;
+ } else {
+ meth_id = evp_method_id(name_id, operation_id);
+ if (meth_id != 0)
+ ossl_method_store_cache_set(store, prov, meth_id, propq,
+ method, up_ref_method, free_method);
+ }
}
/*
diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c
index e3ccc6c4cc2f..4b96a6b9e9e2 100644
--- a/crypto/http/http_client.c
+++ b/crypto/http/http_client.c
@@ -487,13 +487,17 @@ static int parse_http_line1(char *line, int *found_keep_alive)
static int check_set_resp_len(OSSL_HTTP_REQ_CTX *rctx, size_t len)
{
- if (rctx->max_resp_len != 0 && len > rctx->max_resp_len)
+ if (rctx->max_resp_len != 0 && len > rctx->max_resp_len) {
ERR_raise_data(ERR_LIB_HTTP, HTTP_R_MAX_RESP_LEN_EXCEEDED,
"length=%zu, max=%zu", len, rctx->max_resp_len);
- if (rctx->resp_len != 0 && rctx->resp_len != len)
+ return 0;
+ }
+ if (rctx->resp_len != 0 && rctx->resp_len != len) {
ERR_raise_data(ERR_LIB_HTTP, HTTP_R_INCONSISTENT_CONTENT_LENGTH,
"ASN.1 length=%zu, Content-Length=%zu",
len, rctx->resp_len);
+ return 0;
+ }
rctx->resp_len = len;
return 1;
}
diff --git a/crypto/http/http_lib.c b/crypto/http/http_lib.c
index e45f60b72287..30c1cd04fc00 100644
--- a/crypto/http/http_lib.c
+++ b/crypto/http/http_lib.c
@@ -118,7 +118,7 @@ int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost,
port = ++p;
/* remaining port spec handling is also done for the default values */
/* make sure a decimal port number is given */
- if (!sscanf(port, "%u", &portnum) || portnum > 65535) {
+ if (sscanf(port, "%u", &portnum) <= 0 || portnum > 65535) {
ERR_raise_data(ERR_LIB_HTTP, HTTP_R_INVALID_PORT_NUMBER, "%s", port);
goto err;
}
diff --git a/crypto/mem_sec.c b/crypto/mem_sec.c
index 6ba75486a897..5cdeedb8d127 100644
--- a/crypto/mem_sec.c
+++ b/crypto/mem_sec.c
@@ -238,11 +238,17 @@ int CRYPTO_secure_allocated(const void *ptr)
size_t CRYPTO_secure_used(void)
{
+ size_t ret = 0;
+
#ifndef OPENSSL_NO_SECURE_MEMORY
- return secure_mem_used;
-#else
- return 0;
+ if (!CRYPTO_THREAD_read_lock(sec_malloc_lock))
+ return 0;
+
+ ret = secure_mem_used;
+
+ CRYPTO_THREAD_unlock(sec_malloc_lock);
#endif /* OPENSSL_NO_SECURE_MEMORY */
+ return ret;
}
size_t CRYPTO_secure_actual_size(void *ptr)
diff --git a/crypto/modes/asm/ghash-alpha.pl b/crypto/modes/asm/ghash-alpha.pl
new file mode 100644
index 000000000000..c350e9015550
--- /dev/null
+++ b/crypto/modes/asm/ghash-alpha.pl
@@ -0,0 +1,467 @@
+#! /usr/bin/env perl
+# Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# March 2010
+#
+# The module implements "4-bit" GCM GHASH function and underlying
+# single multiplication operation in GF(2^128). "4-bit" means that it
+# uses 256 bytes per-key table [+128 bytes shared table]. Even though
+# loops are aggressively modulo-scheduled in respect to references to
+# Htbl and Z.hi updates for 8 cycles per byte, measured performance is
+# ~12 cycles per processed byte on 21264 CPU. It seems to be a dynamic
+# scheduling "glitch," because uprofile(1) indicates uniform sample
+# distribution, as if all instruction bundles execute in 1.5 cycles.
+# Meaning that it could have been even faster, yet 12 cycles is ~60%
+# better than gcc-generated code and ~80% than code generated by vendor
+# compiler.
+
+$cnt="v0"; # $0
+$t0="t0";
+$t1="t1";
+$t2="t2";
+$Thi0="t3"; # $4
+$Tlo0="t4";
+$Thi1="t5";
+$Tlo1="t6";
+$rem="t7"; # $8
+#################
+$Xi="a0"; # $16, input argument block
+$Htbl="a1";
+$inp="a2";
+$len="a3";
+$nlo="a4"; # $20
+$nhi="a5";
+$Zhi="t8";
+$Zlo="t9";
+$Xhi="t10"; # $24
+$Xlo="t11";
+$remp="t12";
+$rem_4bit="AT"; # $28
+
+{ my $N;
+ sub loop() {
+
+ $N++;
+$code.=<<___;
+.align 4
+ extbl $Xlo,7,$nlo
+ and $nlo,0xf0,$nhi
+ sll $nlo,4,$nlo
+ and $nlo,0xf0,$nlo
+
+ addq $nlo,$Htbl,$nlo
+ ldq $Zlo,8($nlo)
+ addq $nhi,$Htbl,$nhi
+ ldq $Zhi,0($nlo)
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ lda $cnt,6(zero)
+ extbl $Xlo,6,$nlo
+
+ ldq $Tlo1,8($nhi)
+ s8addq $remp,$rem_4bit,$remp
+ ldq $Thi1,0($nhi)
+ srl $Zlo,4,$Zlo
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ xor $t0,$Zlo,$Zlo
+ and $nlo,0xf0,$nhi
+
+ xor $Tlo1,$Zlo,$Zlo
+ sll $nlo,4,$nlo
+ xor $Thi1,$Zhi,$Zhi
+ and $nlo,0xf0,$nlo
+
+ addq $nlo,$Htbl,$nlo
+ ldq $Tlo0,8($nlo)
+ addq $nhi,$Htbl,$nhi
+ ldq $Thi0,0($nlo)
+
+.Looplo$N:
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ subq $cnt,1,$cnt
+ srl $Zlo,4,$Zlo
+
+ ldq $Tlo1,8($nhi)
+ xor $rem,$Zhi,$Zhi
+ ldq $Thi1,0($nhi)
+ s8addq $remp,$rem_4bit,$remp
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ xor $t0,$Zlo,$Zlo
+ extbl $Xlo,$cnt,$nlo
+
+ and $nlo,0xf0,$nhi
+ xor $Thi0,$Zhi,$Zhi
+ xor $Tlo0,$Zlo,$Zlo
+ sll $nlo,4,$nlo
+
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ and $nlo,0xf0,$nlo
+ srl $Zlo,4,$Zlo
+
+ s8addq $remp,$rem_4bit,$remp
+ xor $rem,$Zhi,$Zhi
+ addq $nlo,$Htbl,$nlo
+ addq $nhi,$Htbl,$nhi
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ ldq $Tlo0,8($nlo)
+ xor $t0,$Zlo,$Zlo
+
+ xor $Tlo1,$Zlo,$Zlo
+ xor $Thi1,$Zhi,$Zhi
+ ldq $Thi0,0($nlo)
+ bne $cnt,.Looplo$N
+
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ lda $cnt,7(zero)
+ srl $Zlo,4,$Zlo
+
+ ldq $Tlo1,8($nhi)
+ xor $rem,$Zhi,$Zhi
+ ldq $Thi1,0($nhi)
+ s8addq $remp,$rem_4bit,$remp
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ xor $t0,$Zlo,$Zlo
+ extbl $Xhi,$cnt,$nlo
+
+ and $nlo,0xf0,$nhi
+ xor $Thi0,$Zhi,$Zhi
+ xor $Tlo0,$Zlo,$Zlo
+ sll $nlo,4,$nlo
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ and $nlo,0xf0,$nlo
+ srl $Zlo,4,$Zlo
+
+ s8addq $remp,$rem_4bit,$remp
+ xor $rem,$Zhi,$Zhi
+ addq $nlo,$Htbl,$nlo
+ addq $nhi,$Htbl,$nhi
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ ldq $Tlo0,8($nlo)
+ xor $t0,$Zlo,$Zlo
+
+ xor $Tlo1,$Zlo,$Zlo
+ xor $Thi1,$Zhi,$Zhi
+ ldq $Thi0,0($nlo)
+ unop
+
+
+.Loophi$N:
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ subq $cnt,1,$cnt
+ srl $Zlo,4,$Zlo
+
+ ldq $Tlo1,8($nhi)
+ xor $rem,$Zhi,$Zhi
+ ldq $Thi1,0($nhi)
+ s8addq $remp,$rem_4bit,$remp
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ xor $t0,$Zlo,$Zlo
+ extbl $Xhi,$cnt,$nlo
+
+ and $nlo,0xf0,$nhi
+ xor $Thi0,$Zhi,$Zhi
+ xor $Tlo0,$Zlo,$Zlo
+ sll $nlo,4,$nlo
+
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ and $nlo,0xf0,$nlo
+ srl $Zlo,4,$Zlo
+
+ s8addq $remp,$rem_4bit,$remp
+ xor $rem,$Zhi,$Zhi
+ addq $nlo,$Htbl,$nlo
+ addq $nhi,$Htbl,$nhi
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ ldq $Tlo0,8($nlo)
+ xor $t0,$Zlo,$Zlo
+
+ xor $Tlo1,$Zlo,$Zlo
+ xor $Thi1,$Zhi,$Zhi
+ ldq $Thi0,0($nlo)
+ bne $cnt,.Loophi$N
+
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ srl $Zlo,4,$Zlo
+
+ ldq $Tlo1,8($nhi)
+ xor $rem,$Zhi,$Zhi
+ ldq $Thi1,0($nhi)
+ s8addq $remp,$rem_4bit,$remp
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ xor $t0,$Zlo,$Zlo
+
+ xor $Tlo0,$Zlo,$Zlo
+ xor $Thi0,$Zhi,$Zhi
+
+ and $Zlo,0x0f,$remp
+ sll $Zhi,60,$t0
+ srl $Zlo,4,$Zlo
+
+ s8addq $remp,$rem_4bit,$remp
+ xor $rem,$Zhi,$Zhi
+
+ ldq $rem,0($remp)
+ srl $Zhi,4,$Zhi
+ xor $Tlo1,$Zlo,$Zlo
+ xor $Thi1,$Zhi,$Zhi
+ xor $t0,$Zlo,$Zlo
+ xor $rem,$Zhi,$Zhi
+___
+}}
+
+$code=<<___;
+#ifdef __linux__
+#include <asm/regdef.h>
+#else
+#include <asm.h>
+#include <regdef.h>
+#endif
+
+.text
+
+.set noat
+.set noreorder
+.globl gcm_gmult_4bit
+.align 4
+.ent gcm_gmult_4bit
+gcm_gmult_4bit:
+ .frame sp,0,ra
+ .prologue 0
+
+ ldq $Xlo,8($Xi)
+ ldq $Xhi,0($Xi)
+
+ bsr $t0,picmeup
+ nop
+___
+
+ &loop();
+
+$code.=<<___;
+ srl $Zlo,24,$t0 # byte swap
+ srl $Zlo,8,$t1
+
+ sll $Zlo,8,$t2
+ sll $Zlo,24,$Zlo
+ zapnot $t0,0x11,$t0
+ zapnot $t1,0x22,$t1
+
+ zapnot $Zlo,0x88,$Zlo
+ or $t0,$t1,$t0
+ zapnot $t2,0x44,$t2
+
+ or $Zlo,$t0,$Zlo
+ srl $Zhi,24,$t0
+ srl $Zhi,8,$t1
+
+ or $Zlo,$t2,$Zlo
+ sll $Zhi,8,$t2
+ sll $Zhi,24,$Zhi
+
+ srl $Zlo,32,$Xlo
+ sll $Zlo,32,$Zlo
+
+ zapnot $t0,0x11,$t0
+ zapnot $t1,0x22,$t1
+ or $Zlo,$Xlo,$Xlo
+
+ zapnot $Zhi,0x88,$Zhi
+ or $t0,$t1,$t0
+ zapnot $t2,0x44,$t2
+
+ or $Zhi,$t0,$Zhi
+ or $Zhi,$t2,$Zhi
+
+ srl $Zhi,32,$Xhi
+ sll $Zhi,32,$Zhi
+
+ or $Zhi,$Xhi,$Xhi
+ stq $Xlo,8($Xi)
+ stq $Xhi,0($Xi)
+
+ ret (ra)
+.end gcm_gmult_4bit
+___
+
+$inhi="s0";
+$inlo="s1";
+
+$code.=<<___;
+.globl gcm_ghash_4bit
+.align 4
+.ent gcm_ghash_4bit
+gcm_ghash_4bit:
+ lda sp,-32(sp)
+ stq ra,0(sp)
+ stq s0,8(sp)
+ stq s1,16(sp)
+ .mask 0x04000600,-32
+ .frame sp,32,ra
+ .prologue 0
+
+ ldq_u $inhi,0($inp)
+ ldq_u $Thi0,7($inp)
+ ldq_u $inlo,8($inp)
+ ldq_u $Tlo0,15($inp)
+ ldq $Xhi,0($Xi)
+ ldq $Xlo,8($Xi)
+
+ bsr $t0,picmeup
+ nop
+
+.Louter:
+ extql $inhi,$inp,$inhi
+ extqh $Thi0,$inp,$Thi0
+ or $inhi,$Thi0,$inhi
+ lda $inp,16($inp)
+
+ extql $inlo,$inp,$inlo
+ extqh $Tlo0,$inp,$Tlo0
+ or $inlo,$Tlo0,$inlo
+ subq $len,16,$len
+
+ xor $Xlo,$inlo,$Xlo
+ xor $Xhi,$inhi,$Xhi
+___
+
+ &loop();
+
+$code.=<<___;
+ srl $Zlo,24,$t0 # byte swap
+ srl $Zlo,8,$t1
+
+ sll $Zlo,8,$t2
+ sll $Zlo,24,$Zlo
+ zapnot $t0,0x11,$t0
+ zapnot $t1,0x22,$t1
+
+ zapnot $Zlo,0x88,$Zlo
+ or $t0,$t1,$t0
+ zapnot $t2,0x44,$t2
+
+ or $Zlo,$t0,$Zlo
+ srl $Zhi,24,$t0
+ srl $Zhi,8,$t1
+
+ or $Zlo,$t2,$Zlo
+ sll $Zhi,8,$t2
+ sll $Zhi,24,$Zhi
+
+ srl $Zlo,32,$Xlo
+ sll $Zlo,32,$Zlo
+ beq $len,.Ldone
+
+ zapnot $t0,0x11,$t0
+ zapnot $t1,0x22,$t1
+ or $Zlo,$Xlo,$Xlo
+ ldq_u $inhi,0($inp)
+
+ zapnot $Zhi,0x88,$Zhi
+ or $t0,$t1,$t0
+ zapnot $t2,0x44,$t2
+ ldq_u $Thi0,7($inp)
+
+ or $Zhi,$t0,$Zhi
+ or $Zhi,$t2,$Zhi
+ ldq_u $inlo,8($inp)
+ ldq_u $Tlo0,15($inp)
+
+ srl $Zhi,32,$Xhi
+ sll $Zhi,32,$Zhi
+
+ or $Zhi,$Xhi,$Xhi
+ br zero,.Louter
+
+.Ldone:
+ zapnot $t0,0x11,$t0
+ zapnot $t1,0x22,$t1
+ or $Zlo,$Xlo,$Xlo
+
+ zapnot $Zhi,0x88,$Zhi
+ or $t0,$t1,$t0
+ zapnot $t2,0x44,$t2
+
+ or $Zhi,$t0,$Zhi
+ or $Zhi,$t2,$Zhi
+
+ srl $Zhi,32,$Xhi
+ sll $Zhi,32,$Zhi
+
+ or $Zhi,$Xhi,$Xhi
+
+ stq $Xlo,8($Xi)
+ stq $Xhi,0($Xi)
+
+ .set noreorder
+ /*ldq ra,0(sp)*/
+ ldq s0,8(sp)
+ ldq s1,16(sp)
+ lda sp,32(sp)
+ ret (ra)
+.end gcm_ghash_4bit
+
+.align 4
+.ent picmeup
+picmeup:
+ .frame sp,0,$t0
+ .prologue 0
+ br $rem_4bit,.Lpic
+.Lpic: lda $rem_4bit,12($rem_4bit)
+ ret ($t0)
+.end picmeup
+ nop
+rem_4bit:
+ .long 0,0x0000<<16, 0,0x1C20<<16, 0,0x3840<<16, 0,0x2460<<16
+ .long 0,0x7080<<16, 0,0x6CA0<<16, 0,0x48C0<<16, 0,0x54E0<<16
+ .long 0,0xE100<<16, 0,0xFD20<<16, 0,0xD940<<16, 0,0xC560<<16
+ .long 0,0x9180<<16, 0,0x8DA0<<16, 0,0xA9C0<<16, 0,0xB5E0<<16
+.ascii "GHASH for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
+.align 4
+
+___
+$output=pop and open STDOUT,">$output";
+print $code;
+close STDOUT or die "error closing STDOUT: $!";
+
diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c
index 85d30eb58ae0..dc501cbb8b22 100644
--- a/crypto/objects/obj_dat.c
+++ b/crypto/objects/obj_dat.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -62,7 +62,7 @@ static unsigned long added_obj_hash(const ADDED_OBJ *ca)
a = ca->obj;
switch (ca->type) {
case ADDED_DATA:
- ret = a->length << 20L;
+ ret = (unsigned long)a->length << 20UL;
p = (unsigned char *)a->data;
for (i = 0; i < a->length; i++)
ret ^= p[i] << ((i * 3) % 24);
diff --git a/crypto/param_build.c b/crypto/param_build.c
index 51c8681f3be5..56537e676b77 100644
--- a/crypto/param_build.c
+++ b/crypto/param_build.c
@@ -239,9 +239,9 @@ int OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key,
OSSL_PARAM_BLD_DEF *pd;
int secure;
- if (bsize == 0) {
+ if (bsize == 0)
bsize = strlen(buf);
- } else if (bsize > INT_MAX) {
+ if (bsize > INT_MAX) {
ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG);
return 0;
}
@@ -258,9 +258,9 @@ int OSSL_PARAM_BLD_push_utf8_ptr(OSSL_PARAM_BLD *bld, const char *key,
{
OSSL_PARAM_BLD_DEF *pd;
- if (bsize == 0) {
+ if (bsize == 0)
bsize = strlen(buf);
- } else if (bsize > INT_MAX) {
+ if (bsize > INT_MAX) {
ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG);
return 0;
}
diff --git a/crypto/params_from_text.c b/crypto/params_from_text.c
index 360f8933e135..a323bf2616ad 100644
--- a/crypto/params_from_text.c
+++ b/crypto/params_from_text.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -118,7 +118,13 @@ static int prepare_from_text(const OSSL_PARAM *paramdefs, const char *key,
break;
case OSSL_PARAM_OCTET_STRING:
if (*ishex) {
- *buf_n = strlen(value) >> 1;
+ size_t hexdigits = strlen(value);
+ if ((hexdigits % 2) != 0) {
+ /* We don't accept an odd number of hex digits */
+ ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_ODD_NUMBER_OF_DIGITS);
+ return 0;
+ }
+ *buf_n = hexdigits >> 1;
} else {
*buf_n = value_n;
}
diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl
index 1830b2556599..b2bf96cef01e 100755
--- a/crypto/perlasm/x86_64-xlate.pl
+++ b/crypto/perlasm/x86_64-xlate.pl
@@ -111,7 +111,12 @@ elsif (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
$gnuas=1;
}
elsif (`$ENV{CC} --version 2>/dev/null`
- =~ /clang .*/)
+ =~ /(clang .*|Intel.*oneAPI .*)/)
+{
+ $gnuas=1;
+}
+elsif (`$ENV{CC} -V 2>/dev/null`
+ =~ /nvc .*/)
{
$gnuas=1;
}
diff --git a/crypto/pkcs12/p12_add.c b/crypto/pkcs12/p12_add.c
index 6fd4184af5a5..66dcf92ca11e 100644
--- a/crypto/pkcs12/p12_add.c
+++ b/crypto/pkcs12/p12_add.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2024 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
@@ -78,6 +78,12 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7)
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA);
return NULL;
}
+
+ if (p7->d.data == NULL) {
+ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR);
+ return NULL;
+ }
+
return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
}
@@ -150,6 +156,12 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass,
{
if (!PKCS7_type_is_encrypted(p7))
return NULL;
+
+ if (p7->d.encrypted == NULL) {
+ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR);
+ return NULL;
+ }
+
return PKCS12_item_decrypt_d2i_ex(p7->d.encrypted->enc_data->algorithm,
ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
pass, passlen,
@@ -188,6 +200,12 @@ STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12)
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA);
return NULL;
}
+
+ if (p12->authsafes->d.data == NULL) {
+ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR);
+ return NULL;
+ }
+
p7s = ASN1_item_unpack(p12->authsafes->d.data,
ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
if (p7s != NULL) {
diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c
index 67a885a45f89..f8a6d33ddfae 100644
--- a/crypto/pkcs12/p12_mutl.c
+++ b/crypto/pkcs12/p12_mutl.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2024 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
@@ -98,6 +98,11 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
return 0;
}
+ if (p12->authsafes->d.data == NULL) {
+ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR);
+ return 0;
+ }
+
salt = p12->mac->salt->data;
saltlen = p12->mac->salt->length;
if (p12->mac->iter == NULL)
diff --git a/crypto/pkcs12/p12_npas.c b/crypto/pkcs12/p12_npas.c
index 62230bc6187f..dfcfcf6ae677 100644
--- a/crypto/pkcs12/p12_npas.c
+++ b/crypto/pkcs12/p12_npas.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2024 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
@@ -77,8 +77,9 @@ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass)
bags = PKCS12_unpack_p7data(p7);
} else if (bagnid == NID_pkcs7_encrypted) {
bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
- if (!alg_get(p7->d.encrypted->enc_data->algorithm,
- &pbe_nid, &pbe_iter, &pbe_saltlen))
+ if (p7->d.encrypted == NULL
+ || !alg_get(p7->d.encrypted->enc_data->algorithm,
+ &pbe_nid, &pbe_iter, &pbe_saltlen))
goto err;
} else {
continue;
diff --git a/crypto/pkcs7/pk7_attr.c b/crypto/pkcs7/pk7_attr.c
index e9904c5950c6..80b128c30455 100644
--- a/crypto/pkcs7/pk7_attr.c
+++ b/crypto/pkcs7/pk7_attr.c
@@ -28,8 +28,12 @@ int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
}
seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data,
ASN1_ITEM_rptr(X509_ALGORS));
- return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
- V_ASN1_SEQUENCE, seq);
+ if (!PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
+ V_ASN1_SEQUENCE, seq)) {
+ ASN1_STRING_free(seq);
+ return 0;
+ }
+ return 1;
}
STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
@@ -95,12 +99,18 @@ int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid)
int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t)
{
- if (t == NULL && (t = X509_gmtime_adj(NULL, 0)) == NULL) {
+ ASN1_TIME *tmp = NULL;
+
+ if (t == NULL && (tmp = t = X509_gmtime_adj(NULL, 0)) == NULL) {
ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
return 0;
}
- return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime,
- V_ASN1_UTCTIME, t);
+ if (!PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime,
+ V_ASN1_UTCTIME, t)) {
+ ASN1_TIME_free(tmp);
+ return 0;
+ }
+ return 1;
}
int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
diff --git a/crypto/pkcs7/pk7_mime.c b/crypto/pkcs7/pk7_mime.c
index 49a0da5f819c..d23f7a869f9f 100644
--- a/crypto/pkcs7/pk7_mime.c
+++ b/crypto/pkcs7/pk7_mime.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2024 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
@@ -33,10 +33,13 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
int ctype_nid = OBJ_obj2nid(p7->type);
const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7);
- if (ctype_nid == NID_pkcs7_signed)
+ if (ctype_nid == NID_pkcs7_signed) {
+ if (p7->d.sign == NULL)
+ return 0;
mdalgs = p7->d.sign->md_algs;
- else
+ } else {
mdalgs = NULL;
+ }
flags ^= SMIME_OLDMIME;
diff --git a/crypto/poly1305/asm/poly1305-ppc.pl b/crypto/poly1305/asm/poly1305-ppc.pl
index 9f86134d923f..9f9b27cac336 100755
--- a/crypto/poly1305/asm/poly1305-ppc.pl
+++ b/crypto/poly1305/asm/poly1305-ppc.pl
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
-# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2024 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
@@ -744,7 +744,7 @@ ___
my $LOCALS= 6*$SIZE_T;
my $VSXFRAME = $LOCALS + 6*$SIZE_T;
$VSXFRAME += 128; # local variables
- $VSXFRAME += 13*16; # v20-v31 offload
+ $VSXFRAME += 12*16; # v20-v31 offload
my $BIG_ENDIAN = ($flavour !~ /le/) ? 4 : 0;
@@ -919,12 +919,12 @@ __poly1305_blocks_vsx:
addi r11,r11,32
stvx v22,r10,$sp
addi r10,r10,32
- stvx v23,r10,$sp
- addi r10,r10,32
- stvx v24,r11,$sp
+ stvx v23,r11,$sp
addi r11,r11,32
- stvx v25,r10,$sp
+ stvx v24,r10,$sp
addi r10,r10,32
+ stvx v25,r11,$sp
+ addi r11,r11,32
stvx v26,r10,$sp
addi r10,r10,32
stvx v27,r11,$sp
@@ -1153,12 +1153,12 @@ __poly1305_blocks_vsx:
addi r11,r11,32
stvx v22,r10,$sp
addi r10,r10,32
- stvx v23,r10,$sp
- addi r10,r10,32
- stvx v24,r11,$sp
+ stvx v23,r11,$sp
addi r11,r11,32
- stvx v25,r10,$sp
+ stvx v24,r10,$sp
addi r10,r10,32
+ stvx v25,r11,$sp
+ addi r11,r11,32
stvx v26,r10,$sp
addi r10,r10,32
stvx v27,r11,$sp
@@ -1899,26 +1899,26 @@ Ldone_vsx:
mtspr 256,r12 # restore vrsave
lvx v20,r10,$sp
addi r10,r10,32
- lvx v21,r10,$sp
- addi r10,r10,32
- lvx v22,r11,$sp
+ lvx v21,r11,$sp
addi r11,r11,32
- lvx v23,r10,$sp
+ lvx v22,r10,$sp
addi r10,r10,32
- lvx v24,r11,$sp
+ lvx v23,r11,$sp
addi r11,r11,32
- lvx v25,r10,$sp
+ lvx v24,r10,$sp
addi r10,r10,32
- lvx v26,r11,$sp
+ lvx v25,r11,$sp
addi r11,r11,32
- lvx v27,r10,$sp
+ lvx v26,r10,$sp
addi r10,r10,32
- lvx v28,r11,$sp
+ lvx v27,r11,$sp
addi r11,r11,32
- lvx v29,r10,$sp
+ lvx v28,r10,$sp
addi r10,r10,32
- lvx v30,r11,$sp
- lvx v31,r10,$sp
+ lvx v29,r11,$sp
+ addi r11,r11,32
+ lvx v30,r10,$sp
+ lvx v31,r11,$sp
$POP r27,`$VSXFRAME-$SIZE_T*5`($sp)
$POP r28,`$VSXFRAME-$SIZE_T*4`($sp)
$POP r29,`$VSXFRAME-$SIZE_T*3`($sp)
diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c
index e3a4998df11f..19ea39a786eb 100644
--- a/crypto/property/property_parse.c
+++ b/crypto/property/property_parse.c
@@ -97,9 +97,18 @@ static int parse_number(const char *t[], OSSL_PROPERTY_DEFINITION *res)
const char *s = *t;
int64_t v = 0;
- if (!ossl_isdigit(*s))
- return 0;
do {
+ if (!ossl_isdigit(*s)) {
+ ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_A_DECIMAL_DIGIT,
+ "HERE-->%s", *t);
+ return 0;
+ }
+ /* overflow check */
+ if (v > ((INT64_MAX - (*s - '0')) / 10)) {
+ ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED,
+ "Property %s overflows", *t);
+ return 0;
+ }
v = v * 10 + (*s++ - '0');
} while (ossl_isdigit(*s));
if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
@@ -117,15 +126,27 @@ static int parse_hex(const char *t[], OSSL_PROPERTY_DEFINITION *res)
{
const char *s = *t;
int64_t v = 0;
+ int sval;
- if (!ossl_isxdigit(*s))
- return 0;
do {
+ if (ossl_isdigit(*s)) {
+ sval = *s - '0';
+ } else if (ossl_isxdigit(*s)) {
+ sval = ossl_tolower(*s) - 'a' + 10;
+ } else {
+ ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_HEXADECIMAL_DIGIT,
+ "%s", *t);
+ return 0;
+ }
+
+ if (v > ((INT64_MAX - sval) / 16)) {
+ ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED,
+ "Property %s overflows", *t);
+ return 0;
+ }
+
v <<= 4;
- if (ossl_isdigit(*s))
- v += *s - '0';
- else
- v += ossl_tolower(*s) - 'a';
+ v += sval;
} while (ossl_isxdigit(*++s));
if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_HEXADECIMAL_DIGIT,
@@ -143,9 +164,18 @@ static int parse_oct(const char *t[], OSSL_PROPERTY_DEFINITION *res)
const char *s = *t;
int64_t v = 0;
- if (*s == '9' || *s == '8' || !ossl_isdigit(*s))
- return 0;
do {
+ if (*s == '9' || *s == '8' || !ossl_isdigit(*s)) {
+ ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_OCTAL_DIGIT,
+ "HERE-->%s", *t);
+ return 0;
+ }
+ if (v > ((INT64_MAX - (*s - '0')) / 8)) {
+ ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED,
+ "Property %s overflows", *t);
+ return 0;
+ }
+
v = (v << 3) + (*s - '0');
} while (ossl_isdigit(*++s) && *s != '9' && *s != '8');
if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
diff --git a/crypto/provider_conf.c b/crypto/provider_conf.c
index c13c887c3d4a..9333b8777f2b 100644
--- a/crypto/provider_conf.c
+++ b/crypto/provider_conf.c
@@ -70,13 +70,22 @@ static const char *skip_dot(const char *name)
return name;
}
-static int provider_conf_params(OSSL_PROVIDER *prov,
- OSSL_PROVIDER_INFO *provinfo,
- const char *name, const char *value,
- const CONF *cnf)
+/*
+ * Parse the provider params section
+ * Returns:
+ * 1 for success
+ * 0 for non-fatal errors
+ * < 0 for fatal errors
+ */
+static int provider_conf_params_internal(OSSL_PROVIDER *prov,
+ OSSL_PROVIDER_INFO *provinfo,
+ const char *name, const char *value,
+ const CONF *cnf,
+ STACK_OF(OPENSSL_CSTRING) *visited)
{
STACK_OF(CONF_VALUE) *sect;
int ok = 1;
+ int rc = 0;
sect = NCONF_get_section(cnf, value);
if (sect != NULL) {
@@ -86,6 +95,25 @@ static int provider_conf_params(OSSL_PROVIDER *prov,
OSSL_TRACE1(CONF, "Provider params: start section %s\n", value);
+ /*
+ * Check to see if the provided section value has already
+ * been visited. If it has, then we have a recursive lookup
+ * in the configuration which isn't valid. As such we should error
+ * out
+ */
+ for (i = 0; i < sk_OPENSSL_CSTRING_num(visited); i++) {
+ if (sk_OPENSSL_CSTRING_value(visited, i) == value) {
+ ERR_raise(ERR_LIB_CONF, CONF_R_RECURSIVE_SECTION_REFERENCE);
+ return -1;
+ }
+ }
+
+ /*
+ * We've not visited this node yet, so record it on the stack
+ */
+ if (!sk_OPENSSL_CSTRING_push(visited, value))
+ return -1;
+
if (name != NULL) {
OPENSSL_strlcpy(buffer, name, sizeof(buffer));
OPENSSL_strlcat(buffer, ".", sizeof(buffer));
@@ -95,14 +123,20 @@ static int provider_conf_params(OSSL_PROVIDER *prov,
for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
CONF_VALUE *sectconf = sk_CONF_VALUE_value(sect, i);
- if (buffer_len + strlen(sectconf->name) >= sizeof(buffer))
- return 0;
+ if (buffer_len + strlen(sectconf->name) >= sizeof(buffer)) {
+ sk_OPENSSL_CSTRING_pop(visited);
+ return -1;
+ }
buffer[buffer_len] = '\0';
OPENSSL_strlcat(buffer, sectconf->name, sizeof(buffer));
- if (!provider_conf_params(prov, provinfo, buffer, sectconf->value,
- cnf))
- return 0;
+ rc = provider_conf_params_internal(prov, provinfo, buffer,
+ sectconf->value, cnf, visited);
+ if (rc < 0) {
+ sk_OPENSSL_CSTRING_pop(visited);
+ return rc;
+ }
}
+ sk_OPENSSL_CSTRING_pop(visited);
OSSL_TRACE1(CONF, "Provider params: finish section %s\n", value);
} else {
@@ -116,6 +150,33 @@ static int provider_conf_params(OSSL_PROVIDER *prov,
return ok;
}
+/*
+ * recursively parse the provider configuration section
+ * of the config file.
+ * Returns
+ * 1 on success
+ * 0 on non-fatal error
+ * < 0 on fatal errors
+ */
+static int provider_conf_params(OSSL_PROVIDER *prov,
+ OSSL_PROVIDER_INFO *provinfo,
+ const char *name, const char *value,
+ const CONF *cnf)
+{
+ int rc;
+ STACK_OF(OPENSSL_CSTRING) *visited = sk_OPENSSL_CSTRING_new_null();
+
+ if (visited == NULL)
+ return -1;
+
+ rc = provider_conf_params_internal(prov, provinfo, name,
+ value, cnf, visited);
+
+ sk_OPENSSL_CSTRING_free(visited);
+
+ return rc;
+}
+
static int prov_already_activated(const char *name,
STACK_OF(OSSL_PROVIDER) *activated)
{
@@ -146,6 +207,7 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name,
const char *path = NULL;
long activate = 0;
int ok = 0;
+ int added = 0;
name = skip_dot(name);
OSSL_TRACE1(CONF, "Configuring provider %s\n", name);
@@ -218,7 +280,7 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name,
ok = provider_conf_params(prov, NULL, NULL, value, cnf);
- if (ok) {
+ if (ok > 0) {
if (!ossl_provider_activate(prov, 1, 0)) {
ok = 0;
} else if (!ossl_provider_add_to_store(prov, &actual, 0)) {
@@ -242,7 +304,7 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name,
}
}
}
- if (!ok)
+ if (ok <= 0)
ossl_provider_free(prov);
}
CRYPTO_THREAD_unlock(pcgbl->lock);
@@ -267,19 +329,23 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name,
}
if (ok)
ok = provider_conf_params(NULL, &entry, NULL, value, cnf);
- if (ok && (entry.path != NULL || entry.parameters != NULL))
+ if (ok >= 1 && (entry.path != NULL || entry.parameters != NULL)) {
ok = ossl_provider_info_add_to_store(libctx, &entry);
- if (!ok || (entry.path == NULL && entry.parameters == NULL)) {
- ossl_provider_info_clear(&entry);
+ added = 1;
}
-
+ if (added == 0)
+ ossl_provider_info_clear(&entry);
}
/*
- * Even if ok is 0, we still return success. Failure to load a provider is
- * not fatal. We want to continue to load the rest of the config file.
+ * Provider activation returns a tristate:
+ * 1 for successful activation
+ * 0 for non-fatal activation failure
+ * < 0 for fatal activation failure
+ * We return success (1) for activation, (1) for non-fatal activation
+ * failure, and (0) for fatal activation failure
*/
- return 1;
+ return ok >= 0;
}
static int provider_conf_init(CONF_IMODULE *md, const CONF *cnf)
@@ -302,7 +368,7 @@ static int provider_conf_init(CONF_IMODULE *md, const CONF *cnf)
for (i = 0; i < sk_CONF_VALUE_num(elist); i++) {
cval = sk_CONF_VALUE_value(elist, i);
if (!provider_conf_load(NCONF_get0_libctx((CONF *)cnf),
- cval->name, cval->value, cnf))
+ cval->name, cval->value, cnf))
return 0;
}
diff --git a/crypto/provider_core.c b/crypto/provider_core.c
index 92cce32c5bbf..4cadb6a9f02e 100644
--- a/crypto/provider_core.c
+++ b/crypto/provider_core.c
@@ -936,44 +936,46 @@ static int provider_init(OSSL_PROVIDER *prov)
prov->provctx = tmp_provctx;
prov->dispatch = provider_dispatch;
- for (; provider_dispatch->function_id != 0; provider_dispatch++) {
- switch (provider_dispatch->function_id) {
- case OSSL_FUNC_PROVIDER_TEARDOWN:
- prov->teardown =
- OSSL_FUNC_provider_teardown(provider_dispatch);
- break;
- case OSSL_FUNC_PROVIDER_GETTABLE_PARAMS:
- prov->gettable_params =
- OSSL_FUNC_provider_gettable_params(provider_dispatch);
- break;
- case OSSL_FUNC_PROVIDER_GET_PARAMS:
- prov->get_params =
- OSSL_FUNC_provider_get_params(provider_dispatch);
- break;
- case OSSL_FUNC_PROVIDER_SELF_TEST:
- prov->self_test =
- OSSL_FUNC_provider_self_test(provider_dispatch);
- break;
- case OSSL_FUNC_PROVIDER_GET_CAPABILITIES:
- prov->get_capabilities =
- OSSL_FUNC_provider_get_capabilities(provider_dispatch);
- break;
- case OSSL_FUNC_PROVIDER_QUERY_OPERATION:
- prov->query_operation =
- OSSL_FUNC_provider_query_operation(provider_dispatch);
- break;
- case OSSL_FUNC_PROVIDER_UNQUERY_OPERATION:
- prov->unquery_operation =
- OSSL_FUNC_provider_unquery_operation(provider_dispatch);
- break;
+ if (provider_dispatch != NULL) {
+ for (; provider_dispatch->function_id != 0; provider_dispatch++) {
+ switch (provider_dispatch->function_id) {
+ case OSSL_FUNC_PROVIDER_TEARDOWN:
+ prov->teardown =
+ OSSL_FUNC_provider_teardown(provider_dispatch);
+ break;
+ case OSSL_FUNC_PROVIDER_GETTABLE_PARAMS:
+ prov->gettable_params =
+ OSSL_FUNC_provider_gettable_params(provider_dispatch);
+ break;
+ case OSSL_FUNC_PROVIDER_GET_PARAMS:
+ prov->get_params =
+ OSSL_FUNC_provider_get_params(provider_dispatch);
+ break;
+ case OSSL_FUNC_PROVIDER_SELF_TEST:
+ prov->self_test =
+ OSSL_FUNC_provider_self_test(provider_dispatch);
+ break;
+ case OSSL_FUNC_PROVIDER_GET_CAPABILITIES:
+ prov->get_capabilities =
+ OSSL_FUNC_provider_get_capabilities(provider_dispatch);
+ break;
+ case OSSL_FUNC_PROVIDER_QUERY_OPERATION:
+ prov->query_operation =
+ OSSL_FUNC_provider_query_operation(provider_dispatch);
+ break;
+ case OSSL_FUNC_PROVIDER_UNQUERY_OPERATION:
+ prov->unquery_operation =
+ OSSL_FUNC_provider_unquery_operation(provider_dispatch);
+ break;
#ifndef OPENSSL_NO_ERR
# ifndef FIPS_MODULE
- case OSSL_FUNC_PROVIDER_GET_REASON_STRINGS:
- p_get_reason_strings =
- OSSL_FUNC_provider_get_reason_strings(provider_dispatch);
- break;
+ case OSSL_FUNC_PROVIDER_GET_REASON_STRINGS:
+ p_get_reason_strings =
+ OSSL_FUNC_provider_get_reason_strings(provider_dispatch);
+ break;
# endif
#endif
+ }
}
}
diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c
index 71a17a92349d..c9c661b1ede9 100644
--- a/crypto/rsa/rsa_lib.c
+++ b/crypto/rsa/rsa_lib.c
@@ -999,6 +999,10 @@ int EVP_PKEY_CTX_set_rsa_pss_keygen_md_name(EVP_PKEY_CTX *ctx,
*/
int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
{
+ /* If key type not RSA return error */
+ if (!EVP_PKEY_CTX_is_a(ctx, "RSA"))
+ return -1;
+
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)(md));
}
@@ -1026,6 +1030,10 @@ int EVP_PKEY_CTX_get_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, char *name,
*/
int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
{
+ /* If key type not RSA return error */
+ if (!EVP_PKEY_CTX_is_a(ctx, "RSA"))
+ return -1;
+
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)md);
}
diff --git a/crypto/rsa/rsa_sp800_56b_check.c b/crypto/rsa/rsa_sp800_56b_check.c
index fc8f19b48770..df81397f5478 100644
--- a/crypto/rsa/rsa_sp800_56b_check.c
+++ b/crypto/rsa/rsa_sp800_56b_check.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2018-2024 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2018-2019, Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -289,6 +289,11 @@ int ossl_rsa_sp800_56b_check_public(const RSA *rsa)
return 0;
nbits = BN_num_bits(rsa->n);
+ if (nbits > OPENSSL_RSA_MAX_MODULUS_BITS) {
+ ERR_raise(ERR_LIB_RSA, RSA_R_MODULUS_TOO_LARGE);
+ return 0;
+ }
+
#ifdef FIPS_MODULE
/*
* (Step a): modulus must be 2048 or 3072 (caveat from SP800-56Br1)
@@ -324,7 +329,8 @@ int ossl_rsa_sp800_56b_check_public(const RSA *rsa)
goto err;
}
- ret = ossl_bn_miller_rabin_is_prime(rsa->n, 0, ctx, NULL, 1, &status);
+ /* Highest number of MR rounds from FIPS 186-5 Section B.3 Table B.1 */
+ ret = ossl_bn_miller_rabin_is_prime(rsa->n, 5, ctx, NULL, 1, &status);
#ifdef FIPS_MODULE
if (ret != 1 || status != BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME) {
#else
diff --git a/crypto/sha/asm/sha1-alpha.pl b/crypto/sha/asm/sha1-alpha.pl
new file mode 100644
index 000000000000..0ffc090602e1
--- /dev/null
+++ b/crypto/sha/asm/sha1-alpha.pl
@@ -0,0 +1,329 @@
+#! /usr/bin/env perl
+# Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# SHA1 block procedure for Alpha.
+
+# On 21264 performance is 33% better than code generated by vendor
+# compiler, and 75% better than GCC [3.4], and in absolute terms is
+# 8.7 cycles per processed byte. Implementation features vectorized
+# byte swap, but not Xupdate.
+
+@X=( "\$0", "\$1", "\$2", "\$3", "\$4", "\$5", "\$6", "\$7",
+ "\$8", "\$9", "\$10", "\$11", "\$12", "\$13", "\$14", "\$15");
+$ctx="a0"; # $16
+$inp="a1";
+$num="a2";
+$A="a3";
+$B="a4"; # 20
+$C="a5";
+$D="t8";
+$E="t9"; @V=($A,$B,$C,$D,$E);
+$t0="t10"; # 24
+$t1="t11";
+$t2="ra";
+$t3="t12";
+$K="AT"; # 28
+
+sub BODY_00_19 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+$code.=<<___ if ($i==0);
+ ldq_u @X[0],0+0($inp)
+ ldq_u @X[1],0+7($inp)
+___
+$code.=<<___ if (!($i&1) && $i<14);
+ ldq_u @X[$i+2],($i+2)*4+0($inp)
+ ldq_u @X[$i+3],($i+2)*4+7($inp)
+___
+$code.=<<___ if (!($i&1) && $i<15);
+ extql @X[$i],$inp,@X[$i]
+ extqh @X[$i+1],$inp,@X[$i+1]
+
+ or @X[$i+1],@X[$i],@X[$i] # pair of 32-bit values are fetched
+
+ srl @X[$i],24,$t0 # vectorized byte swap
+ srl @X[$i],8,$t2
+
+ sll @X[$i],8,$t3
+ sll @X[$i],24,@X[$i]
+ zapnot $t0,0x11,$t0
+ zapnot $t2,0x22,$t2
+
+ zapnot @X[$i],0x88,@X[$i]
+ or $t0,$t2,$t0
+ zapnot $t3,0x44,$t3
+ sll $a,5,$t1
+
+ or @X[$i],$t0,@X[$i]
+ addl $K,$e,$e
+ and $b,$c,$t2
+ zapnot $a,0xf,$a
+
+ or @X[$i],$t3,@X[$i]
+ srl $a,27,$t0
+ bic $d,$b,$t3
+ sll $b,30,$b
+
+ extll @X[$i],4,@X[$i+1] # extract upper half
+ or $t2,$t3,$t2
+ addl @X[$i],$e,$e
+
+ addl $t1,$e,$e
+ srl $b,32,$t3
+ zapnot @X[$i],0xf,@X[$i]
+
+ addl $t0,$e,$e
+ addl $t2,$e,$e
+ or $t3,$b,$b
+___
+$code.=<<___ if (($i&1) && $i<15);
+ sll $a,5,$t1
+ addl $K,$e,$e
+ and $b,$c,$t2
+ zapnot $a,0xf,$a
+
+ srl $a,27,$t0
+ addl @X[$i%16],$e,$e
+ bic $d,$b,$t3
+ sll $b,30,$b
+
+ or $t2,$t3,$t2
+ addl $t1,$e,$e
+ srl $b,32,$t3
+ zapnot @X[$i],0xf,@X[$i]
+
+ addl $t0,$e,$e
+ addl $t2,$e,$e
+ or $t3,$b,$b
+___
+$code.=<<___ if ($i>=15); # with forward Xupdate
+ sll $a,5,$t1
+ addl $K,$e,$e
+ and $b,$c,$t2
+ xor @X[($j+2)%16],@X[$j%16],@X[$j%16]
+
+ zapnot $a,0xf,$a
+ addl @X[$i%16],$e,$e
+ bic $d,$b,$t3
+ xor @X[($j+8)%16],@X[$j%16],@X[$j%16]
+
+ srl $a,27,$t0
+ addl $t1,$e,$e
+ or $t2,$t3,$t2
+ xor @X[($j+13)%16],@X[$j%16],@X[$j%16]
+
+ sll $b,30,$b
+ addl $t0,$e,$e
+ srl @X[$j%16],31,$t1
+
+ addl $t2,$e,$e
+ srl $b,32,$t3
+ addl @X[$j%16],@X[$j%16],@X[$j%16]
+
+ or $t3,$b,$b
+ zapnot @X[$i%16],0xf,@X[$i%16]
+ or $t1,@X[$j%16],@X[$j%16]
+___
+}
+
+sub BODY_20_39 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+$code.=<<___ if ($i<79); # with forward Xupdate
+ sll $a,5,$t1
+ addl $K,$e,$e
+ zapnot $a,0xf,$a
+ xor @X[($j+2)%16],@X[$j%16],@X[$j%16]
+
+ sll $b,30,$t3
+ addl $t1,$e,$e
+ xor $b,$c,$t2
+ xor @X[($j+8)%16],@X[$j%16],@X[$j%16]
+
+ srl $b,2,$b
+ addl @X[$i%16],$e,$e
+ xor $d,$t2,$t2
+ xor @X[($j+13)%16],@X[$j%16],@X[$j%16]
+
+ srl @X[$j%16],31,$t1
+ addl $t2,$e,$e
+ srl $a,27,$t0
+ addl @X[$j%16],@X[$j%16],@X[$j%16]
+
+ or $t3,$b,$b
+ addl $t0,$e,$e
+ or $t1,@X[$j%16],@X[$j%16]
+___
+$code.=<<___ if ($i<77);
+ zapnot @X[$i%16],0xf,@X[$i%16]
+___
+$code.=<<___ if ($i==79); # with context fetch
+ sll $a,5,$t1
+ addl $K,$e,$e
+ zapnot $a,0xf,$a
+ ldl @X[0],0($ctx)
+
+ sll $b,30,$t3
+ addl $t1,$e,$e
+ xor $b,$c,$t2
+ ldl @X[1],4($ctx)
+
+ srl $b,2,$b
+ addl @X[$i%16],$e,$e
+ xor $d,$t2,$t2
+ ldl @X[2],8($ctx)
+
+ srl $a,27,$t0
+ addl $t2,$e,$e
+ ldl @X[3],12($ctx)
+
+ or $t3,$b,$b
+ addl $t0,$e,$e
+ ldl @X[4],16($ctx)
+___
+}
+
+sub BODY_40_59 {
+my ($i,$a,$b,$c,$d,$e)=@_;
+my $j=$i+1;
+$code.=<<___; # with forward Xupdate
+ sll $a,5,$t1
+ addl $K,$e,$e
+ zapnot $a,0xf,$a
+ xor @X[($j+2)%16],@X[$j%16],@X[$j%16]
+
+ srl $a,27,$t0
+ and $b,$c,$t2
+ and $b,$d,$t3
+ xor @X[($j+8)%16],@X[$j%16],@X[$j%16]
+
+ sll $b,30,$b
+ addl $t1,$e,$e
+ xor @X[($j+13)%16],@X[$j%16],@X[$j%16]
+
+ srl @X[$j%16],31,$t1
+ addl $t0,$e,$e
+ or $t2,$t3,$t2
+ and $c,$d,$t3
+
+ or $t2,$t3,$t2
+ srl $b,32,$t3
+ addl @X[$i%16],$e,$e
+ addl @X[$j%16],@X[$j%16],@X[$j%16]
+
+ or $t3,$b,$b
+ addl $t2,$e,$e
+ or $t1,@X[$j%16],@X[$j%16]
+ zapnot @X[$i%16],0xf,@X[$i%16]
+___
+}
+
+$code=<<___;
+#ifdef __linux__
+#include <asm/regdef.h>
+#else
+#include <asm.h>
+#include <regdef.h>
+#endif
+
+.text
+
+.set noat
+.set noreorder
+.globl sha1_block_data_order
+.align 5
+.ent sha1_block_data_order
+sha1_block_data_order:
+ lda sp,-64(sp)
+ stq ra,0(sp)
+ stq s0,8(sp)
+ stq s1,16(sp)
+ stq s2,24(sp)
+ stq s3,32(sp)
+ stq s4,40(sp)
+ stq s5,48(sp)
+ stq fp,56(sp)
+ .mask 0x0400fe00,-64
+ .frame sp,64,ra
+ .prologue 0
+
+ ldl $A,0($ctx)
+ ldl $B,4($ctx)
+ sll $num,6,$num
+ ldl $C,8($ctx)
+ ldl $D,12($ctx)
+ ldl $E,16($ctx)
+ addq $inp,$num,$num
+
+.Lloop:
+ .set noreorder
+ ldah $K,23170(zero)
+ zapnot $B,0xf,$B
+ lda $K,31129($K) # K_00_19
+___
+for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
+
+$code.=<<___;
+ ldah $K,28378(zero)
+ lda $K,-5215($K) # K_20_39
+___
+for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+
+$code.=<<___;
+ ldah $K,-28900(zero)
+ lda $K,-17188($K) # K_40_59
+___
+for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
+
+$code.=<<___;
+ ldah $K,-13725(zero)
+ lda $K,-15914($K) # K_60_79
+___
+for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
+
+$code.=<<___;
+ addl @X[0],$A,$A
+ addl @X[1],$B,$B
+ addl @X[2],$C,$C
+ addl @X[3],$D,$D
+ addl @X[4],$E,$E
+ stl $A,0($ctx)
+ stl $B,4($ctx)
+ addq $inp,64,$inp
+ stl $C,8($ctx)
+ stl $D,12($ctx)
+ stl $E,16($ctx)
+ cmpult $inp,$num,$t1
+ bne $t1,.Lloop
+
+ .set noreorder
+ ldq ra,0(sp)
+ ldq s0,8(sp)
+ ldq s1,16(sp)
+ ldq s2,24(sp)
+ ldq s3,32(sp)
+ ldq s4,40(sp)
+ ldq s5,48(sp)
+ ldq fp,56(sp)
+ lda sp,64(sp)
+ ret (ra)
+.end sha1_block_data_order
+.ascii "SHA1 block transform for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
+.align 2
+___
+$output=pop and open STDOUT,">$output";
+print $code;
+close STDOUT or die "error closing STDOUT: $!";
diff --git a/crypto/threads_win.c b/crypto/threads_win.c
new file mode 100644
index 000000000000..dbeda74d73a7
--- /dev/null
+++ b/crypto/threads_win.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#if defined(_WIN32)
+# include <windows.h>
+# if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600
+# define USE_RWLOCK
+# endif
+#endif
+
+/*
+ * VC++ 2008 or earlier x86 compilers do not have an inline implementation
+ * of InterlockedOr64 for 32bit and will fail to run on Windows XP 32bit.
+ * https://docs.microsoft.com/en-us/cpp/intrinsics/interlockedor-intrinsic-functions#requirements
+ * To work around this problem, we implement a manual locking mechanism for
+ * only VC++ 2008 or earlier x86 compilers.
+ */
+
+#if (defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER <= 1600)
+# define NO_INTERLOCKEDOR64
+#endif
+
+#include <openssl/crypto.h>
+
+#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && defined(OPENSSL_SYS_WINDOWS)
+
+# ifdef USE_RWLOCK
+typedef struct {
+ SRWLOCK lock;
+ int exclusive;
+} CRYPTO_win_rwlock;
+# endif
+
+CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
+{
+ CRYPTO_RWLOCK *lock;
+# ifdef USE_RWLOCK
+ CRYPTO_win_rwlock *rwlock;
+
+ if ((lock = OPENSSL_zalloc(sizeof(CRYPTO_win_rwlock))) == NULL)
+ return NULL;
+ rwlock = lock;
+ InitializeSRWLock(&rwlock->lock);
+# else
+
+ if ((lock = OPENSSL_zalloc(sizeof(CRITICAL_SECTION))) == NULL) {
+ /* Don't set error, to avoid recursion blowup. */
+ return NULL;
+ }
+
+# if !defined(_WIN32_WCE)
+ /* 0x400 is the spin count value suggested in the documentation */
+ if (!InitializeCriticalSectionAndSpinCount(lock, 0x400)) {
+ OPENSSL_free(lock);
+ return NULL;
+ }
+# else
+ InitializeCriticalSection(lock);
+# endif
+# endif
+
+ return lock;
+}
+
+__owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
+{
+# ifdef USE_RWLOCK
+ CRYPTO_win_rwlock *rwlock = lock;
+
+ AcquireSRWLockShared(&rwlock->lock);
+# else
+ EnterCriticalSection(lock);
+# endif
+ return 1;
+}
+
+__owur int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
+{
+# ifdef USE_RWLOCK
+ CRYPTO_win_rwlock *rwlock = lock;
+
+ AcquireSRWLockExclusive(&rwlock->lock);
+ rwlock->exclusive = 1;
+# else
+ EnterCriticalSection(lock);
+# endif
+ return 1;
+}
+
+int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
+{
+# ifdef USE_RWLOCK
+ CRYPTO_win_rwlock *rwlock = lock;
+
+ if (rwlock->exclusive) {
+ rwlock->exclusive = 0;
+ ReleaseSRWLockExclusive(&rwlock->lock);
+ } else {
+ ReleaseSRWLockShared(&rwlock->lock);
+ }
+# else
+ LeaveCriticalSection(lock);
+# endif
+ return 1;
+}
+
+void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)
+{
+ if (lock == NULL)
+ return;
+
+# ifndef USE_RWLOCK
+ DeleteCriticalSection(lock);
+# endif
+ OPENSSL_free(lock);
+
+ return;
+}
+
+# define ONCE_UNINITED 0
+# define ONCE_ININIT 1
+# define ONCE_DONE 2
+
+/*
+ * We don't use InitOnceExecuteOnce because that isn't available in WinXP which
+ * we still have to support.
+ */
+int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
+{
+ LONG volatile *lock = (LONG *)once;
+ LONG result;
+
+ if (*lock == ONCE_DONE)
+ return 1;
+
+ do {
+ result = InterlockedCompareExchange(lock, ONCE_ININIT, ONCE_UNINITED);
+ if (result == ONCE_UNINITED) {
+ init();
+ *lock = ONCE_DONE;
+ return 1;
+ }
+ } while (result == ONCE_ININIT);
+
+ return (*lock == ONCE_DONE);
+}
+
+int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
+{
+ *key = TlsAlloc();
+ if (*key == TLS_OUT_OF_INDEXES)
+ return 0;
+
+ return 1;
+}
+
+void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
+{
+ DWORD last_error;
+ void *ret;
+
+ /*
+ * TlsGetValue clears the last error even on success, so that callers may
+ * distinguish it successfully returning NULL or failing. It is documented
+ * to never fail if the argument is a valid index from TlsAlloc, so we do
+ * not need to handle this.
+ *
+ * However, this error-mangling behavior interferes with the caller's use of
+ * GetLastError. In particular SSL_get_error queries the error queue to
+ * determine whether the caller should look at the OS's errors. To avoid
+ * destroying state, save and restore the Windows error.
+ *
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/ms686812(v=vs.85).aspx
+ */
+ last_error = GetLastError();
+ ret = TlsGetValue(*key);
+ SetLastError(last_error);
+ return ret;
+}
+
+int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
+{
+ if (TlsSetValue(*key, val) == 0)
+ return 0;
+
+ return 1;
+}
+
+int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key)
+{
+ if (TlsFree(*key) == 0)
+ return 0;
+
+ return 1;
+}
+
+CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void)
+{
+ return GetCurrentThreadId();
+}
+
+int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b)
+{
+ return (a == b);
+}
+
+int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
+{
+ *ret = (int)InterlockedExchangeAdd((long volatile *)val, (long)amount) + amount;
+ return 1;
+}
+
+int CRYPTO_atomic_or(uint64_t *val, uint64_t op, uint64_t *ret,
+ CRYPTO_RWLOCK *lock)
+{
+#if (defined(NO_INTERLOCKEDOR64))
+ if (lock == NULL || !CRYPTO_THREAD_write_lock(lock))
+ return 0;
+ *val |= op;
+ *ret = *val;
+
+ if (!CRYPTO_THREAD_unlock(lock))
+ return 0;
+
+ return 1;
+#else
+ *ret = (uint64_t)InterlockedOr64((LONG64 volatile *)val, (LONG64)op) | op;
+ return 1;
+#endif
+}
+
+int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock)
+{
+#if (defined(NO_INTERLOCKEDOR64))
+ if (lock == NULL || !CRYPTO_THREAD_read_lock(lock))
+ return 0;
+ *ret = *val;
+ if (!CRYPTO_THREAD_unlock(lock))
+ return 0;
+
+ return 1;
+#else
+ *ret = (uint64_t)InterlockedOr64((LONG64 volatile *)val, 0);
+ return 1;
+#endif
+}
+
+int openssl_init_fork_handlers(void)
+{
+ return 0;
+}
+
+int openssl_get_fork_id(void)
+{
+ return 0;
+}
+#endif
diff --git a/crypto/x509/t_req.c b/crypto/x509/t_req.c
index 095c16510099..63626c0d9810 100644
--- a/crypto/x509/t_req.c
+++ b/crypto/x509/t_req.c
@@ -42,15 +42,15 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
EVP_PKEY *pkey;
STACK_OF(X509_EXTENSION) *exts;
char mlch = ' ';
- int nmindent = 0;
+ int nmindent = 0, printok = 0;
if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
mlch = '\n';
nmindent = 12;
}
- if (nmflags == X509_FLAG_COMPAT)
- nmindent = 16;
+ if (nmflags == XN_FLAG_COMPAT)
+ printok = 1;
if (!(cflag & X509_FLAG_NO_HEADER)) {
if (BIO_write(bp, "Certificate Request:\n", 21) <= 0)
@@ -72,7 +72,7 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
goto err;
if (X509_NAME_print_ex(bp, X509_REQ_get_subject_name(x),
- nmindent, nmflags) < 0)
+ nmindent, nmflags) < printok)
goto err;
if (BIO_write(bp, "\n", 1) <= 0)
goto err;
diff --git a/crypto/x509/t_x509.c b/crypto/x509/t_x509.c
index 95ee5f519fdd..5b0282bc132f 100644
--- a/crypto/x509/t_x509.c
+++ b/crypto/x509/t_x509.c
@@ -60,10 +60,8 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
nmindent = 12;
}
- if (nmflags == X509_FLAG_COMPAT) {
- nmindent = 16;
+ if (nmflags == XN_FLAG_COMPAT)
printok = 1;
- }
if (!(cflag & X509_FLAG_NO_HEADER)) {
if (BIO_write(bp, "Certificate:\n", 13) <= 0)
diff --git a/crypto/x509/v3_addr.c b/crypto/x509/v3_addr.c
index db010720741c..4930f3312422 100644
--- a/crypto/x509/v3_addr.c
+++ b/crypto/x509/v3_addr.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2024 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
@@ -972,6 +972,10 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
* the other input values.
*/
if (safi != NULL) {
+ if (val->value == NULL) {
+ ERR_raise(ERR_LIB_X509V3, X509V3_R_MISSING_VALUE);
+ goto err;
+ }
*safi = strtoul(val->value, &t, 0);
t += strspn(t, " \t");
if (*safi > 0xFF || *t++ != ':') {
diff --git a/crypto/x509/v3_asid.c b/crypto/x509/v3_asid.c
index 86577d6ca48c..c2b6f8a660df 100644
--- a/crypto/x509/v3_asid.c
+++ b/crypto/x509/v3_asid.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2024 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
@@ -169,8 +169,11 @@ int X509v3_asid_add_inherit(ASIdentifiers *asid, int which)
if (*choice == NULL) {
if ((*choice = ASIdentifierChoice_new()) == NULL)
return 0;
- if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL)
+ if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) {
+ ASIdentifierChoice_free(*choice);
+ *choice = NULL;
return 0;
+ }
(*choice)->type = ASIdentifierChoice_inherit;
}
return (*choice)->type == ASIdentifierChoice_inherit;
@@ -196,18 +199,23 @@ int X509v3_asid_add_id_or_range(ASIdentifiers *asid,
default:
return 0;
}
- if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit)
+ if (*choice != NULL && (*choice)->type != ASIdentifierChoice_asIdsOrRanges)
return 0;
if (*choice == NULL) {
if ((*choice = ASIdentifierChoice_new()) == NULL)
return 0;
(*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp);
- if ((*choice)->u.asIdsOrRanges == NULL)
+ if ((*choice)->u.asIdsOrRanges == NULL) {
+ ASIdentifierChoice_free(*choice);
+ *choice = NULL;
return 0;
+ }
(*choice)->type = ASIdentifierChoice_asIdsOrRanges;
}
if ((aor = ASIdOrRange_new()) == NULL)
return 0;
+ if (!sk_ASIdOrRange_reserve((*choice)->u.asIdsOrRanges, 1))
+ goto err;
if (max == NULL) {
aor->type = ASIdOrRange_id;
aor->u.id = min;
@@ -220,7 +228,8 @@ int X509v3_asid_add_id_or_range(ASIdentifiers *asid,
ASN1_INTEGER_free(aor->u.range->max);
aor->u.range->max = max;
}
- if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor)))
+ /* Cannot fail due to the reservation above */
+ if (!ossl_assert(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor)))
goto err;
return 1;
@@ -538,6 +547,11 @@ static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
goto err;
}
+ if (val->value == NULL) {
+ ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR);
+ goto err;
+ }
+
/*
* Handle inheritance.
*/
diff --git a/crypto/x509/v3_crld.c b/crypto/x509/v3_crld.c
index 0289df4de789..07c8379d3521 100644
--- a/crypto/x509/v3_crld.c
+++ b/crypto/x509/v3_crld.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2024 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
@@ -70,6 +70,11 @@ static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
STACK_OF(GENERAL_NAME) *fnm = NULL;
STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
+ if (cnf->value == NULL) {
+ ERR_raise(ERR_LIB_X509V3, X509V3_R_MISSING_VALUE);
+ goto err;
+ }
+
if (strncmp(cnf->name, "fullname", 9) == 0) {
fnm = gnames_from_sectname(ctx, cnf->value);
if (!fnm)
diff --git a/crypto/x509/v3_ist.c b/crypto/x509/v3_ist.c
index 4a3cfa12a471..96c40a3961a2 100644
--- a/crypto/x509/v3_ist.c
+++ b/crypto/x509/v3_ist.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2024 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
@@ -50,25 +50,33 @@ static ISSUER_SIGN_TOOL *v2i_issuer_sign_tool(X509V3_EXT_METHOD *method, X509V3_
}
if (strcmp(cnf->name, "signTool") == 0) {
ist->signTool = ASN1_UTF8STRING_new();
- if (ist->signTool == NULL || !ASN1_STRING_set(ist->signTool, cnf->value, strlen(cnf->value))) {
+ if (ist->signTool == NULL
+ || cnf->value == NULL
+ || !ASN1_STRING_set(ist->signTool, cnf->value, strlen(cnf->value))) {
ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
} else if (strcmp(cnf->name, "cATool") == 0) {
ist->cATool = ASN1_UTF8STRING_new();
- if (ist->cATool == NULL || !ASN1_STRING_set(ist->cATool, cnf->value, strlen(cnf->value))) {
+ if (ist->cATool == NULL
+ || cnf->value == NULL
+ || !ASN1_STRING_set(ist->cATool, cnf->value, strlen(cnf->value))) {
ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
} else if (strcmp(cnf->name, "signToolCert") == 0) {
ist->signToolCert = ASN1_UTF8STRING_new();
- if (ist->signToolCert == NULL || !ASN1_STRING_set(ist->signToolCert, cnf->value, strlen(cnf->value))) {
+ if (ist->signToolCert == NULL
+ || cnf->value == NULL
+ || !ASN1_STRING_set(ist->signToolCert, cnf->value, strlen(cnf->value))) {
ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
} else if (strcmp(cnf->name, "cAToolCert") == 0) {
ist->cAToolCert = ASN1_UTF8STRING_new();
- if (ist->cAToolCert == NULL || !ASN1_STRING_set(ist->cAToolCert, cnf->value, strlen(cnf->value))) {
+ if (ist->cAToolCert == NULL
+ || cnf->value == NULL
+ || !ASN1_STRING_set(ist->cAToolCert, cnf->value, strlen(cnf->value))) {
ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
diff --git a/crypto/x509/v3_san.c b/crypto/x509/v3_san.c
index c081f02e19e4..34ca16a6d72d 100644
--- a/crypto/x509/v3_san.c
+++ b/crypto/x509/v3_san.c
@@ -581,6 +581,8 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL ||
!ASN1_STRING_set(gen->d.ia5, (unsigned char *)value,
strlen(value))) {
+ ASN1_IA5STRING_free(gen->d.ia5);
+ gen->d.ia5 = NULL;
ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -651,16 +653,21 @@ static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
*/
ASN1_TYPE_free(gen->d.otherName->value);
if ((gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)) == NULL)
- return 0;
+ goto err;
objlen = p - value;
objtmp = OPENSSL_strndup(value, objlen);
if (objtmp == NULL)
- return 0;
+ goto err;
gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
OPENSSL_free(objtmp);
if (!gen->d.otherName->type_id)
- return 0;
+ goto err;
return 1;
+
+ err:
+ OTHERNAME_free(gen->d.otherName);
+ gen->d.otherName = NULL;
+ return 0;
}
static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
diff --git a/crypto/x509/v3_sxnet.c b/crypto/x509/v3_sxnet.c
index ca46dc1a5c32..70f5db636c4b 100644
--- a/crypto/x509/v3_sxnet.c
+++ b/crypto/x509/v3_sxnet.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2024 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
@@ -103,8 +103,10 @@ static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
int i;
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
cnf = sk_CONF_VALUE_value(nval, i);
- if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
+ if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1)) {
+ SXNET_free(sx);
return NULL;
+ }
}
return sx;
}
@@ -123,7 +125,11 @@ int SXNET_add_id_asc(SXNET **psx, const char *zone, const char *user, int userle
ERR_raise(ERR_LIB_X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
return 0;
}
- return SXNET_add_id_INTEGER(psx, izone, user, userlen);
+ if (!SXNET_add_id_INTEGER(psx, izone, user, userlen)) {
+ ASN1_INTEGER_free(izone);
+ return 0;
+ }
+ return 1;
}
/* Add an id given the zone as an unsigned long */
@@ -139,8 +145,11 @@ int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, const char *user,
ASN1_INTEGER_free(izone);
return 0;
}
- return SXNET_add_id_INTEGER(psx, izone, user, userlen);
-
+ if (!SXNET_add_id_INTEGER(psx, izone, user, userlen)) {
+ ASN1_INTEGER_free(izone);
+ return 0;
+ }
+ return 1;
}
/*
@@ -187,6 +196,7 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, const char *user,
goto err;
if (!sk_SXNETID_push(sx->ids, id))
goto err;
+ ASN1_INTEGER_free(id->zone);
id->zone = zone;
*psx = sx;
return 1;
diff --git a/crypto/x509/x509_att.c b/crypto/x509/x509_att.c
index d9fe7a3791d1..6a541d7980a3 100644
--- a/crypto/x509/x509_att.c
+++ b/crypto/x509/x509_att.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -71,8 +71,8 @@ X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc)
return ret;
}
-STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
- X509_ATTRIBUTE *attr)
+STACK_OF(X509_ATTRIBUTE) *ossl_x509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+ X509_ATTRIBUTE *attr)
{
X509_ATTRIBUTE *new_attr = NULL;
STACK_OF(X509_ATTRIBUTE) *sk = NULL;
@@ -82,11 +82,6 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
return NULL;
}
- if (*x != NULL && X509at_get_attr_by_OBJ(*x, attr->object, -1) != -1) {
- ERR_raise(ERR_LIB_X509, X509_R_DUPLICATE_ATTRIBUTE);
- return NULL;
- }
-
if (*x == NULL) {
if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
goto err;
@@ -110,18 +105,68 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
return NULL;
}
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+ X509_ATTRIBUTE *attr)
+{
+ if (x == NULL || attr == NULL) {
+ ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ if (*x != NULL && X509at_get_attr_by_OBJ(*x, attr->object, -1) != -1) {
+ ERR_raise(ERR_LIB_X509, X509_R_DUPLICATE_ATTRIBUTE);
+ return NULL;
+ }
+
+ return ossl_x509at_add1_attr(x, attr);
+}
+
+STACK_OF(X509_ATTRIBUTE) *ossl_x509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
+ const ASN1_OBJECT *obj,
+ int type,
+ const unsigned char *bytes,
+ int len)
+{
+ X509_ATTRIBUTE *attr;
+ STACK_OF(X509_ATTRIBUTE) *ret;
+
+ attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
+ if (attr == NULL)
+ return 0;
+ ret = ossl_x509at_add1_attr(x, attr);
+ X509_ATTRIBUTE_free(attr);
+ return ret;
+}
+
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
**x, const ASN1_OBJECT *obj,
int type,
const unsigned char *bytes,
int len)
{
+ if (x == NULL || obj == NULL) {
+ ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ if (*x != NULL && X509at_get_attr_by_OBJ(*x, obj, -1) != -1) {
+ ERR_raise(ERR_LIB_X509, X509_R_DUPLICATE_ATTRIBUTE);
+ return NULL;
+ }
+
+ return ossl_x509at_add1_attr_by_OBJ(x, obj, type, bytes, len);
+}
+
+STACK_OF(X509_ATTRIBUTE) *ossl_x509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
+ int nid, int type,
+ const unsigned char *bytes,
+ int len)
+{
X509_ATTRIBUTE *attr;
STACK_OF(X509_ATTRIBUTE) *ret;
- attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
- if (!attr)
+
+ attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
+ if (attr == NULL)
return 0;
- ret = X509at_add1_attr(x, attr);
+ ret = ossl_x509at_add1_attr(x, attr);
X509_ATTRIBUTE_free(attr);
return ret;
}
@@ -131,12 +176,31 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
const unsigned char *bytes,
int len)
{
+ if (x == NULL) {
+ ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ if (*x != NULL && X509at_get_attr_by_NID(*x, nid, -1) != -1) {
+ ERR_raise(ERR_LIB_X509, X509_R_DUPLICATE_ATTRIBUTE);
+ return NULL;
+ }
+
+ return ossl_x509at_add1_attr_by_NID(x, nid, type, bytes, len);
+}
+
+STACK_OF(X509_ATTRIBUTE) *ossl_x509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
+ const char *attrname,
+ int type,
+ const unsigned char *bytes,
+ int len)
+{
X509_ATTRIBUTE *attr;
STACK_OF(X509_ATTRIBUTE) *ret;
- attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
- if (!attr)
+
+ attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
+ if (attr == NULL)
return 0;
- ret = X509at_add1_attr(x, attr);
+ ret = ossl_x509at_add1_attr(x, attr);
X509_ATTRIBUTE_free(attr);
return ret;
}
diff --git a/crypto/x509/x509_req.c b/crypto/x509/x509_req.c
index 5428bdaf4ca6..0434fbbc6b70 100644
--- a/crypto/x509/x509_req.c
+++ b/crypto/x509/x509_req.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 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
@@ -219,7 +219,7 @@ X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc)
if (req == NULL) {
ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
+ return NULL;
}
attr = X509at_delete_attr(req->req_info.attributes, loc);
if (attr != NULL)