diff options
author | Cy Schubert <cy@FreeBSD.org> | 2024-02-02 04:39:16 +0000 |
---|---|---|
committer | Cy Schubert <cy@FreeBSD.org> | 2024-02-02 09:48:38 +0000 |
commit | 9dd13e84fa8eca8f3462bd55485aa3da8c37f54a (patch) | |
tree | 588240aeb9a7363618b8a687c72588bd74948634 /crypto | |
parent | 825caf7e12445fa4818413cc37c8b45bebb6c3a9 (diff) | |
download | src-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')
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) |