diff --git a/.github/workflows/run-checker-merge.yml b/.github/workflows/run-checker-merge.yml index e5746d75bdf8c..8a1da0c2f2a5b 100644 --- a/.github/workflows/run-checker-merge.yml +++ b/.github/workflows/run-checker-merge.yml @@ -35,6 +35,7 @@ jobs: no-ts, enable-weak-ssl-ciphers, enable-zlib, + enable-pie, ] runs-on: ubuntu-latest steps: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 1df44c4f0094b..c24e7f894d1e0 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -66,7 +66,7 @@ jobs: run: nmake test VERBOSE_FAILURE=yes TESTS=-test_fuzz* HARNESS_JOBS=4 - name: install # Run on 64 bit only as 32 bit is slow enough already - if: $${{ matrix.platform.arch == 'win64' }} + if: ${{ matrix.platform.arch == 'win64' }} run: | mkdir _dest nmake install DESTDIR=_dest diff --git a/.gitignore b/.gitignore index 98184721f2285..d2de49876dde9 100644 --- a/.gitignore +++ b/.gitignore @@ -54,6 +54,7 @@ /include/openssl/ui.h /include/openssl/x509.h /include/openssl/x509v3.h +/include/openssl/x509_acert.h /include/openssl/x509_vfy.h /include/openssl/core_names.h /include/internal/param_names.h diff --git a/CHANGES.md b/CHANGES.md index 21fd185444d77..1258a44b5239e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -59,6 +59,13 @@ OpenSSL 3.4 *Damian Hobson-Garcia* + * Added support to build Position Independent Executables (PIE). Configuration + option `enable-pie` configures the cflag '-fPIE' and ldflag '-pie' to + support Address Space Layout Randomization (ASLR) in the openssl executable, + removes reliance on external toolchain configurations. + + *Craig Lorentzen* + OpenSSL 3.3 ----------- diff --git a/Configurations/00-base-templates.conf b/Configurations/00-base-templates.conf index 55da5ec56c200..a9ccb0ced8792 100644 --- a/Configurations/00-base-templates.conf +++ b/Configurations/00-base-templates.conf @@ -76,6 +76,22 @@ my %targets=( AR => "ar", ARFLAGS => "qc", CC => "cc", + bin_cflags => + sub { + my @flags = (); + if (!defined($disabled{pie})) { + push(@flags, "-fPIE"); + } + return join(" ", @flags); + }, + bin_lflags => + sub { + my @flags = (); + if (!defined($disabled{pie})) { + push(@flags, "-pie"); + } + return join(" ", @flags); + }, lflags => sub { my @libs = (); diff --git a/Configurations/10-main.conf b/Configurations/10-main.conf index ac30adc2c9ffe..36ecf3b263093 100644 --- a/Configurations/10-main.conf +++ b/Configurations/10-main.conf @@ -777,7 +777,14 @@ my %targets = ( asm_arch => 'aarch64', perlasm_scheme => "linux64", }, - + "linux-arm64ilp32-clang" => { # clang config abi by --target + inherit_from => [ "linux-generic32" ], + CC => "clang", + CXX => "clang++", + bn_ops => "SIXTY_FOUR_BIT RC4_CHAR", + asm_arch => 'aarch64', + perlasm_scheme => "linux64", + }, "linux-mips32" => { # Configure script adds minimally required -march for assembly # support, if no -march was specified at command line. diff --git a/Configure b/Configure index cef9e8c3e6662..f7fc016c8cab2 100755 --- a/Configure +++ b/Configure @@ -492,6 +492,7 @@ my @disablables = ( "ocsp", "padlockeng", "pic", + "pie", "pinshared", "poly1305", "posix-io", @@ -584,6 +585,7 @@ our %disabled = ( # "what" => "comment" "external-tests" => "default", "fuzz-afl" => "default", "fuzz-libfuzzer" => "default", + "pie" => "default", "ktls" => "default", "md2" => "default", "msan" => "default", @@ -943,6 +945,10 @@ while (@argvcopy) { delete $disabled{"brotli"}; } + elsif ($1 eq "pie") + { + delete $disabled{"pie"}; + } elsif ($1 eq "zstd-dynamic") { delete $disabled{"zstd"}; diff --git a/INSTALL.md b/INSTALL.md index b486ee1556a25..a34de9bbf8c9e 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -870,6 +870,10 @@ As synonym for `no-padlockeng`. Deprecated and should not be used. Don't build with support for Position Independent Code. +### enable-pie + +Build with support for Position Independent Execution. + ### no-pinshared Don't pin the shared libraries. diff --git a/crypto/asn1/a_time.c b/crypto/asn1/a_time.c index 96ee63d3104ce..7dfbc5faabd15 100644 --- a/crypto/asn1/a_time.c +++ b/crypto/asn1/a_time.c @@ -591,78 +591,3 @@ int ASN1_TIME_compare(const ASN1_TIME *a, const ASN1_TIME *b) return -1; return 0; } - -/* - * tweak for Windows - */ -#ifdef WIN32 -# define timezone _timezone -#endif - -#if defined(__FreeBSD__) || defined(__wasi__) -# define USE_TIMEGM -#endif - -time_t ossl_asn1_string_to_time_t(const char *asn1_string) -{ - ASN1_TIME *timestamp_asn1 = NULL; - struct tm *timestamp_tm = NULL; -#if defined(__DJGPP__) - char *tz = NULL; -#elif !defined(USE_TIMEGM) - time_t timestamp_local; -#endif - time_t timestamp_utc; - - timestamp_asn1 = ASN1_TIME_new(); - if (!ASN1_TIME_set_string(timestamp_asn1, asn1_string)) - { - ASN1_TIME_free(timestamp_asn1); - return -1; - } - - timestamp_tm = OPENSSL_malloc(sizeof(*timestamp_tm)); - if (timestamp_tm == NULL) { - ASN1_TIME_free(timestamp_asn1); - return -1; - } - if (!(ASN1_TIME_to_tm(timestamp_asn1, timestamp_tm))) { - OPENSSL_free(timestamp_tm); - ASN1_TIME_free(timestamp_asn1); - return -1; - } - ASN1_TIME_free(timestamp_asn1); - -#if defined(__DJGPP__) - /* - * This is NOT thread-safe. Do not use this method for platforms other - * than djgpp. - */ - tz = getenv("TZ"); - if (tz != NULL) { - tz = OPENSSL_strdup(tz); - if (tz == NULL) { - OPENSSL_free(timestamp_tm); - return -1; - } - } - setenv("TZ", "UTC", 1); - - timestamp_utc = mktime(timestamp_tm); - - if (tz != NULL) { - setenv("TZ", tz, 1); - OPENSSL_free(tz); - } else { - unsetenv("TZ"); - } -#elif defined(USE_TIMEGM) - timestamp_utc = timegm(timestamp_tm); -#else - timestamp_local = mktime(timestamp_tm); - timestamp_utc = timestamp_local - timezone; -#endif - OPENSSL_free(timestamp_tm); - - return timestamp_utc; -} diff --git a/crypto/chacha/asm/chacha-riscv64-zbb-zvkb.pl b/crypto/chacha/asm/chacha-riscv64-v-zbb.pl old mode 100644 new mode 100755 similarity index 71% rename from crypto/chacha/asm/chacha-riscv64-zbb-zvkb.pl rename to crypto/chacha/asm/chacha-riscv64-v-zbb.pl index 6508af4765388..6518e3fc2441c --- a/crypto/chacha/asm/chacha-riscv64-zbb-zvkb.pl +++ b/crypto/chacha/asm/chacha-riscv64-v-zbb.pl @@ -37,9 +37,10 @@ # - RV64I # - RISC-V Vector ('V') with VLEN >= 128 -# - RISC-V Vector Cryptography Bit-manipulation extension ('Zvkb') # - RISC-V Basic Bit-manipulation extension ('Zbb') # - RISC-V Zicclsm(Main memory supports misaligned loads/stores) +# Optional: +# - RISC-V Vector Cryptography Bit-manipulation extension ('Zvkb') use strict; use warnings; @@ -54,15 +55,18 @@ my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; +my $use_zvkb = $flavour && $flavour =~ /zvkb/i ? 1 : 0; +my $isaext = "_v_zbb" . ( $use_zvkb ? "_zvkb" : "" ); + $output and open STDOUT, ">$output"; my $code = <<___; .text ___ -# void ChaCha20_ctr32_zbb_zvkb(unsigned char *out, const unsigned char *inp, -# size_t len, const unsigned int key[8], -# const unsigned int counter[4]); +# void ChaCha20_ctr32@{[$isaext]}(unsigned char *out, const unsigned char *inp, +# size_t len, const unsigned int key[8], +# const unsigned int counter[4]); ################################################################################ my ( $OUTPUT, $INPUT, $LEN, $KEY, $COUNTER ) = ( "a0", "a1", "a2", "a3", "a4" ); my ( $CONST_DATA0, $CONST_DATA1, $CONST_DATA2, $CONST_DATA3 ) = ( "a5", "a6", @@ -90,6 +94,83 @@ $V22, $V23, $V24, $V25, $V26, $V27, $V28, $V29, $V30, $V31, ) = map( "v$_", ( 0 .. 31 ) ); +sub chacha_sub_round { + my ( + $A0, $B0, $C0, + $A1, $B1, $C1, + $A2, $B2, $C2, + $A3, $B3, $C3, + + $S_A0, $S_B0, $S_C0, + $S_A1, $S_B1, $S_C1, + $S_A2, $S_B2, $S_C2, + $S_A3, $S_B3, $S_C3, + + $ROL_SHIFT, + + $V_T0, $V_T1, $V_T2, $V_T3, + ) = @_; + + # a += b; c ^= a; + my $code = <<___; + @{[vadd_vv $A0, $A0, $B0]} + add $S_A0, $S_A0, $S_B0 + @{[vadd_vv $A1, $A1, $B1]} + add $S_A1, $S_A1, $S_B1 + @{[vadd_vv $A2, $A2, $B2]} + add $S_A2, $S_A2, $S_B2 + @{[vadd_vv $A3, $A3, $B3]} + add $S_A3, $S_A3, $S_B3 + @{[vxor_vv $C0, $C0, $A0]} + xor $S_C0, $S_C0, $S_A0 + @{[vxor_vv $C1, $C1, $A1]} + xor $S_C1, $S_C1, $S_A1 + @{[vxor_vv $C2, $C2, $A2]} + xor $S_C2, $S_C2, $S_A2 + @{[vxor_vv $C3, $C3, $A3]} + xor $S_C3, $S_C3, $S_A3 +___ + + # c <<<= $ROL_SHIFT; + if ($use_zvkb) { + my $ror_part = <<___; + @{[vror_vi $C0, $C0, 32 - $ROL_SHIFT]} + @{[roriw $S_C0, $S_C0, 32 - $ROL_SHIFT]} + @{[vror_vi $C1, $C1, 32 - $ROL_SHIFT]} + @{[roriw $S_C1, $S_C1, 32 - $ROL_SHIFT]} + @{[vror_vi $C2, $C2, 32 - $ROL_SHIFT]} + @{[roriw $S_C2, $S_C2, 32 - $ROL_SHIFT]} + @{[vror_vi $C3, $C3, 32 - $ROL_SHIFT]} + @{[roriw $S_C3, $S_C3, 32 - $ROL_SHIFT]} +___ + + $code .= $ror_part; + } else { + my $ror_part = <<___; + @{[vsll_vi $V_T0, $C0, $ROL_SHIFT]} + @{[vsll_vi $V_T1, $C1, $ROL_SHIFT]} + @{[vsll_vi $V_T2, $C2, $ROL_SHIFT]} + @{[vsll_vi $V_T3, $C3, $ROL_SHIFT]} + @{[vsrl_vi $C0, $C0, 32 - $ROL_SHIFT]} + @{[vsrl_vi $C1, $C1, 32 - $ROL_SHIFT]} + @{[vsrl_vi $C2, $C2, 32 - $ROL_SHIFT]} + @{[vsrl_vi $C3, $C3, 32 - $ROL_SHIFT]} + @{[vor_vv $C0, $C0, $V_T0]} + @{[roriw $S_C0, $S_C0, 32 - $ROL_SHIFT]} + @{[vor_vv $C1, $C1, $V_T1]} + @{[roriw $S_C1, $S_C1, 32 - $ROL_SHIFT]} + @{[vor_vv $C2, $C2, $V_T2]} + @{[roriw $S_C2, $S_C2, 32 - $ROL_SHIFT]} + @{[vor_vv $C3, $C3, $V_T3]} + @{[roriw $S_C3, $S_C3, 32 - $ROL_SHIFT]} +___ + + $code .= $ror_part; + } + + return $code; +} + sub chacha_quad_round_group { my ( $A0, $B0, $C0, $D0, @@ -101,109 +182,59 @@ sub chacha_quad_round_group { $S_A1, $S_B1, $S_C1, $S_D1, $S_A2, $S_B2, $S_C2, $S_D2, $S_A3, $S_B3, $S_C3, $S_D3, + + $V_T0, $V_T1, $V_T2, $V_T3, ) = @_; my $code = <<___; # a += b; d ^= a; d <<<= 16; - @{[vadd_vv $A0, $A0, $B0]} - add $S_A0, $S_A0, $S_B0 - @{[vadd_vv $A1, $A1, $B1]} - add $S_A1, $S_A1, $S_B1 - @{[vadd_vv $A2, $A2, $B2]} - add $S_A2, $S_A2, $S_B2 - @{[vadd_vv $A3, $A3, $B3]} - add $S_A3, $S_A3, $S_B3 - @{[vxor_vv $D0, $D0, $A0]} - xor $S_D0, $S_D0, $S_A0 - @{[vxor_vv $D1, $D1, $A1]} - xor $S_D1, $S_D1, $S_A1 - @{[vxor_vv $D2, $D2, $A2]} - xor $S_D2, $S_D2, $S_A2 - @{[vxor_vv $D3, $D3, $A3]} - xor $S_D3, $S_D3, $S_A3 - @{[vror_vi $D0, $D0, 32 - 16]} - @{[roriw $S_D0, $S_D0, 32 - 16]} - @{[vror_vi $D1, $D1, 32 - 16]} - @{[roriw $S_D1, $S_D1, 32 - 16]} - @{[vror_vi $D2, $D2, 32 - 16]} - @{[roriw $S_D2, $S_D2, 32 - 16]} - @{[vror_vi $D3, $D3, 32 - 16]} - @{[roriw $S_D3, $S_D3, 32 - 16]} + @{[chacha_sub_round + $A0, $B0, $D0, + $A1, $B1, $D1, + $A2, $B2, $D2, + $A3, $B3, $D3, + $S_A0, $S_B0, $S_D0, + $S_A1, $S_B1, $S_D1, + $S_A2, $S_B2, $S_D2, + $S_A3, $S_B3, $S_D3, + 16, + $V_T0, $V_T1, $V_T2, $V_T3]} # c += d; b ^= c; b <<<= 12; - @{[vadd_vv $C0, $C0, $D0]} - add $S_C0, $S_C0, $S_D0 - @{[vadd_vv $C1, $C1, $D1]} - add $S_C1, $S_C1, $S_D1 - @{[vadd_vv $C2, $C2, $D2]} - add $S_C2, $S_C2, $S_D2 - @{[vadd_vv $C3, $C3, $D3]} - add $S_C3, $S_C3, $S_D3 - @{[vxor_vv $B0, $B0, $C0]} - xor $S_B0, $S_B0, $S_C0 - @{[vxor_vv $B1, $B1, $C1]} - xor $S_B1, $S_B1, $S_C1 - @{[vxor_vv $B2, $B2, $C2]} - xor $S_B2, $S_B2, $S_C2 - @{[vxor_vv $B3, $B3, $C3]} - xor $S_B3, $S_B3, $S_C3 - @{[vror_vi $B0, $B0, 32 - 12]} - @{[roriw $S_B0, $S_B0, 32 - 12]} - @{[vror_vi $B1, $B1, 32 - 12]} - @{[roriw $S_B1, $S_B1, 32 - 12]} - @{[vror_vi $B2, $B2, 32 - 12]} - @{[roriw $S_B2, $S_B2, 32 - 12]} - @{[vror_vi $B3, $B3, 32 - 12]} - @{[roriw $S_B3, $S_B3, 32 - 12]} + @{[chacha_sub_round + $C0, $D0, $B0, + $C1, $D1, $B1, + $C2, $D2, $B2, + $C3, $D3, $B3, + $S_C0, $S_D0, $S_B0, + $S_C1, $S_D1, $S_B1, + $S_C2, $S_D2, $S_B2, + $S_C3, $S_D3, $S_B3, + 12, + $V_T0, $V_T1, $V_T2, $V_T3]} # a += b; d ^= a; d <<<= 8; - @{[vadd_vv $A0, $A0, $B0]} - add $S_A0, $S_A0, $S_B0 - @{[vadd_vv $A1, $A1, $B1]} - add $S_A1, $S_A1, $S_B1 - @{[vadd_vv $A2, $A2, $B2]} - add $S_A2, $S_A2, $S_B2 - @{[vadd_vv $A3, $A3, $B3]} - add $S_A3, $S_A3, $S_B3 - @{[vxor_vv $D0, $D0, $A0]} - xor $S_D0, $S_D0, $S_A0 - @{[vxor_vv $D1, $D1, $A1]} - xor $S_D1, $S_D1, $S_A1 - @{[vxor_vv $D2, $D2, $A2]} - xor $S_D2, $S_D2, $S_A2 - @{[vxor_vv $D3, $D3, $A3]} - xor $S_D3, $S_D3, $S_A3 - @{[vror_vi $D0, $D0, 32 - 8]} - @{[roriw $S_D0, $S_D0, 32 - 8]} - @{[vror_vi $D1, $D1, 32 - 8]} - @{[roriw $S_D1, $S_D1, 32 - 8]} - @{[vror_vi $D2, $D2, 32 - 8]} - @{[roriw $S_D2, $S_D2, 32 - 8]} - @{[vror_vi $D3, $D3, 32 - 8]} - @{[roriw $S_D3, $S_D3, 32 - 8]} + @{[chacha_sub_round + $A0, $B0, $D0, + $A1, $B1, $D1, + $A2, $B2, $D2, + $A3, $B3, $D3, + $S_A0, $S_B0, $S_D0, + $S_A1, $S_B1, $S_D1, + $S_A2, $S_B2, $S_D2, + $S_A3, $S_B3, $S_D3, + 8, + $V_T0, $V_T1, $V_T2, $V_T3]} # c += d; b ^= c; b <<<= 7; - @{[vadd_vv $C0, $C0, $D0]} - add $S_C0, $S_C0, $S_D0 - @{[vadd_vv $C1, $C1, $D1]} - add $S_C1, $S_C1, $S_D1 - @{[vadd_vv $C2, $C2, $D2]} - add $S_C2, $S_C2, $S_D2 - @{[vadd_vv $C3, $C3, $D3]} - add $S_C3, $S_C3, $S_D3 - @{[vxor_vv $B0, $B0, $C0]} - xor $S_B0, $S_B0, $S_C0 - @{[vxor_vv $B1, $B1, $C1]} - xor $S_B1, $S_B1, $S_C1 - @{[vxor_vv $B2, $B2, $C2]} - xor $S_B2, $S_B2, $S_C2 - @{[vxor_vv $B3, $B3, $C3]} - xor $S_B3, $S_B3, $S_C3 - @{[vror_vi $B0, $B0, 32 - 7]} - @{[roriw $S_B0, $S_B0, 32 - 7]} - @{[vror_vi $B1, $B1, 32 - 7]} - @{[roriw $S_B1, $S_B1, 32 - 7]} - @{[vror_vi $B2, $B2, 32 - 7]} - @{[roriw $S_B2, $S_B2, 32 - 7]} - @{[vror_vi $B3, $B3, 32 - 7]} - @{[roriw $S_B3, $S_B3, 32 - 7]} + @{[chacha_sub_round + $C0, $D0, $B0, + $C1, $D1, $B1, + $C2, $D2, $B2, + $C3, $D3, $B3, + $S_C0, $S_D0, $S_B0, + $S_C1, $S_D1, $S_B1, + $S_C2, $S_D2, $S_B2, + $S_C3, $S_D3, $S_B3, + 7, + $V_T0, $V_T1, $V_T2, $V_T3]} ___ return $code; @@ -211,9 +242,9 @@ sub chacha_quad_round_group { $code .= <<___; .p2align 3 -.globl ChaCha20_ctr32_zbb_zvkb -.type ChaCha20_ctr32_zbb_zvkb,\@function -ChaCha20_ctr32_zbb_zvkb: +.globl ChaCha20_ctr32@{[$isaext]} +.type ChaCha20_ctr32@{[$isaext]},\@function +ChaCha20_ctr32@{[$isaext]}: addi sp, sp, -96 sd s0, 0(sp) sd s1, 8(sp) @@ -244,7 +275,7 @@ sub chacha_quad_round_group { 1: #### chacha block data - # init chacha const states + # init chacha const states into $V0~$V3 # "expa" little endian li $CONST_DATA0, 0x61707865 @{[vmv_v_x $V0, $CONST_DATA0]} @@ -259,7 +290,7 @@ sub chacha_quad_round_group { lw $KEY0, 0($KEY) @{[vmv_v_x $V3, $CONST_DATA3]} - # init chacha key states + # init chacha key states into $V4~$V11 lw $KEY1, 4($KEY) @{[vmv_v_x $V4, $KEY0]} lw $KEY2, 8($KEY) @@ -276,7 +307,7 @@ sub chacha_quad_round_group { @{[vmv_v_x $V10, $KEY6]} @{[vmv_v_x $V11, $KEY7]} - # init chacha key states + # init chacha key states into $V12~$V13 lw $COUNTER1, 4($COUNTER) @{[vid_v $V12]} lw $NONCE0, 8($COUNTER) @@ -285,17 +316,23 @@ sub chacha_quad_round_group { @{[vmv_v_x $V13, $COUNTER1]} add $COUNTER0, $CURRENT_COUNTER, $VL - # init chacha nonce states + # init chacha nonce states into $V14~$V15 @{[vmv_v_x $V14, $NONCE0]} @{[vmv_v_x $V15, $NONCE1]} li $T0, 64 - # load the top-half of input data + # load the top-half of input data into $V16~$V23 @{[vlsseg_nf_e32_v 8, $V16, $INPUT, $T0]} + # till now in block_loop, we used: + # - $V0~$V15 for chacha states. + # - $V16~$V23 for top-half of input data. + # - $V24~$V31 haven't been used yet. + # 20 round groups li $T0, 10 .Lround_loop: + # we can use $V24~$V31 as temporary registers in round_loop. addi $T0, $T0, -1 @{[chacha_quad_round_group $V0, $V4, $V8, $V12, @@ -305,7 +342,8 @@ sub chacha_quad_round_group { $STATE0, $STATE4, $STATE8, $STATE12, $STATE1, $STATE5, $STATE9, $STATE13, $STATE2, $STATE6, $STATE10, $STATE14, - $STATE3, $STATE7, $STATE11, $STATE15]} + $STATE3, $STATE7, $STATE11, $STATE15, + $V24, $V25, $V26, $V27]} @{[chacha_quad_round_group $V3, $V4, $V9, $V14, $V0, $V5, $V10, $V15, @@ -314,14 +352,17 @@ sub chacha_quad_round_group { $STATE3, $STATE4, $STATE9, $STATE14, $STATE0, $STATE5, $STATE10, $STATE15, $STATE1, $STATE6, $STATE11, $STATE12, - $STATE2, $STATE7, $STATE8, $STATE13]} + $STATE2, $STATE7, $STATE8, $STATE13, + $V24, $V25, $V26, $V27]} bnez $T0, .Lround_loop li $T0, 64 - # load the bottom-half of input data + # load the bottom-half of input data into $V24~$V31 addi $T1, $INPUT, 32 @{[vlsseg_nf_e32_v 8, $V24, $T1, $T0]} + # now, there are no free vector registers until the round_loop exits. + # add chacha top-half initial block states # "expa" little endian li $T0, 0x61707865 @@ -373,7 +414,7 @@ sub chacha_quad_round_group { lw $T2, 24($KEY) @{[vxor_vv $V23, $V23, $V7]} - # save the top-half of output + # save the top-half of output from $V16~$V23 li $T3, 64 @{[vssseg_nf_e32_v 8, $V16, $OUTPUT, $T3]} @@ -419,7 +460,7 @@ sub chacha_quad_round_group { @{[vxor_vv $V31, $V31, $V15]} sw $STATE15, 60(sp) - # save the bottom-half of output + # save the bottom-half of output from $V24~$V31 li $T0, 64 addi $T1, $OUTPUT, 32 @{[vssseg_nf_e32_v 8, $V24, $T1, $T0]} @@ -440,6 +481,7 @@ sub chacha_quad_round_group { mv $T2, sp .Lscalar_data_loop: @{[vsetvli $VL, $T1, "e8", "m8", "ta", "ma"]} + # from this on, vector registers are grouped with lmul = 8 @{[vle8_v $V8, $INPUT]} @{[vle8_v $V16, $T2]} @{[vxor_vv $V8, $V8, $V16]} @@ -468,7 +510,7 @@ sub chacha_quad_round_group { addi sp, sp, 96 ret -.size ChaCha20_ctr32_zbb_zvkb,.-ChaCha20_ctr32_zbb_zvkb +.size ChaCha20_ctr32@{[$isaext]},.-ChaCha20_ctr32@{[$isaext]} ___ print $code; diff --git a/crypto/chacha/build.info b/crypto/chacha/build.info index c1352c9b62dee..c151e190429d1 100644 --- a/crypto/chacha/build.info +++ b/crypto/chacha/build.info @@ -22,7 +22,7 @@ IF[{- !$disabled{asm} -}] $CHACHAASM_c64xplus=chacha-c64xplus.s - $CHACHAASM_riscv64=chacha_riscv.c chacha_enc.c chacha-riscv64-zbb-zvkb.s + $CHACHAASM_riscv64=chacha_riscv.c chacha_enc.c chacha-riscv64-v-zbb.s chacha-riscv64-v-zbb-zvkb.s $CHACHADEF_riscv64=INCLUDE_C_CHACHA20 # Now that we have defined all the arch specific variables, use the @@ -53,4 +53,5 @@ GENERATE[chacha-s390x.S]=asm/chacha-s390x.pl GENERATE[chacha-ia64.S]=asm/chacha-ia64.pl GENERATE[chacha-ia64.s]=chacha-ia64.S GENERATE[chacha-loongarch64.S]=asm/chacha-loongarch64.pl -GENERATE[chacha-riscv64-zbb-zvkb.s]=asm/chacha-riscv64-zbb-zvkb.pl +GENERATE[chacha-riscv64-v-zbb.s]=asm/chacha-riscv64-v-zbb.pl +GENERATE[chacha-riscv64-v-zbb-zvkb.s]=asm/chacha-riscv64-v-zbb.pl zvkb diff --git a/crypto/chacha/chacha_riscv.c b/crypto/chacha/chacha_riscv.c index 8873460e5efe0..9baa39bec3723 100644 --- a/crypto/chacha/chacha_riscv.c +++ b/crypto/chacha/chacha_riscv.c @@ -40,16 +40,23 @@ #include "crypto/chacha.h" #include "crypto/riscv_arch.h" -void ChaCha20_ctr32_zbb_zvkb(unsigned char *out, const unsigned char *inp, - size_t len, const unsigned int key[8], - const unsigned int counter[4]); +void ChaCha20_ctr32_v_zbb_zvkb(unsigned char *out, const unsigned char *inp, + size_t len, const unsigned int key[8], + const unsigned int counter[4]); + +void ChaCha20_ctr32_v_zbb(unsigned char *out, const unsigned char *inp, + size_t len, const unsigned int key[8], + const unsigned int counter[4]); void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, size_t len, const unsigned int key[8], const unsigned int counter[4]) { - if (len > CHACHA_BLK_SIZE && RISCV_HAS_ZVKB() && RISCV_HAS_ZBB() && - riscv_vlen() >= 128) { - ChaCha20_ctr32_zbb_zvkb(out, inp, len, key, counter); + if (len > CHACHA_BLK_SIZE && RISCV_HAS_ZBB() && riscv_vlen() >= 128) { + if (RISCV_HAS_ZVKB()) { + ChaCha20_ctr32_v_zbb_zvkb(out, inp, len, key, counter); + } else { + ChaCha20_ctr32_v_zbb(out, inp, len, key, counter); + } } else { ChaCha20_ctr32_c(out, inp, len, key, counter); } diff --git a/crypto/cms/cms_asn1.c b/crypto/cms/cms_asn1.c index bc6b2769f98cd..9ac848e448b94 100644 --- a/crypto/cms/cms_asn1.c +++ b/crypto/cms/cms_asn1.c @@ -51,6 +51,7 @@ static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, EVP_PKEY_free(si->pkey); X509_free(si->signer); EVP_MD_CTX_free(si->mctx); + EVP_PKEY_CTX_free(si->pctx); } return 1; } @@ -90,11 +91,21 @@ ASN1_SEQUENCE(CMS_OriginatorInfo) = { ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1) } static_ASN1_SEQUENCE_END(CMS_OriginatorInfo) -ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = { +static int cms_ec_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + CMS_EncryptedContentInfo *ec = (CMS_EncryptedContentInfo *)*pval; + + if (operation == ASN1_OP_FREE_POST) + OPENSSL_clear_free(ec->key, ec->keylen); + return 1; +} + +ASN1_NDEF_SEQUENCE_cb(CMS_EncryptedContentInfo, cms_ec_cb) = { ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT), ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR), ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0) -} static_ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo) +} ASN1_NDEF_SEQUENCE_END_cb(CMS_EncryptedContentInfo, CMS_EncryptedContentInfo) ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = { ASN1_EMBED(CMS_KeyTransRecipientInfo, version, INT32), @@ -318,6 +329,10 @@ static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, return 0; break; + case ASN1_OP_FREE_POST: + OPENSSL_free(cms->ctx.propq); + break; + } return 1; } diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c index b877e106199ae..37dfbe538935f 100644 --- a/crypto/cms/cms_env.c +++ b/crypto/cms/cms_env.c @@ -51,15 +51,6 @@ static int cms_get_enveloped_type(const CMS_ContentInfo *cms) return ret; } -void ossl_cms_env_enc_content_free(const CMS_ContentInfo *cinf) -{ - if (cms_get_enveloped_type_simple(cinf) != 0) { - CMS_EncryptedContentInfo *ec = ossl_cms_get0_env_enc_content(cinf); - if (ec != NULL) - OPENSSL_clear_free(ec->key, ec->keylen); - } -} - CMS_EnvelopedData *ossl_cms_get0_enveloped(CMS_ContentInfo *cms) { if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { @@ -289,8 +280,10 @@ BIO *CMS_EnvelopedData_decrypt(CMS_EnvelopedData *env, BIO *detached_data, secret == NULL ? cert : NULL, detached_data, bio, flags); end: - if (ci != NULL) + if (ci != NULL) { ci->d.envelopedData = NULL; /* do not indirectly free |env| */ + ci->contentType = NULL; + } CMS_ContentInfo_free(ci); if (!res) { BIO_free(bio); diff --git a/crypto/cms/cms_lib.c b/crypto/cms/cms_lib.c index afc210c9d0c8a..759e1d46af4cc 100644 --- a/crypto/cms/cms_lib.c +++ b/crypto/cms/cms_lib.c @@ -21,6 +21,7 @@ static STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms); +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(CMS_ContentInfo) IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo) CMS_ContentInfo *d2i_CMS_ContentInfo(CMS_ContentInfo **a, @@ -66,20 +67,6 @@ CMS_ContentInfo *CMS_ContentInfo_new_ex(OSSL_LIB_CTX *libctx, const char *propq) return ci; } -CMS_ContentInfo *CMS_ContentInfo_new(void) -{ - return CMS_ContentInfo_new_ex(NULL, NULL); -} - -void CMS_ContentInfo_free(CMS_ContentInfo *cms) -{ - if (cms != NULL) { - ossl_cms_env_enc_content_free(cms); - OPENSSL_free(cms->ctx.propq); - ASN1_item_free((ASN1_VALUE *)cms, ASN1_ITEM_rptr(CMS_ContentInfo)); - } -} - const CMS_CTX *ossl_cms_get0_cmsctx(const CMS_ContentInfo *cms) { return cms != NULL ? &cms->ctx : NULL; diff --git a/crypto/cms/cms_local.h b/crypto/cms/cms_local.h index 7069021267def..a2b72484c633c 100644 --- a/crypto/cms/cms_local.h +++ b/crypto/cms/cms_local.h @@ -366,6 +366,7 @@ struct CMS_Receipt_st { DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) DECLARE_ASN1_ITEM(CMS_SignerInfo) +DECLARE_ASN1_ITEM(CMS_EncryptedContentInfo) DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber) DECLARE_ASN1_ITEM(CMS_Attributes_Sign) DECLARE_ASN1_ITEM(CMS_Attributes_Verify) @@ -447,7 +448,6 @@ BIO *ossl_cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); int ossl_cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain); BIO *ossl_cms_AuthEnvelopedData_init_bio(CMS_ContentInfo *cms); int ossl_cms_AuthEnvelopedData_final(CMS_ContentInfo *cms, BIO *cmsbio); -void ossl_cms_env_enc_content_free(const CMS_ContentInfo *cinf); CMS_EnvelopedData *ossl_cms_get0_enveloped(CMS_ContentInfo *cms); CMS_AuthEnvelopedData *ossl_cms_get0_auth_enveloped(CMS_ContentInfo *cms); CMS_EncryptedContentInfo *ossl_cms_get0_env_enc_content(const CMS_ContentInfo *cms); diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c index b41e3571b2ff7..a76e795df588b 100644 --- a/crypto/cms/cms_sd.c +++ b/crypto/cms/cms_sd.c @@ -512,8 +512,12 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, ossl_cms_ctx_get0_libctx(ctx), ossl_cms_ctx_get0_propq(ctx), pk, NULL) <= 0) { + si->pctx = NULL; goto err; } + else { + EVP_MD_CTX_set_flags(si->mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); + } } if (sd->signerInfos == NULL) @@ -758,6 +762,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, unsigned char computed_md[EVP_MAX_MD_SIZE]; pctx = si->pctx; + si->pctx = NULL; if (md == NULL) { if (!EVP_DigestFinal_ex(mctx, computed_md, &mdlen)) goto err; @@ -851,6 +856,7 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) ossl_cms_ctx_get0_propq(ctx), si->pkey, NULL) <= 0) goto err; + EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); si->pctx = pctx; } @@ -922,9 +928,16 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) goto err; } mctx = si->mctx; + if (si->pctx != NULL) { + EVP_PKEY_CTX_free(si->pctx); + si->pctx = NULL; + } if (EVP_DigestVerifyInit_ex(mctx, &si->pctx, EVP_MD_get0_name(md), libctx, - propq, si->pkey, NULL) <= 0) + propq, si->pkey, NULL) <= 0) { + si->pctx = NULL; goto err; + } + EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); if (!cms_sd_asn1_ctrl(si, 1)) goto err; @@ -1040,8 +1053,11 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0) goto err; si->pctx = pkctx; - if (!cms_sd_asn1_ctrl(si, 1)) + if (!cms_sd_asn1_ctrl(si, 1)) { + si->pctx = NULL; goto err; + } + si->pctx = NULL; r = EVP_PKEY_verify(pkctx, si->signature->data, si->signature->length, mval, mlen); if (r <= 0) { diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c index 99a72f4dffe3c..4df4487cbc28f 100644 --- a/crypto/cms/cms_smime.c +++ b/crypto/cms/cms_smime.c @@ -236,7 +236,7 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher, if (cms == NULL) return NULL; if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) - return NULL; + goto err; if (!(flags & CMS_DETACHED)) CMS_set_detached(cms, 0); @@ -245,6 +245,7 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher, || CMS_final(cms, in, NULL, flags)) return cms; + err: CMS_ContentInfo_free(cms); return NULL; } diff --git a/crypto/perlasm/riscv.pm b/crypto/perlasm/riscv.pm index 7e45bec812d7f..bd1c3d90a19f7 100644 --- a/crypto/perlasm/riscv.pm +++ b/crypto/perlasm/riscv.pm @@ -598,6 +598,15 @@ sub vmv_v_v { return ".word ".($template | ($vs1 << 15) | ($vd << 7)); } +sub vor_vv { + # vor.vv vd, vs2, vs1 + my $template = 0b0010101_00000_00000_000_00000_1010111; + my $vd = read_vreg shift; + my $vs2 = read_vreg shift; + my $vs1 = read_vreg shift; + return ".word ".($template | ($vs2 << 20) | ($vs1 << 15) | ($vd << 7)); +} + sub vor_vv_v0t { # vor.vv vd, vs2, vs1, v0.t my $template = 0b0010100_00000_00000_000_00000_1010111; @@ -747,6 +756,15 @@ sub vsll_vi { return ".word ".($template | ($vs2 << 20) | ($uimm << 15) | ($vd << 7)); } +sub vsrl_vi { + # vsrl.vi vd, vs2, uimm, vm + my $template = 0b1010001_00000_00000_011_00000_1010111; + my $vd = read_vreg shift; + my $vs2 = read_vreg shift; + my $uimm = shift; + return ".word ".($template | ($vs2 << 20) | ($uimm << 15) | ($vd << 7)); +} + sub vsrl_vx { # vsrl.vx vd, vs2, rs1 my $template = 0b1010001_00000_00000_100_00000_1010111; diff --git a/doc/build.info b/doc/build.info index aab005baaef8d..3214d0843b474 100644 --- a/doc/build.info +++ b/doc/build.info @@ -2747,6 +2747,10 @@ DEPEND[html/man3/SSL_set_session.html]=man3/SSL_set_session.pod GENERATE[html/man3/SSL_set_session.html]=man3/SSL_set_session.pod DEPEND[man/man3/SSL_set_session.3]=man3/SSL_set_session.pod GENERATE[man/man3/SSL_set_session.3]=man3/SSL_set_session.pod +DEPEND[html/man3/SSL_set_session_secret_cb.html]=man3/SSL_set_session_secret_cb.pod +GENERATE[html/man3/SSL_set_session_secret_cb.html]=man3/SSL_set_session_secret_cb.pod +DEPEND[man/man3/SSL_set_session_secret_cb.3]=man3/SSL_set_session_secret_cb.pod +GENERATE[man/man3/SSL_set_session_secret_cb.3]=man3/SSL_set_session_secret_cb.pod DEPEND[html/man3/SSL_set_shutdown.html]=man3/SSL_set_shutdown.pod GENERATE[html/man3/SSL_set_shutdown.html]=man3/SSL_set_shutdown.pod DEPEND[man/man3/SSL_set_shutdown.3]=man3/SSL_set_shutdown.pod @@ -3650,6 +3654,7 @@ html/man3/SSL_set_fd.html \ html/man3/SSL_set_incoming_stream_policy.html \ html/man3/SSL_set_retry_verify.html \ html/man3/SSL_set_session.html \ +html/man3/SSL_set_session_secret_cb.html \ html/man3/SSL_set_shutdown.html \ html/man3/SSL_set_verify_result.html \ html/man3/SSL_shutdown.html \ @@ -4303,6 +4308,7 @@ man/man3/SSL_set_fd.3 \ man/man3/SSL_set_incoming_stream_policy.3 \ man/man3/SSL_set_retry_verify.3 \ man/man3/SSL_set_session.3 \ +man/man3/SSL_set_session_secret_cb.3 \ man/man3/SSL_set_shutdown.3 \ man/man3/SSL_set_verify_result.3 \ man/man3/SSL_shutdown.3 \ diff --git a/doc/man3/SSL_set_session_secret_cb.pod b/doc/man3/SSL_set_session_secret_cb.pod new file mode 100644 index 0000000000000..e79d81d40a3ff --- /dev/null +++ b/doc/man3/SSL_set_session_secret_cb.pod @@ -0,0 +1,69 @@ +=pod + +=head1 NAME + +SSL_set_session_secret_cb, tls_session_secret_cb_fn +- set the session secret callback + +=head1 SYNOPSIS + + #include + + typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, + STACK_OF(SSL_CIPHER) *peer_ciphers, + const SSL_CIPHER **cipher, void *arg); + + int SSL_set_session_secret_cb(SSL *s, + tls_session_secret_cb_fn session_secret_cb, + void *arg); + +=head1 DESCRIPTION + +SSL_set_session_secret_cb() sets the session secret callback to be used +(I), and an optional argument (I) to be passed to that +callback when it is called. This is only useful for an implementation of +EAP-FAST (RFC4851). The presence of the callback also modifies the internal +OpenSSL TLS state machine to match the modified TLS behaviour as described in +RFC4851. Therefore this callback should not be used except when implementing +EAP-FAST. + +The callback is expected to set the master secret to be used by filling in the +data pointed to by I<*secret>. The size of the secret buffer is initially +available in I<*secret_len> and may be updated by the callback (but must not be +larger than the initial value). + +On the server side the set of ciphersuites offered by the peer is provided in +the I stack. Optionally the callback may select the preferred +ciphersuite by setting it in I<*cipher>. + +On the client side the I stack will always be NULL. The callback +may specify the preferred cipher in I<*cipher> and this will be associated with +the B - but it does not affect the ciphersuite selected by the +server. + +The callback is also supplied with an additional argument in I which is the +argument that was provided to the original SSL_set_session_secret_cb() call. + +=head1 RETURN VALUES + +SSL_set_session_secret_cb() returns 1 on success and 0 on failure. + +If the callback returns 1 then this indicates it has successfully set the +secret. A return value of 0 indicates that the secret has not been set. On the +client this will cause an immediate abort of the handshake. + +=head1 SEE ALSO + +L, +L + +=head1 COPYRIGHT + +Copyright 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 +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h index 36af1d7689293..b5683f007cf48 100644 --- a/include/crypto/asn1.h +++ b/include/crypto/asn1.h @@ -147,7 +147,6 @@ EVP_PKEY *ossl_d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a, OSSL_LIB_CTX *libctx, const char *propq); X509_ALGOR *ossl_X509_ALGOR_from_nid(int nid, int ptype, void *pval); -time_t ossl_asn1_string_to_time_t(const char *asn1_string); void ossl_asn1_string_set_bits_left(ASN1_STRING *str, unsigned int num); #endif /* ndef OSSL_CRYPTO_ASN1_H */ diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index eaa9595f8c2f2..3857e027ee0d1 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -907,8 +907,9 @@ int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, return 0; } s->session_id_length = sid_len; - if (sid != s->session_id) + if (sid != s->session_id && sid_len > 0) memcpy(s->session_id, sid, sid_len); + return 1; } diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 47855da5bd13b..1c38548fe047d 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -1959,6 +1959,11 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) } } + if (!s->hit && !tls1_set_server_sigalgs(s)) { + /* SSLfatal() already called */ + goto err; + } + if (!s->hit && s->version >= TLS1_VERSION && !SSL_CONNECTION_IS_TLS13(s) @@ -2110,10 +2115,6 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) #else s->session->compress_meth = (comp == NULL) ? 0 : comp->id; #endif - if (!tls1_set_server_sigalgs(s)) { - /* SSLfatal() already called */ - goto err; - } } sk_SSL_CIPHER_free(ciphers); diff --git a/test/asn1_time_test.c b/test/asn1_time_test.c index 7736fd34161e7..32bc4ff2adb1b 100644 --- a/test/asn1_time_test.c +++ b/test/asn1_time_test.c @@ -434,10 +434,10 @@ static int convert_asn1_to_time_t(int idx) { time_t testdateutc; - testdateutc = ossl_asn1_string_to_time_t(asn1_to_utc[idx].input); + testdateutc = test_asn1_string_to_time_t(asn1_to_utc[idx].input); if (!TEST_time_t_eq(testdateutc, asn1_to_utc[idx].expected)) { - TEST_info("ossl_asn1_string_to_time_t (%s) failed: expected %lli, got %lli\n", + TEST_info("test_asn1_string_to_time_t (%s) failed: expected %lli, got %lli\n", asn1_to_utc[idx].input, (long long int)asn1_to_utc[idx].expected, (long long int)testdateutc); diff --git a/test/build.info b/test/build.info index 9cbca834c8ae0..e2b09ae9650b1 100644 --- a/test/build.info +++ b/test/build.info @@ -26,7 +26,7 @@ IF[{- !$disabled{tests} -}] testutil/format_output.c testutil/load.c testutil/fake_random.c \ testutil/test_cleanup.c testutil/main.c testutil/testutil_init.c \ testutil/options.c testutil/test_options.c testutil/provider.c \ - testutil/apps_shims.c testutil/random.c $LIBAPPSSRC + testutil/apps_shims.c testutil/random.c testutil/helper.c $LIBAPPSSRC INCLUDE[libtestutil.a]=../include ../apps/include .. DEPEND[libtestutil.a]=../libcrypto diff --git a/test/ca_internals_test.c b/test/ca_internals_test.c index 24f7ba3884384..776996b4acad1 100644 --- a/test/ca_internals_test.c +++ b/test/ca_internals_test.c @@ -47,7 +47,7 @@ static int test_do_updatedb(void) } testdate = test_get_argument(2); - testdateutc = ossl_asn1_string_to_time_t(testdate); + testdateutc = test_asn1_string_to_time_t(testdate); if (TEST_time_t_lt(testdateutc, 0)) { return 0; } diff --git a/test/evp_test.c b/test/evp_test.c index 5634631703240..21106dd63343d 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -75,6 +75,7 @@ typedef enum OPTION_choice { OPT_IN_PLACE, OPT_PROVIDER_NAME, OPT_PROV_PROPQUERY, + OPT_DATA_CHUNK, OPT_TEST_ENUM } OPTION_CHOICE; @@ -88,6 +89,8 @@ static KEY_LIST *public_keys; static int find_key(EVP_PKEY **ppk, const char *name, KEY_LIST *lst); static int parse_bin(const char *value, unsigned char **buf, size_t *buflen); +static int parse_bin_chunk(const char *value, size_t offset, size_t max, + unsigned char **buf, size_t *buflen, size_t *out_offset); static int is_digest_disabled(const char *name); static int is_pkey_disabled(const char *name); static int is_mac_disabled(const char *name); @@ -118,6 +121,7 @@ static int memory_err_compare(EVP_TEST *t, const char *err, /* Option specific for evp test */ static int process_mode_in_place; static const char *propquery = NULL; +static int data_chunk_size; static int evp_test_process_mode(char *mode) { @@ -148,23 +152,42 @@ static void evp_test_buffer_free(EVP_TEST_BUFFER *db) } /* append buffer to a list */ -static int evp_test_buffer_append(const char *value, +static int evp_test_buffer_append(const char *value, size_t max_len, STACK_OF(EVP_TEST_BUFFER) **sk) { EVP_TEST_BUFFER *db = NULL; + int rv = 0; + size_t offset = 0; - if (!TEST_ptr(db = OPENSSL_malloc(sizeof(*db)))) + if (*sk == NULL && !TEST_ptr(*sk = sk_EVP_TEST_BUFFER_new_null())) goto err; - if (!parse_bin(value, &db->buf, &db->buflen)) - goto err; - db->count = 1; - db->count_set = 0; + do { + if (!TEST_ptr(db = OPENSSL_zalloc(sizeof(*db)))) + goto err; + if (max_len == 0) { + /* parse all in one shot */ + if ((rv = parse_bin(value, &db->buf, &db->buflen)) != 1) + goto err; + } else { + /* parse in chunks */ + size_t new_offset = 0; - if (*sk == NULL && !TEST_ptr(*sk = sk_EVP_TEST_BUFFER_new_null())) - goto err; - if (!sk_EVP_TEST_BUFFER_push(*sk, db)) - goto err; + if ((rv = parse_bin_chunk(value, offset, max_len, &db->buf, + &db->buflen, &new_offset)) == -1) + goto err; + offset = new_offset; + } + + db->count = 1; + db->count_set = 0; + + if (db->buf == NULL) + evp_test_buffer_free(db); + else if (db->buf != NULL && !sk_EVP_TEST_BUFFER_push(*sk, db)) + goto err; + /* if processing by chunks, continue until the whole value is parsed */ + } while (rv == 1 && max_len != 0); return 1; @@ -338,6 +361,66 @@ static int parse_bin(const char *value, unsigned char **buf, size_t *buflen) return 1; } +/* + * Convert at maximum "max" bytes to a binary allocated buffer. + * Return 1 on success, -1 on failure or 0 for end of value string. + */ +static int parse_bin_chunk(const char *value, size_t offset, size_t max, + unsigned char **buf, size_t *buflen, size_t *out_offset) +{ + size_t vlen; + size_t chunk_len; + const char *value_str = value[0] == '"' ? value + offset + 1 : value + offset; + + if (max < 1) + return -1; + + if (*value == '\0' || strcmp(value, "\"\"") == 0) { + *buf = OPENSSL_malloc(1); + if (*buf == NULL) + return 0; + **buf = 0; + *buflen = 0; + return 0; + } + + if (*value_str == '\0') + return 0; + + vlen = strlen(value_str); + if (value[0] == '"') { + /* Parse string literal */ + if (vlen == 1 && value_str[0] != '"') + /* Missing ending quotation mark */ + return -1; + if (vlen == 1 && value_str[0] == '"') + /* End of value */ + return 0; + vlen--; + chunk_len = max > vlen ? vlen : max; + if ((*buf = unescape(value_str, chunk_len, buflen)) == NULL) + return -1; + } else { + /* Parse hex string chunk */ + long len; + char *chunk = NULL; + + chunk_len = 2 * max > vlen ? vlen : 2 * max; + chunk = OPENSSL_strndup(value_str, chunk_len); + if (chunk == NULL) + return -1; + if (!TEST_ptr(*buf = OPENSSL_hexstr2buf(chunk, &len))) { + OPENSSL_free(chunk); + TEST_openssl_errors(); + return -1; + } + OPENSSL_free(chunk); + *buflen = len; + } + *out_offset = value[0] == '"' ? offset + (*buflen) : offset + 2 * (*buflen); + return 1; +} + /** ** MESSAGE DIGEST TESTS **/ @@ -401,7 +484,7 @@ static int digest_test_parse(EVP_TEST *t, DIGEST_DATA *mdata = t->data; if (strcmp(keyword, "Input") == 0) - return evp_test_buffer_append(value, &mdata->input); + return evp_test_buffer_append(value, data_chunk_size, &mdata->input); if (strcmp(keyword, "Output") == 0) return parse_bin(value, &mdata->output, &mdata->output_len); if (strcmp(keyword, "Count") == 0) @@ -599,6 +682,24 @@ typedef struct cipher_data_st { const char *xts_standard; } CIPHER_DATA; + +/* + * XTS, SIV, CCM, stitched ciphers and Wrap modes have special + * requirements about input lengths so we don't fragment for those + */ +static int cipher_test_valid_fragmentation(CIPHER_DATA *cdat) +{ + return (cdat->aead == EVP_CIPH_CCM_MODE + || cdat->aead == EVP_CIPH_CBC_MODE + || (cdat->aead == -1 + && EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_STREAM_CIPHER) + || ((EVP_CIPHER_get_flags(cdat->cipher) & EVP_CIPH_FLAG_CTS) != 0) + || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_SIV_MODE + || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_GCM_SIV_MODE + || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_XTS_MODE + || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_WRAP_MODE) ? 0 : 1; +} + static int cipher_test_init(EVP_TEST *t, const char *alg) { const EVP_CIPHER *cipher; @@ -639,6 +740,15 @@ static int cipher_test_init(EVP_TEST *t, const char *alg) else cdat->aead = 0; + if (data_chunk_size != 0 && !cipher_test_valid_fragmentation(cdat)) { + ERR_pop_to_mark(); + EVP_CIPHER_free(fetched_cipher); + OPENSSL_free(cdat); + t->skip = 1; + TEST_info("skipping, '%s' does not support fragmentation", alg); + return 1; + } + t->data = cdat; if (fetched_cipher != NULL) TEST_info("%s is fetched", alg); @@ -946,15 +1056,26 @@ static int cipher_test_enc(EVP_TEST *t, int enc, size_t out_misalign, if (expected->aad[0] != NULL && !expected->tls_aad) { t->err = "AAD_SET_ERROR"; if (!frag) { + /* Supply the data all in one go or according to data_chunk_size */ for (i = 0; expected->aad[i] != NULL; i++) { - if (!EVP_CipherUpdate(ctx, NULL, &chunklen, expected->aad[i], - expected->aad_len[i])) - goto err; + size_t aad_len = expected->aad_len[i]; + donelen = 0; + + do { + size_t current_aad_len = (size_t) data_chunk_size; + + if (data_chunk_size == 0 || (size_t) data_chunk_size > aad_len) + current_aad_len = aad_len; + if (!EVP_CipherUpdate(ctx, NULL, &chunklen, + expected->aad[i] + donelen, + current_aad_len)) + goto err; + donelen += current_aad_len; + aad_len -= current_aad_len; + } while (aad_len > 0); } } else { - /* - * Supply the AAD in chunks less than the block size where possible - */ + /* Supply the AAD in chunks less than the block size where possible */ for (i = 0; expected->aad[i] != NULL; i++) { if (expected->aad_len[i] > 0) { if (!EVP_CipherUpdate(ctx, NULL, &chunklen, expected->aad[i], 1)) @@ -1018,9 +1139,19 @@ static int cipher_test_enc(EVP_TEST *t, int enc, size_t out_misalign, t->err = "CIPHERUPDATE_ERROR"; tmplen = 0; if (!frag) { - /* We supply the data all in one go */ - if (!EVP_CipherUpdate(ctx, tmp + out_misalign, &tmplen, in, in_len)) - goto err; + do { + /* Supply the data all in one go or according to data_chunk_size */ + size_t current_in_len = (size_t) data_chunk_size; + + if (data_chunk_size == 0 || (size_t) data_chunk_size > in_len) + current_in_len = in_len; + if (!EVP_CipherUpdate(ctx, tmp + out_misalign + tmplen, &chunklen, + in, current_in_len)) + goto err; + tmplen += chunklen; + in += current_in_len; + in_len -= current_in_len; + } while (in_len > 0); } else { /* Supply the data in chunks less than the block size where possible */ if (in_len > 0) { @@ -1103,23 +1234,6 @@ static int cipher_test_enc(EVP_TEST *t, int enc, size_t out_misalign, return ok; } -/* - * XTS, SIV, CCM, stitched ciphers and Wrap modes have special - * requirements about input lengths so we don't fragment for those - */ -static int cipher_test_valid_fragmentation(CIPHER_DATA *cdat) -{ - return (cdat->aead == EVP_CIPH_CCM_MODE - || cdat->aead == EVP_CIPH_CBC_MODE - || (cdat->aead == -1 - && EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_STREAM_CIPHER) - || ((EVP_CIPHER_get_flags(cdat->cipher) & EVP_CIPH_FLAG_CTS) != 0) - || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_SIV_MODE - || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_GCM_SIV_MODE - || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_XTS_MODE - || EVP_CIPHER_get_mode(cdat->cipher) == EVP_CIPH_WRAP_MODE) ? 0 : 1; -} - static int cipher_test_run(EVP_TEST *t) { CIPHER_DATA *cdat = t->data; @@ -1153,6 +1267,8 @@ static int cipher_test_run(EVP_TEST *t) break; for (frag = 0; frag <= fragmax; frag++) { + if (frag == 1 && data_chunk_size != 0) + break; for (out_misalign = 0; out_misalign <= 1; out_misalign++) { for (inp_misalign = 0; inp_misalign <= 1; inp_misalign++) { /* Skip input misalign tests for in-place processing */ @@ -1410,6 +1526,7 @@ static int mac_test_run_pkey(EVP_TEST *t) unsigned char *got = NULL; size_t got_len; int i; + size_t input_len, donelen; /* We don't do XOF mode via PKEY */ if (expected->xof) @@ -1479,10 +1596,21 @@ static int mac_test_run_pkey(EVP_TEST *t) t->err = "EVPPKEYCTXCTRL_ERROR"; goto err; } - if (!EVP_DigestSignUpdate(mctx, expected->input, expected->input_len)) { - t->err = "DIGESTSIGNUPDATE_ERROR"; - goto err; - } + input_len = expected->input_len; + donelen = 0; + do { + size_t current_len = (size_t) data_chunk_size; + + if (data_chunk_size == 0 || (size_t) data_chunk_size > input_len) + current_len = input_len; + if (!EVP_DigestSignUpdate(mctx, expected->input + donelen, current_len)) { + t->err = "DIGESTSIGNUPDATE_ERROR"; + goto err; + } + donelen += current_len; + input_len -= current_len; + } while (input_len > 0); + if (!EVP_DigestSignFinal(mctx, NULL, &got_len)) { t->err = "DIGESTSIGNFINAL_LENGTH_ERROR"; goto err; @@ -1523,6 +1651,7 @@ static int mac_test_run_mac(EVP_TEST *t) EVP_MAC_settable_ctx_params(expected->mac); int xof; int reinit = 1; + size_t input_len, donelen ; if (expected->alg == NULL) TEST_info("Trying the EVP_MAC %s test", expected->mac_name); @@ -1669,10 +1798,21 @@ static int mac_test_run_mac(EVP_TEST *t) } } retry: - if (!EVP_MAC_update(ctx, expected->input, expected->input_len)) { - t->err = "MAC_UPDATE_ERROR"; - goto err; - } + input_len = expected->input_len; + donelen = 0; + do { + size_t current_len = (size_t) data_chunk_size; + + if (data_chunk_size == 0 || (size_t) data_chunk_size > input_len) + current_len = input_len; + if (!EVP_MAC_update(ctx, expected->input + donelen, current_len)) { + t->err = "MAC_UPDATE_ERROR"; + goto err; + } + donelen += current_len; + input_len -= current_len; + } while (input_len > 0); + xof = expected->xof; if (xof) { if (!TEST_ptr(got = OPENSSL_malloc(expected->output_len))) { @@ -2438,6 +2578,7 @@ static int encode_test_run(EVP_TEST *t) unsigned char *encode_out = NULL, *decode_out = NULL; int output_len, chunk_len; EVP_ENCODE_CTX *decode_ctx = NULL, *encode_ctx = NULL; + size_t input_len, donelen; if (!TEST_ptr(decode_ctx = EVP_ENCODE_CTX_new())) { t->err = "INTERNAL_ERROR"; @@ -2452,13 +2593,25 @@ static int encode_test_run(EVP_TEST *t) goto err; EVP_EncodeInit(encode_ctx); - if (!TEST_true(EVP_EncodeUpdate(encode_ctx, encode_out, &chunk_len, - expected->input, expected->input_len))) - goto err; - output_len = chunk_len; + input_len = expected->input_len; + donelen = 0; + output_len = 0; + do { + size_t current_len = (size_t) data_chunk_size; + + if (data_chunk_size == 0 || (size_t) data_chunk_size > input_len) + current_len = input_len; + if (!TEST_true(EVP_EncodeUpdate(encode_ctx, encode_out, &chunk_len, + expected->input + donelen, + current_len))) + goto err; + donelen += current_len; + input_len -= current_len; + output_len += chunk_len; + } while (input_len > 0); - EVP_EncodeFinal(encode_ctx, encode_out + chunk_len, &chunk_len); + EVP_EncodeFinal(encode_ctx, encode_out + output_len, &chunk_len); output_len += chunk_len; if (!memory_err_compare(t, "BAD_ENCODING", @@ -2471,15 +2624,27 @@ static int encode_test_run(EVP_TEST *t) OPENSSL_malloc(EVP_DECODE_LENGTH(expected->output_len)))) goto err; + output_len = 0; EVP_DecodeInit(decode_ctx); - if (EVP_DecodeUpdate(decode_ctx, decode_out, &chunk_len, expected->output, - expected->output_len) < 0) { - t->err = "DECODE_ERROR"; - goto err; - } - output_len = chunk_len; - if (EVP_DecodeFinal(decode_ctx, decode_out + chunk_len, &chunk_len) != 1) { + input_len = expected->output_len; + donelen = 0; + do { + size_t current_len = (size_t) data_chunk_size; + + if (data_chunk_size == 0 || (size_t) data_chunk_size > input_len) + current_len = input_len; + if (EVP_DecodeUpdate(decode_ctx, decode_out + output_len, &chunk_len, + expected->output + donelen, current_len) < 0) { + t->err = "DECODE_ERROR"; + goto err; + } + donelen += current_len; + input_len -= current_len; + output_len += chunk_len; + } while (input_len > 0); + + if (EVP_DecodeFinal(decode_ctx, decode_out + output_len, &chunk_len) != 1) { t->err = "DECODE_ERROR"; goto err; } @@ -3449,12 +3614,12 @@ static int digestsigver_test_parse(EVP_TEST *t, if (strcmp(keyword, "Input") == 0) { if (mdata->is_oneshot) return parse_bin(value, &mdata->osin, &mdata->osin_len); - return evp_test_buffer_append(value, &mdata->input); + return evp_test_buffer_append(value, data_chunk_size, &mdata->input); } if (strcmp(keyword, "Output") == 0) return parse_bin(value, &mdata->output, &mdata->output_len); - if (!mdata->is_oneshot) { + if (!mdata->is_oneshot && data_chunk_size == 0) { if (strcmp(keyword, "Count") == 0) return evp_test_buffer_set_count(value, mdata->input); if (strcmp(keyword, "Ncopy") == 0) @@ -4161,6 +4326,7 @@ const OPTIONS *test_get_options(void) "The provider to load (when no configuration file, the default value is 'default')" }, { "propquery", OPT_PROV_PROPQUERY, 's', "Property query used when fetching algorithms" }, + { "chunk", OPT_DATA_CHUNK, 'N', "Size of data chunks to be processed, 0 for default size"}, { OPT_HELP_STR, 1, '-', "file\tFile to run tests on.\n" }, { NULL } }; @@ -4182,6 +4348,8 @@ int setup_tests(void) break; case OPT_IN_PLACE: if ((process_mode_in_place = evp_test_process_mode(opt_arg())) == -1) + case OPT_DATA_CHUNK: + if (!opt_int(opt_arg(), &data_chunk_size)) return 0; break; case OPT_PROVIDER_NAME: diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t index 6a9792128be15..07014945a7d82 100644 --- a/test/recipes/80-test_cms.t +++ b/test/recipes/80-test_cms.t @@ -394,6 +394,13 @@ my @smime_cms_tests = ( "-out", "{output}.txt" ], \&final_compare ], + + [ "encrypted content test streaming PEM format -noout, 128 bit AES key", + [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM", + "-aes128", "-secretkey", "000102030405060708090A0B0C0D0E0F", + "-stream", "-noout" ], + [ "{cmd2}", @prov, "-help" ] + ], ); my @smime_cms_cades_tests = ( diff --git a/test/sslapitest.c b/test/sslapitest.c index b57ca8b113333..e948ae01a2a9c 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -10121,6 +10121,94 @@ static int test_ssl_dup(void) return testresult; } +static int secret_cb(SSL *s, void *secretin, int *secret_len, + STACK_OF(SSL_CIPHER) *peer_ciphers, + const SSL_CIPHER **cipher, void *arg) +{ + int i; + unsigned char *secret = secretin; + + /* Just use a fixed master secret */ + for (i = 0; i < *secret_len; i++) + secret[i] = 0xff; + + /* We don't set a preferred cipher */ + + return 1; +} + +/* + * Test the session_secret_cb which is designed for use with EAP-FAST + */ +static int test_session_secret_cb(void) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + SSL_SESSION *secret_sess = NULL; + int testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), + 0, + 0, + &sctx, &cctx, cert, privkey))) + goto end; + + /* Create an initial connection and save the session */ + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + /* session_secret_cb does not support TLSv1.3 */ + if (!TEST_true(SSL_set_min_proto_version(clientssl, TLS1_2_VERSION)) + || !TEST_true(SSL_set_max_proto_version(serverssl, TLS1_2_VERSION))) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + if (!TEST_ptr(secret_sess = SSL_get1_session(clientssl))) + goto end; + + shutdown_ssl_connection(serverssl, clientssl); + serverssl = clientssl = NULL; + + /* Resume the earlier session */ + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + /* + * No session ids for EAP-FAST - otherwise the state machine gets very + * confused. + */ + if (!TEST_true(SSL_SESSION_set1_id(secret_sess, NULL, 0))) + goto end; + + if (!TEST_true(SSL_set_min_proto_version(clientssl, TLS1_2_VERSION)) + || !TEST_true(SSL_set_max_proto_version(serverssl, TLS1_2_VERSION)) + || !TEST_true(SSL_set_session_secret_cb(serverssl, secret_cb, + NULL)) + || !TEST_true(SSL_set_session_secret_cb(clientssl, secret_cb, + NULL)) + || !TEST_true(SSL_set_session(clientssl, secret_sess))) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + testresult = 1; + + end: + SSL_SESSION_free(secret_sess); + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + # ifndef OPENSSL_NO_DH static EVP_PKEY *tmp_dh_params = NULL; @@ -12144,6 +12232,7 @@ int setup_tests(void) #endif #ifndef OPENSSL_NO_TLS1_2 ADD_TEST(test_ssl_dup); + ADD_TEST(test_session_secret_cb); # ifndef OPENSSL_NO_DH ADD_ALL_TESTS(test_set_tmp_dh, 11); ADD_ALL_TESTS(test_dh_auto, 7); diff --git a/test/testutil.h b/test/testutil.h index a247f55ed6b83..35fbdab84e85f 100644 --- a/test/testutil.h +++ b/test/testutil.h @@ -648,5 +648,5 @@ X509 *load_cert_pem(const char *file, OSSL_LIB_CTX *libctx); X509 *load_cert_der(const unsigned char *bytes, int len); STACK_OF(X509) *load_certs_pem(const char *file); X509_REQ *load_csr_der(const char *file, OSSL_LIB_CTX *libctx); - +time_t test_asn1_string_to_time_t(const char *asn1_string); #endif /* OSSL_TESTUTIL_H */ diff --git a/test/testutil/helper.c b/test/testutil/helper.c new file mode 100644 index 0000000000000..8da42b0facdb7 --- /dev/null +++ b/test/testutil/helper.c @@ -0,0 +1,90 @@ +/* + * Copyright 2020-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 +#include +#include +#include "../testutil.h" + +/* + * tweak for Windows + */ +#ifdef WIN32 +# define timezone _timezone +#endif + +#if defined(__FreeBSD__) || defined(__wasi__) +# define USE_TIMEGM +#endif + +time_t test_asn1_string_to_time_t(const char *asn1_string) +{ + ASN1_TIME *timestamp_asn1 = NULL; + struct tm *timestamp_tm = NULL; +#if defined(__DJGPP__) + char *tz = NULL; +#elif !defined(USE_TIMEGM) + time_t timestamp_local; +#endif + time_t timestamp_utc; + + timestamp_asn1 = ASN1_TIME_new(); + if(timestamp_asn1 == NULL) + return -1; + if (!ASN1_TIME_set_string(timestamp_asn1, asn1_string)) + { + ASN1_TIME_free(timestamp_asn1); + return -1; + } + + timestamp_tm = OPENSSL_malloc(sizeof(*timestamp_tm)); + if (timestamp_tm == NULL) { + ASN1_TIME_free(timestamp_asn1); + return -1; + } + if (!(ASN1_TIME_to_tm(timestamp_asn1, timestamp_tm))) { + OPENSSL_free(timestamp_tm); + ASN1_TIME_free(timestamp_asn1); + return -1; + } + ASN1_TIME_free(timestamp_asn1); + +#if defined(__DJGPP__) + /* + * This is NOT thread-safe. Do not use this method for platforms other + * than djgpp. + */ + tz = getenv("TZ"); + if (tz != NULL) { + tz = OPENSSL_strdup(tz); + if (tz == NULL) { + OPENSSL_free(timestamp_tm); + return -1; + } + } + setenv("TZ", "UTC", 1); + + timestamp_utc = mktime(timestamp_tm); + + if (tz != NULL) { + setenv("TZ", tz, 1); + OPENSSL_free(tz); + } else { + unsetenv("TZ"); + } +#elif defined(USE_TIMEGM) + timestamp_utc = timegm(timestamp_tm); +#else + timestamp_local = mktime(timestamp_tm); + timestamp_utc = timestamp_local - timezone; +#endif + OPENSSL_free(timestamp_tm); + + return timestamp_utc; +} diff --git a/test/threadstest.c b/test/threadstest.c index 0e42d63e10f94..9a961bb5c4cc3 100644 --- a/test/threadstest.c +++ b/test/threadstest.c @@ -90,6 +90,9 @@ static int test_lock(void) CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new(); int res; + if (!TEST_ptr(lock)) + return 0; + res = TEST_true(CRYPTO_THREAD_read_lock(lock)) && TEST_true(CRYPTO_THREAD_unlock(lock)) && TEST_true(CRYPTO_THREAD_write_lock(lock)) @@ -225,6 +228,9 @@ static int _torture_rw(void) rwtorturelock = CRYPTO_THREAD_lock_new(); atomiclock = CRYPTO_THREAD_lock_new(); + if (!TEST_ptr(rwtorturelock) || !TEST_ptr(atomiclock)) + goto out; + rwwriter1_iterations = 0; rwwriter2_iterations = 0; rwreader1_iterations = 0; @@ -413,6 +419,9 @@ static int _torture_rcu(void) int rc = 0; atomiclock = CRYPTO_THREAD_lock_new(); + if (!TEST_ptr(atomiclock)) + goto out; + memset(&writer1, 0, sizeof(thread_t)); memset(&writer2, 0, sizeof(thread_t)); memset(&reader1, 0, sizeof(thread_t)); @@ -427,6 +436,8 @@ static int _torture_rcu(void) rcu_torture_result = 1; rcu_lock = ossl_rcu_lock_new(1, NULL); + if (!rcu_lock) + goto out; TEST_info("Staring rcu torture"); t1 = ossl_time_now(); diff --git a/test/v3ext.c b/test/v3ext.c index 3cd6ee6907f36..5ebdef2ebe996 100644 --- a/test/v3ext.c +++ b/test/v3ext.c @@ -269,17 +269,20 @@ static int test_addr_fam_len(void) goto end; if (!ASN1_OCTET_STRING_set(f1->addressFamily, key, keylen)) goto end; + + /* Push and transfer memory ownership to stack */ if (!sk_IPAddressFamily_push(addr, f1)) goto end; + f1 = NULL; /* Shouldn't be able to canonize this as the len is > 3*/ if (!TEST_false(X509v3_addr_canonize(addr))) goto end; - /* Create a well formed IPAddressFamily */ - f1 = sk_IPAddressFamily_pop(addr); - IPAddressFamily_free(f1); + /* Pop and free the new stack element */ + IPAddressFamily_free(sk_IPAddressFamily_pop(addr)); + /* Create a well-formed IPAddressFamily */ key[0] = (afi >> 8) & 0xFF; key[1] = afi & 0xFF; key[2] = 0x1; @@ -297,8 +300,11 @@ static int test_addr_fam_len(void) /* Mark this as inheritance so we skip some of the is_canonize checks */ f1->ipAddressChoice->type = IPAddressChoice_inherit; + + /* Push and transfer memory ownership to stack */ if (!sk_IPAddressFamily_push(addr, f1)) goto end; + f1 = NULL; /* Should be able to canonize now */ if (!TEST_true(X509v3_addr_canonize(addr))) @@ -306,7 +312,10 @@ static int test_addr_fam_len(void) testresult = 1; end: + /* Free stack and any memory owned by detached element */ + IPAddressFamily_free(f1); sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); + ASN1_OCTET_STRING_free(ip1); ASN1_OCTET_STRING_free(ip2); return testresult; diff --git a/util/missingssl.txt b/util/missingssl.txt index 1338feed71188..8da9842a0b57d 100644 --- a/util/missingssl.txt +++ b/util/missingssl.txt @@ -25,7 +25,6 @@ SSL_get_peer_finished(3) SSL_set_SSL_CTX(3) SSL_set_debug(3) SSL_set_not_resumable_session_callback(3) -SSL_set_session_secret_cb(3) SSL_set_session_ticket_ext(3) SSL_set_session_ticket_ext_cb(3) SSL_srp_server_param_with_username(3) diff --git a/util/other.syms b/util/other.syms index df47478f5207c..6bffe6bf186f9 100644 --- a/util/other.syms +++ b/util/other.syms @@ -145,6 +145,7 @@ custom_ext_free_cb datatype custom_ext_parse_cb datatype pem_password_cb datatype ssl_ct_validation_cb datatype +tls_session_secret_cb_fn datatype ASYNC_stack_alloc_fn datatype ASYNC_stack_free_fn datatype PKCS12_create_cb datatype