From c370c2596bb544ebe5df71f0b52669643cebff1c Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Tue, 9 Sep 2025 14:59:14 +0200 Subject: [PATCH] Remove top-level engines dir. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Milan Broz Reviewed-by: Neil Horman Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz Reviewed-by: SaÅ¡a Nedvědický Reviewed-by: Eugene Syromiatnikov Reviewed-by: Norbert Pocs (Merged from https://github.com/openssl/openssl/pull/29305) --- Configurations/unix-Makefile.tmpl | 7 - Configure | 1 - build.info | 3 - engines/asm/e_padlock-x86.pl | 628 ---------- engines/asm/e_padlock-x86_64.pl | 587 --------- engines/build.info | 103 -- engines/e_afalg.c | 935 -------------- engines/e_afalg.ec | 3 - engines/e_afalg.h | 95 -- engines/e_afalg.txt | 22 - engines/e_afalg_err.c | 72 -- engines/e_afalg_err.h | 39 - engines/e_capi.c | 1910 ----------------------------- engines/e_capi.ec | 3 - engines/e_capi.txt | 40 - engines/e_capi_err.c | 101 -- engines/e_capi_err.h | 57 - engines/e_dasync.c | 994 --------------- engines/e_dasync.ec | 3 - engines/e_dasync.txt | 9 - engines/e_dasync_err.c | 56 - engines/e_dasync_err.h | 27 - engines/e_devcrypto.c | 1361 -------------------- engines/e_loader_attic.c | 1717 -------------------------- engines/e_loader_attic.ec | 3 - engines/e_loader_attic.txt | 21 - engines/e_loader_attic_err.c | 73 -- engines/e_loader_attic_err.h | 37 - engines/e_ossltest.c | 914 -------------- engines/e_ossltest.ec | 3 - engines/e_ossltest.txt | 9 - engines/e_ossltest_err.c | 56 - engines/e_ossltest_err.h | 27 - engines/e_padlock.c | 727 ----------- 34 files changed, 10643 deletions(-) delete mode 100644 engines/asm/e_padlock-x86.pl delete mode 100644 engines/asm/e_padlock-x86_64.pl delete mode 100644 engines/build.info delete mode 100644 engines/e_afalg.c delete mode 100644 engines/e_afalg.ec delete mode 100644 engines/e_afalg.h delete mode 100644 engines/e_afalg.txt delete mode 100644 engines/e_afalg_err.c delete mode 100644 engines/e_afalg_err.h delete mode 100644 engines/e_capi.c delete mode 100644 engines/e_capi.ec delete mode 100644 engines/e_capi.txt delete mode 100644 engines/e_capi_err.c delete mode 100644 engines/e_capi_err.h delete mode 100644 engines/e_dasync.c delete mode 100644 engines/e_dasync.ec delete mode 100644 engines/e_dasync.txt delete mode 100644 engines/e_dasync_err.c delete mode 100644 engines/e_dasync_err.h delete mode 100644 engines/e_devcrypto.c delete mode 100644 engines/e_loader_attic.c delete mode 100644 engines/e_loader_attic.ec delete mode 100644 engines/e_loader_attic.txt delete mode 100644 engines/e_loader_attic_err.c delete mode 100644 engines/e_loader_attic_err.h delete mode 100644 engines/e_ossltest.c delete mode 100644 engines/e_ossltest.ec delete mode 100644 engines/e_ossltest.txt delete mode 100644 engines/e_ossltest_err.c delete mode 100644 engines/e_ossltest_err.h delete mode 100644 engines/e_padlock.c diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl index 25c637c2ec6..d9c4f319a97 100644 --- a/Configurations/unix-Makefile.tmpl +++ b/Configurations/unix-Makefile.tmpl @@ -1295,13 +1295,6 @@ errors: ( b=`pwd`; set -e; cd $(SRCDIR); \ $(PERL) util/ck_errf.pl -strict -internal; \ $(PERL) -I$$b util/mkerr.pl $(ERROR_REBUILD) -internal ) - ( b=`pwd`; set -e; cd $(SRCDIR)/engines; \ - for E in *.ec ; do \ - $(PERL) ../util/ck_errf.pl -strict \ - -conf $$E `basename $$E .ec`.c; \ - $(PERL) -I$$b ../util/mkerr.pl $(ERROR_REBUILD) -static \ - -conf $$E `basename $$E .ec`.c ; \ - done ) {- use File::Basename; diff --git a/Configure b/Configure index 37cc8f21635..adbd3230c1f 100755 --- a/Configure +++ b/Configure @@ -1955,7 +1955,6 @@ foreach my $what (sort keys %disabled) { my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT"; push @{$config{openssl_feature_defines}}, $macro; - $skipdir{engines} = $what if $what eq 'engine'; $skipdir{"crypto/$skipdir"} = $what unless $what eq 'async' || $what eq 'err' || $what eq 'dso' || $what eq 'http'; } diff --git a/build.info b/build.info index e3115da36d3..1faec4d8de0 100644 --- a/build.info +++ b/build.info @@ -8,9 +8,6 @@ ENDIF IF[{- !$disabled{demos} -}] SUBDIRS=demos ENDIF -IF[{- !$disabled{'deprecated-3.0'} -}] - SUBDIRS=engines -ENDIF SUBDIRS=exporters LIBS=libcrypto libssl diff --git a/engines/asm/e_padlock-x86.pl b/engines/asm/e_padlock-x86.pl deleted file mode 100644 index 18dab8ffee6..00000000000 --- a/engines/asm/e_padlock-x86.pl +++ /dev/null @@ -1,628 +0,0 @@ -#! /usr/bin/env perl -# Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved. -# -# Licensed under the Apache License 2.0 (the "License"). You may not use -# this file except in compliance with the License. You can obtain a copy -# in the file LICENSE in the source distribution or at -# https://www.openssl.org/source/license.html - - -# ==================================================================== -# Written by Andy Polyakov, @dot-asm, initially for use in the OpenSSL -# project. The module is, however, dual licensed under OpenSSL and -# CRYPTOGAMS licenses depending on where you obtain it. For further -# details see https://github.com/dot-asm/cryptogams/. -# ==================================================================== - -# September 2011 -# -# Assembler helpers for Padlock engine. Compared to original engine -# version relying on inline assembler and compiled with gcc 3.4.6 it -# was measured to provide ~100% improvement on misaligned data in ECB -# mode and ~75% in CBC mode. For aligned data improvement can be -# observed for short inputs only, e.g. 45% for 64-byte messages in -# ECB mode, 20% in CBC. Difference in performance for aligned vs. -# misaligned data depends on misalignment and is either ~1.8x or 2.9x. -# These are approximately same factors as for hardware support, so -# there is little reason to rely on the latter. On the contrary, it -# might actually hurt performance in mixture of aligned and misaligned -# buffers, because a) if you choose to flip 'align' flag in control -# word on per-buffer basis, then you'd have to reload key context, -# which incurs penalty; b) if you choose to set 'align' flag -# permanently, it limits performance even for aligned data to ~1/2. -# All above mentioned results were collected on 1.5GHz C7. Nano on the -# other hand handles unaligned data more gracefully. Depending on -# algorithm and how unaligned data is, hardware can be up to 70% more -# efficient than below software alignment procedures, nor does 'align' -# flag have affect on aligned performance [if has any meaning at all]. -# Therefore suggestion is to unconditionally set 'align' flag on Nano -# for optimal performance. - -$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -push(@INC,"${dir}","${dir}../../crypto/perlasm"); -require "x86asm.pl"; - -$output=pop and open STDOUT,">$output"; - -&asm_init($ARGV[0]); - -%PADLOCK_PREFETCH=(ecb=>128, cbc=>64); # prefetch errata -$PADLOCK_CHUNK=512; # Must be a power of 2 larger than 16 - -$ctx="edx"; -$out="edi"; -$inp="esi"; -$len="ecx"; -$chunk="ebx"; - -&function_begin_B("padlock_capability"); - &push ("ebx"); - &pushf (); - &pop ("eax"); - &mov ("ecx","eax"); - &xor ("eax",1<<21); - &push ("eax"); - &popf (); - &pushf (); - &pop ("eax"); - &xor ("ecx","eax"); - &xor ("eax","eax"); - &bt ("ecx",21); - &jnc (&label("noluck")); - &cpuid (); - &xor ("eax","eax"); - &cmp ("ebx","0x".unpack("H*",'tneC')); - &jne (&label("zhaoxin")); - &cmp ("edx","0x".unpack("H*",'Hrua')); - &jne (&label("noluck")); - &cmp ("ecx","0x".unpack("H*",'slua')); - &jne (&label("noluck")); - &jmp (&label("zhaoxinEnd")); -&set_label("zhaoxin"); - &cmp ("ebx","0x".unpack("H*",'hS ')); - &jne (&label("noluck")); - &cmp ("edx","0x".unpack("H*",'hgna')); - &jne (&label("noluck")); - &cmp ("ecx","0x".unpack("H*",' ia')); - &jne (&label("noluck")); -&set_label("zhaoxinEnd"); - &mov ("eax",0xC0000000); - &cpuid (); - &mov ("edx","eax"); - &xor ("eax","eax"); - &cmp ("edx",0xC0000001); - &jb (&label("noluck")); - &mov ("eax",1); - &cpuid (); - &or ("eax",0x0f); - &xor ("ebx","ebx"); - &and ("eax",0x0fff); - &cmp ("eax",0x06ff); # check for Nano - &sete ("bl"); - &mov ("eax",0xC0000001); - &push ("ebx"); - &cpuid (); - &pop ("ebx"); - &mov ("eax","edx"); - &shl ("ebx",4); # bit#4 denotes Nano - &and ("eax",0xffffffef); - &or ("eax","ebx") -&set_label("noluck"); - &pop ("ebx"); - &ret (); -&function_end_B("padlock_capability") - -&function_begin_B("padlock_key_bswap"); - &mov ("edx",&wparam(0)); - &mov ("ecx",&DWP(240,"edx")); - &inc ("ecx"); - &shl ("ecx",2); -&set_label("bswap_loop"); - &mov ("eax",&DWP(0,"edx")); - &bswap ("eax"); - &mov (&DWP(0,"edx"),"eax"); - &lea ("edx",&DWP(4,"edx")); - &sub ("ecx",1); - &jnz (&label("bswap_loop")); - &ret (); -&function_end_B("padlock_key_bswap"); - -# This is heuristic key context tracing. At first one -# believes that one should use atomic swap instructions, -# but it's not actually necessary. Point is that if -# padlock_saved_context was changed by another thread -# after we've read it and before we compare it with ctx, -# our key *shall* be reloaded upon thread context switch -# and we are therefore set in either case... -&static_label("padlock_saved_context"); - -&function_begin_B("padlock_verify_context"); - &mov ($ctx,&wparam(0)); - &lea ("eax",($::win32 or $::coff) ? &DWP(&label("padlock_saved_context")) : - &DWP(&label("padlock_saved_context")."-".&label("verify_pic_point"))); - &pushf (); - &call ("_padlock_verify_ctx"); -&set_label("verify_pic_point"); - &lea ("esp",&DWP(4,"esp")); - &ret (); -&function_end_B("padlock_verify_context"); - -&function_begin_B("_padlock_verify_ctx"); - &add ("eax",&DWP(0,"esp")) if(!($::win32 or $::coff));# &padlock_saved_context - &bt (&DWP(4,"esp"),30); # eflags - &jnc (&label("verified")); - &cmp ($ctx,&DWP(0,"eax")); - &je (&label("verified")); - &pushf (); - &popf (); -&set_label("verified"); - &mov (&DWP(0,"eax"),$ctx); - &ret (); -&function_end_B("_padlock_verify_ctx"); - -&function_begin_B("padlock_reload_key"); - &pushf (); - &popf (); - &ret (); -&function_end_B("padlock_reload_key"); - -&function_begin_B("padlock_aes_block"); - &push ("edi"); - &push ("esi"); - &push ("ebx"); - &mov ($out,&wparam(0)); # must be 16-byte aligned - &mov ($inp,&wparam(1)); # must be 16-byte aligned - &mov ($ctx,&wparam(2)); - &mov ($len,1); - &lea ("ebx",&DWP(32,$ctx)); # key - &lea ($ctx,&DWP(16,$ctx)); # control word - &data_byte(0xf3,0x0f,0xa7,0xc8); # rep xcryptecb - &pop ("ebx"); - &pop ("esi"); - &pop ("edi"); - &ret (); -&function_end_B("padlock_aes_block"); - -sub generate_mode { -my ($mode,$opcode) = @_; -# int padlock_$mode_encrypt(void *out, const void *inp, -# struct padlock_cipher_data *ctx, size_t len); -&function_begin("padlock_${mode}_encrypt"); - &mov ($out,&wparam(0)); - &mov ($inp,&wparam(1)); - &mov ($ctx,&wparam(2)); - &mov ($len,&wparam(3)); - &test ($ctx,15); - &jnz (&label("${mode}_abort")); - &test ($len,15); - &jnz (&label("${mode}_abort")); - &lea ("eax",($::win32 or $::coff) ? &DWP(&label("padlock_saved_context")) : - &DWP(&label("padlock_saved_context")."-".&label("${mode}_pic_point"))); - &pushf (); - &cld (); - &call ("_padlock_verify_ctx"); -&set_label("${mode}_pic_point"); - &lea ($ctx,&DWP(16,$ctx)); # control word - &xor ("eax","eax"); - if ($mode eq "ctr32") { - &movq ("mm0",&QWP(-16,$ctx)); # load [upper part of] counter - } else { - &xor ("ebx","ebx"); - &test (&DWP(0,$ctx),1<<5); # align bit in control word - &jnz (&label("${mode}_aligned")); - &test ($out,0x0f); - &setz ("al"); # !out_misaligned - &test ($inp,0x0f); - &setz ("bl"); # !inp_misaligned - &test ("eax","ebx"); - &jnz (&label("${mode}_aligned")); - &neg ("eax"); - } - &mov ($chunk,$PADLOCK_CHUNK); - ¬ ("eax"); # out_misaligned?-1:0 - &lea ("ebp",&DWP(-24,"esp")); - &cmp ($len,$chunk); - &cmovc ($chunk,$len); # chunk=len>PADLOCK_CHUNK?PADLOCK_CHUNK:len - &and ("eax",$chunk); # out_misaligned?chunk:0 - &mov ($chunk,$len); - &neg ("eax"); - &and ($chunk,$PADLOCK_CHUNK-1); # chunk=len%PADLOCK_CHUNK - &lea ("esp",&DWP(0,"eax","ebp")); # alloca - &mov ("eax",$PADLOCK_CHUNK); - &cmovz ($chunk,"eax"); # chunk=chunk?:PADLOCK_CHUNK - &mov ("eax","ebp"); - &and ("ebp",-16); - &and ("esp",-16); - &mov (&DWP(16,"ebp"),"eax"); - if ($PADLOCK_PREFETCH{$mode}) { - &cmp ($len,$chunk); - &ja (&label("${mode}_loop")); - &mov ("eax",$inp); # check if prefetch crosses page - &cmp ("ebp","esp"); - &cmove ("eax",$out); - &add ("eax",$len); - &neg ("eax"); - &and ("eax",0xfff); # distance to page boundary - &cmp ("eax",$PADLOCK_PREFETCH{$mode}); - &mov ("eax",-$PADLOCK_PREFETCH{$mode}); - &cmovae ("eax",$chunk); # mask=distanceExceptionCode == STATUS_ACCESS_VIOLATION - &jne (&label("ret")); - &add (&DWP(184,"ecx"),4); # skip over rep sha* - &mov ("eax",0); # ExceptionContinueExecution -&set_label("ret"); - &ret (); -&function_end_B("_win32_segv_handler"); -&safeseh("_win32_segv_handler") if ($::win32); - -&function_begin_B("padlock_sha1_oneshot"); - &push ("edi"); - &push ("esi"); - &xor ("eax","eax"); - &mov ("edi",&wparam(0)); - &mov ("esi",&wparam(1)); - &mov ("ecx",&wparam(2)); - if ($::win32 or $::coff) { - &push (&::islabel("_win32_segv_handler")); - &data_byte(0x64,0xff,0x30); # push %fs:(%eax) - &data_byte(0x64,0x89,0x20); # mov %esp,%fs:(%eax) - } - &mov ("edx","esp"); # put aside %esp - &add ("esp",-128); # 32 is enough but spec says 128 - &movups ("xmm0",&QWP(0,"edi")); # copy-in context - &and ("esp",-16); - &mov ("eax",&DWP(16,"edi")); - &movaps (&QWP(0,"esp"),"xmm0"); - &mov ("edi","esp"); - &mov (&DWP(16,"esp"),"eax"); - &xor ("eax","eax"); - &data_byte(0xf3,0x0f,0xa6,0xc8); # rep xsha1 - &movaps ("xmm0",&QWP(0,"esp")); - &mov ("eax",&DWP(16,"esp")); - &mov ("esp","edx"); # restore %esp - if ($::win32 or $::coff) { - &data_byte(0x64,0x8f,0x05,0,0,0,0); # pop %fs:0 - &lea ("esp",&DWP(4,"esp")); - } - &mov ("edi",&wparam(0)); - &movups (&QWP(0,"edi"),"xmm0"); # copy-out context - &mov (&DWP(16,"edi"),"eax"); - &pop ("esi"); - &pop ("edi"); - &ret (); -&function_end_B("padlock_sha1_oneshot"); - -&function_begin_B("padlock_sha1_blocks"); - &push ("edi"); - &push ("esi"); - &mov ("edi",&wparam(0)); - &mov ("esi",&wparam(1)); - &mov ("edx","esp"); # put aside %esp - &mov ("ecx",&wparam(2)); - &add ("esp",-128); - &movups ("xmm0",&QWP(0,"edi")); # copy-in context - &and ("esp",-16); - &mov ("eax",&DWP(16,"edi")); - &movaps (&QWP(0,"esp"),"xmm0"); - &mov ("edi","esp"); - &mov (&DWP(16,"esp"),"eax"); - &mov ("eax",-1); - &data_byte(0xf3,0x0f,0xa6,0xc8); # rep xsha1 - &movaps ("xmm0",&QWP(0,"esp")); - &mov ("eax",&DWP(16,"esp")); - &mov ("esp","edx"); # restore %esp - &mov ("edi",&wparam(0)); - &movups (&QWP(0,"edi"),"xmm0"); # copy-out context - &mov (&DWP(16,"edi"),"eax"); - &pop ("esi"); - &pop ("edi"); - &ret (); -&function_end_B("padlock_sha1_blocks"); - -&function_begin_B("padlock_sha256_oneshot"); - &push ("edi"); - &push ("esi"); - &xor ("eax","eax"); - &mov ("edi",&wparam(0)); - &mov ("esi",&wparam(1)); - &mov ("ecx",&wparam(2)); - if ($::win32 or $::coff) { - &push (&::islabel("_win32_segv_handler")); - &data_byte(0x64,0xff,0x30); # push %fs:(%eax) - &data_byte(0x64,0x89,0x20); # mov %esp,%fs:(%eax) - } - &mov ("edx","esp"); # put aside %esp - &add ("esp",-128); - &movups ("xmm0",&QWP(0,"edi")); # copy-in context - &and ("esp",-16); - &movups ("xmm1",&QWP(16,"edi")); - &movaps (&QWP(0,"esp"),"xmm0"); - &mov ("edi","esp"); - &movaps (&QWP(16,"esp"),"xmm1"); - &xor ("eax","eax"); - &data_byte(0xf3,0x0f,0xa6,0xd0); # rep xsha256 - &movaps ("xmm0",&QWP(0,"esp")); - &movaps ("xmm1",&QWP(16,"esp")); - &mov ("esp","edx"); # restore %esp - if ($::win32 or $::coff) { - &data_byte(0x64,0x8f,0x05,0,0,0,0); # pop %fs:0 - &lea ("esp",&DWP(4,"esp")); - } - &mov ("edi",&wparam(0)); - &movups (&QWP(0,"edi"),"xmm0"); # copy-out context - &movups (&QWP(16,"edi"),"xmm1"); - &pop ("esi"); - &pop ("edi"); - &ret (); -&function_end_B("padlock_sha256_oneshot"); - -&function_begin_B("padlock_sha256_blocks"); - &push ("edi"); - &push ("esi"); - &mov ("edi",&wparam(0)); - &mov ("esi",&wparam(1)); - &mov ("ecx",&wparam(2)); - &mov ("edx","esp"); # put aside %esp - &add ("esp",-128); - &movups ("xmm0",&QWP(0,"edi")); # copy-in context - &and ("esp",-16); - &movups ("xmm1",&QWP(16,"edi")); - &movaps (&QWP(0,"esp"),"xmm0"); - &mov ("edi","esp"); - &movaps (&QWP(16,"esp"),"xmm1"); - &mov ("eax",-1); - &data_byte(0xf3,0x0f,0xa6,0xd0); # rep xsha256 - &movaps ("xmm0",&QWP(0,"esp")); - &movaps ("xmm1",&QWP(16,"esp")); - &mov ("esp","edx"); # restore %esp - &mov ("edi",&wparam(0)); - &movups (&QWP(0,"edi"),"xmm0"); # copy-out context - &movups (&QWP(16,"edi"),"xmm1"); - &pop ("esi"); - &pop ("edi"); - &ret (); -&function_end_B("padlock_sha256_blocks"); - -&function_begin_B("padlock_sha512_blocks"); - &push ("edi"); - &push ("esi"); - &mov ("edi",&wparam(0)); - &mov ("esi",&wparam(1)); - &mov ("ecx",&wparam(2)); - &mov ("edx","esp"); # put aside %esp - &add ("esp",-128); - &movups ("xmm0",&QWP(0,"edi")); # copy-in context - &and ("esp",-16); - &movups ("xmm1",&QWP(16,"edi")); - &movups ("xmm2",&QWP(32,"edi")); - &movups ("xmm3",&QWP(48,"edi")); - &movaps (&QWP(0,"esp"),"xmm0"); - &mov ("edi","esp"); - &movaps (&QWP(16,"esp"),"xmm1"); - &movaps (&QWP(32,"esp"),"xmm2"); - &movaps (&QWP(48,"esp"),"xmm3"); - &data_byte(0xf3,0x0f,0xa6,0xe0); # rep xsha512 - &movaps ("xmm0",&QWP(0,"esp")); - &movaps ("xmm1",&QWP(16,"esp")); - &movaps ("xmm2",&QWP(32,"esp")); - &movaps ("xmm3",&QWP(48,"esp")); - &mov ("esp","edx"); # restore %esp - &mov ("edi",&wparam(0)); - &movups (&QWP(0,"edi"),"xmm0"); # copy-out context - &movups (&QWP(16,"edi"),"xmm1"); - &movups (&QWP(32,"edi"),"xmm2"); - &movups (&QWP(48,"edi"),"xmm3"); - &pop ("esi"); - &pop ("edi"); - &ret (); -&function_end_B("padlock_sha512_blocks"); - -&asciz ("VIA Padlock x86 module, CRYPTOGAMS by "); -&align (16); - -&dataseg(); -# Essentially this variable belongs in thread local storage. -# Having this variable global on the other hand can only cause -# few bogus key reloads [if any at all on signle-CPU system], -# so we accept the penalty... -&set_label("padlock_saved_context",4); -&data_word(0); - -&asm_finish(); - -close STDOUT; diff --git a/engines/asm/e_padlock-x86_64.pl b/engines/asm/e_padlock-x86_64.pl deleted file mode 100644 index 651af734191..00000000000 --- a/engines/asm/e_padlock-x86_64.pl +++ /dev/null @@ -1,587 +0,0 @@ -#! /usr/bin/env perl -# Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved. -# -# Licensed under the Apache License 2.0 (the "License"). You may not use -# this file except in compliance with the License. You can obtain a copy -# in the file LICENSE in the source distribution or at -# https://www.openssl.org/source/license.html - - -# ==================================================================== -# Written by Andy Polyakov, @dot-asm, initially for use in the OpenSSL -# project. The module is, however, dual licensed under OpenSSL and -# CRYPTOGAMS licenses depending on where you obtain it. For further -# details see https://github.com/dot-asm/cryptogams/. -# ==================================================================== - -# September 2011 -# -# Assembler helpers for Padlock engine. See even e_padlock-x86.pl for -# details. - -# $output is the last argument if it looks like a file (it has an extension) -# $flavour is the first argument if it doesn't look like a file -$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; -$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; - -$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); - -$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or -( $xlate="${dir}../../crypto/perlasm/x86_64-xlate.pl" and -f $xlate) or -die "can't locate x86_64-xlate.pl"; - -open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" - or die "can't call $xlate: $!"; -*STDOUT=*OUT; - -$code=".text\n"; - -%PADLOCK_PREFETCH=(ecb=>128, cbc=>64, ctr32=>32); # prefetch errata -$PADLOCK_CHUNK=512; # Must be a power of 2 between 32 and 2^20 - -$ctx="%rdx"; -$out="%rdi"; -$inp="%rsi"; -$len="%rcx"; -$chunk="%rbx"; - -($arg1,$arg2,$arg3,$arg4)=$win64?("%rcx","%rdx","%r8", "%r9") : # Win64 order - ("%rdi","%rsi","%rdx","%rcx"); # Unix order - -$code.=<<___; -.globl padlock_capability -.type padlock_capability,\@abi-omnipotent -.align 16 -padlock_capability: - mov %rbx,%r8 - xor %eax,%eax - cpuid - xor %eax,%eax - cmp \$`"0x".unpack("H*",'tneC')`,%ebx - jne .Lzhaoxin - cmp \$`"0x".unpack("H*",'Hrua')`,%edx - jne .Lnoluck - cmp \$`"0x".unpack("H*",'slua')`,%ecx - jne .Lnoluck - jmp .LzhaoxinEnd -.Lzhaoxin: - cmp \$`"0x".unpack("H*",'hS ')`,%ebx - jne .Lnoluck - cmp \$`"0x".unpack("H*",'hgna')`,%edx - jne .Lnoluck - cmp \$`"0x".unpack("H*",' ia')`,%ecx - jne .Lnoluck -.LzhaoxinEnd: - mov \$0xC0000000,%eax - cpuid - mov %eax,%edx - xor %eax,%eax - cmp \$0xC0000001,%edx - jb .Lnoluck - mov \$0xC0000001,%eax - cpuid - mov %edx,%eax - and \$0xffffffef,%eax - or \$0x10,%eax # set Nano bit#4 -.Lnoluck: - mov %r8,%rbx - ret -.size padlock_capability,.-padlock_capability - -.globl padlock_key_bswap -.type padlock_key_bswap,\@abi-omnipotent,0 -.align 16 -padlock_key_bswap: - mov 240($arg1),%edx - inc %edx - shl \$2,%edx -.Lbswap_loop: - mov ($arg1),%eax - bswap %eax - mov %eax,($arg1) - lea 4($arg1),$arg1 - sub \$1,%edx - jnz .Lbswap_loop - ret -.size padlock_key_bswap,.-padlock_key_bswap - -.globl padlock_verify_context -.type padlock_verify_context,\@abi-omnipotent -.align 16 -padlock_verify_context: - mov $arg1,$ctx - pushf - lea .Lpadlock_saved_context(%rip),%rax - call _padlock_verify_ctx - lea 8(%rsp),%rsp - ret -.size padlock_verify_context,.-padlock_verify_context - -.type _padlock_verify_ctx,\@abi-omnipotent -.align 16 -_padlock_verify_ctx: - mov 8(%rsp),%r8 - bt \$30,%r8 - jnc .Lverified - cmp (%rax),$ctx - je .Lverified - pushf - popf -.Lverified: - mov $ctx,(%rax) - ret -.size _padlock_verify_ctx,.-_padlock_verify_ctx - -.globl padlock_reload_key -.type padlock_reload_key,\@abi-omnipotent -.align 16 -padlock_reload_key: - pushf - popf - ret -.size padlock_reload_key,.-padlock_reload_key - -.globl padlock_aes_block -.type padlock_aes_block,\@function,3 -.align 16 -padlock_aes_block: - mov %rbx,%r8 - mov \$1,$len - lea 32($ctx),%rbx # key - lea 16($ctx),$ctx # control word - .byte 0xf3,0x0f,0xa7,0xc8 # rep xcryptecb - mov %r8,%rbx - ret -.size padlock_aes_block,.-padlock_aes_block - -.globl padlock_xstore -.type padlock_xstore,\@function,2 -.align 16 -padlock_xstore: - mov %esi,%edx - .byte 0x0f,0xa7,0xc0 # xstore - ret -.size padlock_xstore,.-padlock_xstore - -.globl padlock_sha1_oneshot -.type padlock_sha1_oneshot,\@function,3 -.align 16 -padlock_sha1_oneshot: - mov %rdx,%rcx - mov %rdi,%rdx # put aside %rdi - movups (%rdi),%xmm0 # copy-in context - sub \$128+8,%rsp - mov 16(%rdi),%eax - movaps %xmm0,(%rsp) - mov %rsp,%rdi - mov %eax,16(%rsp) - xor %rax,%rax - .byte 0xf3,0x0f,0xa6,0xc8 # rep xsha1 - movaps (%rsp),%xmm0 - mov 16(%rsp),%eax - add \$128+8,%rsp - movups %xmm0,(%rdx) # copy-out context - mov %eax,16(%rdx) - ret -.size padlock_sha1_oneshot,.-padlock_sha1_oneshot - -.globl padlock_sha1_blocks -.type padlock_sha1_blocks,\@function,3 -.align 16 -padlock_sha1_blocks: - mov %rdx,%rcx - mov %rdi,%rdx # put aside %rdi - movups (%rdi),%xmm0 # copy-in context - sub \$128+8,%rsp - mov 16(%rdi),%eax - movaps %xmm0,(%rsp) - mov %rsp,%rdi - mov %eax,16(%rsp) - mov \$-1,%rax - .byte 0xf3,0x0f,0xa6,0xc8 # rep xsha1 - movaps (%rsp),%xmm0 - mov 16(%rsp),%eax - add \$128+8,%rsp - movups %xmm0,(%rdx) # copy-out context - mov %eax,16(%rdx) - ret -.size padlock_sha1_blocks,.-padlock_sha1_blocks - -.globl padlock_sha256_oneshot -.type padlock_sha256_oneshot,\@function,3 -.align 16 -padlock_sha256_oneshot: - mov %rdx,%rcx - mov %rdi,%rdx # put aside %rdi - movups (%rdi),%xmm0 # copy-in context - sub \$128+8,%rsp - movups 16(%rdi),%xmm1 - movaps %xmm0,(%rsp) - mov %rsp,%rdi - movaps %xmm1,16(%rsp) - xor %rax,%rax - .byte 0xf3,0x0f,0xa6,0xd0 # rep xsha256 - movaps (%rsp),%xmm0 - movaps 16(%rsp),%xmm1 - add \$128+8,%rsp - movups %xmm0,(%rdx) # copy-out context - movups %xmm1,16(%rdx) - ret -.size padlock_sha256_oneshot,.-padlock_sha256_oneshot - -.globl padlock_sha256_blocks -.type padlock_sha256_blocks,\@function,3 -.align 16 -padlock_sha256_blocks: - mov %rdx,%rcx - mov %rdi,%rdx # put aside %rdi - movups (%rdi),%xmm0 # copy-in context - sub \$128+8,%rsp - movups 16(%rdi),%xmm1 - movaps %xmm0,(%rsp) - mov %rsp,%rdi - movaps %xmm1,16(%rsp) - mov \$-1,%rax - .byte 0xf3,0x0f,0xa6,0xd0 # rep xsha256 - movaps (%rsp),%xmm0 - movaps 16(%rsp),%xmm1 - add \$128+8,%rsp - movups %xmm0,(%rdx) # copy-out context - movups %xmm1,16(%rdx) - ret -.size padlock_sha256_blocks,.-padlock_sha256_blocks - -.globl padlock_sha512_blocks -.type padlock_sha512_blocks,\@function,3 -.align 16 -padlock_sha512_blocks: - mov %rdx,%rcx - mov %rdi,%rdx # put aside %rdi - movups (%rdi),%xmm0 # copy-in context - sub \$128+8,%rsp - movups 16(%rdi),%xmm1 - movups 32(%rdi),%xmm2 - movups 48(%rdi),%xmm3 - movaps %xmm0,(%rsp) - mov %rsp,%rdi - movaps %xmm1,16(%rsp) - movaps %xmm2,32(%rsp) - movaps %xmm3,48(%rsp) - .byte 0xf3,0x0f,0xa6,0xe0 # rep xha512 - movaps (%rsp),%xmm0 - movaps 16(%rsp),%xmm1 - movaps 32(%rsp),%xmm2 - movaps 48(%rsp),%xmm3 - add \$128+8,%rsp - movups %xmm0,(%rdx) # copy-out context - movups %xmm1,16(%rdx) - movups %xmm2,32(%rdx) - movups %xmm3,48(%rdx) - ret -.size padlock_sha512_blocks,.-padlock_sha512_blocks -___ - -sub generate_mode { -my ($mode,$opcode) = @_; -# int padlock_$mode_encrypt(void *out, const void *inp, -# struct padlock_cipher_data *ctx, size_t len); -$code.=<<___; -.globl padlock_${mode}_encrypt -.type padlock_${mode}_encrypt,\@function,4 -.align 16 -padlock_${mode}_encrypt: - push %rbp - push %rbx - - xor %eax,%eax - test \$15,$ctx - jnz .L${mode}_abort - test \$15,$len - jnz .L${mode}_abort - lea .Lpadlock_saved_context(%rip),%rax - pushf - cld - call _padlock_verify_ctx - lea 16($ctx),$ctx # control word - xor %eax,%eax - xor %ebx,%ebx - testl \$`1<<5`,($ctx) # align bit in control word - jnz .L${mode}_aligned - test \$0x0f,$out - setz %al # !out_misaligned - test \$0x0f,$inp - setz %bl # !inp_misaligned - test %ebx,%eax - jnz .L${mode}_aligned - neg %rax - mov \$$PADLOCK_CHUNK,$chunk - not %rax # out_misaligned?-1:0 - lea (%rsp),%rbp - cmp $chunk,$len - cmovc $len,$chunk # chunk=len>PADLOCK_CHUNK?PADLOCK_CHUNK:len - and $chunk,%rax # out_misaligned?chunk:0 - mov $len,$chunk - neg %rax - and \$$PADLOCK_CHUNK-1,$chunk # chunk%=PADLOCK_CHUNK - lea (%rax,%rbp),%rsp - mov \$$PADLOCK_CHUNK,%rax - cmovz %rax,$chunk # chunk=chunk?:PADLOCK_CHUNK -___ -$code.=<<___ if ($mode eq "ctr32"); -.L${mode}_reenter: - mov -4($ctx),%eax # pull 32-bit counter - bswap %eax - neg %eax - and \$`$PADLOCK_CHUNK/16-1`,%eax - mov \$$PADLOCK_CHUNK,$chunk - shl \$4,%eax - cmovz $chunk,%rax - cmp %rax,$len - cmova %rax,$chunk # don't let counter cross PADLOCK_CHUNK - cmovbe $len,$chunk -___ -$code.=<<___ if ($PADLOCK_PREFETCH{$mode}); - cmp $chunk,$len - ja .L${mode}_loop - mov $inp,%rax # check if prefetch crosses page - cmp %rsp,%rbp - cmove $out,%rax - add $len,%rax - neg %rax - and \$0xfff,%rax # distance to page boundary - cmp \$$PADLOCK_PREFETCH{$mode},%rax - mov \$-$PADLOCK_PREFETCH{$mode},%rax - cmovae $chunk,%rax # mask=distance" -.align 16 -.data -.align 8 -.Lpadlock_saved_context: - .quad 0 -___ -$code =~ s/\`([^\`]*)\`/eval($1)/gem; - -print $code; - -close STDOUT; diff --git a/engines/build.info b/engines/build.info deleted file mode 100644 index 19e3eab0c18..00000000000 --- a/engines/build.info +++ /dev/null @@ -1,103 +0,0 @@ -IF[{- !$disabled{"engine"} -}] - $PADLOCKASM= - IF[{- !$disabled{asm} -}] - $PADLOCKASM_x86=e_padlock-x86.S - $PADLOCKASM_x86_64=e_padlock-x86_64.s - - # Now that we have defined all the arch specific variables, use the - # appropriate one, and define the appropriate macros - IF[$PADLOCKASM_{- $target{asm_arch} -}] - $PADLOCKASM=$PADLOCKASM_{- $target{asm_arch} -} - $PADLOCKDEF=PADLOCK_ASM - ENDIF - ENDIF - - IF[{- $disabled{"dynamic-engine"} -}] - LIBS=../libcrypto - IF[{- !$disabled{padlockeng} -}] - SOURCE[../libcrypto]=e_padlock.c $PADLOCKASM - DEFINE[../libcrypto]=$PADLOCKDEF - ENDIF - IF[{- !$disabled{capieng} -}] - SOURCE[../libcrypto]=e_capi.c - ENDIF - IF[{- !$disabled{afalgeng} -}] - SOURCE[../libcrypto]=e_afalg.c - ENDIF - IF[{- !$disabled{"devcryptoeng"} -}] - SOURCE[../libcrypto]=e_devcrypto.c - ENDIF - ELSE - IF[{- !$disabled{padlockeng} -}] - MODULES{engine}=padlock - SOURCE[padlock]=e_padlock.c $PADLOCKASM - DEFINE[padlock]=$PADLOCKDEF - DEPEND[padlock]=../libcrypto - INCLUDE[padlock]=../include - IF[{- defined $target{shared_defflag} -}] - SOURCE[padlock]=padlock.ld - GENERATE[padlock.ld]=../util/engines.num - ENDIF - ENDIF - IF[{- !$disabled{capieng} -}] - MODULES{engine}=capi - SOURCE[capi]=e_capi.c - DEPEND[capi]=../libcrypto - INCLUDE[capi]=../include - IF[{- defined $target{shared_defflag} -}] - SOURCE[capi]=capi.ld - GENERATE[capi.ld]=../util/engines.num - ENDIF - ENDIF - IF[{- !$disabled{afalgeng} -}] - MODULES{engine}=afalg - SOURCE[afalg]=e_afalg.c - DEPEND[afalg]=../libcrypto - INCLUDE[afalg]= ../include - IF[{- defined $target{shared_defflag} -}] - SOURCE[afalg]=afalg.ld - GENERATE[afalg.ld]=../util/engines.num - ENDIF - ENDIF - IF[{- !$disabled{"devcryptoeng"} -}] - MODULES{engine}=devcrypto - SOURCE[devcrypto]=e_devcrypto.c - DEPEND[devcrypto]=../libcrypto - INCLUDE[devcrypto]=../include - IF[{- defined $target{shared_defflag} -}] - SOURCE[devcrypto]=devcrypto.ld - GENERATE[devcrypto.ld]=../util/engines.num - ENDIF - ENDIF - IF[{- !$disabled{"loadereng"} -}] - MODULES{engine}=loader_attic - SOURCE[loader_attic]=e_loader_attic.c ../crypto/pem/pvkfmt.c - DEFINE[loader_attic]=OPENSSL_NO_PROVIDER_CODE - DEPEND[loader_attic]=../libcrypto - INCLUDE[loader_attic]=../include - IF[{- defined $target{shared_defflag} -}] - SOURCE[loader_attic]=loader_attic.ld - GENERATE[loader_attic.ld]=../util/engines.num - ENDIF - ENDIF - - MODULES{noinst,engine}=ossltest dasync - SOURCE[dasync]=e_dasync.c - DEPEND[dasync]=../libcrypto - INCLUDE[dasync]=../include - IF[{- defined $target{shared_defflag} -}] - SOURCE[dasync]=dasync.ld - GENERATE[dasync.ld]=../util/engines.num - ENDIF - - SOURCE[ossltest]=e_ossltest.c - DEPEND[ossltest]=../libcrypto - INCLUDE[ossltest]=../include - IF[{- defined $target{shared_defflag} -}] - SOURCE[ossltest]=ossltest.ld - GENERATE[ossltest.ld]=../util/engines.num - ENDIF - ENDIF - GENERATE[e_padlock-x86.S]=asm/e_padlock-x86.pl - GENERATE[e_padlock-x86_64.s]=asm/e_padlock-x86_64.pl -ENDIF diff --git a/engines/e_afalg.c b/engines/e_afalg.c deleted file mode 100644 index f10e79669ce..00000000000 --- a/engines/e_afalg.c +++ /dev/null @@ -1,935 +0,0 @@ -/* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* We need to use some deprecated APIs */ -#define OPENSSL_SUPPRESS_DEPRECATED - -/* Required for vmsplice */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif -#include -#include -#include - -#include -#include -#include -#include "internal/nelem.h" - -#include -#include -#define K_MAJ 4 -#define K_MIN1 1 -#define K_MIN2 0 -#if LINUX_VERSION_CODE < KERNEL_VERSION(K_MAJ, K_MIN1, K_MIN2) || \ - !defined(AF_ALG) -# ifndef PEDANTIC -# warning "AFALG ENGINE requires Kernel Headers >= 4.1.0" -# warning "Skipping Compilation of AFALG engine" -# endif -void engine_load_afalg_int(void); -void engine_load_afalg_int(void) -{ -} -#else - -# include -# include -# include - -# include -# include -# include - -/* clang-format off */ -# include "e_afalg.h" -# include "e_afalg_err.c" -/* clang-format on */ - -# ifndef SOL_ALG -# define SOL_ALG 279 -# endif - -# ifdef ALG_ZERO_COPY -# ifndef SPLICE_F_GIFT -# define SPLICE_F_GIFT (0x08) -# endif -# endif - -# define ALG_AES_IV_LEN 16 -# define ALG_IV_LEN(len) (sizeof(struct af_alg_iv) + (len)) -# define ALG_OP_TYPE unsigned int -# define ALG_OP_LEN (sizeof(ALG_OP_TYPE)) - -void engine_load_afalg_int(void); - -/* Local Linkage Functions */ -static int afalg_init_aio(afalg_aio *aio); -static int afalg_fin_cipher_aio(afalg_aio *ptr, int sfd, - unsigned char *buf, size_t len); -static int afalg_create_sk(afalg_ctx *actx, const char *ciphertype, - const char *ciphername); -static int afalg_destroy(ENGINE *e); -static int afalg_init(ENGINE *e); -static int afalg_finish(ENGINE *e); -static const EVP_CIPHER *afalg_aes_cbc(int nid); -static cbc_handles *get_cipher_handle(int nid); -static int afalg_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid); -static int afalg_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); -static int afalg_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl); -static int afalg_cipher_cleanup(EVP_CIPHER_CTX *ctx); -static int afalg_chk_platform(void); - -/* Engine Id and Name */ -static const char *engine_afalg_id = "afalg"; -static const char *engine_afalg_name = "AFALG engine support"; - -static int afalg_cipher_nids[] = { - NID_aes_128_cbc, - NID_aes_192_cbc, - NID_aes_256_cbc, -}; - -static cbc_handles cbc_handle[] = {{AES_KEY_SIZE_128, NULL}, - {AES_KEY_SIZE_192, NULL}, - {AES_KEY_SIZE_256, NULL}}; - -static ossl_inline int io_setup(unsigned n, aio_context_t *ctx) -{ - return syscall(__NR_io_setup, n, ctx); -} - -static ossl_inline int eventfd(int n) -{ - return syscall(__NR_eventfd2, n, 0); -} - -static ossl_inline int io_destroy(aio_context_t ctx) -{ - return syscall(__NR_io_destroy, ctx); -} - -static ossl_inline int io_read(aio_context_t ctx, long n, struct iocb **iocb) -{ - return syscall(__NR_io_submit, ctx, n, iocb); -} - -/* A version of 'struct timespec' with 32-bit time_t and nanoseconds. */ -struct __timespec32 { - __kernel_long_t tv_sec; - __kernel_long_t tv_nsec; -}; - -static ossl_inline int io_getevents(aio_context_t ctx, long min, long max, - struct io_event *events, - struct timespec *timeout) -{ -#if defined(__NR_io_pgetevents_time64) - /* Check if we are a 32-bit architecture with a 64-bit time_t */ - if (sizeof(*timeout) != sizeof(struct __timespec32)) { - int ret = syscall(__NR_io_pgetevents_time64, ctx, min, max, events, - timeout, NULL); - if (ret == 0 || errno != ENOSYS) - return ret; - } -#endif - -#if defined(__NR_io_getevents) - if (sizeof(*timeout) == sizeof(struct __timespec32)) - /* - * time_t matches our architecture length, we can just use - * __NR_io_getevents - */ - return syscall(__NR_io_getevents, ctx, min, max, events, timeout); - else { - /* - * We don't have __NR_io_pgetevents_time64, but we are using a - * 64-bit time_t on a 32-bit architecture. If we can fit the - * timeout value in a 32-bit time_t, then let's do that - * and then use the __NR_io_getevents syscall. - */ - if (timeout && timeout->tv_sec == (long)timeout->tv_sec) { - struct __timespec32 ts32; - - ts32.tv_sec = (__kernel_long_t) timeout->tv_sec; - ts32.tv_nsec = (__kernel_long_t) timeout->tv_nsec; - - return syscall(__NR_io_getevents, ctx, min, max, events, &ts32); - } else { - return syscall(__NR_io_getevents, ctx, min, max, events, NULL); - } - } -#endif - - errno = ENOSYS; - return -1; -} - -static void afalg_waitfd_cleanup(ASYNC_WAIT_CTX *ctx, const void *key, - OSSL_ASYNC_FD waitfd, void *custom) -{ - close(waitfd); -} - -static int afalg_setup_async_event_notification(afalg_aio *aio) -{ - ASYNC_JOB *job; - ASYNC_WAIT_CTX *waitctx; - void *custom = NULL; - int ret; - - if ((job = ASYNC_get_current_job()) != NULL) { - /* Async mode */ - waitctx = ASYNC_get_wait_ctx(job); - if (waitctx == NULL) { - ALG_WARN("%s(%d): ASYNC_get_wait_ctx error", __FILE__, __LINE__); - return 0; - } - /* Get waitfd from ASYNC_WAIT_CTX if it is already set */ - ret = ASYNC_WAIT_CTX_get_fd(waitctx, engine_afalg_id, - &aio->efd, &custom); - if (ret == 0) { - /* - * waitfd is not set in ASYNC_WAIT_CTX, create a new one - * and set it. efd will be signaled when AIO operation completes - */ - aio->efd = eventfd(0); - if (aio->efd == -1) { - ALG_PERR("%s(%d): Failed to get eventfd : ", __FILE__, - __LINE__); - AFALGerr(AFALG_F_AFALG_SETUP_ASYNC_EVENT_NOTIFICATION, - AFALG_R_EVENTFD_FAILED); - return 0; - } - ret = ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_afalg_id, - aio->efd, custom, - afalg_waitfd_cleanup); - if (ret == 0) { - ALG_WARN("%s(%d): Failed to set wait fd", __FILE__, __LINE__); - close(aio->efd); - return 0; - } - /* make fd non-blocking in async mode */ - if (fcntl(aio->efd, F_SETFL, O_NONBLOCK) != 0) { - ALG_WARN("%s(%d): Failed to set event fd as NONBLOCKING", - __FILE__, __LINE__); - } - } - aio->mode = MODE_ASYNC; - } else { - /* Sync mode */ - aio->efd = eventfd(0); - if (aio->efd == -1) { - ALG_PERR("%s(%d): Failed to get eventfd : ", __FILE__, __LINE__); - AFALGerr(AFALG_F_AFALG_SETUP_ASYNC_EVENT_NOTIFICATION, - AFALG_R_EVENTFD_FAILED); - return 0; - } - aio->mode = MODE_SYNC; - } - return 1; -} - -static int afalg_init_aio(afalg_aio *aio) -{ - int r = -1; - - /* Initialise for AIO */ - aio->aio_ctx = 0; - r = io_setup(MAX_INFLIGHTS, &aio->aio_ctx); - if (r < 0) { - ALG_PERR("%s(%d): io_setup error : ", __FILE__, __LINE__); - AFALGerr(AFALG_F_AFALG_INIT_AIO, AFALG_R_IO_SETUP_FAILED); - return 0; - } - - memset(aio->cbt, 0, sizeof(aio->cbt)); - aio->efd = -1; - aio->mode = MODE_UNINIT; - - return 1; -} - -static int afalg_fin_cipher_aio(afalg_aio *aio, int sfd, unsigned char *buf, - size_t len) -{ - int r; - int retry = 0; - unsigned int done = 0; - struct iocb *cb; - struct timespec timeout; - struct io_event events[MAX_INFLIGHTS]; - u_int64_t eval = 0; - - timeout.tv_sec = 0; - timeout.tv_nsec = 0; - - /* if efd has not been initialised yet do it here */ - if (aio->mode == MODE_UNINIT) { - r = afalg_setup_async_event_notification(aio); - if (r == 0) - return 0; - } - - cb = &(aio->cbt[0 % MAX_INFLIGHTS]); - memset(cb, '\0', sizeof(*cb)); - cb->aio_fildes = sfd; - cb->aio_lio_opcode = IOCB_CMD_PREAD; - /* - * The pointer has to be converted to unsigned value first to avoid - * sign extension on cast to 64 bit value in 32-bit builds - */ - cb->aio_buf = (size_t)buf; - cb->aio_offset = 0; - cb->aio_data = 0; - cb->aio_nbytes = len; - cb->aio_flags = IOCB_FLAG_RESFD; - cb->aio_resfd = aio->efd; - - /* - * Perform AIO read on AFALG socket, this in turn performs an async - * crypto operation in kernel space - */ - r = io_read(aio->aio_ctx, 1, &cb); - if (r < 0) { - ALG_PWARN("%s(%d): io_read failed : ", __FILE__, __LINE__); - return 0; - } - - do { - /* While AIO read is being performed pause job */ - ASYNC_pause_job(); - - /* Check for completion of AIO read */ - r = read(aio->efd, &eval, sizeof(eval)); - if (r < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) - continue; - ALG_PERR("%s(%d): read failed for event fd : ", __FILE__, __LINE__); - return 0; - } else if (r == 0 || eval <= 0) { - ALG_WARN("%s(%d): eventfd read %d bytes, eval = %lu\n", __FILE__, - __LINE__, r, eval); - } - if (eval > 0) { - -#ifdef OSSL_SANITIZE_MEMORY - /* - * In a memory sanitiser build, the changes to memory made by the - * system call aren't reliably detected. By initialising the - * memory here, the sanitiser is told that they are okay. - */ - memset(events, 0, sizeof(events)); -#endif - - /* Get results of AIO read */ - r = io_getevents(aio->aio_ctx, 1, MAX_INFLIGHTS, - events, &timeout); - if (r > 0) { - /* - * events.res indicates the actual status of the operation. - * Handle the error condition first. - */ - if (events[0].res < 0) { - /* - * Underlying operation cannot be completed at the time - * of previous submission. Resubmit for the operation. - */ - if (events[0].res == -EBUSY && retry++ < 3) { - r = io_read(aio->aio_ctx, 1, &cb); - if (r < 0) { - ALG_PERR("%s(%d): retry %d for io_read failed : ", - __FILE__, __LINE__, retry); - return 0; - } - continue; - } else { - char strbuf[32]; - /* - * sometimes __s64 is defined as long long int - * but on some archs ( like mips64 or powerpc64 ) it's just long int - * - * to be able to use BIO_snprintf() with %lld without warnings - * copy events[0].res to an long long int variable - * - * because long long int should always be at least 64 bit this should work - */ - long long int op_ret = events[0].res; - - /* - * Retries exceed for -EBUSY or unrecoverable error - * condition for this instance of operation. - */ - ALG_WARN - ("%s(%d): Crypto Operation failed with code %lld\n", - __FILE__, __LINE__, events[0].res); - BIO_snprintf(strbuf, sizeof(strbuf), "%lld", op_ret); - switch (events[0].res) { - case -ENOMEM: - AFALGerr(0, AFALG_R_KERNEL_OP_FAILED); - ERR_add_error_data(3, "-ENOMEM ( code ", strbuf, " )"); - break; - default: - AFALGerr(0, AFALG_R_KERNEL_OP_FAILED); - ERR_add_error_data(2, "code ", strbuf); - break; - } - return 0; - } - } - /* Operation successful. */ - done = 1; - } else if (r < 0) { - ALG_PERR("%s(%d): io_getevents failed : ", __FILE__, __LINE__); - return 0; - } else { - ALG_WARN("%s(%d): io_geteventd read 0 bytes\n", __FILE__, - __LINE__); - } - } - } while (!done); - - return 1; -} - -static ossl_inline void afalg_set_op_sk(struct cmsghdr *cmsg, - const ALG_OP_TYPE op) -{ - cmsg->cmsg_level = SOL_ALG; - cmsg->cmsg_type = ALG_SET_OP; - cmsg->cmsg_len = CMSG_LEN(ALG_OP_LEN); - memcpy(CMSG_DATA(cmsg), &op, ALG_OP_LEN); -} - -static void afalg_set_iv_sk(struct cmsghdr *cmsg, const unsigned char *iv, - const unsigned int len) -{ - struct af_alg_iv *aiv; - - cmsg->cmsg_level = SOL_ALG; - cmsg->cmsg_type = ALG_SET_IV; - cmsg->cmsg_len = CMSG_LEN(ALG_IV_LEN(len)); - aiv = (struct af_alg_iv *)CMSG_DATA(cmsg); - aiv->ivlen = len; - memcpy(aiv->iv, iv, len); -} - -static ossl_inline int afalg_set_key(afalg_ctx *actx, const unsigned char *key, - const int klen) -{ - int ret; - ret = setsockopt(actx->bfd, SOL_ALG, ALG_SET_KEY, key, klen); - if (ret < 0) { - ALG_PERR("%s(%d): Failed to set socket option : ", __FILE__, __LINE__); - AFALGerr(AFALG_F_AFALG_SET_KEY, AFALG_R_SOCKET_SET_KEY_FAILED); - return 0; - } - return 1; -} - -static int afalg_create_sk(afalg_ctx *actx, const char *ciphertype, - const char *ciphername) -{ - struct sockaddr_alg sa; - int r = -1; - - actx->bfd = actx->sfd = -1; - - memset(&sa, 0, sizeof(sa)); - sa.salg_family = AF_ALG; - OPENSSL_strlcpy((char *) sa.salg_type, ciphertype, sizeof(sa.salg_type)); - OPENSSL_strlcpy((char *) sa.salg_name, ciphername, sizeof(sa.salg_name)); - - actx->bfd = socket(AF_ALG, SOCK_SEQPACKET, 0); - if (actx->bfd == -1) { - ALG_PERR("%s(%d): Failed to open socket : ", __FILE__, __LINE__); - AFALGerr(AFALG_F_AFALG_CREATE_SK, AFALG_R_SOCKET_CREATE_FAILED); - goto err; - } - - r = bind(actx->bfd, (struct sockaddr *)&sa, sizeof(sa)); - if (r < 0) { - ALG_PERR("%s(%d): Failed to bind socket : ", __FILE__, __LINE__); - AFALGerr(AFALG_F_AFALG_CREATE_SK, AFALG_R_SOCKET_BIND_FAILED); - goto err; - } - - actx->sfd = accept(actx->bfd, NULL, 0); - if (actx->sfd < 0) { - ALG_PERR("%s(%d): Socket Accept Failed : ", __FILE__, __LINE__); - AFALGerr(AFALG_F_AFALG_CREATE_SK, AFALG_R_SOCKET_ACCEPT_FAILED); - goto err; - } - - return 1; - - err: - if (actx->bfd >= 0) - close(actx->bfd); - if (actx->sfd >= 0) - close(actx->sfd); - actx->bfd = actx->sfd = -1; - return 0; -} - -static int afalg_start_cipher_sk(afalg_ctx *actx, const unsigned char *in, - size_t inl, const unsigned char *iv, - unsigned int enc) -{ - struct msghdr msg; - struct cmsghdr *cmsg; - struct iovec iov; - ssize_t sbytes; -# ifdef ALG_ZERO_COPY - int ret; -# endif - char cbuf[CMSG_SPACE(ALG_IV_LEN(ALG_AES_IV_LEN)) + CMSG_SPACE(ALG_OP_LEN)]; - - memset(&msg, 0, sizeof(msg)); - memset(cbuf, 0, sizeof(cbuf)); - msg.msg_control = cbuf; - msg.msg_controllen = sizeof(cbuf); - - /* - * cipher direction (i.e. encrypt or decrypt) and iv are sent to the - * kernel as part of sendmsg()'s ancillary data - */ - cmsg = CMSG_FIRSTHDR(&msg); - afalg_set_op_sk(cmsg, enc); - cmsg = CMSG_NXTHDR(&msg, cmsg); - afalg_set_iv_sk(cmsg, iv, ALG_AES_IV_LEN); - - /* iov that describes input data */ - iov.iov_base = (unsigned char *)in; - iov.iov_len = inl; - - msg.msg_flags = MSG_MORE; - -# ifdef ALG_ZERO_COPY - /* - * ZERO_COPY mode - * Works best when buffer is 4k aligned - * OPENS: out of place processing (i.e. out != in) - */ - - /* Input data is not sent as part of call to sendmsg() */ - msg.msg_iovlen = 0; - msg.msg_iov = NULL; - - /* Sendmsg() sends iv and cipher direction to the kernel */ - sbytes = sendmsg(actx->sfd, &msg, 0); - if (sbytes < 0) { - ALG_PERR("%s(%d): sendmsg failed for zero copy cipher operation : ", - __FILE__, __LINE__); - return 0; - } - - /* - * vmsplice and splice are used to pin the user space input buffer for - * kernel space processing avoiding copies from user to kernel space - */ - ret = vmsplice(actx->zc_pipe[1], &iov, 1, SPLICE_F_GIFT); - if (ret < 0) { - ALG_PERR("%s(%d): vmsplice failed : ", __FILE__, __LINE__); - return 0; - } - - ret = splice(actx->zc_pipe[0], NULL, actx->sfd, NULL, inl, 0); - if (ret < 0) { - ALG_PERR("%s(%d): splice failed : ", __FILE__, __LINE__); - return 0; - } -# else - msg.msg_iovlen = 1; - msg.msg_iov = &iov; - - /* Sendmsg() sends iv, cipher direction and input data to the kernel */ - sbytes = sendmsg(actx->sfd, &msg, 0); - if (sbytes < 0) { - ALG_PERR("%s(%d): sendmsg failed for cipher operation : ", __FILE__, - __LINE__); - return 0; - } - - if (sbytes != (ssize_t) inl) { - ALG_WARN("Cipher operation send bytes %zd != inlen %zd\n", sbytes, - inl); - return 0; - } -# endif - - return 1; -} - -static int afalg_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - int ciphertype; - int ret, len; - afalg_ctx *actx; - const char *ciphername; - - if (ctx == NULL || key == NULL) { - ALG_WARN("%s(%d): Null Parameter\n", __FILE__, __LINE__); - return 0; - } - - if (EVP_CIPHER_CTX_get0_cipher(ctx) == NULL) { - ALG_WARN("%s(%d): Cipher object NULL\n", __FILE__, __LINE__); - return 0; - } - - actx = EVP_CIPHER_CTX_get_cipher_data(ctx); - if (actx == NULL) { - ALG_WARN("%s(%d): Cipher data NULL\n", __FILE__, __LINE__); - return 0; - } - - ciphertype = EVP_CIPHER_CTX_get_nid(ctx); - switch (ciphertype) { - case NID_aes_128_cbc: - case NID_aes_192_cbc: - case NID_aes_256_cbc: - ciphername = "cbc(aes)"; - break; - default: - ALG_WARN("%s(%d): Unsupported Cipher type %d\n", __FILE__, __LINE__, - ciphertype); - return 0; - } - - if (ALG_AES_IV_LEN != EVP_CIPHER_CTX_get_iv_length(ctx)) { - ALG_WARN("%s(%d): Unsupported IV length :%d\n", __FILE__, __LINE__, - EVP_CIPHER_CTX_get_iv_length(ctx)); - return 0; - } - - /* Setup AFALG socket for crypto processing */ - ret = afalg_create_sk(actx, "skcipher", ciphername); - if (ret < 1) - return 0; - - if ((len = EVP_CIPHER_CTX_get_key_length(ctx)) <= 0) - goto err; - ret = afalg_set_key(actx, key, len); - if (ret < 1) - goto err; - - /* Setup AIO ctx to allow async AFALG crypto processing */ - if (afalg_init_aio(&actx->aio) == 0) - goto err; - -# ifdef ALG_ZERO_COPY - pipe(actx->zc_pipe); -# endif - - actx->init_done = MAGIC_INIT_NUM; - - return 1; - -err: - close(actx->sfd); - close(actx->bfd); - return 0; -} - -static int afalg_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - afalg_ctx *actx; - int ret; - char nxtiv[ALG_AES_IV_LEN] = { 0 }; - - if (ctx == NULL || out == NULL || in == NULL) { - ALG_WARN("NULL parameter passed to function %s(%d)\n", __FILE__, - __LINE__); - return 0; - } - - actx = (afalg_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx); - if (actx == NULL || actx->init_done != MAGIC_INIT_NUM) { - ALG_WARN("%s afalg ctx passed\n", - ctx == NULL ? "NULL" : "Uninitialised"); - return 0; - } - - /* - * set iv now for decrypt operation as the input buffer can be - * overwritten for inplace operation where in = out. - */ - if (EVP_CIPHER_CTX_is_encrypting(ctx) == 0) { - memcpy(nxtiv, in + (inl - ALG_AES_IV_LEN), ALG_AES_IV_LEN); - } - - /* Send input data to kernel space */ - ret = afalg_start_cipher_sk(actx, (unsigned char *)in, inl, - EVP_CIPHER_CTX_iv(ctx), - EVP_CIPHER_CTX_is_encrypting(ctx)); - if (ret < 1) { - return 0; - } - - /* Perform async crypto operation in kernel space */ - ret = afalg_fin_cipher_aio(&actx->aio, actx->sfd, out, inl); - if (ret < 1) - return 0; - - if (EVP_CIPHER_CTX_is_encrypting(ctx)) { - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), out + (inl - ALG_AES_IV_LEN), - ALG_AES_IV_LEN); - } else { - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), nxtiv, ALG_AES_IV_LEN); - } - - return 1; -} - -static int afalg_cipher_cleanup(EVP_CIPHER_CTX *ctx) -{ - afalg_ctx *actx; - - if (ctx == NULL) { - ALG_WARN("NULL parameter passed to function %s(%d)\n", __FILE__, - __LINE__); - return 0; - } - - actx = (afalg_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx); - if (actx == NULL || actx->init_done != MAGIC_INIT_NUM) - return 1; - - close(actx->sfd); - close(actx->bfd); -# ifdef ALG_ZERO_COPY - close(actx->zc_pipe[0]); - close(actx->zc_pipe[1]); -# endif - /* close efd in sync mode, async mode is closed in afalg_waitfd_cleanup() */ - if (actx->aio.mode == MODE_SYNC) - close(actx->aio.efd); - io_destroy(actx->aio.aio_ctx); - - return 1; -} - -static cbc_handles *get_cipher_handle(int nid) -{ - switch (nid) { - case NID_aes_128_cbc: - return &cbc_handle[AES_CBC_128]; - case NID_aes_192_cbc: - return &cbc_handle[AES_CBC_192]; - case NID_aes_256_cbc: - return &cbc_handle[AES_CBC_256]; - default: - return NULL; - } -} - -static const EVP_CIPHER *afalg_aes_cbc(int nid) -{ - cbc_handles *cipher_handle = get_cipher_handle(nid); - - if (cipher_handle == NULL) - return NULL; - if (cipher_handle->_hidden == NULL - && ((cipher_handle->_hidden = - EVP_CIPHER_meth_new(nid, - AES_BLOCK_SIZE, - cipher_handle->key_size)) == NULL - || !EVP_CIPHER_meth_set_iv_length(cipher_handle->_hidden, - AES_IV_LEN) - || !EVP_CIPHER_meth_set_flags(cipher_handle->_hidden, - EVP_CIPH_CBC_MODE | - EVP_CIPH_FLAG_DEFAULT_ASN1) - || !EVP_CIPHER_meth_set_init(cipher_handle->_hidden, - afalg_cipher_init) - || !EVP_CIPHER_meth_set_do_cipher(cipher_handle->_hidden, - afalg_do_cipher) - || !EVP_CIPHER_meth_set_cleanup(cipher_handle->_hidden, - afalg_cipher_cleanup) - || !EVP_CIPHER_meth_set_impl_ctx_size(cipher_handle->_hidden, - sizeof(afalg_ctx)))) { - EVP_CIPHER_meth_free(cipher_handle->_hidden); - cipher_handle->_hidden= NULL; - } - return cipher_handle->_hidden; -} - -static int afalg_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid) -{ - int r = 1; - - if (cipher == NULL) { - *nids = afalg_cipher_nids; - return OSSL_NELEM(afalg_cipher_nids); - } - - switch (nid) { - case NID_aes_128_cbc: - case NID_aes_192_cbc: - case NID_aes_256_cbc: - *cipher = afalg_aes_cbc(nid); - break; - default: - *cipher = NULL; - r = 0; - } - return r; -} - -static int bind_afalg(ENGINE *e) -{ - /* Ensure the afalg error handling is set up */ - unsigned short i; - ERR_load_AFALG_strings(); - - if (!ENGINE_set_id(e, engine_afalg_id) - || !ENGINE_set_name(e, engine_afalg_name) - || !ENGINE_set_destroy_function(e, afalg_destroy) - || !ENGINE_set_init_function(e, afalg_init) - || !ENGINE_set_finish_function(e, afalg_finish)) { - AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); - return 0; - } - - /* - * Create _hidden_aes_xxx_cbc by calling afalg_aes_xxx_cbc - * now, as bind_aflag can only be called by one thread at a - * time. - */ - for (i = 0; i < OSSL_NELEM(afalg_cipher_nids); i++) { - if (afalg_aes_cbc(afalg_cipher_nids[i]) == NULL) { - AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); - return 0; - } - } - - if (!ENGINE_set_ciphers(e, afalg_ciphers)) { - AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); - return 0; - } - - return 1; -} - -static int afalg_chk_platform(void) -{ - int ret; - int i; - int kver[3] = { -1, -1, -1 }; - int sock; - char *str; - struct utsname ut; - - ret = uname(&ut); - if (ret != 0) { - AFALGerr(AFALG_F_AFALG_CHK_PLATFORM, - AFALG_R_FAILED_TO_GET_PLATFORM_INFO); - return 0; - } - - str = strtok(ut.release, "."); - for (i = 0; i < 3 && str != NULL; i++) { - kver[i] = atoi(str); - str = strtok(NULL, "."); - } - - if (KERNEL_VERSION(kver[0], kver[1], kver[2]) - < KERNEL_VERSION(K_MAJ, K_MIN1, K_MIN2)) { - ALG_ERR("ASYNC AFALG not supported this kernel(%d.%d.%d)\n", - kver[0], kver[1], kver[2]); - ALG_ERR("ASYNC AFALG requires kernel version %d.%d.%d or later\n", - K_MAJ, K_MIN1, K_MIN2); - AFALGerr(AFALG_F_AFALG_CHK_PLATFORM, - AFALG_R_KERNEL_DOES_NOT_SUPPORT_ASYNC_AFALG); - return 0; - } - - /* Test if we can actually create an AF_ALG socket */ - sock = socket(AF_ALG, SOCK_SEQPACKET, 0); - if (sock == -1) { - AFALGerr(AFALG_F_AFALG_CHK_PLATFORM, AFALG_R_SOCKET_CREATE_FAILED); - return 0; - } - close(sock); - - return 1; -} - -static ENGINE *engine_afalg(void) -{ - ENGINE *ret = ENGINE_new(); - if (ret == NULL) - return NULL; - if (!bind_afalg(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void engine_load_afalg_int(void) -{ - ENGINE *toadd; - - if (!afalg_chk_platform()) - return; - - toadd = engine_afalg(); - if (toadd == NULL) - return; - ERR_set_mark(); - ENGINE_add(toadd); - /* - * If the "add" worked, it gets a structural reference. So either way, we - * release our just-created reference. - */ - ENGINE_free(toadd); - /* - * If the "add" didn't work, it was probably a conflict because it was - * already added (eg. someone calling ENGINE_load_blah then calling - * ENGINE_load_builtin_engines() perhaps). - */ - ERR_pop_to_mark(); -} - -static int afalg_init(ENGINE *e) -{ - return 1; -} - -static int afalg_finish(ENGINE *e) -{ - return 1; -} - -static int free_cbc(void) -{ - short unsigned int i; - for (i = 0; i < OSSL_NELEM(afalg_cipher_nids); i++) { - EVP_CIPHER_meth_free(cbc_handle[i]._hidden); - cbc_handle[i]._hidden = NULL; - } - return 1; -} - -static int afalg_destroy(ENGINE *e) -{ - ERR_unload_AFALG_strings(); - free_cbc(); - return 1; -} - -#endif /* KERNEL VERSION */ diff --git a/engines/e_afalg.ec b/engines/e_afalg.ec deleted file mode 100644 index 6d7420fe5c3..00000000000 --- a/engines/e_afalg.ec +++ /dev/null @@ -1,3 +0,0 @@ -# The INPUT HEADER is scanned for declarations -# LIBNAME INPUT HEADER ERROR-TABLE FILE -L AFALG e_afalg_err.h e_afalg_err.c diff --git a/engines/e_afalg.h b/engines/e_afalg.h deleted file mode 100644 index b8e4911d21e..00000000000 --- a/engines/e_afalg.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 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 - */ - -#ifndef OSSL_ENGINES_E_AFALG_H -# define OSSL_ENGINES_E_AFALG_H - -# if defined(__GNUC__) && __GNUC__ >= 4 && \ - (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) -# pragma GCC diagnostic ignored "-Wvariadic-macros" -# endif - -# ifdef ALG_DEBUG -# define ALG_DGB(x, ...) fprintf(stderr, "ALG_DBG: " x, __VA_ARGS__) -# define ALG_INFO(x, ...) fprintf(stderr, "ALG_INFO: " x, __VA_ARGS__) -# define ALG_WARN(x, ...) fprintf(stderr, "ALG_WARN: " x, __VA_ARGS__) -# else -# define ALG_DGB(x, ...) -# define ALG_INFO(x, ...) -# define ALG_WARN(x, ...) -# endif - -# define ALG_ERR(x, ...) fprintf(stderr, "ALG_ERR: " x, __VA_ARGS__) -# define ALG_PERR(x, ...) \ - do { \ - fprintf(stderr, "ALG_PERR: " x, __VA_ARGS__); \ - perror(NULL); \ - } while(0) -# define ALG_PWARN(x, ...) \ - do { \ - fprintf(stderr, "ALG_PERR: " x, __VA_ARGS__); \ - perror(NULL); \ - } while(0) - -# ifndef AES_BLOCK_SIZE -# define AES_BLOCK_SIZE 16 -# endif -# define AES_KEY_SIZE_128 16 -# define AES_KEY_SIZE_192 24 -# define AES_KEY_SIZE_256 32 -# define AES_IV_LEN 16 - -# define MAX_INFLIGHTS 1 - -typedef enum { - MODE_UNINIT = 0, - MODE_SYNC, - MODE_ASYNC -} op_mode; - -enum { - AES_CBC_128 = 0, - AES_CBC_192, - AES_CBC_256 -}; - -struct cbc_cipher_handles { - int key_size; - EVP_CIPHER *_hidden; -}; - -typedef struct cbc_cipher_handles cbc_handles; - -struct afalg_aio_st { - int efd; - op_mode mode; - aio_context_t aio_ctx; - struct io_event events[MAX_INFLIGHTS]; - struct iocb cbt[MAX_INFLIGHTS]; -}; -typedef struct afalg_aio_st afalg_aio; - -/* - * MAGIC Number to identify correct initialisation - * of afalg_ctx. - */ -# define MAGIC_INIT_NUM 0x1890671 - -struct afalg_ctx_st { - int init_done; - int sfd; - int bfd; -# ifdef ALG_ZERO_COPY - int zc_pipe[2]; -# endif - afalg_aio aio; -}; - -typedef struct afalg_ctx_st afalg_ctx; -#endif diff --git a/engines/e_afalg.txt b/engines/e_afalg.txt deleted file mode 100644 index 9b5fee84752..00000000000 --- a/engines/e_afalg.txt +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 1999-2022 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 - -#Reason codes -AFALG_R_EVENTFD_FAILED:108:eventfd failed -AFALG_R_FAILED_TO_GET_PLATFORM_INFO:111:failed to get platform info -AFALG_R_INIT_FAILED:100:init failed -AFALG_R_IO_SETUP_FAILED:105:io setup failed -AFALG_R_KERNEL_DOES_NOT_SUPPORT_AFALG:101:kernel does not support afalg -AFALG_R_KERNEL_DOES_NOT_SUPPORT_ASYNC_AFALG:107:\ - kernel does not support async afalg -AFALG_R_KERNEL_OP_FAILED:112:kernel op failed -AFALG_R_MEM_ALLOC_FAILED:102:mem alloc failed -AFALG_R_SOCKET_ACCEPT_FAILED:110:socket accept failed -AFALG_R_SOCKET_BIND_FAILED:103:socket bind failed -AFALG_R_SOCKET_CREATE_FAILED:109:socket create failed -AFALG_R_SOCKET_OPERATION_FAILED:104:socket operation failed -AFALG_R_SOCKET_SET_KEY_FAILED:106:socket set key failed diff --git a/engines/e_afalg_err.c b/engines/e_afalg_err.c deleted file mode 100644 index fa38678e9e7..00000000000 --- a/engines/e_afalg_err.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2022 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 "e_afalg_err.h" - -#ifndef OPENSSL_NO_ERR - -static ERR_STRING_DATA AFALG_str_reasons[] = { - {ERR_PACK(0, 0, AFALG_R_EVENTFD_FAILED), "eventfd failed"}, - {ERR_PACK(0, 0, AFALG_R_FAILED_TO_GET_PLATFORM_INFO), - "failed to get platform info"}, - {ERR_PACK(0, 0, AFALG_R_INIT_FAILED), "init failed"}, - {ERR_PACK(0, 0, AFALG_R_IO_SETUP_FAILED), "io setup failed"}, - {ERR_PACK(0, 0, AFALG_R_KERNEL_DOES_NOT_SUPPORT_AFALG), - "kernel does not support afalg"}, - {ERR_PACK(0, 0, AFALG_R_KERNEL_DOES_NOT_SUPPORT_ASYNC_AFALG), - "kernel does not support async afalg"}, - {ERR_PACK(0, 0, AFALG_R_KERNEL_OP_FAILED), "kernel op failed"}, - {ERR_PACK(0, 0, AFALG_R_MEM_ALLOC_FAILED), "mem alloc failed"}, - {ERR_PACK(0, 0, AFALG_R_SOCKET_ACCEPT_FAILED), "socket accept failed"}, - {ERR_PACK(0, 0, AFALG_R_SOCKET_BIND_FAILED), "socket bind failed"}, - {ERR_PACK(0, 0, AFALG_R_SOCKET_CREATE_FAILED), "socket create failed"}, - {ERR_PACK(0, 0, AFALG_R_SOCKET_OPERATION_FAILED), - "socket operation failed"}, - {ERR_PACK(0, 0, AFALG_R_SOCKET_SET_KEY_FAILED), "socket set key failed"}, - {0, NULL} -}; - -#endif - -static int lib_code = 0; -static int error_loaded = 0; - -static int ERR_load_AFALG_strings(void) -{ - if (lib_code == 0) - lib_code = ERR_get_next_error_library(); - - if (!error_loaded) { -#ifndef OPENSSL_NO_ERR - ERR_load_strings(lib_code, AFALG_str_reasons); -#endif - error_loaded = 1; - } - return 1; -} - -static void ERR_unload_AFALG_strings(void) -{ - if (error_loaded) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(lib_code, AFALG_str_reasons); -#endif - error_loaded = 0; - } -} - -static void ERR_AFALG_error(int function, int reason, const char *file, int line) -{ - if (lib_code == 0) - lib_code = ERR_get_next_error_library(); - ERR_raise(lib_code, reason); - ERR_set_debug(file, line, NULL); -} diff --git a/engines/e_afalg_err.h b/engines/e_afalg_err.h deleted file mode 100644 index 8328b21e8ea..00000000000 --- a/engines/e_afalg_err.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2022 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 - */ - -#ifndef OSSL_E_AFALG_ERR_H -# define OSSL_E_AFALG_ERR_H -# pragma once - -# include -# include - - -# define AFALGerr(f, r) ERR_AFALG_error(0, (r), OPENSSL_FILE, OPENSSL_LINE) - - -/* - * AFALG reason codes. - */ -# define AFALG_R_EVENTFD_FAILED 108 -# define AFALG_R_FAILED_TO_GET_PLATFORM_INFO 111 -# define AFALG_R_INIT_FAILED 100 -# define AFALG_R_IO_SETUP_FAILED 105 -# define AFALG_R_KERNEL_DOES_NOT_SUPPORT_AFALG 101 -# define AFALG_R_KERNEL_DOES_NOT_SUPPORT_ASYNC_AFALG 107 -# define AFALG_R_KERNEL_OP_FAILED 112 -# define AFALG_R_MEM_ALLOC_FAILED 102 -# define AFALG_R_SOCKET_ACCEPT_FAILED 110 -# define AFALG_R_SOCKET_BIND_FAILED 103 -# define AFALG_R_SOCKET_CREATE_FAILED 109 -# define AFALG_R_SOCKET_OPERATION_FAILED 104 -# define AFALG_R_SOCKET_SET_KEY_FAILED 106 - -#endif diff --git a/engines/e_capi.c b/engines/e_capi.c deleted file mode 100644 index 05a267bfe57..00000000000 --- a/engines/e_capi.c +++ /dev/null @@ -1,1910 +0,0 @@ -/* - * Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* We need to use some deprecated APIs */ -#define OPENSSL_SUPPRESS_DEPRECATED - -#ifdef _WIN32 -# ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0400 -# endif -# include -# include - -# include -# include -# include -# include -# ifndef alloca -# define alloca _alloca -# endif - -# include - -# ifndef OPENSSL_NO_CAPIENG - -# include -# include -# include -# include - -/* - * This module uses several "new" interfaces, among which is - * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is - * one of possible values you can pass to function in question. By - * checking if it's defined we can see if wincrypt.h and accompanying - * crypt32.lib are in shape. The native MingW32 headers up to and - * including __W32API_VERSION 3.14 lack of struct DSSPUBKEY and the - * defines CERT_STORE_PROV_SYSTEM_A and CERT_STORE_READONLY_FLAG, - * so we check for these too and avoid compiling. - * Yes, it's rather "weak" test and if compilation fails, - * then re-configure with -DOPENSSL_NO_CAPIENG. - */ -# if defined(CERT_KEY_PROV_INFO_PROP_ID) && \ - defined(CERT_STORE_PROV_SYSTEM_A) && \ - defined(CERT_STORE_READONLY_FLAG) -# define __COMPILE_CAPIENG -# endif /* CERT_KEY_PROV_INFO_PROP_ID */ -# endif /* OPENSSL_NO_CAPIENG */ -#endif /* _WIN32 */ - -#ifdef __COMPILE_CAPIENG - -# undef X509_EXTENSIONS - -/* Definitions which may be missing from earlier version of headers */ -# ifndef CERT_STORE_OPEN_EXISTING_FLAG -# define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000 -# endif - -# ifndef CERT_STORE_CREATE_NEW_FLAG -# define CERT_STORE_CREATE_NEW_FLAG 0x00002000 -# endif - -# ifndef CERT_SYSTEM_STORE_CURRENT_USER -# define CERT_SYSTEM_STORE_CURRENT_USER 0x00010000 -# endif - -# ifndef ALG_SID_SHA_256 -# define ALG_SID_SHA_256 12 -# endif -# ifndef ALG_SID_SHA_384 -# define ALG_SID_SHA_384 13 -# endif -# ifndef ALG_SID_SHA_512 -# define ALG_SID_SHA_512 14 -# endif - -# ifndef CALG_SHA_256 -# define CALG_SHA_256 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256) -# endif -# ifndef CALG_SHA_384 -# define CALG_SHA_384 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_384) -# endif -# ifndef CALG_SHA_512 -# define CALG_SHA_512 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_512) -# endif - -# ifndef PROV_RSA_AES -# define PROV_RSA_AES 24 -# endif - -# include -# include -# include - -/* clang-format off */ -# include "e_capi_err.h" -# include "e_capi_err.c" -/* clang-format on */ - -static const char *engine_capi_id = "capi"; -static const char *engine_capi_name = "CryptoAPI ENGINE"; - -typedef struct CAPI_CTX_st CAPI_CTX; -typedef struct CAPI_KEY_st CAPI_KEY; - -static void capi_addlasterror(void); -static void capi_adderror(DWORD err); - -static void CAPI_trace(CAPI_CTX *ctx, char *format, ...); - -static int capi_list_providers(CAPI_CTX *ctx, BIO *out); -static int capi_list_containers(CAPI_CTX *ctx, BIO *out); -int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *storename); -void capi_free_key(CAPI_KEY *key); - -static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, - HCERTSTORE hstore); - -CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id); - -static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, void *callback_data); -static int capi_rsa_sign(int dtype, const unsigned char *m, - unsigned int m_len, unsigned char *sigret, - unsigned int *siglen, const RSA *rsa); -static int capi_rsa_priv_enc(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int capi_rsa_priv_dec(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int capi_rsa_free(RSA *rsa); - -# ifndef OPENSSL_NO_DSA -static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, - DSA *dsa); -static int capi_dsa_free(DSA *dsa); -# endif - -static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, - STACK_OF(X509_NAME) *ca_dn, X509 **pcert, - EVP_PKEY **pkey, STACK_OF(X509) **pother, - UI_METHOD *ui_method, - void *callback_data); - -static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); -# ifdef OPENSSL_CAPIENG_DIALOG -static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); -# endif - -void engine_load_capi_int(void); - -typedef PCCERT_CONTEXT(WINAPI *CERTDLG)(HCERTSTORE, HWND, LPCWSTR, - LPCWSTR, DWORD, DWORD, void *); -typedef HWND(WINAPI *GETCONSWIN)(void); - -/* - * This structure contains CAPI ENGINE specific data: it contains various - * global options and affects how other functions behave. - */ - -# define CAPI_DBG_TRACE 2 -# define CAPI_DBG_ERROR 1 - -struct CAPI_CTX_st { - int debug_level; - char *debug_file; - /* Parameters to use for container lookup */ - DWORD keytype; - LPSTR cspname; - DWORD csptype; - /* Certificate store name to use */ - LPSTR storename; - LPSTR ssl_client_store; - /* System store flags */ - DWORD store_flags; -/* Lookup string meanings in load_private_key */ -# define CAPI_LU_SUBSTR 1 /* Substring of subject: uses "storename" */ -# define CAPI_LU_FNAME 2 /* Friendly name: uses storename */ -# define CAPI_LU_CONTNAME 3 /* Container name: uses cspname, keytype */ - int lookup_method; -/* Info to dump with dumpcerts option */ -# define CAPI_DMP_SUMMARY 0x1 /* Issuer and serial name strings */ -# define CAPI_DMP_FNAME 0x2 /* Friendly name */ -# define CAPI_DMP_FULL 0x4 /* Full X509_print dump */ -# define CAPI_DMP_PEM 0x8 /* Dump PEM format certificate */ -# define CAPI_DMP_PSKEY 0x10 /* Dump pseudo key (if possible) */ -# define CAPI_DMP_PKEYINFO 0x20 /* Dump key info (if possible) */ - DWORD dump_flags; - int (*client_cert_select) (ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); - CERTDLG certselectdlg; - GETCONSWIN getconswindow; -}; - -static CAPI_CTX *capi_ctx_new(void); -static void capi_ctx_free(CAPI_CTX *ctx); -static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, - int check); -static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx); - -# define CAPI_CMD_LIST_CERTS ENGINE_CMD_BASE -# define CAPI_CMD_LOOKUP_CERT (ENGINE_CMD_BASE + 1) -# define CAPI_CMD_DEBUG_LEVEL (ENGINE_CMD_BASE + 2) -# define CAPI_CMD_DEBUG_FILE (ENGINE_CMD_BASE + 3) -# define CAPI_CMD_KEYTYPE (ENGINE_CMD_BASE + 4) -# define CAPI_CMD_LIST_CSPS (ENGINE_CMD_BASE + 5) -# define CAPI_CMD_SET_CSP_IDX (ENGINE_CMD_BASE + 6) -# define CAPI_CMD_SET_CSP_NAME (ENGINE_CMD_BASE + 7) -# define CAPI_CMD_SET_CSP_TYPE (ENGINE_CMD_BASE + 8) -# define CAPI_CMD_LIST_CONTAINERS (ENGINE_CMD_BASE + 9) -# define CAPI_CMD_LIST_OPTIONS (ENGINE_CMD_BASE + 10) -# define CAPI_CMD_LOOKUP_METHOD (ENGINE_CMD_BASE + 11) -# define CAPI_CMD_STORE_NAME (ENGINE_CMD_BASE + 12) -# define CAPI_CMD_STORE_FLAGS (ENGINE_CMD_BASE + 13) - -static const ENGINE_CMD_DEFN capi_cmd_defns[] = { - {CAPI_CMD_LIST_CERTS, - "list_certs", - "List all certificates in store", - ENGINE_CMD_FLAG_NO_INPUT}, - {CAPI_CMD_LOOKUP_CERT, - "lookup_cert", - "Lookup and output certificates", - ENGINE_CMD_FLAG_STRING}, - {CAPI_CMD_DEBUG_LEVEL, - "debug_level", - "debug level (1=errors, 2=trace)", - ENGINE_CMD_FLAG_NUMERIC}, - {CAPI_CMD_DEBUG_FILE, - "debug_file", - "debugging filename)", - ENGINE_CMD_FLAG_STRING}, - {CAPI_CMD_KEYTYPE, - "key_type", - "Key type: 1=AT_KEYEXCHANGE (default), 2=AT_SIGNATURE", - ENGINE_CMD_FLAG_NUMERIC}, - {CAPI_CMD_LIST_CSPS, - "list_csps", - "List all CSPs", - ENGINE_CMD_FLAG_NO_INPUT}, - {CAPI_CMD_SET_CSP_IDX, - "csp_idx", - "Set CSP by index", - ENGINE_CMD_FLAG_NUMERIC}, - {CAPI_CMD_SET_CSP_NAME, - "csp_name", - "Set CSP name, (default CSP used if not specified)", - ENGINE_CMD_FLAG_STRING}, - {CAPI_CMD_SET_CSP_TYPE, - "csp_type", - "Set CSP type, (default RSA_PROV_FULL)", - ENGINE_CMD_FLAG_NUMERIC}, - {CAPI_CMD_LIST_CONTAINERS, - "list_containers", - "list container names", - ENGINE_CMD_FLAG_NO_INPUT}, - {CAPI_CMD_LIST_OPTIONS, - "list_options", - "Set list options (1=summary,2=friendly name, 4=full printout, 8=PEM output, 16=XXX, " - "32=private key info)", - ENGINE_CMD_FLAG_NUMERIC}, - {CAPI_CMD_LOOKUP_METHOD, - "lookup_method", - "Set key lookup method (1=substring, 2=friendlyname, 3=container name)", - ENGINE_CMD_FLAG_NUMERIC}, - {CAPI_CMD_STORE_NAME, - "store_name", - "certificate store name, default \"MY\"", - ENGINE_CMD_FLAG_STRING}, - {CAPI_CMD_STORE_FLAGS, - "store_flags", - "Certificate store flags: 1 = system store", - ENGINE_CMD_FLAG_NUMERIC}, - - {0, NULL, NULL, 0} -}; - -static int capi_idx = -1; -static int rsa_capi_idx = -1; -static int dsa_capi_idx = -1; -static int cert_capi_idx = -1; - -static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - int ret = 1; - CAPI_CTX *ctx; - BIO *out; - LPSTR tmpstr; - if (capi_idx == -1) { - CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED); - return 0; - } - ctx = ENGINE_get_ex_data(e, capi_idx); - out = BIO_new_fp(stdout, BIO_NOCLOSE); - if (out == NULL) { - CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_FILE_OPEN_ERROR); - return 0; - } - switch (cmd) { - case CAPI_CMD_LIST_CSPS: - ret = capi_list_providers(ctx, out); - break; - - case CAPI_CMD_LIST_CERTS: - ret = capi_list_certs(ctx, out, NULL); - break; - - case CAPI_CMD_LOOKUP_CERT: - ret = capi_list_certs(ctx, out, p); - break; - - case CAPI_CMD_LIST_CONTAINERS: - ret = capi_list_containers(ctx, out); - break; - - case CAPI_CMD_STORE_NAME: - tmpstr = OPENSSL_strdup(p); - if (tmpstr != NULL) { - OPENSSL_free(ctx->storename); - ctx->storename = tmpstr; - CAPI_trace(ctx, "Setting store name to %s\n", p); - } else { - ret = 0; - } - break; - - case CAPI_CMD_STORE_FLAGS: - if (i & 1) { - ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE; - ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER; - } else { - ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER; - ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE; - } - CAPI_trace(ctx, "Setting flags to %d\n", i); - break; - - case CAPI_CMD_DEBUG_LEVEL: - ctx->debug_level = (int)i; - CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level); - break; - - case CAPI_CMD_DEBUG_FILE: - tmpstr = OPENSSL_strdup(p); - if (tmpstr != NULL) { - ctx->debug_file = tmpstr; - CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file); - } else { - ret = 0; - } - break; - - case CAPI_CMD_KEYTYPE: - ctx->keytype = i; - CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype); - break; - - case CAPI_CMD_SET_CSP_IDX: - ret = capi_ctx_set_provname_idx(ctx, i); - break; - - case CAPI_CMD_LIST_OPTIONS: - ctx->dump_flags = i; - break; - - case CAPI_CMD_LOOKUP_METHOD: - if (i < 1 || i > 3) { - CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD); - BIO_free(out); - return 0; - } - ctx->lookup_method = i; - break; - - case CAPI_CMD_SET_CSP_NAME: - ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1); - break; - - case CAPI_CMD_SET_CSP_TYPE: - ctx->csptype = i; - break; - - default: - CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND); - ret = 0; - } - - BIO_free(out); - return ret; - -} - -static RSA_METHOD *capi_rsa_method = NULL; -# ifndef OPENSSL_NO_DSA -static DSA_METHOD *capi_dsa_method = NULL; -# endif - -static int use_aes_csp = 0; -static const WCHAR rsa_aes_cspname[] = - L"Microsoft Enhanced RSA and AES Cryptographic Provider"; -static const WCHAR rsa_enh_cspname[] = - L"Microsoft Enhanced Cryptographic Provider v1.0"; - -static int capi_init(ENGINE *e) -{ - CAPI_CTX *ctx; - const RSA_METHOD *ossl_rsa_meth; -# ifndef OPENSSL_NO_DSA - const DSA_METHOD *ossl_dsa_meth; -# endif - HCRYPTPROV hprov; - - if (capi_idx < 0) { - capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0); - if (capi_idx < 0) { - CAPIerr(CAPI_F_CAPI_INIT, ERR_R_ENGINE_LIB); - goto err; - } - - cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0); - - /* Setup RSA_METHOD */ - rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0); - ossl_rsa_meth = RSA_PKCS1_OpenSSL(); - if (!RSA_meth_set_pub_enc(capi_rsa_method, - RSA_meth_get_pub_enc(ossl_rsa_meth)) - || !RSA_meth_set_pub_dec(capi_rsa_method, - RSA_meth_get_pub_dec(ossl_rsa_meth)) - || !RSA_meth_set_priv_enc(capi_rsa_method, capi_rsa_priv_enc) - || !RSA_meth_set_priv_dec(capi_rsa_method, capi_rsa_priv_dec) - || !RSA_meth_set_mod_exp(capi_rsa_method, - RSA_meth_get_mod_exp(ossl_rsa_meth)) - || !RSA_meth_set_bn_mod_exp(capi_rsa_method, - RSA_meth_get_bn_mod_exp(ossl_rsa_meth)) - || !RSA_meth_set_finish(capi_rsa_method, capi_rsa_free) - || !RSA_meth_set_sign(capi_rsa_method, capi_rsa_sign)) { - CAPIerr(CAPI_F_CAPI_INIT, ERR_R_RSA_LIB); - goto err; - } - -# ifndef OPENSSL_NO_DSA - /* Setup DSA Method */ - dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0); - ossl_dsa_meth = DSA_OpenSSL(); - if (!DSA_meth_set_sign(capi_dsa_method, capi_dsa_do_sign) - || !DSA_meth_set_verify(capi_dsa_method, - DSA_meth_get_verify(ossl_dsa_meth)) - || !DSA_meth_set_finish(capi_dsa_method, capi_dsa_free) - || !DSA_meth_set_mod_exp(capi_dsa_method, - DSA_meth_get_mod_exp(ossl_dsa_meth)) - || !DSA_meth_set_bn_mod_exp(capi_dsa_method, - DSA_meth_get_bn_mod_exp(ossl_dsa_meth))) { - CAPIerr(CAPI_F_CAPI_INIT, ERR_R_DSA_LIB); - goto err; - } -# endif - } - - ctx = capi_ctx_new(); - if (ctx == NULL) { - CAPIerr(CAPI_F_CAPI_INIT, ERR_R_CAPI_LIB); - goto err; - } - - ENGINE_set_ex_data(e, capi_idx, ctx); - -# ifdef OPENSSL_CAPIENG_DIALOG - { - HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL")); - HMODULE kernel = GetModuleHandle(TEXT("KERNEL32.DLL")); - if (cryptui) - ctx->certselectdlg = - (CERTDLG) GetProcAddress(cryptui, - "CryptUIDlgSelectCertificateFromStore"); - if (kernel) - ctx->getconswindow = - (GETCONSWIN) GetProcAddress(kernel, "GetConsoleWindow"); - if (cryptui && !OPENSSL_isservice()) - ctx->client_cert_select = cert_select_dialog; - } -# endif - - /* See if there is RSA+AES CSP */ - if (CryptAcquireContextW(&hprov, NULL, rsa_aes_cspname, PROV_RSA_AES, - CRYPT_VERIFYCONTEXT)) { - use_aes_csp = 1; - CryptReleaseContext(hprov, 0); - } - - return 1; - - err: - return 0; -} - -static int capi_destroy(ENGINE *e) -{ - RSA_meth_free(capi_rsa_method); - capi_rsa_method = NULL; -# ifndef OPENSSL_NO_DSA - DSA_meth_free(capi_dsa_method); - capi_dsa_method = NULL; -# endif - ERR_unload_CAPI_strings(); - return 1; -} - -static int capi_finish(ENGINE *e) -{ - CAPI_CTX *ctx; - ctx = ENGINE_get_ex_data(e, capi_idx); - capi_ctx_free(ctx); - ENGINE_set_ex_data(e, capi_idx, NULL); - return 1; -} - -/* - * CryptoAPI key application data. This contains a handle to the private key - * container (for sign operations) and a handle to the key (for decrypt - * operations). - */ - -struct CAPI_KEY_st { - /* Associated certificate context (if any) */ - PCCERT_CONTEXT pcert; - HCRYPTPROV hprov; - HCRYPTKEY key; - DWORD keyspec; -}; - -static int bind_capi(ENGINE *e) -{ - capi_rsa_method = RSA_meth_new("CryptoAPI RSA method", 0); - if (capi_rsa_method == NULL) - return 0; -# ifndef OPENSSL_NO_DSA - capi_dsa_method = DSA_meth_new("CryptoAPI DSA method", 0); - if (capi_dsa_method == NULL) - goto memerr; -# endif - if (!ENGINE_set_id(e, engine_capi_id) - || !ENGINE_set_name(e, engine_capi_name) - || !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) - || !ENGINE_set_init_function(e, capi_init) - || !ENGINE_set_finish_function(e, capi_finish) - || !ENGINE_set_destroy_function(e, capi_destroy) - || !ENGINE_set_RSA(e, capi_rsa_method) -# ifndef OPENSSL_NO_DSA - || !ENGINE_set_DSA(e, capi_dsa_method) -# endif - || !ENGINE_set_load_privkey_function(e, capi_load_privkey) - || !ENGINE_set_load_ssl_client_cert_function(e, - capi_load_ssl_client_cert) - || !ENGINE_set_cmd_defns(e, capi_cmd_defns) - || !ENGINE_set_ctrl_function(e, capi_ctrl)) - goto memerr; - ERR_load_CAPI_strings(); - - return 1; - memerr: - RSA_meth_free(capi_rsa_method); - capi_rsa_method = NULL; -# ifndef OPENSSL_NO_DSA - DSA_meth_free(capi_dsa_method); - capi_dsa_method = NULL; -# endif - return 0; -} - -static ENGINE *engine_capi(void) -{ - ENGINE *ret = ENGINE_new(); - if (ret == NULL) - return NULL; - if (!bind_capi(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void engine_load_capi_int(void) -{ - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_capi(); - if (!toadd) - return; - ERR_set_mark(); - ENGINE_add(toadd); - /* - * If the "add" worked, it gets a structural reference. So either way, we - * release our just-created reference. - */ - ENGINE_free(toadd); - /* - * If the "add" didn't work, it was probably a conflict because it was - * already added (eg. someone calling ENGINE_load_blah then calling - * ENGINE_load_builtin_engines() perhaps). - */ - ERR_pop_to_mark(); -} - -static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen) -{ - int i; - /* - * Reverse buffer in place: since this is a keyblob structure that will - * be freed up after conversion anyway it doesn't matter if we change - * it. - */ - for (i = 0; i < binlen / 2; i++) { - unsigned char c; - c = bin[i]; - bin[i] = bin[binlen - i - 1]; - bin[binlen - i - 1] = c; - } - - if (!BN_bin2bn(bin, binlen, bn)) - return 0; - return 1; -} - -/* Given a CAPI_KEY get an EVP_PKEY structure */ - -static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY *key) -{ - unsigned char *pubkey = NULL; - DWORD len; - BLOBHEADER *bh; - RSA *rkey = NULL; - DSA *dkey = NULL; - EVP_PKEY *ret = NULL; - if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len)) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR); - capi_addlasterror(); - return NULL; - } - - pubkey = OPENSSL_malloc(len); - - if (pubkey == NULL) - goto err; - - if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len)) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR); - capi_addlasterror(); - goto err; - } - - bh = (BLOBHEADER *) pubkey; - if (bh->bType != PUBLICKEYBLOB) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB); - goto err; - } - if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX) { - RSAPUBKEY *rp; - DWORD rsa_modlen; - BIGNUM *e = NULL, *n = NULL; - unsigned char *rsa_modulus; - rp = (RSAPUBKEY *) (bh + 1); - if (rp->magic != 0x31415352) { - char magstr[10]; - BIO_snprintf(magstr, 10, "%lx", rp->magic); - CAPIerr(CAPI_F_CAPI_GET_PKEY, - CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); - ERR_add_error_data(2, "magic=0x", magstr); - goto err; - } - rsa_modulus = (unsigned char *)(rp + 1); - rkey = RSA_new_method(eng); - if (!rkey) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_RSA_LIB); - goto err; - } - - e = BN_new(); - n = BN_new(); - - if (e == NULL || n == NULL) { - BN_free(e); - BN_free(n); - CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_BN_LIB); - goto err; - } - - RSA_set0_key(rkey, n, e, NULL); - - if (!BN_set_word(e, rp->pubexp)) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_BN_LIB); - goto err; - } - - rsa_modlen = rp->bitlen / 8; - if (!lend_tobn(n, rsa_modulus, rsa_modlen)) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_BN_LIB); - goto err; - } - - RSA_set_ex_data(rkey, rsa_capi_idx, key); - - if ((ret = EVP_PKEY_new()) == NULL) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_EVP_LIB); - goto err; - } - - EVP_PKEY_assign_RSA(ret, rkey); - rkey = NULL; - -# ifndef OPENSSL_NO_DSA - } else if (bh->aiKeyAlg == CALG_DSS_SIGN) { - DSSPUBKEY *dp; - DWORD dsa_plen; - unsigned char *btmp; - BIGNUM *p, *q, *g, *pub_key; - dp = (DSSPUBKEY *) (bh + 1); - if (dp->magic != 0x31535344) { - char magstr[10]; - BIO_snprintf(magstr, 10, "%lx", dp->magic); - CAPIerr(CAPI_F_CAPI_GET_PKEY, - CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); - ERR_add_error_data(2, "magic=0x", magstr); - goto err; - } - dsa_plen = dp->bitlen / 8; - btmp = (unsigned char *)(dp + 1); - dkey = DSA_new_method(eng); - if (!dkey) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_DSA_LIB); - goto err; - } - p = BN_new(); - q = BN_new(); - g = BN_new(); - pub_key = BN_new(); - if (p == NULL || q == NULL || g == NULL || pub_key == NULL) { - BN_free(p); - BN_free(q); - BN_free(g); - BN_free(pub_key); - CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_BN_LIB); - goto err; - } - DSA_set0_pqg(dkey, p, q, g); - DSA_set0_key(dkey, pub_key, NULL); - if (!lend_tobn(p, btmp, dsa_plen)) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_CAPI_LIB); - goto err; - } - btmp += dsa_plen; - if (!lend_tobn(q, btmp, 20)) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_CAPI_LIB); - goto err; - } - btmp += 20; - if (!lend_tobn(g, btmp, dsa_plen)) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_CAPI_LIB); - goto err; - } - btmp += dsa_plen; - if (!lend_tobn(pub_key, btmp, dsa_plen)) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_CAPI_LIB); - goto err; - } - btmp += dsa_plen; - - DSA_set_ex_data(dkey, dsa_capi_idx, key); - - if ((ret = EVP_PKEY_new()) == NULL) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_EVP_LIB); - goto err; - } - - EVP_PKEY_assign_DSA(ret, dkey); - dkey = NULL; -# endif - } else { - char algstr[10]; - BIO_snprintf(algstr, 10, "%ux", bh->aiKeyAlg); - CAPIerr(CAPI_F_CAPI_GET_PKEY, - CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM); - ERR_add_error_data(2, "aiKeyAlg=0x", algstr); - goto err; - } - - err: - OPENSSL_free(pubkey); - if (!ret) { - RSA_free(rkey); -# ifndef OPENSSL_NO_DSA - DSA_free(dkey); -# endif - } - - return ret; -} - -static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, void *callback_data) -{ - CAPI_CTX *ctx; - CAPI_KEY *key; - EVP_PKEY *ret; - ctx = ENGINE_get_ex_data(eng, capi_idx); - - if (!ctx) { - CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT); - return NULL; - } - - key = capi_find_key(ctx, key_id); - - if (!key) - return NULL; - - ret = capi_get_pkey(eng, key); - - if (!ret) - capi_free_key(key); - return ret; - -} - -/* CryptoAPI RSA operations */ - -int capi_rsa_priv_enc(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - CAPIerr(CAPI_F_CAPI_RSA_PRIV_ENC, CAPI_R_FUNCTION_NOT_SUPPORTED); - return -1; -} - -int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len, - unsigned char *sigret, unsigned int *siglen, const RSA *rsa) -{ - ALG_ID alg; - HCRYPTHASH hash; - DWORD slen; - unsigned int i; - int ret = -1; - CAPI_KEY *capi_key; - CAPI_CTX *ctx; - - ctx = ENGINE_get_ex_data(RSA_get0_engine(rsa), capi_idx); - - CAPI_trace(ctx, "Called CAPI_rsa_sign()\n"); - - capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); - if (!capi_key) { - CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY); - return -1; - } - /* Convert the signature type to a CryptoAPI algorithm ID */ - switch (dtype) { - case NID_sha256: - alg = CALG_SHA_256; - break; - - case NID_sha384: - alg = CALG_SHA_384; - break; - - case NID_sha512: - alg = CALG_SHA_512; - break; - - case NID_sha1: - alg = CALG_SHA1; - break; - - case NID_md5: - alg = CALG_MD5; - break; - - case NID_md5_sha1: - alg = CALG_SSL3_SHAMD5; - break; - default: - { - char algstr[10]; - BIO_snprintf(algstr, 10, "%x", dtype); - CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID); - ERR_add_error_data(2, "NID=0x", algstr); - return -1; - } - } - - /* Create the hash object */ - if (!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash)) { - CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT); - capi_addlasterror(); - return -1; - } - /* Set the hash value to the value passed */ - - if (!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0)) { - CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE); - capi_addlasterror(); - goto err; - } - - /* Finally sign it */ - slen = RSA_size(rsa); - if (!CryptSignHash(hash, capi_key->keyspec, NULL, 0, sigret, &slen)) { - CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH); - capi_addlasterror(); - goto err; - } else { - ret = 1; - /* Inplace byte reversal of signature */ - for (i = 0; i < slen / 2; i++) { - unsigned char c; - c = sigret[i]; - sigret[i] = sigret[slen - i - 1]; - sigret[slen - i - 1] = c; - } - *siglen = slen; - } - - /* Now cleanup */ - - err: - CryptDestroyHash(hash); - - return ret; -} - -int capi_rsa_priv_dec(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - int i; - unsigned char *tmpbuf; - CAPI_KEY *capi_key; - CAPI_CTX *ctx; - DWORD flags = 0; - DWORD dlen; - - if (flen <= 0) - return flen; - - ctx = ENGINE_get_ex_data(RSA_get0_engine(rsa), capi_idx); - - CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n"); - - capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); - if (!capi_key) { - CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY); - return -1; - } - - switch (padding) { - case RSA_PKCS1_PADDING: - /* Nothing to do */ - break; -#ifdef CRYPT_DECRYPT_RSA_NO_PADDING_CHECK - case RSA_NO_PADDING: - flags = CRYPT_DECRYPT_RSA_NO_PADDING_CHECK; - break; -#endif - default: - { - char errstr[10]; - BIO_snprintf(errstr, 10, "%d", padding); - CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING); - ERR_add_error_data(2, "padding=", errstr); - return -1; - } - } - - /* Create temp reverse order version of input */ - if ((tmpbuf = OPENSSL_malloc(flen)) == NULL) - return -1; - for (i = 0; i < flen; i++) - tmpbuf[flen - i - 1] = from[i]; - - /* Finally decrypt it */ - dlen = flen; - if (!CryptDecrypt(capi_key->key, 0, TRUE, flags, tmpbuf, &dlen)) { - CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR); - capi_addlasterror(); - OPENSSL_cleanse(tmpbuf, dlen); - OPENSSL_free(tmpbuf); - return -1; - } else { - memcpy(to, tmpbuf, (flen = (int)dlen)); - } - OPENSSL_cleanse(tmpbuf, flen); - OPENSSL_free(tmpbuf); - - return flen; -} - -static int capi_rsa_free(RSA *rsa) -{ - CAPI_KEY *capi_key; - capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); - capi_free_key(capi_key); - RSA_set_ex_data(rsa, rsa_capi_idx, 0); - return 1; -} - -# ifndef OPENSSL_NO_DSA -/* CryptoAPI DSA operations */ - -static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, - DSA *dsa) -{ - HCRYPTHASH hash; - DWORD slen; - DSA_SIG *ret = NULL; - CAPI_KEY *capi_key; - CAPI_CTX *ctx; - unsigned char csigbuf[40]; - - ctx = ENGINE_get_ex_data(DSA_get0_engine(dsa), capi_idx); - - CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n"); - - capi_key = DSA_get_ex_data(dsa, dsa_capi_idx); - - if (!capi_key) { - CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY); - return NULL; - } - - if (dlen != 20) { - CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH); - return NULL; - } - - /* Create the hash object */ - if (!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash)) { - CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT); - capi_addlasterror(); - return NULL; - } - - /* Set the hash value to the value passed */ - if (!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0)) { - CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE); - capi_addlasterror(); - goto err; - } - - /* Finally sign it */ - slen = sizeof(csigbuf); - if (!CryptSignHash(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen)) { - CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH); - capi_addlasterror(); - goto err; - } else { - BIGNUM *r = BN_new(), *s = BN_new(); - - if (r == NULL || s == NULL - || !lend_tobn(r, csigbuf, 20) - || !lend_tobn(s, csigbuf + 20, 20) - || (ret = DSA_SIG_new()) == NULL) { - BN_free(r); /* BN_free checks for BIGNUM * being NULL */ - BN_free(s); - goto err; - } - DSA_SIG_set0(ret, r, s); - } - - /* Now cleanup */ - - err: - OPENSSL_cleanse(csigbuf, 40); - CryptDestroyHash(hash); - return ret; -} - -static int capi_dsa_free(DSA *dsa) -{ - CAPI_KEY *capi_key; - capi_key = DSA_get_ex_data(dsa, dsa_capi_idx); - capi_free_key(capi_key); - DSA_set_ex_data(dsa, dsa_capi_idx, 0); - return 1; -} -# endif - -static void capi_vtrace(CAPI_CTX *ctx, int level, char *format, - va_list argptr) -{ - BIO *out; - - if (!ctx || (ctx->debug_level < level) || (!ctx->debug_file)) - return; - out = BIO_new_file(ctx->debug_file, "a+"); - if (out == NULL) { - CAPIerr(CAPI_F_CAPI_VTRACE, CAPI_R_FILE_OPEN_ERROR); - return; - } - BIO_vprintf(out, format, argptr); - BIO_free(out); -} - -static void CAPI_trace(CAPI_CTX *ctx, char *format, ...) -{ - va_list args; - va_start(args, format); - capi_vtrace(ctx, CAPI_DBG_TRACE, format, args); - va_end(args); -} - -static void capi_addlasterror(void) -{ - capi_adderror(GetLastError()); -} - -static void capi_adderror(DWORD err) -{ - char errstr[10]; - BIO_snprintf(errstr, 10, "%lX", err); - ERR_add_error_data(2, "Error code= 0x", errstr); -} - -static char *wide_to_asc(LPCWSTR wstr) -{ - char *str; - int len_0, sz; - size_t len_1; - - if (!wstr) - return NULL; - - len_1 = wcslen(wstr) + 1; - - if (len_1 > INT_MAX) { - CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_FUNCTION_NOT_SUPPORTED); - return NULL; - } - - len_0 = (int)len_1; /* WideCharToMultiByte expects int */ - sz = WideCharToMultiByte(CP_ACP, 0, wstr, len_0, NULL, 0, NULL, NULL); - if (!sz) { - CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR); - return NULL; - } - str = OPENSSL_malloc(sz); - if (str == NULL) - return NULL; - if (!WideCharToMultiByte(CP_ACP, 0, wstr, len_0, str, sz, NULL, NULL)) { - OPENSSL_free(str); - CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR); - return NULL; - } - return str; -} - -static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, - DWORD idx) -{ - DWORD len, err; - LPTSTR name; - CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx); - if (!CryptEnumProviders(idx, NULL, 0, ptype, NULL, &len)) { - err = GetLastError(); - if (err == ERROR_NO_MORE_ITEMS) - return 2; - CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR); - capi_adderror(err); - return 0; - } - name = OPENSSL_malloc(len); - if (name == NULL) - return 0; - if (!CryptEnumProviders(idx, NULL, 0, ptype, name, &len)) { - err = GetLastError(); - OPENSSL_free(name); - if (err == ERROR_NO_MORE_ITEMS) - return 2; - CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR); - capi_adderror(err); - return 0; - } - if (sizeof(TCHAR) != sizeof(char)) { - *pname = wide_to_asc((WCHAR *)name); - OPENSSL_free(name); - if (*pname == NULL) - return 0; - } else { - *pname = (char *)name; - } - CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", *pname, - *ptype); - - return 1; -} - -static int capi_list_providers(CAPI_CTX *ctx, BIO *out) -{ - DWORD idx, ptype; - int ret; - LPSTR provname = NULL; - CAPI_trace(ctx, "capi_list_providers\n"); - BIO_printf(out, "Available CSPs:\n"); - for (idx = 0;; idx++) { - ret = capi_get_provname(ctx, &provname, &ptype, idx); - if (ret == 2) - break; - if (ret == 0) - break; - BIO_printf(out, "%lu. %s, type %lu\n", idx, provname, ptype); - OPENSSL_free(provname); - } - return 1; -} - -static int capi_list_containers(CAPI_CTX *ctx, BIO *out) -{ - int ret = 1; - HCRYPTPROV hprov; - DWORD err, idx, flags, buflen = 0, clen; - LPSTR cname; - LPWSTR cspname = NULL; - - CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, - ctx->csptype); - if (ctx->cspname != NULL) { - if ((clen = MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, - NULL, 0))) { - cspname = alloca(clen * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, (WCHAR *)cspname, - clen); - } - if (cspname == NULL) { - CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE); - capi_addlasterror(); - return 0; - } - } - if (!CryptAcquireContextW(&hprov, NULL, cspname, ctx->csptype, - CRYPT_VERIFYCONTEXT)) { - CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, - CAPI_R_CRYPTACQUIRECONTEXT_ERROR); - capi_addlasterror(); - return 0; - } - if (!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, NULL, &buflen, - CRYPT_FIRST)) { - CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR); - capi_addlasterror(); - CryptReleaseContext(hprov, 0); - return 0; - } - CAPI_trace(ctx, "Got max container len %d\n", buflen); - if (buflen == 0) - buflen = 1024; - cname = OPENSSL_malloc(buflen); - if (cname == NULL) - goto err; - - for (idx = 0;; idx++) { - clen = buflen; - cname[0] = 0; - - if (idx == 0) - flags = CRYPT_FIRST; - else - flags = 0; - if (!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, (BYTE *)cname, - &clen, flags)) { - err = GetLastError(); - if (err == ERROR_NO_MORE_ITEMS) - goto done; - CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR); - capi_adderror(err); - goto err; - } - CAPI_trace(ctx, "Container name %s, len=%d, index=%d, flags=%d\n", - cname, clen, idx, flags); - if (!cname[0] && (clen == buflen)) { - CAPI_trace(ctx, "Enumerate bug: using workaround\n"); - goto done; - } - BIO_printf(out, "%lu. %s\n", idx, cname); - } - err: - - ret = 0; - - done: - OPENSSL_free(cname); - CryptReleaseContext(hprov, 0); - - return ret; -} - -static CRYPT_KEY_PROV_INFO *capi_get_prov_info(CAPI_CTX *ctx, - PCCERT_CONTEXT cert) -{ - DWORD len; - CRYPT_KEY_PROV_INFO *pinfo; - - if (!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, - NULL, &len)) - return NULL; - pinfo = OPENSSL_malloc(len); - if (pinfo == NULL) - return NULL; - if (!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, - pinfo, &len)) { - CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, - CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO); - capi_addlasterror(); - OPENSSL_free(pinfo); - return NULL; - } - return pinfo; -} - -static void capi_dump_prov_info(CAPI_CTX *ctx, BIO *out, - CRYPT_KEY_PROV_INFO *pinfo) -{ - char *provname = NULL, *contname = NULL; - - if (pinfo == NULL) { - BIO_printf(out, " No Private Key\n"); - return; - } - provname = wide_to_asc(pinfo->pwszProvName); - contname = wide_to_asc(pinfo->pwszContainerName); - if (provname == NULL || contname == NULL) - goto err; - - BIO_printf(out, " Private Key Info:\n"); - BIO_printf(out, " Provider Name: %s, Provider Type %lu\n", provname, - pinfo->dwProvType); - BIO_printf(out, " Container Name: %s, Key Type %lu\n", contname, - pinfo->dwKeySpec); - err: - OPENSSL_free(provname); - OPENSSL_free(contname); -} - -static char *capi_cert_get_fname(CAPI_CTX *ctx, PCCERT_CONTEXT cert) -{ - LPWSTR wfname; - DWORD dlen; - - CAPI_trace(ctx, "capi_cert_get_fname\n"); - if (!CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, - NULL, &dlen)) - return NULL; - wfname = OPENSSL_malloc(dlen); - if (wfname == NULL) - return NULL; - if (CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, - wfname, &dlen)) { - char *fname = wide_to_asc(wfname); - OPENSSL_free(wfname); - return fname; - } - CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME); - capi_addlasterror(); - - OPENSSL_free(wfname); - return NULL; -} - -static void capi_dump_cert(CAPI_CTX *ctx, BIO *out, PCCERT_CONTEXT cert) -{ - X509 *x; - const unsigned char *p; - unsigned long flags = ctx->dump_flags; - if (flags & CAPI_DMP_FNAME) { - char *fname; - fname = capi_cert_get_fname(ctx, cert); - if (fname) { - BIO_printf(out, " Friendly Name \"%s\"\n", fname); - OPENSSL_free(fname); - } else { - BIO_printf(out, " \n"); - } - } - - p = cert->pbCertEncoded; - x = d2i_X509(NULL, &p, cert->cbCertEncoded); - if (!x) - BIO_printf(out, " \n"); - if (flags & CAPI_DMP_SUMMARY) { - BIO_printf(out, " Subject: "); - X509_NAME_print_ex(out, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); - BIO_printf(out, "\n Issuer: "); - X509_NAME_print_ex(out, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE); - BIO_printf(out, "\n"); - } - if (flags & CAPI_DMP_FULL) - X509_print_ex(out, x, XN_FLAG_ONELINE, 0); - - if (flags & CAPI_DMP_PKEYINFO) { - CRYPT_KEY_PROV_INFO *pinfo; - pinfo = capi_get_prov_info(ctx, cert); - capi_dump_prov_info(ctx, out, pinfo); - OPENSSL_free(pinfo); - } - - if (flags & CAPI_DMP_PEM) - PEM_write_bio_X509(out, x); - X509_free(x); -} - -static HCERTSTORE capi_open_store(CAPI_CTX *ctx, char *storename) -{ - HCERTSTORE hstore; - - if (!storename) - storename = ctx->storename; - if (!storename) - storename = "MY"; - CAPI_trace(ctx, "Opening certificate store %s\n", storename); - - hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, - ctx->store_flags, storename); - if (!hstore) { - CAPIerr(CAPI_F_CAPI_OPEN_STORE, CAPI_R_ERROR_OPENING_STORE); - capi_addlasterror(); - } - return hstore; -} - -int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *id) -{ - char *storename; - int idx; - int ret = 1; - HCERTSTORE hstore; - PCCERT_CONTEXT cert = NULL; - - storename = ctx->storename; - if (!storename) - storename = "MY"; - CAPI_trace(ctx, "Listing certs for store %s\n", storename); - - hstore = capi_open_store(ctx, storename); - if (!hstore) - return 0; - if (id) { - cert = capi_find_cert(ctx, id, hstore); - if (!cert) { - ret = 0; - goto err; - } - capi_dump_cert(ctx, out, cert); - CertFreeCertificateContext(cert); - } else { - for (idx = 0;; idx++) { - cert = CertEnumCertificatesInStore(hstore, cert); - if (!cert) - break; - BIO_printf(out, "Certificate %d\n", idx); - capi_dump_cert(ctx, out, cert); - } - } - err: - CertCloseStore(hstore, 0); - return ret; -} - -static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, - HCERTSTORE hstore) -{ - PCCERT_CONTEXT cert = NULL; - char *fname = NULL; - int match; - switch (ctx->lookup_method) { - case CAPI_LU_SUBSTR: - return CertFindCertificateInStore(hstore, X509_ASN_ENCODING, 0, - CERT_FIND_SUBJECT_STR_A, id, NULL); - case CAPI_LU_FNAME: - for (;;) { - cert = CertEnumCertificatesInStore(hstore, cert); - if (!cert) - return NULL; - fname = capi_cert_get_fname(ctx, cert); - if (fname) { - if (strcmp(fname, id)) - match = 0; - else - match = 1; - OPENSSL_free(fname); - if (match) - return cert; - } - } - default: - return NULL; - } -} - -static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const WCHAR *contname, - const WCHAR *provname, DWORD ptype, - DWORD keyspec) -{ - DWORD dwFlags = 0; - CAPI_KEY *key = OPENSSL_malloc(sizeof(*key)); - - if (key == NULL) - return NULL; - /* If PROV_RSA_AES supported use it instead */ - if (ptype == PROV_RSA_FULL && use_aes_csp && - wcscmp(provname, rsa_enh_cspname) == 0) { - provname = rsa_aes_cspname; - ptype = PROV_RSA_AES; - } - if (ctx && ctx->debug_level >= CAPI_DBG_TRACE && ctx->debug_file) { - /* - * above 'if' is [complementary] copy from CAPI_trace and serves - * as optimization to minimize [below] malloc-ations - */ - char *_contname = wide_to_asc(contname); - char *_provname = wide_to_asc(provname); - - CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", - _contname, _provname, ptype); - OPENSSL_free(_provname); - OPENSSL_free(_contname); - } - if (ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE) - dwFlags = CRYPT_MACHINE_KEYSET; - if (!CryptAcquireContextW(&key->hprov, contname, provname, ptype, - dwFlags)) { - CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR); - capi_addlasterror(); - goto err; - } - if (!CryptGetUserKey(key->hprov, keyspec, &key->key)) { - CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR); - capi_addlasterror(); - CryptReleaseContext(key->hprov, 0); - goto err; - } - key->keyspec = keyspec; - key->pcert = NULL; - return key; - - err: - OPENSSL_free(key); - return NULL; -} - -static CAPI_KEY *capi_get_cert_key(CAPI_CTX *ctx, PCCERT_CONTEXT cert) -{ - CAPI_KEY *key = NULL; - CRYPT_KEY_PROV_INFO *pinfo = NULL; - - pinfo = capi_get_prov_info(ctx, cert); - - if (pinfo != NULL) - key = capi_get_key(ctx, pinfo->pwszContainerName, pinfo->pwszProvName, - pinfo->dwProvType, pinfo->dwKeySpec); - - OPENSSL_free(pinfo); - return key; -} - -CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id) -{ - PCCERT_CONTEXT cert; - HCERTSTORE hstore; - CAPI_KEY *key = NULL; - - switch (ctx->lookup_method) { - case CAPI_LU_SUBSTR: - case CAPI_LU_FNAME: - hstore = capi_open_store(ctx, NULL); - if (!hstore) - return NULL; - cert = capi_find_cert(ctx, id, hstore); - if (cert) { - key = capi_get_cert_key(ctx, cert); - CertFreeCertificateContext(cert); - } - CertCloseStore(hstore, 0); - break; - - case CAPI_LU_CONTNAME: - { - WCHAR *contname, *provname; - DWORD len; - - if ((len = MultiByteToWideChar(CP_ACP, 0, id, -1, NULL, 0)) && - (contname = alloca(len * sizeof(WCHAR)), - MultiByteToWideChar(CP_ACP, 0, id, -1, contname, len)) && - (len = MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, - NULL, 0)) && - (provname = alloca(len * sizeof(WCHAR)), - MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, - provname, len))) - key = capi_get_key(ctx, contname, provname, - ctx->csptype, ctx->keytype); - } - break; - } - - return key; -} - -void capi_free_key(CAPI_KEY *key) -{ - if (!key) - return; - CryptDestroyKey(key->key); - CryptReleaseContext(key->hprov, 0); - if (key->pcert) - CertFreeCertificateContext(key->pcert); - OPENSSL_free(key); -} - -/* Initialize a CAPI_CTX structure */ - -static CAPI_CTX *capi_ctx_new(void) -{ - CAPI_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); - - if (ctx == NULL) - return NULL; - ctx->csptype = PROV_RSA_FULL; - ctx->dump_flags = CAPI_DMP_SUMMARY | CAPI_DMP_FNAME; - ctx->keytype = AT_KEYEXCHANGE; - ctx->store_flags = CERT_STORE_OPEN_EXISTING_FLAG | - CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_CURRENT_USER; - ctx->lookup_method = CAPI_LU_SUBSTR; - ctx->client_cert_select = cert_select_simple; - return ctx; -} - -static void capi_ctx_free(CAPI_CTX *ctx) -{ - CAPI_trace(ctx, "Calling capi_ctx_free with %lx\n", ctx); - if (!ctx) - return; - OPENSSL_free(ctx->cspname); - OPENSSL_free(ctx->debug_file); - OPENSSL_free(ctx->storename); - OPENSSL_free(ctx->ssl_client_store); - OPENSSL_free(ctx); -} - -static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, - int check) -{ - LPSTR tmpcspname; - - CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type); - if (check) { - HCRYPTPROV hprov; - LPWSTR name = NULL; - DWORD len; - - if ((len = MultiByteToWideChar(CP_ACP, 0, pname, -1, NULL, 0))) { - name = alloca(len * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, pname, -1, (WCHAR *)name, len); - } - if (name == NULL || !CryptAcquireContextW(&hprov, NULL, name, type, - CRYPT_VERIFYCONTEXT)) { - CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, - CAPI_R_CRYPTACQUIRECONTEXT_ERROR); - capi_addlasterror(); - return 0; - } - CryptReleaseContext(hprov, 0); - } - tmpcspname = OPENSSL_strdup(pname); - if (tmpcspname == NULL) - return 0; - OPENSSL_free(ctx->cspname); - ctx->cspname = tmpcspname; - ctx->csptype = type; - return 1; -} - -static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx) -{ - LPSTR pname; - DWORD type; - int res; - if (capi_get_provname(ctx, &pname, &type, idx) != 1) - return 0; - res = capi_ctx_set_provname(ctx, pname, type, 0); - OPENSSL_free(pname); - return res; -} - -static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x) -{ - int i; - X509_NAME *nm; - /* Special case: empty list: match anything */ - if (sk_X509_NAME_num(ca_dn) <= 0) - return 1; - for (i = 0; i < sk_X509_NAME_num(ca_dn); i++) { - nm = sk_X509_NAME_value(ca_dn, i); - if (!X509_NAME_cmp(nm, X509_get_issuer_name(x))) - return 1; - } - return 0; -} - -static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, - STACK_OF(X509_NAME) *ca_dn, X509 **pcert, - EVP_PKEY **pkey, STACK_OF(X509) **pother, - UI_METHOD *ui_method, - void *callback_data) -{ - STACK_OF(X509) *certs = NULL; - X509 *x; - char *storename; - const unsigned char *p; - int i, client_cert_idx; - HCERTSTORE hstore; - PCCERT_CONTEXT cert = NULL, excert = NULL; - CAPI_CTX *ctx; - CAPI_KEY *key; - ctx = ENGINE_get_ex_data(e, capi_idx); - - *pcert = NULL; - *pkey = NULL; - - storename = ctx->ssl_client_store; - if (!storename) - storename = "MY"; - - hstore = capi_open_store(ctx, storename); - if (!hstore) - return 0; - /* Enumerate all certificates collect any matches */ - for (i = 0;; i++) { - cert = CertEnumCertificatesInStore(hstore, cert); - if (!cert) - break; - p = cert->pbCertEncoded; - x = d2i_X509(NULL, &p, cert->cbCertEncoded); - if (!x) { - CAPI_trace(ctx, "Can't Parse Certificate %d\n", i); - continue; - } - if (cert_issuer_match(ca_dn, x) - && X509_check_purpose(x, X509_PURPOSE_SSL_CLIENT, 0)) { - key = capi_get_cert_key(ctx, cert); - if (!key) { - X509_free(x); - continue; - } - /* - * Match found: attach extra data to it so we can retrieve the - * key later. - */ - excert = CertDuplicateCertificateContext(cert); - key->pcert = excert; - X509_set_ex_data(x, cert_capi_idx, key); - - if (!certs) - certs = sk_X509_new_null(); - - if (!sk_X509_push(certs, x)) { - X509_free(x); - continue; - } - } else { - X509_free(x); - } - } - - if (cert) - CertFreeCertificateContext(cert); - if (hstore) - CertCloseStore(hstore, 0); - - if (!certs) - return 0; - - /* Select the appropriate certificate */ - - client_cert_idx = ctx->client_cert_select(e, ssl, certs); - - /* Set the selected certificate and free the rest */ - - for (i = 0; i < sk_X509_num(certs); i++) { - x = sk_X509_value(certs, i); - if (i == client_cert_idx) - *pcert = x; - else { - key = X509_get_ex_data(x, cert_capi_idx); - capi_free_key(key); - X509_free(x); - } - } - - sk_X509_free(certs); - - if (*pcert == NULL) - return 0; - - /* Setup key for selected certificate */ - - key = X509_get_ex_data(*pcert, cert_capi_idx); - *pkey = capi_get_pkey(e, key); - X509_set_ex_data(*pcert, cert_capi_idx, NULL); - - return 1; - -} - -/* Simple client cert selection function: always select first */ - -static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs) -{ - return 0; -} - -# ifdef OPENSSL_CAPIENG_DIALOG - -/* - * More complex cert selection function, using standard function - * CryptUIDlgSelectCertificateFromStore() to produce a dialog box. - */ - -/* - * Definitions which are in cryptuiapi.h but this is not present in older - * versions of headers. - */ - -# ifndef CRYPTUI_SELECT_LOCATION_COLUMN -# define CRYPTUI_SELECT_LOCATION_COLUMN 0x000000010 -# define CRYPTUI_SELECT_INTENDEDUSE_COLUMN 0x000000004 -# endif - -# define dlg_title L"OpenSSL Application SSL Client Certificate Selection" -# define dlg_prompt L"Select a certificate to use for authentication" -# define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \ - |CRYPTUI_SELECT_INTENDEDUSE_COLUMN - -static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs) -{ - X509 *x; - HCERTSTORE dstore; - PCCERT_CONTEXT cert; - CAPI_CTX *ctx; - CAPI_KEY *key; - HWND hwnd; - int i, idx = -1; - if (sk_X509_num(certs) == 1) - return 0; - ctx = ENGINE_get_ex_data(e, capi_idx); - /* Create an in memory store of certificates */ - dstore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, - CERT_STORE_CREATE_NEW_FLAG, NULL); - if (!dstore) { - CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_CREATING_STORE); - capi_addlasterror(); - goto err; - } - /* Add all certificates to store */ - for (i = 0; i < sk_X509_num(certs); i++) { - x = sk_X509_value(certs, i); - key = X509_get_ex_data(x, cert_capi_idx); - - if (!CertAddCertificateContextToStore(dstore, key->pcert, - CERT_STORE_ADD_NEW, NULL)) { - CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_ADDING_CERT); - capi_addlasterror(); - goto err; - } - - } - hwnd = GetForegroundWindow(); - if (!hwnd) - hwnd = GetActiveWindow(); - if (!hwnd && ctx->getconswindow) - hwnd = ctx->getconswindow(); - /* Call dialog to select one */ - cert = ctx->certselectdlg(dstore, hwnd, dlg_title, dlg_prompt, - dlg_columns, 0, NULL); - - /* Find matching cert from list */ - if (cert) { - for (i = 0; i < sk_X509_num(certs); i++) { - x = sk_X509_value(certs, i); - key = X509_get_ex_data(x, cert_capi_idx); - if (CertCompareCertificate - (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert->pCertInfo, - key->pcert->pCertInfo)) { - idx = i; - break; - } - } - } - - err: - if (dstore) - CertCloseStore(dstore, 0); - return idx; - -} -# endif - -#else /* !__COMPILE_CAPIENG */ -# include -void engine_load_capi_int(void); -void engine_load_capi_int(void) -{ -} -#endif diff --git a/engines/e_capi.ec b/engines/e_capi.ec deleted file mode 100644 index d9c7aa510fd..00000000000 --- a/engines/e_capi.ec +++ /dev/null @@ -1,3 +0,0 @@ -# The INPUT HEADER is scanned for declarations -# LIBNAME INPUT HEADER ERROR-TABLE FILE -L CAPI e_capi_err.h e_capi_err.c diff --git a/engines/e_capi.txt b/engines/e_capi.txt deleted file mode 100644 index 58f4a159623..00000000000 --- a/engines/e_capi.txt +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 1999-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 - -#Reason codes -CAPI_R_CANT_CREATE_HASH_OBJECT:100:can't create hash object -CAPI_R_CANT_FIND_CAPI_CONTEXT:101:can't find capi context -CAPI_R_CANT_GET_KEY:102:can't get key -CAPI_R_CANT_SET_HASH_VALUE:103:can't set hash value -CAPI_R_CRYPTACQUIRECONTEXT_ERROR:104:cryptacquirecontext error -CAPI_R_CRYPTENUMPROVIDERS_ERROR:105:cryptenumproviders error -CAPI_R_DECRYPT_ERROR:106:decrypt error -CAPI_R_ENGINE_NOT_INITIALIZED:107:engine not initialized -CAPI_R_ENUMCONTAINERS_ERROR:108:enumcontainers error -CAPI_R_ERROR_ADDING_CERT:109:error adding cert -CAPI_R_ERROR_CREATING_STORE:110:error creating store -CAPI_R_ERROR_GETTING_FRIENDLY_NAME:111:error getting friendly name -CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO:112:error getting key provider info -CAPI_R_ERROR_OPENING_STORE:113:error opening store -CAPI_R_ERROR_SIGNING_HASH:114:error signing hash -CAPI_R_FILE_OPEN_ERROR:115:file open error -CAPI_R_FUNCTION_NOT_SUPPORTED:116:function not supported -CAPI_R_GETUSERKEY_ERROR:117:getuserkey error -CAPI_R_INVALID_DIGEST_LENGTH:118:invalid digest length -CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER:119:\ - invalid dsa public key blob magic number -CAPI_R_INVALID_LOOKUP_METHOD:120:invalid lookup method -CAPI_R_INVALID_PUBLIC_KEY_BLOB:121:invalid public key blob -CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER:122:\ - invalid rsa public key blob magic number -CAPI_R_PUBKEY_EXPORT_ERROR:123:pubkey export error -CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR:124:pubkey export length error -CAPI_R_UNKNOWN_COMMAND:125:unknown command -CAPI_R_UNSUPPORTED_ALGORITHM_NID:126:unsupported algorithm nid -CAPI_R_UNSUPPORTED_PADDING:127:unsupported padding -CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM:128:unsupported public key algorithm -CAPI_R_WIN32_ERROR:129:win32 error diff --git a/engines/e_capi_err.c b/engines/e_capi_err.c deleted file mode 100644 index 2588c153044..00000000000 --- a/engines/e_capi_err.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * 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 - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "e_capi_err.h" - -#ifndef OPENSSL_NO_ERR - -static ERR_STRING_DATA CAPI_str_reasons[] = { - {ERR_PACK(0, 0, CAPI_R_CANT_CREATE_HASH_OBJECT), "can't create hash object"}, - {ERR_PACK(0, 0, CAPI_R_CANT_FIND_CAPI_CONTEXT), "can't find capi context"}, - {ERR_PACK(0, 0, CAPI_R_CANT_GET_KEY), "can't get key"}, - {ERR_PACK(0, 0, CAPI_R_CANT_SET_HASH_VALUE), "can't set hash value"}, - {ERR_PACK(0, 0, CAPI_R_CRYPTACQUIRECONTEXT_ERROR), - "cryptacquirecontext error"}, - {ERR_PACK(0, 0, CAPI_R_CRYPTENUMPROVIDERS_ERROR), - "cryptenumproviders error"}, - {ERR_PACK(0, 0, CAPI_R_DECRYPT_ERROR), "decrypt error"}, - {ERR_PACK(0, 0, CAPI_R_ENGINE_NOT_INITIALIZED), "engine not initialized"}, - {ERR_PACK(0, 0, CAPI_R_ENUMCONTAINERS_ERROR), "enumcontainers error"}, - {ERR_PACK(0, 0, CAPI_R_ERROR_ADDING_CERT), "error adding cert"}, - {ERR_PACK(0, 0, CAPI_R_ERROR_CREATING_STORE), "error creating store"}, - {ERR_PACK(0, 0, CAPI_R_ERROR_GETTING_FRIENDLY_NAME), - "error getting friendly name"}, - {ERR_PACK(0, 0, CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO), - "error getting key provider info"}, - {ERR_PACK(0, 0, CAPI_R_ERROR_OPENING_STORE), "error opening store"}, - {ERR_PACK(0, 0, CAPI_R_ERROR_SIGNING_HASH), "error signing hash"}, - {ERR_PACK(0, 0, CAPI_R_FILE_OPEN_ERROR), "file open error"}, - {ERR_PACK(0, 0, CAPI_R_FUNCTION_NOT_SUPPORTED), "function not supported"}, - {ERR_PACK(0, 0, CAPI_R_GETUSERKEY_ERROR), "getuserkey error"}, - {ERR_PACK(0, 0, CAPI_R_INVALID_DIGEST_LENGTH), "invalid digest length"}, - {ERR_PACK(0, 0, CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER), - "invalid dsa public key blob magic number"}, - {ERR_PACK(0, 0, CAPI_R_INVALID_LOOKUP_METHOD), "invalid lookup method"}, - {ERR_PACK(0, 0, CAPI_R_INVALID_PUBLIC_KEY_BLOB), "invalid public key blob"}, - {ERR_PACK(0, 0, CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER), - "invalid rsa public key blob magic number"}, - {ERR_PACK(0, 0, CAPI_R_PUBKEY_EXPORT_ERROR), "pubkey export error"}, - {ERR_PACK(0, 0, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR), - "pubkey export length error"}, - {ERR_PACK(0, 0, CAPI_R_UNKNOWN_COMMAND), "unknown command"}, - {ERR_PACK(0, 0, CAPI_R_UNSUPPORTED_ALGORITHM_NID), - "unsupported algorithm nid"}, - {ERR_PACK(0, 0, CAPI_R_UNSUPPORTED_PADDING), "unsupported padding"}, - {ERR_PACK(0, 0, CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM), - "unsupported public key algorithm"}, - {ERR_PACK(0, 0, CAPI_R_WIN32_ERROR), "win32 error"}, - {0, NULL} -}; - -#endif - -static int lib_code = 0; -static int error_loaded = 0; - -static int ERR_load_CAPI_strings(void) -{ - if (lib_code == 0) - lib_code = ERR_get_next_error_library(); - - if (!error_loaded) { -#ifndef OPENSSL_NO_ERR - ERR_load_strings(lib_code, CAPI_str_reasons); -#endif - error_loaded = 1; - } - return 1; -} - -static void ERR_unload_CAPI_strings(void) -{ - if (error_loaded) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(lib_code, CAPI_str_reasons); -#endif - error_loaded = 0; - } -} - -static void ERR_CAPI_error(int function, int reason, const char *file, int line) -{ - if (lib_code == 0) - lib_code = ERR_get_next_error_library(); - ERR_raise(lib_code, reason); - ERR_set_debug(file, line, NULL); -} - -static int ERR_CAPI_lib(void) -{ - if (lib_code == 0) - lib_code = ERR_get_next_error_library(); - return lib_code; -} diff --git a/engines/e_capi_err.h b/engines/e_capi_err.h deleted file mode 100644 index 480a8269d3a..00000000000 --- a/engines/e_capi_err.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2022 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 - */ - -#ifndef OSSL_E_CAPI_ERR_H -# define OSSL_E_CAPI_ERR_H -# pragma once - -# include -# include - - -# define CAPIerr(f, r) ERR_CAPI_error(0, (r), OPENSSL_FILE, OPENSSL_LINE) -# define ERR_R_CAPI_LIB ERR_CAPI_lib() - - -/* - * CAPI reason codes. - */ -# define CAPI_R_CANT_CREATE_HASH_OBJECT 100 -# define CAPI_R_CANT_FIND_CAPI_CONTEXT 101 -# define CAPI_R_CANT_GET_KEY 102 -# define CAPI_R_CANT_SET_HASH_VALUE 103 -# define CAPI_R_CRYPTACQUIRECONTEXT_ERROR 104 -# define CAPI_R_CRYPTENUMPROVIDERS_ERROR 105 -# define CAPI_R_DECRYPT_ERROR 106 -# define CAPI_R_ENGINE_NOT_INITIALIZED 107 -# define CAPI_R_ENUMCONTAINERS_ERROR 108 -# define CAPI_R_ERROR_ADDING_CERT 109 -# define CAPI_R_ERROR_CREATING_STORE 110 -# define CAPI_R_ERROR_GETTING_FRIENDLY_NAME 111 -# define CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO 112 -# define CAPI_R_ERROR_OPENING_STORE 113 -# define CAPI_R_ERROR_SIGNING_HASH 114 -# define CAPI_R_FILE_OPEN_ERROR 115 -# define CAPI_R_FUNCTION_NOT_SUPPORTED 116 -# define CAPI_R_GETUSERKEY_ERROR 117 -# define CAPI_R_INVALID_DIGEST_LENGTH 118 -# define CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER 119 -# define CAPI_R_INVALID_LOOKUP_METHOD 120 -# define CAPI_R_INVALID_PUBLIC_KEY_BLOB 121 -# define CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER 122 -# define CAPI_R_PUBKEY_EXPORT_ERROR 123 -# define CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR 124 -# define CAPI_R_UNKNOWN_COMMAND 125 -# define CAPI_R_UNSUPPORTED_ALGORITHM_NID 126 -# define CAPI_R_UNSUPPORTED_PADDING 127 -# define CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM 128 -# define CAPI_R_WIN32_ERROR 129 - -#endif diff --git a/engines/e_dasync.c b/engines/e_dasync.c deleted file mode 100644 index 300d061e4e2..00000000000 --- a/engines/e_dasync.c +++ /dev/null @@ -1,994 +0,0 @@ -/* - * Copyright 2015-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 - * https://www.openssl.org/source/license.html - */ - -/* We need to use some engine deprecated APIs */ -#define OPENSSL_SUPPRESS_DEPRECATED - -/* - * SHA-1 low level APIs are deprecated for public use, but still ok for - * internal use. Note, that due to symbols not being exported, only the - * #defines and structures can be accessed, in this case SHA_CBLOCK and - * sizeof(SHA_CTX). - */ -#include "internal/deprecated.h" - -#include -#if defined(_WIN32) -# include -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(OPENSSL_SYS_UNIX) && defined(OPENSSL_THREADS) -# undef ASYNC_POSIX -# define ASYNC_POSIX -# include -#elif defined(_WIN32) -# undef ASYNC_WIN -# define ASYNC_WIN -#endif - -/* clang-format off */ -#include "e_dasync_err.c" -/* clang-format on */ - -/* Engine Id and Name */ -static const char *engine_dasync_id = "dasync"; -static const char *engine_dasync_name = "Dummy Async engine support"; - - -/* Engine Lifetime functions */ -static int dasync_destroy(ENGINE *e); -static int dasync_init(ENGINE *e); -static int dasync_finish(ENGINE *e); -void engine_load_dasync_int(void); - - -/* Set up digests. Just SHA1 for now */ -static int dasync_digests(ENGINE *e, const EVP_MD **digest, - const int **nids, int nid); - -static void dummy_pause_job(void); - -/* SHA1 */ -static int dasync_sha1_init(EVP_MD_CTX *ctx); -static int dasync_sha1_update(EVP_MD_CTX *ctx, const void *data, - size_t count); -static int dasync_sha1_final(EVP_MD_CTX *ctx, unsigned char *md); - -/* - * Holds the EVP_MD object for sha1 in this engine. Set up once only during - * engine bind and can then be reused many times. - */ -static EVP_MD *_hidden_sha1_md = NULL; -static const EVP_MD *dasync_sha1(void) -{ - return _hidden_sha1_md; -} -static void destroy_digests(void) -{ - EVP_MD_meth_free(_hidden_sha1_md); - _hidden_sha1_md = NULL; -} - -static int dasync_digest_nids(const int **nids) -{ - static int digest_nids[2] = { 0, 0 }; - static int pos = 0; - static int init = 0; - - if (!init) { - const EVP_MD *md; - if ((md = dasync_sha1()) != NULL) - digest_nids[pos++] = EVP_MD_get_type(md); - digest_nids[pos] = 0; - init = 1; - } - *nids = digest_nids; - return pos; -} - -/* RSA */ -static int dasync_pkey(ENGINE *e, EVP_PKEY_METHOD **pmeth, - const int **pnids, int nid); - -static int dasync_rsa_init(EVP_PKEY_CTX *ctx); -static void dasync_rsa_cleanup(EVP_PKEY_CTX *ctx); -static int dasync_rsa_paramgen_init(EVP_PKEY_CTX *ctx); -static int dasync_rsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); -static int dasync_rsa_keygen_init(EVP_PKEY_CTX *ctx); -static int dasync_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); -static int dasync_rsa_encrypt_init(EVP_PKEY_CTX *ctx); -static int dasync_rsa_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *in, - size_t inlen); -static int dasync_rsa_decrypt_init(EVP_PKEY_CTX *ctx); -static int dasync_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *in, - size_t inlen); -static int dasync_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); -static int dasync_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, - const char *value); - -static EVP_PKEY_METHOD *dasync_rsa; -static const EVP_PKEY_METHOD *dasync_rsa_orig; - -/* AES */ - -static int dasync_aes128_cbc_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, - void *ptr); -static int dasync_aes128_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); -static int dasync_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl); -static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx); - -static int dasync_aes256_ctr_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, - void *ptr); -static int dasync_aes256_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); -static int dasync_aes256_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl); -static int dasync_aes256_ctr_cleanup(EVP_CIPHER_CTX *ctx); - -static int dasync_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, - int arg, void *ptr); -static int dasync_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *key, - const unsigned char *iv, - int enc); -static int dasync_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, - unsigned char *out, - const unsigned char *in, - size_t inl); -static int dasync_aes128_cbc_hmac_sha1_cleanup(EVP_CIPHER_CTX *ctx); - -struct dasync_pipeline_ctx { - void *inner_cipher_data; - unsigned int numpipes; - unsigned char **inbufs; - unsigned char **outbufs; - size_t *lens; - unsigned char tlsaad[SSL_MAX_PIPELINES][EVP_AEAD_TLS1_AAD_LEN]; - unsigned int aadctr; -}; - -/* - * Holds the EVP_CIPHER object for aes_128_cbc in this engine. Set up once only - * during engine bind and can then be reused many times. - */ -static EVP_CIPHER *_hidden_aes_128_cbc = NULL; -static const EVP_CIPHER *dasync_aes_128_cbc(void) -{ - return _hidden_aes_128_cbc; -} - -static EVP_CIPHER *_hidden_aes_256_ctr = NULL; -static const EVP_CIPHER *dasync_aes_256_ctr(void) -{ - return _hidden_aes_256_ctr; -} - -/* - * Holds the EVP_CIPHER object for aes_128_cbc_hmac_sha1 in this engine. Set up - * once only during engine bind and can then be reused many times. - * - * This 'stitched' cipher depends on the EVP_aes_128_cbc_hmac_sha1() cipher, - * which is implemented only if the AES-NI instruction set extension is available - * (see OPENSSL_IA32CAP(3)). If that's not the case, then this cipher will not - * be available either. - * - * Note: Since it is a legacy mac-then-encrypt cipher, modern TLS peers (which - * negotiate the encrypt-then-mac extension) won't negotiate it anyway. - */ -static EVP_CIPHER *_hidden_aes_128_cbc_hmac_sha1 = NULL; -static const EVP_CIPHER *dasync_aes_128_cbc_hmac_sha1(void) -{ - return _hidden_aes_128_cbc_hmac_sha1; -} - -static void destroy_ciphers(void) -{ - EVP_CIPHER_meth_free(_hidden_aes_128_cbc); - EVP_CIPHER_meth_free(_hidden_aes_256_ctr); - EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1); - _hidden_aes_128_cbc = NULL; - _hidden_aes_256_ctr = NULL; - _hidden_aes_128_cbc_hmac_sha1 = NULL; -} - -static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid); - -static int dasync_cipher_nids[] = { - NID_aes_128_cbc, - NID_aes_256_ctr, - NID_aes_128_cbc_hmac_sha1, - 0 -}; - -static int bind_dasync(ENGINE *e) -{ - /* Setup RSA */ - if ((dasync_rsa_orig = EVP_PKEY_meth_find(EVP_PKEY_RSA)) == NULL - || (dasync_rsa = EVP_PKEY_meth_new(EVP_PKEY_RSA, - EVP_PKEY_FLAG_AUTOARGLEN)) == NULL) - return 0; - EVP_PKEY_meth_set_init(dasync_rsa, dasync_rsa_init); - EVP_PKEY_meth_set_cleanup(dasync_rsa, dasync_rsa_cleanup); - EVP_PKEY_meth_set_paramgen(dasync_rsa, dasync_rsa_paramgen_init, - dasync_rsa_paramgen); - EVP_PKEY_meth_set_keygen(dasync_rsa, dasync_rsa_keygen_init, - dasync_rsa_keygen); - EVP_PKEY_meth_set_encrypt(dasync_rsa, dasync_rsa_encrypt_init, - dasync_rsa_encrypt); - EVP_PKEY_meth_set_decrypt(dasync_rsa, dasync_rsa_decrypt_init, - dasync_rsa_decrypt); - EVP_PKEY_meth_set_ctrl(dasync_rsa, dasync_rsa_ctrl, - dasync_rsa_ctrl_str); - - /* Ensure the dasync error handling is set up */ - ERR_load_DASYNC_strings(); - - if (!ENGINE_set_id(e, engine_dasync_id) - || !ENGINE_set_name(e, engine_dasync_name) - || !ENGINE_set_pkey_meths(e, dasync_pkey) - || !ENGINE_set_digests(e, dasync_digests) - || !ENGINE_set_ciphers(e, dasync_ciphers) - || !ENGINE_set_destroy_function(e, dasync_destroy) - || !ENGINE_set_init_function(e, dasync_init) - || !ENGINE_set_finish_function(e, dasync_finish)) { - DASYNCerr(DASYNC_F_BIND_DASYNC, DASYNC_R_INIT_FAILED); - return 0; - } - - /* - * Set up the EVP_CIPHER and EVP_MD objects for the ciphers/digests - * supplied by this engine - */ - _hidden_sha1_md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption); - if (_hidden_sha1_md == NULL - || !EVP_MD_meth_set_result_size(_hidden_sha1_md, SHA_DIGEST_LENGTH) - || !EVP_MD_meth_set_input_blocksize(_hidden_sha1_md, SHA_CBLOCK) - || !EVP_MD_meth_set_app_datasize(_hidden_sha1_md, - sizeof(EVP_MD *) + sizeof(SHA_CTX)) - || !EVP_MD_meth_set_flags(_hidden_sha1_md, EVP_MD_FLAG_DIGALGID_ABSENT) - || !EVP_MD_meth_set_init(_hidden_sha1_md, dasync_sha1_init) - || !EVP_MD_meth_set_update(_hidden_sha1_md, dasync_sha1_update) - || !EVP_MD_meth_set_final(_hidden_sha1_md, dasync_sha1_final)) { - EVP_MD_meth_free(_hidden_sha1_md); - _hidden_sha1_md = NULL; - } - - _hidden_aes_128_cbc = EVP_CIPHER_meth_new(NID_aes_128_cbc, - 16 /* block size */, - 16 /* key len */); - if (_hidden_aes_128_cbc == NULL - || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc,16) - || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc, - EVP_CIPH_FLAG_DEFAULT_ASN1 - | EVP_CIPH_CBC_MODE - | EVP_CIPH_FLAG_PIPELINE - | EVP_CIPH_CUSTOM_COPY) - || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc, - dasync_aes128_init_key) - || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc, - dasync_aes128_cbc_cipher) - || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_128_cbc, - dasync_aes128_cbc_cleanup) - || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc, - dasync_aes128_cbc_ctrl) - || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc, - sizeof(struct dasync_pipeline_ctx))) { - EVP_CIPHER_meth_free(_hidden_aes_128_cbc); - _hidden_aes_128_cbc = NULL; - } - - _hidden_aes_256_ctr = EVP_CIPHER_meth_new(NID_aes_256_ctr, - 1 /* block size */, - 32 /* key len */); - if (_hidden_aes_256_ctr == NULL - || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_256_ctr,16) - || !EVP_CIPHER_meth_set_flags(_hidden_aes_256_ctr, - EVP_CIPH_FLAG_DEFAULT_ASN1 - | EVP_CIPH_CTR_MODE - | EVP_CIPH_FLAG_PIPELINE - | EVP_CIPH_CUSTOM_COPY) - || !EVP_CIPHER_meth_set_init(_hidden_aes_256_ctr, - dasync_aes256_init_key) - || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_256_ctr, - dasync_aes256_ctr_cipher) - || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_256_ctr, - dasync_aes256_ctr_cleanup) - || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_256_ctr, - dasync_aes256_ctr_ctrl) - || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_256_ctr, - sizeof(struct dasync_pipeline_ctx))) { - EVP_CIPHER_meth_free(_hidden_aes_256_ctr); - _hidden_aes_256_ctr = NULL; - } - - _hidden_aes_128_cbc_hmac_sha1 = EVP_CIPHER_meth_new( - NID_aes_128_cbc_hmac_sha1, - 16 /* block size */, - 16 /* key len */); - if (_hidden_aes_128_cbc_hmac_sha1 == NULL - || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc_hmac_sha1,16) - || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc_hmac_sha1, - EVP_CIPH_CBC_MODE - | EVP_CIPH_FLAG_DEFAULT_ASN1 - | EVP_CIPH_FLAG_AEAD_CIPHER - | EVP_CIPH_FLAG_PIPELINE - | EVP_CIPH_CUSTOM_COPY) - || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc_hmac_sha1, - dasync_aes128_cbc_hmac_sha1_init_key) - || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc_hmac_sha1, - dasync_aes128_cbc_hmac_sha1_cipher) - || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_128_cbc_hmac_sha1, - dasync_aes128_cbc_hmac_sha1_cleanup) - || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc_hmac_sha1, - dasync_aes128_cbc_hmac_sha1_ctrl) - || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc_hmac_sha1, - sizeof(struct dasync_pipeline_ctx))) { - EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1); - _hidden_aes_128_cbc_hmac_sha1 = NULL; - } - - return 1; -} - -static void destroy_pkey(void) -{ - /* - * We don't actually need to free the dasync_rsa method since this is - * automatically freed for us by libcrypto. - */ - dasync_rsa_orig = NULL; - dasync_rsa = NULL; -} - -static ENGINE *engine_dasync(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_dasync(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void engine_load_dasync_int(void) -{ - ENGINE *toadd = engine_dasync(); - if (!toadd) - return; - ERR_set_mark(); - ENGINE_add(toadd); - /* - * If the "add" worked, it gets a structural reference. So either way, we - * release our just-created reference. - */ - ENGINE_free(toadd); - /* - * If the "add" didn't work, it was probably a conflict because it was - * already added (eg. someone calling ENGINE_load_blah then calling - * ENGINE_load_builtin_engines() perhaps). - */ - ERR_pop_to_mark(); -} - -static int dasync_init(ENGINE *e) -{ - return 1; -} - - -static int dasync_finish(ENGINE *e) -{ - return 1; -} - - -static int dasync_destroy(ENGINE *e) -{ - destroy_digests(); - destroy_ciphers(); - destroy_pkey(); - ERR_unload_DASYNC_strings(); - return 1; -} - -static int dasync_pkey(ENGINE *e, EVP_PKEY_METHOD **pmeth, - const int **pnids, int nid) -{ - static const int rnid = EVP_PKEY_RSA; - - if (pmeth == NULL) { - *pnids = &rnid; - return 1; - } - - if (nid == EVP_PKEY_RSA) { - *pmeth = dasync_rsa; - return 1; - } - - *pmeth = NULL; - return 0; -} - -static int dasync_digests(ENGINE *e, const EVP_MD **digest, - const int **nids, int nid) -{ - int ok = 1; - if (!digest) { - /* We are returning a list of supported nids */ - return dasync_digest_nids(nids); - } - /* We are being asked for a specific digest */ - switch (nid) { - case NID_sha1: - *digest = dasync_sha1(); - break; - default: - ok = 0; - *digest = NULL; - break; - } - return ok; -} - -static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid) -{ - int ok = 1; - if (cipher == NULL) { - /* We are returning a list of supported nids */ - *nids = dasync_cipher_nids; - return (sizeof(dasync_cipher_nids) - - 1) / sizeof(dasync_cipher_nids[0]); - } - /* We are being asked for a specific cipher */ - switch (nid) { - case NID_aes_128_cbc: - *cipher = dasync_aes_128_cbc(); - break; - case NID_aes_256_ctr: - *cipher = dasync_aes_256_ctr(); - break; - case NID_aes_128_cbc_hmac_sha1: - *cipher = dasync_aes_128_cbc_hmac_sha1(); - break; - default: - ok = 0; - *cipher = NULL; - break; - } - return ok; -} - -static void wait_cleanup(ASYNC_WAIT_CTX *ctx, const void *key, - OSSL_ASYNC_FD readfd, void *pvwritefd) -{ - OSSL_ASYNC_FD *pwritefd = (OSSL_ASYNC_FD *)pvwritefd; -#if defined(ASYNC_WIN) - CloseHandle(readfd); - CloseHandle(*pwritefd); -#elif defined(ASYNC_POSIX) - close(readfd); - close(*pwritefd); -#endif - OPENSSL_free(pwritefd); -} - -#define DUMMY_CHAR 'X' - -static void dummy_pause_job(void) { - ASYNC_JOB *job; - ASYNC_WAIT_CTX *waitctx; - ASYNC_callback_fn callback; - void *callback_arg; - OSSL_ASYNC_FD pipefds[2] = {0, 0}; - OSSL_ASYNC_FD *writefd; -#if defined(ASYNC_WIN) - DWORD numwritten, numread; - char buf = DUMMY_CHAR; -#elif defined(ASYNC_POSIX) - char buf = DUMMY_CHAR; -#endif - - if ((job = ASYNC_get_current_job()) == NULL) - return; - - waitctx = ASYNC_get_wait_ctx(job); - - if (ASYNC_WAIT_CTX_get_callback(waitctx, &callback, &callback_arg) && callback != NULL) { - /* - * In the Dummy async engine we are cheating. We call the callback that the job - * is complete before the call to ASYNC_pause_job(). A real - * async engine would only call the callback when the job was actually complete - */ - (*callback)(callback_arg); - ASYNC_pause_job(); - return; - } - - - if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_dasync_id, &pipefds[0], - (void **)&writefd)) { - pipefds[1] = *writefd; - } else { - writefd = OPENSSL_malloc(sizeof(*writefd)); - if (writefd == NULL) - return; -#if defined(ASYNC_WIN) - if (CreatePipe(&pipefds[0], &pipefds[1], NULL, 256) == 0) { - OPENSSL_free(writefd); - return; - } -#elif defined(ASYNC_POSIX) - if (pipe(pipefds) != 0) { - OPENSSL_free(writefd); - return; - } -#endif - *writefd = pipefds[1]; - - if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_dasync_id, pipefds[0], - writefd, wait_cleanup)) { - wait_cleanup(waitctx, engine_dasync_id, pipefds[0], writefd); - return; - } - } - /* - * In the Dummy async engine we are cheating. We signal that the job - * is complete by waking it before the call to ASYNC_pause_job(). A real - * async engine would only wake when the job was actually complete - */ -#if defined(ASYNC_WIN) - WriteFile(pipefds[1], &buf, 1, &numwritten, NULL); -#elif defined(ASYNC_POSIX) - if (write(pipefds[1], &buf, 1) < 0) - return; -#endif - - /* Ignore errors - we carry on anyway */ - ASYNC_pause_job(); - - /* Clear the wake signal */ -#if defined(ASYNC_WIN) - ReadFile(pipefds[0], &buf, 1, &numread, NULL); -#elif defined(ASYNC_POSIX) - if (read(pipefds[0], &buf, 1) < 0) - return; -#endif -} - -/* - * SHA1 implementation. At the moment we just defer to the standard - * implementation - */ -static int dasync_sha1_init(EVP_MD_CTX *ctx) -{ - dummy_pause_job(); - - return EVP_MD_meth_get_init(EVP_sha1())(ctx); -} - -static int dasync_sha1_update(EVP_MD_CTX *ctx, const void *data, - size_t count) -{ - dummy_pause_job(); - - return EVP_MD_meth_get_update(EVP_sha1())(ctx, data, count); -} - -static int dasync_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) -{ - dummy_pause_job(); - - return EVP_MD_meth_get_final(EVP_sha1())(ctx, md); -} - -/* Cipher helper functions */ - -static int dasync_cipher_ctrl_helper(EVP_CIPHER_CTX *ctx, int type, int arg, - void *ptr, int aeadcapable, - const EVP_CIPHER *ciph) -{ - int ret; - struct dasync_pipeline_ctx *pipe_ctx = - (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); - - if (pipe_ctx == NULL) - return 0; - - switch (type) { - case EVP_CTRL_COPY: - { - size_t sz = EVP_CIPHER_impl_ctx_size(ciph); - void *inner_cipher_data = OPENSSL_malloc(sz); - - if (inner_cipher_data == NULL) - return -1; - memcpy(inner_cipher_data, pipe_ctx->inner_cipher_data, sz); - pipe_ctx->inner_cipher_data = inner_cipher_data; - } - break; - - case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS: - pipe_ctx->numpipes = arg; - pipe_ctx->outbufs = (unsigned char **)ptr; - break; - - case EVP_CTRL_SET_PIPELINE_INPUT_BUFS: - pipe_ctx->numpipes = arg; - pipe_ctx->inbufs = (unsigned char **)ptr; - break; - - case EVP_CTRL_SET_PIPELINE_INPUT_LENS: - pipe_ctx->numpipes = arg; - pipe_ctx->lens = (size_t *)ptr; - break; - - case EVP_CTRL_AEAD_SET_MAC_KEY: - if (!aeadcapable) - return -1; - EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data); - ret = EVP_CIPHER_meth_get_ctrl(EVP_aes_128_cbc_hmac_sha1()) - (ctx, type, arg, ptr); - EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx); - return ret; - - case EVP_CTRL_AEAD_TLS1_AAD: - { - unsigned char *p = ptr; - unsigned int len; - - if (!aeadcapable || arg != EVP_AEAD_TLS1_AAD_LEN) - return -1; - - if (pipe_ctx->aadctr >= SSL_MAX_PIPELINES) - return -1; - - memcpy(pipe_ctx->tlsaad[pipe_ctx->aadctr], ptr, - EVP_AEAD_TLS1_AAD_LEN); - pipe_ctx->aadctr++; - - len = p[arg - 2] << 8 | p[arg - 1]; - - if (EVP_CIPHER_CTX_is_encrypting(ctx)) { - if ((p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) { - if (len < AES_BLOCK_SIZE) - return 0; - len -= AES_BLOCK_SIZE; - } - - return ((len + SHA_DIGEST_LENGTH + AES_BLOCK_SIZE) - & -AES_BLOCK_SIZE) - len; - } else { - return SHA_DIGEST_LENGTH; - } - } - - default: - return 0; - } - - return 1; -} - -static int dasync_cipher_init_key_helper(EVP_CIPHER_CTX *ctx, - const unsigned char *key, - const unsigned char *iv, int enc, - const EVP_CIPHER *cipher) -{ - int ret; - struct dasync_pipeline_ctx *pipe_ctx = - (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); - - if (pipe_ctx->inner_cipher_data == NULL - && EVP_CIPHER_impl_ctx_size(cipher) != 0) { - pipe_ctx->inner_cipher_data = OPENSSL_zalloc( - EVP_CIPHER_impl_ctx_size(cipher)); - if (pipe_ctx->inner_cipher_data == NULL) - return 0; - } - - pipe_ctx->numpipes = 0; - pipe_ctx->aadctr = 0; - - EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data); - ret = EVP_CIPHER_meth_get_init(cipher)(ctx, key, iv, enc); - EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx); - - return ret; -} - -static int dasync_cipher_helper(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl, - const EVP_CIPHER *cipher) -{ - int ret = 1; - unsigned int i, pipes; - struct dasync_pipeline_ctx *pipe_ctx = - (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); - - pipes = pipe_ctx->numpipes; - EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data); - if (pipes == 0) { - if (pipe_ctx->aadctr != 0) { - if (pipe_ctx->aadctr != 1) - return -1; - EVP_CIPHER_meth_get_ctrl(cipher) - (ctx, EVP_CTRL_AEAD_TLS1_AAD, - EVP_AEAD_TLS1_AAD_LEN, - pipe_ctx->tlsaad[0]); - } - ret = EVP_CIPHER_meth_get_do_cipher(cipher) - (ctx, out, in, inl); - } else { - if (pipe_ctx->aadctr > 0 && pipe_ctx->aadctr != pipes) - return -1; - for (i = 0; i < pipes; i++) { - if (pipe_ctx->aadctr > 0) { - EVP_CIPHER_meth_get_ctrl(cipher) - (ctx, EVP_CTRL_AEAD_TLS1_AAD, - EVP_AEAD_TLS1_AAD_LEN, - pipe_ctx->tlsaad[i]); - } - ret = ret && EVP_CIPHER_meth_get_do_cipher(cipher) - (ctx, pipe_ctx->outbufs[i], pipe_ctx->inbufs[i], - pipe_ctx->lens[i]); - } - pipe_ctx->numpipes = 0; - } - pipe_ctx->aadctr = 0; - EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx); - return ret; -} - -static int dasync_cipher_cleanup_helper(EVP_CIPHER_CTX *ctx, - const EVP_CIPHER *cipher) -{ - struct dasync_pipeline_ctx *pipe_ctx = - (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); - - OPENSSL_clear_free(pipe_ctx->inner_cipher_data, - EVP_CIPHER_impl_ctx_size(cipher)); - - return 1; -} - -/* - * AES128 CBC Implementation - */ - -static int dasync_aes128_cbc_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, - void *ptr) -{ - return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 0, EVP_aes_128_cbc()); -} - -static int dasync_aes128_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - return dasync_cipher_init_key_helper(ctx, key, iv, enc, EVP_aes_128_cbc()); -} - -static int dasync_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_128_cbc()); -} - -static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx) -{ - return dasync_cipher_cleanup_helper(ctx, EVP_aes_128_cbc()); -} - -static int dasync_aes256_ctr_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, - void *ptr) -{ - return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 0, EVP_aes_256_ctr()); -} - -static int dasync_aes256_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - return dasync_cipher_init_key_helper(ctx, key, iv, enc, EVP_aes_256_ctr()); -} - -static int dasync_aes256_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_256_ctr()); -} - -static int dasync_aes256_ctr_cleanup(EVP_CIPHER_CTX *ctx) -{ - return dasync_cipher_cleanup_helper(ctx, EVP_aes_256_ctr()); -} - - -/* - * AES128 CBC HMAC SHA1 Implementation - */ - -static int dasync_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, - int arg, void *ptr) -{ - return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 1, EVP_aes_128_cbc_hmac_sha1()); -} - -static int dasync_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *key, - const unsigned char *iv, - int enc) -{ - /* - * We can safely assume that EVP_aes_128_cbc_hmac_sha1() != NULL, - * see comment before the definition of dasync_aes_128_cbc_hmac_sha1(). - */ - return dasync_cipher_init_key_helper(ctx, key, iv, enc, - EVP_aes_128_cbc_hmac_sha1()); -} - -static int dasync_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, - unsigned char *out, - const unsigned char *in, - size_t inl) -{ - return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_128_cbc_hmac_sha1()); -} - -static int dasync_aes128_cbc_hmac_sha1_cleanup(EVP_CIPHER_CTX *ctx) -{ - /* - * We can safely assume that EVP_aes_128_cbc_hmac_sha1() != NULL, - * see comment before the definition of dasync_aes_128_cbc_hmac_sha1(). - */ - return dasync_cipher_cleanup_helper(ctx, EVP_aes_128_cbc_hmac_sha1()); -} - - -/* - * RSA implementation - */ -static int dasync_rsa_init(EVP_PKEY_CTX *ctx) -{ - static int (*pinit)(EVP_PKEY_CTX *ctx); - - if (pinit == NULL) - EVP_PKEY_meth_get_init(dasync_rsa_orig, &pinit); - return pinit(ctx); -} - -static void dasync_rsa_cleanup(EVP_PKEY_CTX *ctx) -{ - static void (*pcleanup)(EVP_PKEY_CTX *ctx); - - if (pcleanup == NULL) - EVP_PKEY_meth_get_cleanup(dasync_rsa_orig, &pcleanup); - pcleanup(ctx); -} - -static int dasync_rsa_paramgen_init(EVP_PKEY_CTX *ctx) -{ - static int (*pparamgen_init)(EVP_PKEY_CTX *ctx); - - if (pparamgen_init == NULL) - EVP_PKEY_meth_get_paramgen(dasync_rsa_orig, &pparamgen_init, NULL); - return pparamgen_init != NULL ? pparamgen_init(ctx) : 1; -} - -static int dasync_rsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - static int (*pparamgen)(EVP_PKEY_CTX *c, EVP_PKEY *pkey); - - if (pparamgen == NULL) - EVP_PKEY_meth_get_paramgen(dasync_rsa_orig, NULL, &pparamgen); - return pparamgen != NULL ? pparamgen(ctx, pkey) : 1; -} - -static int dasync_rsa_keygen_init(EVP_PKEY_CTX *ctx) -{ - static int (*pkeygen_init)(EVP_PKEY_CTX *ctx); - - if (pkeygen_init == NULL) - EVP_PKEY_meth_get_keygen(dasync_rsa_orig, &pkeygen_init, NULL); - return pkeygen_init != NULL ? pkeygen_init(ctx) : 1; -} - -static int dasync_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - static int (*pkeygen)(EVP_PKEY_CTX *c, EVP_PKEY *pkey); - - if (pkeygen == NULL) - EVP_PKEY_meth_get_keygen(dasync_rsa_orig, NULL, &pkeygen); - return pkeygen(ctx, pkey); -} - -static int dasync_rsa_encrypt_init(EVP_PKEY_CTX *ctx) -{ - static int (*pencrypt_init)(EVP_PKEY_CTX *ctx); - - if (pencrypt_init == NULL) - EVP_PKEY_meth_get_encrypt(dasync_rsa_orig, &pencrypt_init, NULL); - return pencrypt_init != NULL ? pencrypt_init(ctx) : 1; -} - -static int dasync_rsa_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *in, - size_t inlen) -{ - static int (*pencryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *in, - size_t inlen); - - if (pencryptfn == NULL) - EVP_PKEY_meth_get_encrypt(dasync_rsa_orig, NULL, &pencryptfn); - return pencryptfn(ctx, out, outlen, in, inlen); -} - -static int dasync_rsa_decrypt_init(EVP_PKEY_CTX *ctx) -{ - static int (*pdecrypt_init)(EVP_PKEY_CTX *ctx); - - if (pdecrypt_init == NULL) - EVP_PKEY_meth_get_decrypt(dasync_rsa_orig, &pdecrypt_init, NULL); - return pdecrypt_init != NULL ? pdecrypt_init(ctx) : 1; -} - -static int dasync_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *in, - size_t inlen) -{ - static int (*pdecrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *in, - size_t inlen); - - if (pdecrypt == NULL) - EVP_PKEY_meth_get_decrypt(dasync_rsa_orig, NULL, &pdecrypt); - return pdecrypt(ctx, out, outlen, in, inlen); -} - -static int dasync_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - static int (*pctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); - - if (pctrl == NULL) - EVP_PKEY_meth_get_ctrl(dasync_rsa_orig, &pctrl, NULL); - return pctrl(ctx, type, p1, p2); -} - -static int dasync_rsa_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, - const char *value) -{ - static int (*pctrl_str)(EVP_PKEY_CTX *ctx, const char *type, - const char *value); - - if (pctrl_str == NULL) - EVP_PKEY_meth_get_ctrl(dasync_rsa_orig, NULL, &pctrl_str); - return pctrl_str(ctx, type, value); -} diff --git a/engines/e_dasync.ec b/engines/e_dasync.ec deleted file mode 100644 index 3d56ebcc5f6..00000000000 --- a/engines/e_dasync.ec +++ /dev/null @@ -1,3 +0,0 @@ -# The INPUT HEADER is scanned for declarations -# LIBNAME INPUT HEADER ERROR-TABLE FILE -L DASYNC e_dasync_err.h e_dasync_err.c diff --git a/engines/e_dasync.txt b/engines/e_dasync.txt deleted file mode 100644 index d050a148c30..00000000000 --- a/engines/e_dasync.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright 1999-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 - -#Reason codes -DASYNC_R_INIT_FAILED:100:init failed diff --git a/engines/e_dasync_err.c b/engines/e_dasync_err.c deleted file mode 100644 index 16021f3196d..00000000000 --- a/engines/e_dasync_err.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-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 "e_dasync_err.h" - -#ifndef OPENSSL_NO_ERR - -static ERR_STRING_DATA DASYNC_str_reasons[] = { - {ERR_PACK(0, 0, DASYNC_R_INIT_FAILED), "init failed"}, - {0, NULL} -}; - -#endif - -static int lib_code = 0; -static int error_loaded = 0; - -static int ERR_load_DASYNC_strings(void) -{ - if (lib_code == 0) - lib_code = ERR_get_next_error_library(); - - if (!error_loaded) { -#ifndef OPENSSL_NO_ERR - ERR_load_strings(lib_code, DASYNC_str_reasons); -#endif - error_loaded = 1; - } - return 1; -} - -static void ERR_unload_DASYNC_strings(void) -{ - if (error_loaded) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(lib_code, DASYNC_str_reasons); -#endif - error_loaded = 0; - } -} - -static void ERR_DASYNC_error(int function, int reason, const char *file, int line) -{ - if (lib_code == 0) - lib_code = ERR_get_next_error_library(); - ERR_raise(lib_code, reason); - ERR_set_debug(file, line, NULL); -} diff --git a/engines/e_dasync_err.h b/engines/e_dasync_err.h deleted file mode 100644 index 7a067c6037a..00000000000 --- a/engines/e_dasync_err.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-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 - */ - -#ifndef OSSL_E_DASYNC_ERR_H -# define OSSL_E_DASYNC_ERR_H -# pragma once - -# include -# include - - -# define DASYNCerr(f, r) ERR_DASYNC_error(0, (r), OPENSSL_FILE, OPENSSL_LINE) - - -/* - * DASYNC reason codes. - */ -# define DASYNC_R_INIT_FAILED 100 - -#endif diff --git a/engines/e_devcrypto.c b/engines/e_devcrypto.c deleted file mode 100644 index 5b333fe4eee..00000000000 --- a/engines/e_devcrypto.c +++ /dev/null @@ -1,1361 +0,0 @@ -/* - * Copyright 2017-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 - */ - -/* We need to use some deprecated APIs */ -#define OPENSSL_SUPPRESS_DEPRECATED - -#include "internal/e_os.h" -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "crypto/cryptodev.h" -#include "internal/nelem.h" - -/* #define ENGINE_DEVCRYPTO_DEBUG */ - -#if CRYPTO_ALGORITHM_MIN < CRYPTO_ALGORITHM_MAX -# define CHECK_BSD_STYLE_MACROS -#endif - -#define engine_devcrypto_id "devcrypto" - -/* - * Use session2_op on FreeBSD which permits requesting specific - * drivers or classes of drivers at session creation time. - */ -#ifdef CIOCGSESSION2 -typedef struct session2_op session_op_t; -#else -typedef struct session_op session_op_t; -#endif - -/* - * ONE global file descriptor for all sessions. This allows operations - * such as digest session data copying (see digest_copy()), but is also - * saner... why re-open /dev/crypto for every session? - */ -static int cfd = -1; -#define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */ -#define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */ -#define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */ - -#define DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS DEVCRYPTO_REJECT_SOFTWARE -static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS; - -/* - * cipher/digest status & acceleration definitions - * Make sure the defaults are set to 0 - */ -struct driver_info_st { - enum devcrypto_status_t { - DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */ - DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */ - DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */ - DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */ - DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */ - } status; - - enum devcrypto_accelerated_t { - DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */ - DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unknown */ - DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */ - } accelerated; - - char *driver_name; -}; - -void engine_load_devcrypto_int(void); - -static int clean_devcrypto_session(session_op_t *sess) { - if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) { - ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); - return 0; - } - memset(sess, 0, sizeof(*sess)); - return 1; -} - -/****************************************************************************** - * - * Ciphers - * - * Because they all do the same basic operation, we have only one set of - * method functions for them all to share, and a mapping table between - * NIDs and cryptodev IDs, with all the necessary size data. - * - *****/ - -struct cipher_ctx { - session_op_t sess; - int op; /* COP_ENCRYPT or COP_DECRYPT */ - unsigned long mode; /* EVP_CIPH_*_MODE */ - - /* to handle ctr mode being a stream cipher */ - unsigned char partial[EVP_MAX_BLOCK_LENGTH]; - unsigned int blocksize, num; -}; - -static const struct cipher_data_st { - int nid; - int blocksize; - int keylen; - int ivlen; - int flags; - int devcryptoid; -} cipher_data[] = { -#ifndef OPENSSL_NO_DES - { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC }, - { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC }, -#endif -#ifndef OPENSSL_NO_BF - { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC }, -#endif -#ifndef OPENSSL_NO_CAST - { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC }, -#endif - { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, - { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, - { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, -#ifndef OPENSSL_NO_RC4 - { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4 }, -#endif -#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_CTR) - { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, - { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, - { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, -#endif -#if 0 /* Not yet supported */ - { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS }, - { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS }, -#endif -#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB) - { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, - { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, - { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, -#endif -#if 0 /* Not yet supported */ - { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, - { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, - { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, -#endif -#ifndef OPENSSL_NO_CAMELLIA - { NID_camellia_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, - CRYPTO_CAMELLIA_CBC }, - { NID_camellia_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, - CRYPTO_CAMELLIA_CBC }, - { NID_camellia_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, - CRYPTO_CAMELLIA_CBC }, -#endif -}; - -static size_t find_cipher_data_index(int nid) -{ - size_t i; - - for (i = 0; i < OSSL_NELEM(cipher_data); i++) - if (nid == cipher_data[i].nid) - return i; - return (size_t)-1; -} - -static size_t get_cipher_data_index(int nid) -{ - size_t i = find_cipher_data_index(nid); - - if (i != (size_t)-1) - return i; - - /* - * Code further down must make sure that only NIDs in the table above - * are used. If any other NID reaches this function, there's a grave - * coding error further down. - */ - assert("Code that never should be reached" == NULL); - return -1; -} - -static const struct cipher_data_st *get_cipher_data(int nid) -{ - return &cipher_data[get_cipher_data_index(nid)]; -} - -/* - * Following are the three necessary functions to map OpenSSL functionality - * with cryptodev. - */ - -static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - struct cipher_ctx *cipher_ctx = - (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); - const struct cipher_data_st *cipher_d = - get_cipher_data(EVP_CIPHER_CTX_get_nid(ctx)); - int ret; - - /* cleanup a previous session */ - if (cipher_ctx->sess.ses != 0 && - clean_devcrypto_session(&cipher_ctx->sess) == 0) - return 0; - - cipher_ctx->sess.cipher = cipher_d->devcryptoid; - cipher_ctx->sess.keylen = cipher_d->keylen; - cipher_ctx->sess.key = (void *)key; - cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT; - cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE; - cipher_ctx->blocksize = cipher_d->blocksize; -#ifdef CIOCGSESSION2 - cipher_ctx->sess.crid = (use_softdrivers == DEVCRYPTO_USE_SOFTWARE) ? - CRYPTO_FLAG_SOFTWARE | CRYPTO_FLAG_HARDWARE : - CRYPTO_FLAG_HARDWARE; - ret = ioctl(cfd, CIOCGSESSION2, &cipher_ctx->sess); -#else - ret = ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess); -#endif - if (ret < 0) { - ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); - return 0; - } - - return 1; -} - -static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - struct cipher_ctx *cipher_ctx = - (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); - struct crypt_op cryp; - unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); -#if !defined(COP_FLAG_WRITE_IV) - unsigned char saved_iv[EVP_MAX_IV_LENGTH]; - const unsigned char *ivptr; - size_t nblocks, ivlen; -#endif - - memset(&cryp, 0, sizeof(cryp)); - cryp.ses = cipher_ctx->sess.ses; - cryp.len = inl; - cryp.src = (void *)in; - cryp.dst = (void *)out; - cryp.iv = (void *)iv; - cryp.op = cipher_ctx->op; -#if !defined(COP_FLAG_WRITE_IV) - cryp.flags = 0; - - ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); - if (ivlen > 0) - switch (cipher_ctx->mode) { - case EVP_CIPH_CBC_MODE: - assert(inl >= ivlen); - if (!EVP_CIPHER_CTX_is_encrypting(ctx)) { - ivptr = in + inl - ivlen; - memcpy(saved_iv, ivptr, ivlen); - } - break; - - case EVP_CIPH_CTR_MODE: - break; - - default: /* should not happen */ - return 0; - } -#else - cryp.flags = COP_FLAG_WRITE_IV; -#endif - - if (ioctl(cfd, CIOCCRYPT, &cryp) < 0) { - ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); - return 0; - } - -#if !defined(COP_FLAG_WRITE_IV) - if (ivlen > 0) - switch (cipher_ctx->mode) { - case EVP_CIPH_CBC_MODE: - assert(inl >= ivlen); - if (EVP_CIPHER_CTX_is_encrypting(ctx)) - ivptr = out + inl - ivlen; - else - ivptr = saved_iv; - - memcpy(iv, ivptr, ivlen); - break; - - case EVP_CIPH_CTR_MODE: - nblocks = (inl + cipher_ctx->blocksize - 1) - / cipher_ctx->blocksize; - do { - ivlen--; - nblocks += iv[ivlen]; - iv[ivlen] = (uint8_t) nblocks; - nblocks >>= 8; - } while (ivlen); - break; - - default: /* should not happen */ - return 0; - } -#endif - - return 1; -} - -static int ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - struct cipher_ctx *cipher_ctx = - (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); - size_t nblocks, len; - - /* initial partial block */ - while (cipher_ctx->num && inl) { - (*out++) = *(in++) ^ cipher_ctx->partial[cipher_ctx->num]; - --inl; - cipher_ctx->num = (cipher_ctx->num + 1) % cipher_ctx->blocksize; - } - - /* full blocks */ - if (inl > cipher_ctx->blocksize) { - nblocks = inl/cipher_ctx->blocksize; - len = nblocks * cipher_ctx->blocksize; - if (cipher_do_cipher(ctx, out, in, len) < 1) - return 0; - inl -= len; - out += len; - in += len; - } - - /* final partial block */ - if (inl) { - memset(cipher_ctx->partial, 0, cipher_ctx->blocksize); - if (cipher_do_cipher(ctx, cipher_ctx->partial, cipher_ctx->partial, - cipher_ctx->blocksize) < 1) - return 0; - while (inl--) { - out[cipher_ctx->num] = in[cipher_ctx->num] - ^ cipher_ctx->partial[cipher_ctx->num]; - cipher_ctx->num++; - } - } - - return 1; -} - -static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2) -{ - struct cipher_ctx *cipher_ctx = - (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); - EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2; - struct cipher_ctx *to_cipher_ctx; - - switch (type) { - - case EVP_CTRL_COPY: - if (cipher_ctx == NULL) - return 1; - /* when copying the context, a new session needs to be initialized */ - to_cipher_ctx = - (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(to_ctx); - memset(&to_cipher_ctx->sess, 0, sizeof(to_cipher_ctx->sess)); - return cipher_init(to_ctx, (void *)cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx), - (cipher_ctx->op == COP_ENCRYPT)); - - case EVP_CTRL_INIT: - memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess)); - return 1; - - default: - break; - } - - return -1; -} - -static int cipher_cleanup(EVP_CIPHER_CTX *ctx) -{ - struct cipher_ctx *cipher_ctx = - (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); - - return clean_devcrypto_session(&cipher_ctx->sess); -} - -/* - * Keep tables of known nids, associated methods, selected ciphers, and driver - * info. - * Note that known_cipher_nids[] isn't necessarily indexed the same way as - * cipher_data[] above, which the other tables are. - */ -static int known_cipher_nids[OSSL_NELEM(cipher_data)]; -static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */ -static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, }; -static int selected_ciphers[OSSL_NELEM(cipher_data)]; -static struct driver_info_st cipher_driver_info[OSSL_NELEM(cipher_data)]; - - -static int devcrypto_test_cipher(size_t cipher_data_index) -{ - return (cipher_driver_info[cipher_data_index].status == DEVCRYPTO_STATUS_USABLE - && selected_ciphers[cipher_data_index] == 1 - && (cipher_driver_info[cipher_data_index].accelerated - == DEVCRYPTO_ACCELERATED - || use_softdrivers == DEVCRYPTO_USE_SOFTWARE - || (cipher_driver_info[cipher_data_index].accelerated - != DEVCRYPTO_NOT_ACCELERATED - && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE))); -} - -static void prepare_cipher_methods(void) -{ - size_t i; - session_op_t sess; - unsigned long cipher_mode; -#ifdef CIOCGSESSION2 - struct crypt_find_op fop; - enum devcrypto_accelerated_t accelerated; -#elif defined(CIOCGSESSINFO) - struct session_info_op siop; -#endif - - memset(&cipher_driver_info, 0, sizeof(cipher_driver_info)); - - memset(&sess, 0, sizeof(sess)); - sess.key = (void *)"01234567890123456789012345678901234567890123456789"; - - for (i = 0, known_cipher_nids_amount = 0; - i < OSSL_NELEM(cipher_data); i++) { - - selected_ciphers[i] = 1; - /* - * Check that the cipher is usable - */ - sess.cipher = cipher_data[i].devcryptoid; - sess.keylen = cipher_data[i].keylen; -#ifdef CIOCGSESSION2 - /* - * When using CIOCGSESSION2, first try to allocate a hardware - * ("accelerated") session. If that fails, fall back to - * allocating a software session. - */ - sess.crid = CRYPTO_FLAG_HARDWARE; - if (ioctl(cfd, CIOCGSESSION2, &sess) == 0) { - accelerated = DEVCRYPTO_ACCELERATED; - } else { - sess.crid = CRYPTO_FLAG_SOFTWARE; - if (ioctl(cfd, CIOCGSESSION2, &sess) < 0) { - cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; - continue; - } - accelerated = DEVCRYPTO_NOT_ACCELERATED; - } -#else - if (ioctl(cfd, CIOCGSESSION, &sess) < 0) { - cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; - continue; - } -#endif - - cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE; - - if ((known_cipher_methods[i] = - EVP_CIPHER_meth_new(cipher_data[i].nid, - cipher_mode == EVP_CIPH_CTR_MODE ? 1 : - cipher_data[i].blocksize, - cipher_data[i].keylen)) == NULL - || !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i], - cipher_data[i].ivlen) - || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i], - cipher_data[i].flags - | EVP_CIPH_CUSTOM_COPY - | EVP_CIPH_CTRL_INIT - | EVP_CIPH_FLAG_DEFAULT_ASN1) - || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init) - || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i], - cipher_mode == EVP_CIPH_CTR_MODE ? - ctr_do_cipher : - cipher_do_cipher) - || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl) - || !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i], - cipher_cleanup) - || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i], - sizeof(struct cipher_ctx))) { - cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; - EVP_CIPHER_meth_free(known_cipher_methods[i]); - known_cipher_methods[i] = NULL; - } else { - cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE; -#ifdef CIOCGSESSION2 - cipher_driver_info[i].accelerated = accelerated; - fop.crid = sess.crid; - if (ioctl(cfd, CIOCFINDDEV, &fop) == 0) { - cipher_driver_info[i].driver_name = - OPENSSL_strndup(fop.name, sizeof(fop.name)); - } -#elif defined(CIOCGSESSINFO) - siop.ses = sess.ses; - if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) { - cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; - } else { - cipher_driver_info[i].driver_name = - OPENSSL_strndup(siop.cipher_info.cra_driver_name, - CRYPTODEV_MAX_ALG_NAME); - if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)) - cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; - else - cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; - } -#endif /* CIOCGSESSINFO */ - } - ioctl(cfd, CIOCFSESSION, &sess.ses); - if (devcrypto_test_cipher(i)) { - known_cipher_nids[known_cipher_nids_amount++] = - cipher_data[i].nid; - } - } -} - -static void rebuild_known_cipher_nids(ENGINE *e) -{ - size_t i; - - for (i = 0, known_cipher_nids_amount = 0; i < OSSL_NELEM(cipher_data); i++) { - if (devcrypto_test_cipher(i)) - known_cipher_nids[known_cipher_nids_amount++] = cipher_data[i].nid; - } - ENGINE_unregister_ciphers(e); - ENGINE_register_ciphers(e); -} - -static const EVP_CIPHER *get_cipher_method(int nid) -{ - size_t i = get_cipher_data_index(nid); - - if (i == (size_t)-1) - return NULL; - return known_cipher_methods[i]; -} - -static int get_cipher_nids(const int **nids) -{ - *nids = known_cipher_nids; - return known_cipher_nids_amount; -} - -static void destroy_cipher_method(int nid) -{ - size_t i = get_cipher_data_index(nid); - - EVP_CIPHER_meth_free(known_cipher_methods[i]); - known_cipher_methods[i] = NULL; -} - -static void destroy_all_cipher_methods(void) -{ - size_t i; - - for (i = 0; i < OSSL_NELEM(cipher_data); i++) { - destroy_cipher_method(cipher_data[i].nid); - OPENSSL_free(cipher_driver_info[i].driver_name); - cipher_driver_info[i].driver_name = NULL; - } -} - -static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid) -{ - if (cipher == NULL) - return get_cipher_nids(nids); - - *cipher = get_cipher_method(nid); - - return *cipher != NULL; -} - -static void devcrypto_select_all_ciphers(int *cipher_list) -{ - size_t i; - - for (i = 0; i < OSSL_NELEM(cipher_data); i++) - cipher_list[i] = 1; -} - -static int cryptodev_select_cipher_cb(const char *str, int len, void *usr) -{ - int *cipher_list = (int *)usr; - char *name; - const EVP_CIPHER *EVP; - size_t i; - - if (len == 0) - return 1; - if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL) - return 0; - EVP = EVP_get_cipherbyname(name); - if (EVP == NULL) - fprintf(stderr, "devcrypto: unknown cipher %s\n", name); - else if ((i = find_cipher_data_index(EVP_CIPHER_get_nid(EVP))) != (size_t)-1) - cipher_list[i] = 1; - else - fprintf(stderr, "devcrypto: cipher %s not available\n", name); - OPENSSL_free(name); - return 1; -} - -static void dump_cipher_info(void) -{ - size_t i; - const char *name; - - fprintf (stderr, "Information about ciphers supported by the /dev/crypto" - " engine:\n"); -#ifndef CIOCGSESSINFO - fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n"); -#endif - for (i = 0; i < OSSL_NELEM(cipher_data); i++) { - name = OBJ_nid2sn(cipher_data[i].nid); - fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ", - name ? name : "unknown", cipher_data[i].nid, - cipher_data[i].devcryptoid); - if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) { - fprintf (stderr, "CIOCGSESSION (session open call) failed\n"); - continue; - } - fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ? - cipher_driver_info[i].driver_name : "unknown"); - if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED) - fprintf(stderr, "(hw accelerated)"); - else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED) - fprintf(stderr, "(software)"); - else - fprintf(stderr, "(acceleration status unknown)"); - if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE) - fprintf (stderr, ". Cipher setup failed"); - fprintf(stderr, "\n"); - } - fprintf(stderr, "\n"); -} - -/* - * We only support digests if the cryptodev implementation supports multiple - * data updates and session copying. Otherwise, we would be forced to maintain - * a cache, which is perilous if there's a lot of data coming in (if someone - * wants to checksum an OpenSSL tarball, for example). - */ -#if defined(CIOCCPHASH) && defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL) -#define IMPLEMENT_DIGEST - -/****************************************************************************** - * - * Digests - * - * Because they all do the same basic operation, we have only one set of - * method functions for them all to share, and a mapping table between - * NIDs and cryptodev IDs, with all the necessary size data. - * - *****/ - -struct digest_ctx { - session_op_t sess; - /* This signals that the init function was called, not that it succeeded. */ - int init_called; - unsigned char digest_res[HASH_MAX_LEN]; -}; - -static const struct digest_data_st { - int nid; - int blocksize; - int digestlen; - int devcryptoid; -} digest_data[] = { -#ifndef OPENSSL_NO_MD5 - { NID_md5, /* MD5_CBLOCK */ 64, 16, CRYPTO_MD5 }, -#endif - { NID_sha1, SHA_CBLOCK, 20, CRYPTO_SHA1 }, -#ifndef OPENSSL_NO_RMD160 -# if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_RIPEMD160) - { NID_ripemd160, /* RIPEMD160_CBLOCK */ 64, 20, CRYPTO_RIPEMD160 }, -# endif -#endif -#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_224) - { NID_sha224, SHA256_CBLOCK, 224 / 8, CRYPTO_SHA2_224 }, -#endif -#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_256) - { NID_sha256, SHA256_CBLOCK, 256 / 8, CRYPTO_SHA2_256 }, -#endif -#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_384) - { NID_sha384, SHA512_CBLOCK, 384 / 8, CRYPTO_SHA2_384 }, -#endif -#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_512) - { NID_sha512, SHA512_CBLOCK, 512 / 8, CRYPTO_SHA2_512 }, -#endif -}; - -static size_t find_digest_data_index(int nid) -{ - size_t i; - - for (i = 0; i < OSSL_NELEM(digest_data); i++) - if (nid == digest_data[i].nid) - return i; - return (size_t)-1; -} - -static size_t get_digest_data_index(int nid) -{ - size_t i = find_digest_data_index(nid); - - if (i != (size_t)-1) - return i; - - /* - * Code further down must make sure that only NIDs in the table above - * are used. If any other NID reaches this function, there's a grave - * coding error further down. - */ - assert("Code that never should be reached" == NULL); - return -1; -} - -static const struct digest_data_st *get_digest_data(int nid) -{ - return &digest_data[get_digest_data_index(nid)]; -} - -/* - * Following are the five necessary functions to map OpenSSL functionality - * with cryptodev: init, update, final, cleanup, and copy. - */ - -static int digest_init(EVP_MD_CTX *ctx) -{ - struct digest_ctx *digest_ctx = - (struct digest_ctx *)EVP_MD_CTX_get0_md_data(ctx); - const struct digest_data_st *digest_d = - get_digest_data(EVP_MD_CTX_get_type(ctx)); - - digest_ctx->init_called = 1; - - memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess)); - digest_ctx->sess.mac = digest_d->devcryptoid; - if (ioctl(cfd, CIOCGSESSION, &digest_ctx->sess) < 0) { - ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); - return 0; - } - return 1; -} - -static int digest_op(struct digest_ctx *ctx, const void *src, size_t srclen, - void *res, unsigned int flags) -{ - struct crypt_op cryp; - - memset(&cryp, 0, sizeof(cryp)); - cryp.ses = ctx->sess.ses; - cryp.len = srclen; - cryp.src = (void *)src; - cryp.dst = NULL; - cryp.mac = res; - cryp.flags = flags; - return ioctl(cfd, CIOCCRYPT, &cryp); -} - -static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - struct digest_ctx *digest_ctx = - (struct digest_ctx *)EVP_MD_CTX_get0_md_data(ctx); - - if (count == 0) - return 1; - - if (digest_ctx == NULL) - return 0; - - if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) { - if (digest_op(digest_ctx, data, count, digest_ctx->digest_res, 0) >= 0) - return 1; - } else if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) >= 0) { - return 1; - } - - ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); - return 0; -} - -static int digest_final(EVP_MD_CTX *ctx, unsigned char *md) -{ - struct digest_ctx *digest_ctx = - (struct digest_ctx *)EVP_MD_CTX_get0_md_data(ctx); - - if (md == NULL || digest_ctx == NULL) - return 0; - - if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) { - memcpy(md, digest_ctx->digest_res, EVP_MD_CTX_get_size(ctx)); - } else if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) { - ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); - return 0; - } - - return 1; -} - -static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) -{ - struct digest_ctx *digest_from = - (struct digest_ctx *)EVP_MD_CTX_get0_md_data(from); - struct digest_ctx *digest_to = - (struct digest_ctx *)EVP_MD_CTX_get0_md_data(to); - struct cphash_op cphash; - - if (digest_from == NULL || digest_from->init_called != 1) - return 1; - - if (!digest_init(to)) { - ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); - return 0; - } - - cphash.src_ses = digest_from->sess.ses; - cphash.dst_ses = digest_to->sess.ses; - if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) { - ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); - return 0; - } - return 1; -} - -static int digest_cleanup(EVP_MD_CTX *ctx) -{ - struct digest_ctx *digest_ctx = - (struct digest_ctx *)EVP_MD_CTX_get0_md_data(ctx); - - if (digest_ctx == NULL) - return 1; - - return clean_devcrypto_session(&digest_ctx->sess); -} - -/* - * Keep tables of known nids, associated methods, selected digests, and - * driver info. - * Note that known_digest_nids[] isn't necessarily indexed the same way as - * digest_data[] above, which the other tables are. - */ -static int known_digest_nids[OSSL_NELEM(digest_data)]; -static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */ -static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, }; -static int selected_digests[OSSL_NELEM(digest_data)]; -static struct driver_info_st digest_driver_info[OSSL_NELEM(digest_data)]; - -static int devcrypto_test_digest(size_t digest_data_index) -{ - return (digest_driver_info[digest_data_index].status == DEVCRYPTO_STATUS_USABLE - && selected_digests[digest_data_index] == 1 - && (digest_driver_info[digest_data_index].accelerated - == DEVCRYPTO_ACCELERATED - || use_softdrivers == DEVCRYPTO_USE_SOFTWARE - || (digest_driver_info[digest_data_index].accelerated - != DEVCRYPTO_NOT_ACCELERATED - && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE))); -} - -static void rebuild_known_digest_nids(ENGINE *e) -{ - size_t i; - - for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); i++) { - if (devcrypto_test_digest(i)) - known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid; - } - ENGINE_unregister_digests(e); - ENGINE_register_digests(e); -} - -static void prepare_digest_methods(void) -{ - size_t i; - session_op_t sess1, sess2; -#ifdef CIOCGSESSINFO - struct session_info_op siop; -#endif - struct cphash_op cphash; - - memset(&digest_driver_info, 0, sizeof(digest_driver_info)); - - memset(&sess1, 0, sizeof(sess1)); - memset(&sess2, 0, sizeof(sess2)); - - for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); - i++) { - - selected_digests[i] = 1; - - /* - * Check that the digest is usable - */ - sess1.mac = digest_data[i].devcryptoid; - sess2.ses = 0; - if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) { - digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; - goto finish; - } - -#ifdef CIOCGSESSINFO - /* gather hardware acceleration info from the driver */ - siop.ses = sess1.ses; - if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) { - digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; - } else { - digest_driver_info[i].driver_name = - OPENSSL_strndup(siop.hash_info.cra_driver_name, - CRYPTODEV_MAX_ALG_NAME); - if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY) - digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; - else - digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; - } -#endif - - /* digest must be capable of hash state copy */ - sess2.mac = sess1.mac; - if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) { - digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; - goto finish; - } - cphash.src_ses = sess1.ses; - cphash.dst_ses = sess2.ses; - if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) { - digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH; - goto finish; - } - if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid, - NID_undef)) == NULL - || !EVP_MD_meth_set_input_blocksize(known_digest_methods[i], - digest_data[i].blocksize) - || !EVP_MD_meth_set_result_size(known_digest_methods[i], - digest_data[i].digestlen) - || !EVP_MD_meth_set_init(known_digest_methods[i], digest_init) - || !EVP_MD_meth_set_update(known_digest_methods[i], digest_update) - || !EVP_MD_meth_set_final(known_digest_methods[i], digest_final) - || !EVP_MD_meth_set_copy(known_digest_methods[i], digest_copy) - || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup) - || !EVP_MD_meth_set_app_datasize(known_digest_methods[i], - sizeof(struct digest_ctx))) { - digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; - EVP_MD_meth_free(known_digest_methods[i]); - known_digest_methods[i] = NULL; - goto finish; - } - digest_driver_info[i].status = DEVCRYPTO_STATUS_USABLE; -finish: - ioctl(cfd, CIOCFSESSION, &sess1.ses); - if (sess2.ses != 0) - ioctl(cfd, CIOCFSESSION, &sess2.ses); - if (devcrypto_test_digest(i)) - known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid; - } -} - -static const EVP_MD *get_digest_method(int nid) -{ - size_t i = get_digest_data_index(nid); - - if (i == (size_t)-1) - return NULL; - return known_digest_methods[i]; -} - -static int get_digest_nids(const int **nids) -{ - *nids = known_digest_nids; - return known_digest_nids_amount; -} - -static void destroy_digest_method(int nid) -{ - size_t i = get_digest_data_index(nid); - - EVP_MD_meth_free(known_digest_methods[i]); - known_digest_methods[i] = NULL; -} - -static void destroy_all_digest_methods(void) -{ - size_t i; - - for (i = 0; i < OSSL_NELEM(digest_data); i++) { - destroy_digest_method(digest_data[i].nid); - OPENSSL_free(digest_driver_info[i].driver_name); - digest_driver_info[i].driver_name = NULL; - } -} - -static int devcrypto_digests(ENGINE *e, const EVP_MD **digest, - const int **nids, int nid) -{ - if (digest == NULL) - return get_digest_nids(nids); - - *digest = get_digest_method(nid); - - return *digest != NULL; -} - -static void devcrypto_select_all_digests(int *digest_list) -{ - size_t i; - - for (i = 0; i < OSSL_NELEM(digest_data); i++) - digest_list[i] = 1; -} - -static int cryptodev_select_digest_cb(const char *str, int len, void *usr) -{ - int *digest_list = (int *)usr; - char *name; - const EVP_MD *EVP; - size_t i; - - if (len == 0) - return 1; - if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL) - return 0; - EVP = EVP_get_digestbyname(name); - if (EVP == NULL) - fprintf(stderr, "devcrypto: unknown digest %s\n", name); - else if ((i = find_digest_data_index(EVP_MD_get_type(EVP))) != (size_t)-1) - digest_list[i] = 1; - else - fprintf(stderr, "devcrypto: digest %s not available\n", name); - OPENSSL_free(name); - return 1; -} - -static void dump_digest_info(void) -{ - size_t i; - const char *name; - - fprintf (stderr, "Information about digests supported by the /dev/crypto" - " engine:\n"); -#ifndef CIOCGSESSINFO - fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n"); -#endif - - for (i = 0; i < OSSL_NELEM(digest_data); i++) { - name = OBJ_nid2sn(digest_data[i].nid); - fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s", - name ? name : "unknown", digest_data[i].nid, - digest_data[i].devcryptoid, - digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown"); - if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) { - fprintf (stderr, ". CIOCGSESSION (session open) failed\n"); - continue; - } - if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED) - fprintf(stderr, " (hw accelerated)"); - else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED) - fprintf(stderr, " (software)"); - else - fprintf(stderr, " (acceleration status unknown)"); - if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE) - fprintf (stderr, ". Cipher setup failed\n"); - else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH) - fprintf(stderr, ", CIOCCPHASH failed\n"); - else - fprintf(stderr, ", CIOCCPHASH capable\n"); - } - fprintf(stderr, "\n"); -} - -#endif - -/****************************************************************************** - * - * CONTROL COMMANDS - * - *****/ - -#define DEVCRYPTO_CMD_USE_SOFTDRIVERS ENGINE_CMD_BASE -#define DEVCRYPTO_CMD_CIPHERS (ENGINE_CMD_BASE + 1) -#define DEVCRYPTO_CMD_DIGESTS (ENGINE_CMD_BASE + 2) -#define DEVCRYPTO_CMD_DUMP_INFO (ENGINE_CMD_BASE + 3) - -static const ENGINE_CMD_DEFN devcrypto_cmds[] = { -#if defined(CIOCGSESSINFO) || defined(CIOCGSESSION2) - {DEVCRYPTO_CMD_USE_SOFTDRIVERS, - "USE_SOFTDRIVERS", - "specifies whether to use software (not accelerated) drivers (" - OPENSSL_MSTR(DEVCRYPTO_REQUIRE_ACCELERATED) "=use only accelerated drivers, " - OPENSSL_MSTR(DEVCRYPTO_USE_SOFTWARE) "=allow all drivers, " - OPENSSL_MSTR(DEVCRYPTO_REJECT_SOFTWARE) - "=use if acceleration can't be determined) [default=" - OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS) "]", - ENGINE_CMD_FLAG_NUMERIC}, -#endif - - {DEVCRYPTO_CMD_CIPHERS, - "CIPHERS", - "either ALL, NONE, or a comma-separated list of ciphers to enable [default=ALL]", - ENGINE_CMD_FLAG_STRING}, - -#ifdef IMPLEMENT_DIGEST - {DEVCRYPTO_CMD_DIGESTS, - "DIGESTS", - "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]", - ENGINE_CMD_FLAG_STRING}, -#endif - - {DEVCRYPTO_CMD_DUMP_INFO, - "DUMP_INFO", - "dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'", - ENGINE_CMD_FLAG_NO_INPUT}, - - {0, NULL, NULL, 0} -}; - -static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - int *new_list; - switch (cmd) { -#if defined(CIOCGSESSINFO) || defined(CIOCGSESSION2) - case DEVCRYPTO_CMD_USE_SOFTDRIVERS: - switch (i) { - case DEVCRYPTO_REQUIRE_ACCELERATED: - case DEVCRYPTO_USE_SOFTWARE: - case DEVCRYPTO_REJECT_SOFTWARE: - break; - default: - fprintf(stderr, "devcrypto: invalid value (%ld) for USE_SOFTDRIVERS\n", i); - return 0; - } - if (use_softdrivers == i) - return 1; - use_softdrivers = i; -#ifdef IMPLEMENT_DIGEST - rebuild_known_digest_nids(e); -#endif - rebuild_known_cipher_nids(e); - return 1; -#endif /* CIOCGSESSINFO || CIOCGSESSION2 */ - - case DEVCRYPTO_CMD_CIPHERS: - if (p == NULL) - return 1; - if (OPENSSL_strcasecmp((const char *)p, "ALL") == 0) { - devcrypto_select_all_ciphers(selected_ciphers); - } else if (OPENSSL_strcasecmp((const char*)p, "NONE") == 0) { - memset(selected_ciphers, 0, sizeof(selected_ciphers)); - } else { - new_list=OPENSSL_zalloc(sizeof(selected_ciphers)); - if (!CONF_parse_list(p, ',', 1, cryptodev_select_cipher_cb, new_list)) { - OPENSSL_free(new_list); - return 0; - } - memcpy(selected_ciphers, new_list, sizeof(selected_ciphers)); - OPENSSL_free(new_list); - } - rebuild_known_cipher_nids(e); - return 1; - -#ifdef IMPLEMENT_DIGEST - case DEVCRYPTO_CMD_DIGESTS: - if (p == NULL) - return 1; - if (OPENSSL_strcasecmp((const char *)p, "ALL") == 0) { - devcrypto_select_all_digests(selected_digests); - } else if (OPENSSL_strcasecmp((const char*)p, "NONE") == 0) { - memset(selected_digests, 0, sizeof(selected_digests)); - } else { - new_list=OPENSSL_zalloc(sizeof(selected_digests)); - if (!CONF_parse_list(p, ',', 1, cryptodev_select_digest_cb, new_list)) { - OPENSSL_free(new_list); - return 0; - } - memcpy(selected_digests, new_list, sizeof(selected_digests)); - OPENSSL_free(new_list); - } - rebuild_known_digest_nids(e); - return 1; -#endif /* IMPLEMENT_DIGEST */ - - case DEVCRYPTO_CMD_DUMP_INFO: - dump_cipher_info(); -#ifdef IMPLEMENT_DIGEST - dump_digest_info(); -#endif - return 1; - - default: - break; - } - return 0; -} - -/****************************************************************************** - * - * LOAD / UNLOAD - * - *****/ - -/* - * Opens /dev/crypto - */ -static int open_devcrypto(void) -{ - int fd; - - if (cfd >= 0) - return 1; - - if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) { -#ifndef ENGINE_DEVCRYPTO_DEBUG - if (errno != ENOENT && errno != ENXIO) -#endif - fprintf(stderr, "Could not open /dev/crypto: %s\n", strerror(errno)); - return 0; - } - -#ifdef CRIOGET - if (ioctl(fd, CRIOGET, &cfd) < 0) { - fprintf(stderr, "Could not create crypto fd: %s\n", strerror(errno)); - close(fd); - cfd = -1; - return 0; - } - close(fd); -#else - cfd = fd; -#endif - - return 1; -} - -static int close_devcrypto(void) -{ - int ret; - - if (cfd < 0) - return 1; - ret = close(cfd); - cfd = -1; - if (ret != 0) { - fprintf(stderr, "Error closing /dev/crypto: %s\n", strerror(errno)); - return 0; - } - return 1; -} - -static int devcrypto_unload(ENGINE *e) -{ - destroy_all_cipher_methods(); -#ifdef IMPLEMENT_DIGEST - destroy_all_digest_methods(); -#endif - - close_devcrypto(); - - return 1; -} - -static int bind_devcrypto(ENGINE *e) { - - if (!ENGINE_set_id(e, engine_devcrypto_id) - || !ENGINE_set_name(e, "/dev/crypto engine") - || !ENGINE_set_destroy_function(e, devcrypto_unload) - || !ENGINE_set_cmd_defns(e, devcrypto_cmds) - || !ENGINE_set_ctrl_function(e, devcrypto_ctrl)) - return 0; - - prepare_cipher_methods(); -#ifdef IMPLEMENT_DIGEST - prepare_digest_methods(); -#endif - - return (ENGINE_set_ciphers(e, devcrypto_ciphers) -#ifdef IMPLEMENT_DIGEST - && ENGINE_set_digests(e, devcrypto_digests) -#endif -/* - * Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD - * implementations, it seems to only exist in FreeBSD, and regarding the - * parameters in its crypt_kop, the manual crypto(4) has this to say: - * - * The semantics of these arguments are currently undocumented. - * - * Reading through the FreeBSD source code doesn't give much more than - * their CRK_MOD_EXP implementation for ubsec. - * - * It doesn't look much better with cryptodev-linux. They have the crypt_kop - * structure as well as the command (CRK_*) in cryptodev.h, but no support - * seems to be implemented at all for the moment. - * - * At the time of writing, it seems impossible to write proper support for - * FreeBSD's asym features without some very deep knowledge and access to - * specific kernel modules. - * - * /Richard Levitte, 2017-05-11 - */ -#if 0 - && ENGINE_set_RSA(e, devcrypto_rsa) -# ifndef OPENSSL_NO_DSA - && ENGINE_set_DSA(e, devcrypto_dsa) -# endif -# ifndef OPENSSL_NO_DH - && ENGINE_set_DH(e, devcrypto_dh) -# endif -# ifndef OPENSSL_NO_EC - && ENGINE_set_EC(e, devcrypto_ec) -# endif -#endif - ); -} - -/* - * In case this engine is built into libcrypto, then it doesn't offer any - * ability to be dynamically loadable. - */ -void engine_load_devcrypto_int(void) -{ - ENGINE *e = NULL; - - if (!open_devcrypto()) - return; - - if ((e = ENGINE_new()) == NULL - || !bind_devcrypto(e)) { - close_devcrypto(); - ENGINE_free(e); - return; - } - - ERR_set_mark(); - ENGINE_add(e); - /* - * If the "add" worked, it gets a structural reference. So either way, we - * release our just-created reference. - */ - ENGINE_free(e); /* Loose our local reference */ - /* - * If the "add" didn't work, it was probably a conflict because it was - * already added (eg. someone calling ENGINE_load_blah then calling - * ENGINE_load_builtin_engines() perhaps). - */ - ERR_pop_to_mark(); -} diff --git a/engines/e_loader_attic.c b/engines/e_loader_attic.c deleted file mode 100644 index 5607796eabd..00000000000 --- a/engines/e_loader_attic.c +++ /dev/null @@ -1,1717 +0,0 @@ -/* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* THIS ENGINE IS FOR TESTING PURPOSES ONLY. */ - -/* This file has quite some overlap with providers/implementations/storemgmt/file_store.c */ - -/* - * We need to use some asn1_meth deprecated APIs - */ -#define OPENSSL_SUPPRESS_DEPRECATED - -#include "internal/e_os.h" /* for stat */ -#include -#include -#include -#include - -#include -#include /* For d2i_DSAPrivateKey */ -#include -#include -#include -#include /* For the PKCS8 stuff o.O */ -#include /* For d2i_RSAPrivateKey */ -#include -#include -#include -#include -#include /* For the PKCS8 stuff o.O */ -#include "internal/asn1.h" /* For asn1_d2i_read_bio */ -#include "internal/o_dir.h" -#include "internal/cryptlib.h" -#include "crypto/ctype.h" /* For ossl_isdigit */ -#include "crypto/pem.h" /* For PVK and "blob" PEM headers */ - -/* clang-format off */ -#include "e_loader_attic_err.c" -/* clang-format on */ - -DEFINE_STACK_OF(OSSL_STORE_INFO) - -#ifndef S_ISDIR -# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) -#endif - -/*- - * Password prompting - * ------------------ - */ - -static char *file_get_pass(const UI_METHOD *ui_method, char *pass, - size_t maxsize, const char *desc, const char *info, - void *data) -{ - UI *ui = UI_new(); - char *prompt = NULL; - - if (ui == NULL) { - ATTICerr(0, ERR_R_UI_LIB); - return NULL; - } - - if (ui_method != NULL) - UI_set_method(ui, ui_method); - UI_add_user_data(ui, data); - - if ((prompt = UI_construct_prompt(ui, desc, info)) == NULL) { - ATTICerr(0, ERR_R_UI_LIB); - pass = NULL; - } else if (UI_add_input_string(ui, prompt, UI_INPUT_FLAG_DEFAULT_PWD, - pass, 0, (int)(maxsize - 1)) <= 0) { - ATTICerr(0, ERR_R_UI_LIB); - pass = NULL; - } else { - switch (UI_process(ui)) { - case -2: - ATTICerr(0, ATTIC_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED); - pass = NULL; - break; - case -1: - ATTICerr(0, ERR_R_UI_LIB); - pass = NULL; - break; - default: - break; - } - } - - OPENSSL_free(prompt); - UI_free(ui); - return pass; -} - -struct pem_pass_data { - const UI_METHOD *ui_method; - void *data; - const char *prompt_desc; - const char *prompt_info; -}; - -static int file_fill_pem_pass_data(struct pem_pass_data *pass_data, - const char *desc, const char *info, - const UI_METHOD *ui_method, void *ui_data) -{ - if (pass_data == NULL) - return 0; - pass_data->ui_method = ui_method; - pass_data->data = ui_data; - pass_data->prompt_desc = desc; - pass_data->prompt_info = info; - return 1; -} - -/* This is used anywhere a pem_password_cb is needed */ -static int file_get_pem_pass(char *buf, int num, int w, void *data) -{ - struct pem_pass_data *pass_data = data; - char *pass = file_get_pass(pass_data->ui_method, buf, num, - pass_data->prompt_desc, pass_data->prompt_info, - pass_data->data); - - return pass == NULL ? 0 : (int)strlen(pass); -} - -/* - * Check if |str| ends with |suffix| preceded by a space, and if it does, - * return the index of that space. If there is no such suffix in |str|, - * return -1. - * For |str| == "FOO BAR" and |suffix| == "BAR", the returned value is 3. - */ -static int check_suffix(const char *str, const char *suffix) -{ - int str_len = (int)strlen(str); - int suffix_len = (int)(strlen(suffix) + 1); - const char *p = NULL; - - if (suffix_len >= str_len) - return -1; - p = str + str_len - suffix_len; - if (*p != ' ' - || strcmp(p + 1, suffix) != 0) - return -1; - return (int)(p - str); -} - -/* - * EMBEDDED is a special type of OSSL_STORE_INFO, specially for the file - * handlers, so we define it internally. This uses the possibility to - * create an OSSL_STORE_INFO with a generic data pointer and arbitrary - * type number. - * - * This is used by a FILE_HANDLER's try_decode function to signal that it - * has decoded the incoming blob into a new blob, and that the attempted - * decoding should be immediately restarted with the new blob, using the - * new PEM name. - */ -/* Negative numbers are never used for public OSSL_STORE_INFO types */ -#define STORE_INFO_EMBEDDED -1 - -/* This is the embedded data */ -struct embedded_st { - BUF_MEM *blob; - char *pem_name; -}; - -/* Helper functions */ -static struct embedded_st *get0_EMBEDDED(OSSL_STORE_INFO *info) -{ - return OSSL_STORE_INFO_get0_data(STORE_INFO_EMBEDDED, info); -} - -static void store_info_free(OSSL_STORE_INFO *info) -{ - struct embedded_st *data; - - if (info != NULL && (data = get0_EMBEDDED(info)) != NULL) { - BUF_MEM_free(data->blob); - OPENSSL_free(data->pem_name); - OPENSSL_free(data); - } - OSSL_STORE_INFO_free(info); -} - -static OSSL_STORE_INFO *new_EMBEDDED(const char *new_pem_name, - BUF_MEM *embedded) -{ - OSSL_STORE_INFO *info = NULL; - struct embedded_st *data = NULL; - - if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) - return NULL; - if ((info = OSSL_STORE_INFO_new(STORE_INFO_EMBEDDED, data)) == NULL) { - ATTICerr(0, ERR_R_OSSL_STORE_LIB); - OPENSSL_free(data); - return NULL; - } - - data->blob = embedded; - data->pem_name = - new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name); - - if (new_pem_name != NULL && data->pem_name == NULL) { - store_info_free(info); - info = NULL; - } - - return info; -} - -/*- - * The file scheme decoders - * ------------------------ - * - * Each possible data type has its own decoder, which either operates - * through a given PEM name, or attempts to decode to see if the blob - * it's given is decodable for its data type. The assumption is that - * only the correct data type will match the content. - */ - -/*- - * The try_decode function is called to check if the blob of data can - * be used by this handler, and if it can, decodes it into a supported - * OpenSSL type and returns an OSSL_STORE_INFO with the decoded data. - * Input: - * pem_name: If this blob comes from a PEM file, this holds - * the PEM name. If it comes from another type of - * file, this is NULL. - * pem_header: If this blob comes from a PEM file, this holds - * the PEM headers. If it comes from another type of - * file, this is NULL. - * blob: The blob of data to match with what this handler - * can use. - * len: The length of the blob. - * handler_ctx: For a handler marked repeatable, this pointer can - * be used to create a context for the handler. IT IS - * THE HANDLER'S RESPONSIBILITY TO CREATE AND DESTROY - * THIS CONTEXT APPROPRIATELY, i.e. create on first call - * and destroy when about to return NULL. - * matchcount: A pointer to an int to count matches for this data. - * Usually becomes 0 (no match) or 1 (match!), but may - * be higher in the (unlikely) event that the data matches - * more than one possibility. The int will always be - * zero when the function is called. - * ui_method: Application UI method for getting a password, pin - * or any other interactive data. - * ui_data: Application data to be passed to ui_method when - * it's called. - * libctx: The library context to be used if applicable - * propq: The property query string for any algorithm fetches - * Output: - * an OSSL_STORE_INFO - */ -typedef OSSL_STORE_INFO *(*file_try_decode_fn)(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **handler_ctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, const char *uri, - OSSL_LIB_CTX *libctx, - const char *propq); -/* - * The eof function should return 1 if there's no more data to be found - * with the handler_ctx, otherwise 0. This is only used when the handler is - * marked repeatable. - */ -typedef int (*file_eof_fn)(void *handler_ctx); -/* - * The destroy_ctx function is used to destroy the handler_ctx that was - * initiated by a repeatable try_decode function. This is only used when - * the handler is marked repeatable. - */ -typedef void (*file_destroy_ctx_fn)(void **handler_ctx); - -typedef struct file_handler_st { - const char *name; - file_try_decode_fn try_decode; - file_eof_fn eof; - file_destroy_ctx_fn destroy_ctx; - - /* flags */ - int repeatable; -} FILE_HANDLER; - -/* - * PKCS#12 decoder. It operates by decoding all of the blob content, - * extracting all the interesting data from it and storing them internally, - * then serving them one piece at a time. - */ -static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, const char *uri, - OSSL_LIB_CTX *libctx, - const char *propq) -{ - OSSL_STORE_INFO *store_info = NULL; - STACK_OF(OSSL_STORE_INFO) *ctx = *pctx; - - if (ctx == NULL) { - /* Initial parsing */ - PKCS12 *p12; - - if (pem_name != NULL || len > LONG_MAX) - /* No match, there is no PEM PKCS12 tag */ - return NULL; - - if ((p12 = d2i_PKCS12(NULL, &blob, (long)len)) != NULL) { - char *pass = NULL; - char tpass[PEM_BUFSIZE]; - EVP_PKEY *pkey = NULL; - X509 *cert = NULL; - STACK_OF(X509) *chain = NULL; - - *matchcount = 1; - - if (!PKCS12_mac_present(p12) - || PKCS12_verify_mac(p12, "", 0) - || PKCS12_verify_mac(p12, NULL, 0)) { - pass = ""; - } else { - if ((pass = file_get_pass(ui_method, tpass, PEM_BUFSIZE, - "PKCS12 import", uri, - ui_data)) == NULL) { - ATTICerr(0, ATTIC_R_PASSPHRASE_CALLBACK_ERROR); - goto p12_end; - } - if (!PKCS12_verify_mac(p12, pass, (int)strlen(pass))) { - ATTICerr(0, ATTIC_R_ERROR_VERIFYING_PKCS12_MAC); - goto p12_end; - } - } - - if (PKCS12_parse(p12, pass, &pkey, &cert, &chain)) { - OSSL_STORE_INFO *osi_pkey = NULL; - OSSL_STORE_INFO *osi_cert = NULL; - OSSL_STORE_INFO *osi_ca = NULL; - int ok = 1; - - if ((ctx = sk_OSSL_STORE_INFO_new_null()) != NULL) { - if (pkey != NULL) { - if ((osi_pkey = OSSL_STORE_INFO_new_PKEY(pkey)) != NULL - /* clearing pkey here avoids case distinctions */ - && (pkey = NULL) == NULL - && sk_OSSL_STORE_INFO_push(ctx, osi_pkey) != 0) - osi_pkey = NULL; - else - ok = 0; - } - if (ok && cert != NULL) { - if ((osi_cert = OSSL_STORE_INFO_new_CERT(cert)) != NULL - /* clearing cert here avoids case distinctions */ - && (cert = NULL) == NULL - && sk_OSSL_STORE_INFO_push(ctx, osi_cert) != 0) - osi_cert = NULL; - else - ok = 0; - } - while (ok && sk_X509_num(chain) > 0) { - X509 *ca = sk_X509_value(chain, 0); - - if ((osi_ca = OSSL_STORE_INFO_new_CERT(ca)) != NULL - && sk_X509_shift(chain) != NULL - && sk_OSSL_STORE_INFO_push(ctx, osi_ca) != 0) - osi_ca = NULL; - else - ok = 0; - } - } - EVP_PKEY_free(pkey); - X509_free(cert); - OSSL_STACK_OF_X509_free(chain); - store_info_free(osi_pkey); - store_info_free(osi_cert); - store_info_free(osi_ca); - if (!ok) { - sk_OSSL_STORE_INFO_pop_free(ctx, store_info_free); - ctx = NULL; - } - *pctx = ctx; - } - } - p12_end: - PKCS12_free(p12); - if (ctx == NULL) - return NULL; - } - - *matchcount = 1; - store_info = sk_OSSL_STORE_INFO_shift(ctx); - return store_info; -} - -static int eof_PKCS12(void *ctx_) -{ - STACK_OF(OSSL_STORE_INFO) *ctx = ctx_; - - return ctx == NULL || sk_OSSL_STORE_INFO_num(ctx) == 0; -} - -static void destroy_ctx_PKCS12(void **pctx) -{ - STACK_OF(OSSL_STORE_INFO) *ctx = *pctx; - - sk_OSSL_STORE_INFO_pop_free(ctx, store_info_free); - *pctx = NULL; -} - -static FILE_HANDLER PKCS12_handler = { - "PKCS12", - try_decode_PKCS12, - eof_PKCS12, - destroy_ctx_PKCS12, - 1 /* repeatable */ -}; - -/* - * Encrypted PKCS#8 decoder. It operates by just decrypting the given blob - * into a new blob, which is returned as an EMBEDDED STORE_INFO. The whole - * decoding process will then start over with the new blob. - */ -static OSSL_STORE_INFO *try_decode_PKCS8Encrypted(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, - const char *uri, - OSSL_LIB_CTX *libctx, - const char *propq) -{ - X509_SIG *p8 = NULL; - char kbuf[PEM_BUFSIZE]; - char *pass = NULL; - const X509_ALGOR *dalg = NULL; - const ASN1_OCTET_STRING *doct = NULL; - OSSL_STORE_INFO *store_info = NULL; - BUF_MEM *mem = NULL; - unsigned char *new_data = NULL; - int new_data_len; - - if (pem_name != NULL) { - if (strcmp(pem_name, PEM_STRING_PKCS8) != 0) - return NULL; - *matchcount = 1; - } - - if (len > LONG_MAX || (p8 = d2i_X509_SIG(NULL, &blob, (long)len)) == NULL) - return NULL; - - *matchcount = 1; - - if ((mem = BUF_MEM_new()) == NULL) { - ATTICerr(0, ERR_R_BUF_LIB); - goto nop8; - } - - if ((pass = file_get_pass(ui_method, kbuf, PEM_BUFSIZE, - "PKCS8 decrypt pass phrase", uri, - ui_data)) == NULL) { - ATTICerr(0, ATTIC_R_BAD_PASSWORD_READ); - goto nop8; - } - - X509_SIG_get0(p8, &dalg, &doct); - if (!PKCS12_pbe_crypt(dalg, pass, (int)strlen(pass), - doct->data, doct->length, - &new_data, &new_data_len, 0)) - goto nop8; - - mem->data = (char *)new_data; - mem->max = mem->length = (size_t)new_data_len; - X509_SIG_free(p8); - p8 = NULL; - - store_info = new_EMBEDDED(PEM_STRING_PKCS8INF, mem); - if (store_info == NULL) { - ATTICerr(0, ERR_R_OSSL_STORE_LIB); - goto nop8; - } - - return store_info; - nop8: - X509_SIG_free(p8); - BUF_MEM_free(mem); - return NULL; -} - -static FILE_HANDLER PKCS8Encrypted_handler = { - "PKCS8Encrypted", - try_decode_PKCS8Encrypted -}; - -/* - * Private key decoder. Decodes all sorts of private keys, both PKCS#8 - * encoded ones and old style PEM ones (with the key type is encoded into - * the PEM name). - */ -static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, const char *uri, - OSSL_LIB_CTX *libctx, - const char *propq) -{ - OSSL_STORE_INFO *store_info = NULL; - EVP_PKEY *pkey = NULL; - const EVP_PKEY_ASN1_METHOD *ameth = NULL; - - if (len > LONG_MAX) - return NULL; - if (pem_name != NULL) { - if (strcmp(pem_name, PEM_STRING_PKCS8INF) == 0) { - PKCS8_PRIV_KEY_INFO *p8inf = - d2i_PKCS8_PRIV_KEY_INFO(NULL, &blob, (long)len); - - *matchcount = 1; - if (p8inf != NULL) - pkey = EVP_PKCS82PKEY_ex(p8inf, libctx, propq); - PKCS8_PRIV_KEY_INFO_free(p8inf); - } else { - int slen; - int pkey_id; - - if ((slen = check_suffix(pem_name, "PRIVATE KEY")) > 0 - && (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name, - slen)) != NULL - && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, - ameth)) { - *matchcount = 1; - pkey = d2i_PrivateKey_ex(pkey_id, NULL, &blob, (long)len, - libctx, propq); - } - } - } else { - int i; - - for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { - EVP_PKEY *tmp_pkey = NULL; - const unsigned char *tmp_blob = blob; - int pkey_id, pkey_flags; - - ameth = EVP_PKEY_asn1_get0(i); - if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, &pkey_flags, NULL, - NULL, ameth) - || (pkey_flags & ASN1_PKEY_ALIAS) != 0) - continue; - - ERR_set_mark(); /* prevent flooding error queue */ - tmp_pkey = d2i_PrivateKey_ex(pkey_id, NULL, &tmp_blob, (long)len, - libctx, propq); - if (tmp_pkey != NULL) { - if (pkey != NULL) - EVP_PKEY_free(tmp_pkey); - else - pkey = tmp_pkey; - (*matchcount)++; - } - ERR_pop_to_mark(); - } - - if (*matchcount > 1) { - EVP_PKEY_free(pkey); - pkey = NULL; - } - } - if (pkey == NULL) - /* No match */ - return NULL; - - store_info = OSSL_STORE_INFO_new_PKEY(pkey); - if (store_info == NULL) - EVP_PKEY_free(pkey); - - return store_info; -} - -static FILE_HANDLER PrivateKey_handler = { - "PrivateKey", - try_decode_PrivateKey -}; - -/* - * Public key decoder. Only supports SubjectPublicKeyInfo formatted keys. - */ -static OSSL_STORE_INFO *try_decode_PUBKEY(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, const char *uri, - OSSL_LIB_CTX *libctx, - const char *propq) -{ - OSSL_STORE_INFO *store_info = NULL; - EVP_PKEY *pkey = NULL; - - if (pem_name != NULL) { - if (strcmp(pem_name, PEM_STRING_PUBLIC) != 0) - /* No match */ - return NULL; - *matchcount = 1; - } - - if (len > LONG_MAX || (pkey = d2i_PUBKEY(NULL, &blob, (long)len)) != NULL) { - *matchcount = 1; - store_info = OSSL_STORE_INFO_new_PUBKEY(pkey); - } - - return store_info; -} - -static FILE_HANDLER PUBKEY_handler = { - "PUBKEY", - try_decode_PUBKEY -}; - -/* - * Key parameter decoder. - */ -static OSSL_STORE_INFO *try_decode_params(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, const char *uri, - OSSL_LIB_CTX *libctx, - const char *propq) -{ - OSSL_STORE_INFO *store_info = NULL; - EVP_PKEY *pkey = NULL; - const EVP_PKEY_ASN1_METHOD *ameth = NULL; - - if (len > LONG_MAX) - return NULL; - if (pem_name != NULL) { - int slen; - int pkey_id; - - if ((slen = check_suffix(pem_name, "PARAMETERS")) > 0 - && (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name, slen)) != NULL - && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, - ameth)) { - *matchcount = 1; - pkey = d2i_KeyParams(pkey_id, NULL, &blob, (long)len); - } - } else { - int i; - - for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { - EVP_PKEY *tmp_pkey = NULL; - const unsigned char *tmp_blob = blob; - int pkey_id, pkey_flags; - - ameth = EVP_PKEY_asn1_get0(i); - if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, &pkey_flags, NULL, - NULL, ameth) - || (pkey_flags & ASN1_PKEY_ALIAS) != 0) - continue; - - ERR_set_mark(); /* prevent flooding error queue */ - - tmp_pkey = d2i_KeyParams(pkey_id, NULL, &tmp_blob, (long)len); - - if (tmp_pkey != NULL) { - if (pkey != NULL) - EVP_PKEY_free(tmp_pkey); - else - pkey = tmp_pkey; - (*matchcount)++; - } - ERR_pop_to_mark(); - } - - if (*matchcount > 1) { - EVP_PKEY_free(pkey); - pkey = NULL; - } - } - if (pkey == NULL) - /* No match */ - return NULL; - - store_info = OSSL_STORE_INFO_new_PARAMS(pkey); - if (store_info == NULL) - EVP_PKEY_free(pkey); - - return store_info; -} - -static FILE_HANDLER params_handler = { - "params", - try_decode_params -}; - -/* - * X.509 certificate decoder. - */ -static OSSL_STORE_INFO *try_decode_X509Certificate(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, - const char *uri, - OSSL_LIB_CTX *libctx, - const char *propq) -{ - OSSL_STORE_INFO *store_info = NULL; - X509 *cert = NULL; - - /* - * In most cases, we can try to interpret the serialized data as a trusted - * cert (X509 + X509_AUX) and fall back to reading it as a normal cert - * (just X509), but if the PEM name specifically declares it as a trusted - * cert, then no fallback should be engaged. |ignore_trusted| tells if - * the fallback can be used (1) or not (0). - */ - int ignore_trusted = 1; - - if (len > LONG_MAX) - return NULL; - if (pem_name != NULL) { - if (strcmp(pem_name, PEM_STRING_X509_TRUSTED) == 0) - ignore_trusted = 0; - else if (strcmp(pem_name, PEM_STRING_X509_OLD) != 0 - && strcmp(pem_name, PEM_STRING_X509) != 0) - /* No match */ - return NULL; - *matchcount = 1; - } - - cert = X509_new_ex(libctx, propq); - if (cert == NULL) - return NULL; - - if ((d2i_X509_AUX(&cert, &blob, (long)len)) != NULL - || (ignore_trusted && (d2i_X509(&cert, &blob, (long)len)) != NULL)) { - *matchcount = 1; - store_info = OSSL_STORE_INFO_new_CERT(cert); - } - - if (store_info == NULL) - X509_free(cert); - - return store_info; -} - -static FILE_HANDLER X509Certificate_handler = { - "X509Certificate", - try_decode_X509Certificate -}; - -/* - * X.509 CRL decoder. - */ -static OSSL_STORE_INFO *try_decode_X509CRL(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, const char *uri, - OSSL_LIB_CTX *libctx, - const char *propq) -{ - OSSL_STORE_INFO *store_info = NULL; - X509_CRL *crl = NULL; - - if (len > LONG_MAX) - return NULL; - if (pem_name != NULL) { - if (strcmp(pem_name, PEM_STRING_X509_CRL) != 0) - /* No match */ - return NULL; - *matchcount = 1; - } - - if ((crl = d2i_X509_CRL(NULL, &blob, (long)len)) != NULL) { - *matchcount = 1; - store_info = OSSL_STORE_INFO_new_CRL(crl); - } - - if (store_info == NULL) - X509_CRL_free(crl); - - return store_info; -} - -static FILE_HANDLER X509CRL_handler = { - "X509CRL", - try_decode_X509CRL -}; - -/* - * To finish it all off, we collect all the handlers. - */ -static const FILE_HANDLER *file_handlers[] = { - &PKCS12_handler, - &PKCS8Encrypted_handler, - &X509Certificate_handler, - &X509CRL_handler, - ¶ms_handler, - &PUBKEY_handler, - &PrivateKey_handler, -}; - - -/*- - * The loader itself - * ----------------- - */ - -struct ossl_store_loader_ctx_st { - char *uri; /* The URI we currently try to load */ - enum { - is_raw = 0, - is_pem, - is_dir - } type; - int errcnt; -#define FILE_FLAG_SECMEM (1<<0) -#define FILE_FLAG_ATTACHED (1<<1) - unsigned int flags; - union { - struct { /* Used with is_raw and is_pem */ - BIO *file; - - /* - * The following are used when the handler is marked as - * repeatable - */ - const FILE_HANDLER *last_handler; - void *last_handler_ctx; - } file; - struct { /* Used with is_dir */ - OPENSSL_DIR_CTX *ctx; - int end_reached; - - /* - * When a search expression is given, these are filled in. - * |search_name| contains the file basename to look for. - * The string is exactly 8 characters long. - */ - char search_name[9]; - - /* - * The directory reading utility we have combines opening with - * reading the first name. To make sure we can detect the end - * at the right time, we read early and cache the name. - */ - const char *last_entry; - int last_errno; - } dir; - } _; - - /* Expected object type. May be unspecified */ - int expected_type; - - OSSL_LIB_CTX *libctx; - char *propq; -}; - -static void OSSL_STORE_LOADER_CTX_free(OSSL_STORE_LOADER_CTX *ctx) -{ - if (ctx == NULL) - return; - - OPENSSL_free(ctx->propq); - OPENSSL_free(ctx->uri); - if (ctx->type != is_dir) { - if (ctx->_.file.last_handler != NULL) { - ctx->_.file.last_handler->destroy_ctx(&ctx->_.file.last_handler_ctx); - ctx->_.file.last_handler_ctx = NULL; - ctx->_.file.last_handler = NULL; - } - } - OPENSSL_free(ctx); -} - -static int file_find_type(OSSL_STORE_LOADER_CTX *ctx) -{ - BIO *buff = NULL; - char peekbuf[4096] = { 0, }; - - if ((buff = BIO_new(BIO_f_buffer())) == NULL) - return 0; - - ctx->_.file.file = BIO_push(buff, ctx->_.file.file); - if (BIO_buffer_peek(ctx->_.file.file, peekbuf, sizeof(peekbuf) - 1) > 0) { - peekbuf[sizeof(peekbuf) - 1] = '\0'; - if (strstr(peekbuf, "-----BEGIN ") != NULL) - ctx->type = is_pem; - } - return 1; -} - -static OSSL_STORE_LOADER_CTX *file_open_ex - (const OSSL_STORE_LOADER *loader, const char *uri, - OSSL_LIB_CTX *libctx, const char *propq, - const UI_METHOD *ui_method, void *ui_data) -{ - OSSL_STORE_LOADER_CTX *ctx = NULL; - struct stat st; - const char *path_data[2]; - size_t path_data_n = 0, i; - const char *path, *p = uri, *q; - - /* - * First step, just take the URI as is. - */ - path_data[path_data_n++] = uri; - - /* - * Second step, if the URI appears to start with the "file" scheme, - * extract the path and make that the second path to check. - * There's a special case if the URI also contains an authority, then - * the full URI shouldn't be used as a path anywhere. - */ - if (CHECK_AND_SKIP_CASE_PREFIX(p, "file:")) { - q = p; - if (CHECK_AND_SKIP_PREFIX(q, "//")) { - path_data_n--; /* Invalidate using the full URI */ - if (CHECK_AND_SKIP_CASE_PREFIX(q, "localhost/") - || CHECK_AND_SKIP_PREFIX(q, "/")) { - /* - * In this case, we step back on char to ensure that the - * first slash is preserved, making the path always absolute - */ - p = q - 1; - } else { - ATTICerr(0, ATTIC_R_URI_AUTHORITY_UNSUPPORTED); - return NULL; - } - } -#ifdef _WIN32 - /* Windows "file:" URIs with a drive letter start with a '/' */ - if (p[0] == '/' && p[2] == ':' && p[3] == '/') { - char c = tolower((unsigned char)p[1]); - - if (c >= 'a' && c <= 'z') { - /* Skip past the slash, making the path a normal Windows path */ - p++; - } - } -#endif - path_data[path_data_n++] = p; - } - - - for (i = 0, path = NULL; path == NULL && i < path_data_n; i++) { - if (stat(path_data[i], &st) < 0) { - ERR_raise_data(ERR_LIB_SYS, errno, - "calling stat(%s)", - path_data[i]); - } else { - path = path_data[i]; - } - } - if (path == NULL) { - return NULL; - } - - /* Successfully found a working path */ - - ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) - return NULL; - ctx->uri = OPENSSL_strdup(uri); - if (ctx->uri == NULL) - goto err; - - if (S_ISDIR(st.st_mode)) { - ctx->type = is_dir; - ctx->_.dir.last_entry = OPENSSL_DIR_read(&ctx->_.dir.ctx, path); - ctx->_.dir.last_errno = errno; - if (ctx->_.dir.last_entry == NULL) { - if (ctx->_.dir.last_errno != 0) { - ERR_raise(ERR_LIB_SYS, ctx->_.dir.last_errno); - goto err; - } - ctx->_.dir.end_reached = 1; - } - } else if ((ctx->_.file.file = BIO_new_file(path, "rb")) == NULL - || !file_find_type(ctx)) { - BIO_free_all(ctx->_.file.file); - goto err; - } - if (propq != NULL) { - ctx->propq = OPENSSL_strdup(propq); - if (ctx->propq == NULL) - goto err; - } - ctx->libctx = libctx; - - return ctx; - err: - OSSL_STORE_LOADER_CTX_free(ctx); - return NULL; -} - -static OSSL_STORE_LOADER_CTX *file_open - (const OSSL_STORE_LOADER *loader, const char *uri, - const UI_METHOD *ui_method, void *ui_data) -{ - return file_open_ex(loader, uri, NULL, NULL, ui_method, ui_data); -} - -static OSSL_STORE_LOADER_CTX *file_attach - (const OSSL_STORE_LOADER *loader, BIO *bp, - OSSL_LIB_CTX *libctx, const char *propq, - const UI_METHOD *ui_method, void *ui_data) -{ - OSSL_STORE_LOADER_CTX *ctx = NULL; - - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL - || (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL)) { - OSSL_STORE_LOADER_CTX_free(ctx); - return NULL; - } - ctx->libctx = libctx; - ctx->flags |= FILE_FLAG_ATTACHED; - ctx->_.file.file = bp; - if (!file_find_type(ctx)) { - /* Safety measure */ - ctx->_.file.file = NULL; - goto err; - } - return ctx; -err: - OSSL_STORE_LOADER_CTX_free(ctx); - return NULL; -} - -static int file_ctrl(OSSL_STORE_LOADER_CTX *ctx, int cmd, va_list args) -{ - int ret = 1; - - switch (cmd) { - case OSSL_STORE_C_USE_SECMEM: - { - int on = *(va_arg(args, int *)); - - switch (on) { - case 0: - ctx->flags &= ~FILE_FLAG_SECMEM; - break; - case 1: - ctx->flags |= FILE_FLAG_SECMEM; - break; - default: - ATTICerr(0, ERR_R_PASSED_INVALID_ARGUMENT); - ret = 0; - break; - } - } - break; - default: - break; - } - - return ret; -} - -static int file_expect(OSSL_STORE_LOADER_CTX *ctx, int expected) -{ - ctx->expected_type = expected; - return 1; -} - -static int file_find(OSSL_STORE_LOADER_CTX *ctx, - const OSSL_STORE_SEARCH *search) -{ - /* - * If ctx == NULL, the library is looking to know if this loader supports - * the given search type. - */ - - if (OSSL_STORE_SEARCH_get_type(search) == OSSL_STORE_SEARCH_BY_NAME) { - unsigned long hash = 0; - - if (ctx == NULL) - return 1; - - if (ctx->type != is_dir) { - ATTICerr(0, ATTIC_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES); - return 0; - } - - hash = X509_NAME_hash_ex(OSSL_STORE_SEARCH_get0_name(search), - NULL, NULL, NULL); - BIO_snprintf(ctx->_.dir.search_name, sizeof(ctx->_.dir.search_name), - "%08lx", hash); - return 1; - } - - if (ctx != NULL) - ATTICerr(0, ATTIC_R_UNSUPPORTED_SEARCH_TYPE); - return 0; -} - -static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx, - const char *pem_name, - const char *pem_header, - unsigned char *data, size_t len, - const UI_METHOD *ui_method, - void *ui_data, int *matchcount) -{ - OSSL_STORE_INFO *result = NULL; - BUF_MEM *new_mem = NULL; - char *new_pem_name = NULL; - int t = 0; - - again: - { - size_t i = 0; - void *handler_ctx = NULL; - const FILE_HANDLER **matching_handlers = - OPENSSL_zalloc(sizeof(*matching_handlers) - * OSSL_NELEM(file_handlers)); - - if (matching_handlers == NULL) - goto err; - - *matchcount = 0; - for (i = 0; i < OSSL_NELEM(file_handlers); i++) { - const FILE_HANDLER *handler = file_handlers[i]; - int try_matchcount = 0; - void *tmp_handler_ctx = NULL; - OSSL_STORE_INFO *tmp_result; - unsigned long err; - - ERR_set_mark(); - tmp_result = - handler->try_decode(pem_name, pem_header, data, len, - &tmp_handler_ctx, &try_matchcount, - ui_method, ui_data, ctx->uri, - ctx->libctx, ctx->propq); - /* avoid flooding error queue with low-level ASN.1 parse errors */ - err = ERR_peek_last_error(); - if (ERR_GET_LIB(err) == ERR_LIB_ASN1 - && ERR_GET_REASON(err) == ERR_R_NESTED_ASN1_ERROR) - ERR_pop_to_mark(); - else - ERR_clear_last_mark(); - - if (try_matchcount > 0) { - - matching_handlers[*matchcount] = handler; - - if (handler_ctx) - handler->destroy_ctx(&handler_ctx); - handler_ctx = tmp_handler_ctx; - - if ((*matchcount += try_matchcount) > 1) { - /* more than one match => ambiguous, kill any result */ - store_info_free(result); - store_info_free(tmp_result); - if (handler->destroy_ctx != NULL) - handler->destroy_ctx(&handler_ctx); - handler_ctx = NULL; - tmp_result = NULL; - result = NULL; - } - if (result == NULL) - result = tmp_result; - if (result == NULL) /* e.g., PKCS#12 file decryption error */ - break; - } - } - - if (result != NULL - && *matchcount == 1 && matching_handlers[0]->repeatable) { - ctx->_.file.last_handler = matching_handlers[0]; - ctx->_.file.last_handler_ctx = handler_ctx; - } - - OPENSSL_free(matching_handlers); - } - - err: - OPENSSL_free(new_pem_name); - BUF_MEM_free(new_mem); - - if (result != NULL - && (t = OSSL_STORE_INFO_get_type(result)) == STORE_INFO_EMBEDDED) { - struct embedded_st *embedded = get0_EMBEDDED(result); - - /* "steal" the embedded data */ - pem_name = new_pem_name = embedded->pem_name; - new_mem = embedded->blob; - data = (unsigned char *)new_mem->data; - len = new_mem->length; - embedded->pem_name = NULL; - embedded->blob = NULL; - - store_info_free(result); - result = NULL; - goto again; - } - - return result; -} - -static OSSL_STORE_INFO *file_load_try_repeat(OSSL_STORE_LOADER_CTX *ctx, - const UI_METHOD *ui_method, - void *ui_data) -{ - OSSL_STORE_INFO *result = NULL; - int try_matchcount = 0; - - if (ctx->_.file.last_handler != NULL) { - result = - ctx->_.file.last_handler->try_decode(NULL, NULL, NULL, 0, - &ctx->_.file.last_handler_ctx, - &try_matchcount, - ui_method, ui_data, ctx->uri, - ctx->libctx, ctx->propq); - - if (result == NULL) { - ctx->_.file.last_handler->destroy_ctx(&ctx->_.file.last_handler_ctx); - ctx->_.file.last_handler_ctx = NULL; - ctx->_.file.last_handler = NULL; - } - } - return result; -} - -static void pem_free_flag(void *pem_data, int secure, size_t num) -{ - if (secure) - OPENSSL_secure_clear_free(pem_data, num); - else - OPENSSL_free(pem_data); -} -static int file_read_pem(BIO *bp, char **pem_name, char **pem_header, - unsigned char **data, long *len, - const UI_METHOD *ui_method, void *ui_data, - const char *uri, int secure) -{ - int i = secure - ? PEM_read_bio_ex(bp, pem_name, pem_header, data, len, - PEM_FLAG_SECURE | PEM_FLAG_EAY_COMPATIBLE) - : PEM_read_bio(bp, pem_name, pem_header, data, len); - - if (i <= 0) - return 0; - - /* - * 10 is the number of characters in "Proc-Type:", which - * PEM_get_EVP_CIPHER_INFO() requires to be present. - * If the PEM header has less characters than that, it's - * not worth spending cycles on it. - */ - if (strlen(*pem_header) > 10) { - EVP_CIPHER_INFO cipher; - struct pem_pass_data pass_data; - - if (!PEM_get_EVP_CIPHER_INFO(*pem_header, &cipher) - || !file_fill_pem_pass_data(&pass_data, "PEM pass phrase", uri, - ui_method, ui_data) - || !PEM_do_header(&cipher, *data, len, file_get_pem_pass, - &pass_data)) { - return 0; - } - } - return 1; -} - -static OSSL_STORE_INFO *file_try_read_msblob(BIO *bp, int *matchcount) -{ - OSSL_STORE_INFO *result = NULL; - int ispub = -1; - - { - unsigned int magic = 0, bitlen = 0; - int isdss = 0; - unsigned char peekbuf[16] = { 0, }; - const unsigned char *p = peekbuf; - - if (BIO_buffer_peek(bp, peekbuf, sizeof(peekbuf)) <= 0) - return 0; - if (ossl_do_blob_header(&p, sizeof(peekbuf), &magic, &bitlen, - &isdss, &ispub) <= 0) - return 0; - } - - (*matchcount)++; - - { - EVP_PKEY *tmp = ispub - ? b2i_PublicKey_bio(bp) - : b2i_PrivateKey_bio(bp); - - if (tmp == NULL - || (result = OSSL_STORE_INFO_new_PKEY(tmp)) == NULL) { - EVP_PKEY_free(tmp); - return 0; - } - } - - return result; -} - -static OSSL_STORE_INFO *file_try_read_PVK(BIO *bp, const UI_METHOD *ui_method, - void *ui_data, const char *uri, - int *matchcount) -{ - OSSL_STORE_INFO *result = NULL; - - { - unsigned int saltlen = 0, keylen = 0; - int isdss = -1; - unsigned char peekbuf[24] = { 0, }; - const unsigned char *p = peekbuf; - - if (BIO_buffer_peek(bp, peekbuf, sizeof(peekbuf)) <= 0) - return 0; - if (!ossl_do_PVK_header(&p, sizeof(peekbuf), 0, &isdss, &saltlen, &keylen)) - return 0; - } - - (*matchcount)++; - - { - EVP_PKEY *tmp = NULL; - struct pem_pass_data pass_data; - - if (!file_fill_pem_pass_data(&pass_data, "PVK pass phrase", uri, - ui_method, ui_data) - || (tmp = b2i_PVK_bio(bp, file_get_pem_pass, &pass_data)) == NULL - || (result = OSSL_STORE_INFO_new_PKEY(tmp)) == NULL) { - EVP_PKEY_free(tmp); - return 0; - } - } - - return result; -} - -static int file_read_asn1(BIO *bp, unsigned char **data, long *len) -{ - BUF_MEM *mem = NULL; - - if (asn1_d2i_read_bio(bp, &mem) < 0) - return 0; - - *data = (unsigned char *)mem->data; - *len = (long)mem->length; - OPENSSL_free(mem); - - return 1; -} - -static int file_name_to_uri(OSSL_STORE_LOADER_CTX *ctx, const char *name, - char **data) -{ - assert(name != NULL); - assert(data != NULL); - { - const char *pathsep = ossl_ends_with_dirsep(ctx->uri) ? "" : "/"; - long calculated_length = (long)(strlen(ctx->uri) + strlen(pathsep) - + strlen(name) + 1 /* \0 */); - - *data = OPENSSL_zalloc(calculated_length); - if (*data == NULL) - return 0; - - OPENSSL_strlcat(*data, ctx->uri, calculated_length); - OPENSSL_strlcat(*data, pathsep, calculated_length); - OPENSSL_strlcat(*data, name, calculated_length); - } - return 1; -} - -static int file_name_check(OSSL_STORE_LOADER_CTX *ctx, const char *name) -{ - const char *p = NULL; - size_t len = strlen(ctx->_.dir.search_name); - - /* If there are no search criteria, all names are accepted */ - if (ctx->_.dir.search_name[0] == '\0') - return 1; - - /* If the expected type isn't supported, no name is accepted */ - if (ctx->expected_type != 0 - && ctx->expected_type != OSSL_STORE_INFO_CERT - && ctx->expected_type != OSSL_STORE_INFO_CRL) - return 0; - - /* - * First, check the basename - */ - if (OPENSSL_strncasecmp(name, ctx->_.dir.search_name, len) != 0 - || name[len] != '.') - return 0; - p = &name[len + 1]; - - /* - * Then, if the expected type is a CRL, check that the extension starts - * with 'r' - */ - if (*p == 'r') { - p++; - if (ctx->expected_type != 0 - && ctx->expected_type != OSSL_STORE_INFO_CRL) - return 0; - } else if (ctx->expected_type == OSSL_STORE_INFO_CRL) { - return 0; - } - - /* - * Last, check that the rest of the extension is a decimal number, at - * least one digit long. - */ - if (!isdigit((unsigned char)*p)) - return 0; - while (isdigit((unsigned char)*p)) - p++; - -#ifdef __VMS - /* - * One extra step here, check for a possible generation number. - */ - if (*p == ';') - for (p++; *p != '\0'; p++) - if (!ossl_isdigit(*p)) - break; -#endif - - /* - * If we've reached the end of the string at this point, we've successfully - * found a fitting file name. - */ - return *p == '\0'; -} - -static int file_eof(OSSL_STORE_LOADER_CTX *ctx); -static int file_error(OSSL_STORE_LOADER_CTX *ctx); -static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx, - const UI_METHOD *ui_method, - void *ui_data) -{ - OSSL_STORE_INFO *result = NULL; - - ctx->errcnt = 0; - - if (ctx->type == is_dir) { - do { - char *newname = NULL; - - if (ctx->_.dir.last_entry == NULL) { - if (!ctx->_.dir.end_reached) { - assert(ctx->_.dir.last_errno != 0); - ERR_raise(ERR_LIB_SYS, ctx->_.dir.last_errno); - ctx->errcnt++; - } - return NULL; - } - - if (ctx->_.dir.last_entry[0] != '.' - && file_name_check(ctx, ctx->_.dir.last_entry) - && !file_name_to_uri(ctx, ctx->_.dir.last_entry, &newname)) - return NULL; - - /* - * On the first call (with a NULL context), OPENSSL_DIR_read() - * cares about the second argument. On the following calls, it - * only cares that it isn't NULL. Therefore, we can safely give - * it our URI here. - */ - ctx->_.dir.last_entry = OPENSSL_DIR_read(&ctx->_.dir.ctx, ctx->uri); - ctx->_.dir.last_errno = errno; - if (ctx->_.dir.last_entry == NULL && ctx->_.dir.last_errno == 0) - ctx->_.dir.end_reached = 1; - - if (newname != NULL - && (result = OSSL_STORE_INFO_new_NAME(newname)) == NULL) { - OPENSSL_free(newname); - ATTICerr(0, ERR_R_OSSL_STORE_LIB); - return NULL; - } - } while (result == NULL && !file_eof(ctx)); - } else { - int matchcount = -1; - - again: - result = file_load_try_repeat(ctx, ui_method, ui_data); - if (result != NULL) - return result; - - if (file_eof(ctx)) - return NULL; - - do { - char *pem_name = NULL; /* PEM record name */ - char *pem_header = NULL; /* PEM record header */ - unsigned char *data = NULL; /* DER encoded data */ - long len = 0; /* DER encoded data length */ - - matchcount = -1; - if (ctx->type == is_pem) { - if (!file_read_pem(ctx->_.file.file, &pem_name, &pem_header, - &data, &len, ui_method, ui_data, ctx->uri, - (ctx->flags & FILE_FLAG_SECMEM) != 0)) { - ctx->errcnt++; - goto endloop; - } - } else { - if ((result = file_try_read_msblob(ctx->_.file.file, - &matchcount)) != NULL - || (result = file_try_read_PVK(ctx->_.file.file, - ui_method, ui_data, ctx->uri, - &matchcount)) != NULL) - goto endloop; - - if (!file_read_asn1(ctx->_.file.file, &data, &len)) { - ctx->errcnt++; - goto endloop; - } - } - - result = file_load_try_decode(ctx, pem_name, pem_header, data, len, - ui_method, ui_data, &matchcount); - - if (result != NULL) - goto endloop; - - /* - * If a PEM name matches more than one handler, the handlers are - * badly coded. - */ - if (!ossl_assert(pem_name == NULL || matchcount <= 1)) { - ctx->errcnt++; - goto endloop; - } - - if (matchcount > 1) { - ATTICerr(0, ATTIC_R_AMBIGUOUS_CONTENT_TYPE); - } else if (matchcount == 1) { - /* - * If there are other errors on the stack, they already show - * what the problem is. - */ - if (ERR_peek_error() == 0) { - ATTICerr(0, ATTIC_R_UNSUPPORTED_CONTENT_TYPE); - if (pem_name != NULL) - ERR_add_error_data(3, "PEM type is '", pem_name, "'"); - } - } - if (matchcount > 0) - ctx->errcnt++; - - endloop: - pem_free_flag(pem_name, (ctx->flags & FILE_FLAG_SECMEM) != 0, 0); - pem_free_flag(pem_header, (ctx->flags & FILE_FLAG_SECMEM) != 0, 0); - pem_free_flag(data, (ctx->flags & FILE_FLAG_SECMEM) != 0, len); - } while (matchcount == 0 && !file_eof(ctx) && !file_error(ctx)); - - /* We bail out on ambiguity */ - if (matchcount > 1) { - store_info_free(result); - return NULL; - } - - if (result != NULL - && ctx->expected_type != 0 - && ctx->expected_type != OSSL_STORE_INFO_get_type(result)) { - store_info_free(result); - goto again; - } - } - - return result; -} - -static int file_error(OSSL_STORE_LOADER_CTX *ctx) -{ - return ctx->errcnt > 0; -} - -static int file_eof(OSSL_STORE_LOADER_CTX *ctx) -{ - if (ctx->type == is_dir) - return ctx->_.dir.end_reached; - - if (ctx->_.file.last_handler != NULL - && !ctx->_.file.last_handler->eof(ctx->_.file.last_handler_ctx)) - return 0; - return BIO_eof(ctx->_.file.file); -} - -static int file_close(OSSL_STORE_LOADER_CTX *ctx) -{ - if ((ctx->flags & FILE_FLAG_ATTACHED) == 0) { - if (ctx->type == is_dir) - OPENSSL_DIR_end(&ctx->_.dir.ctx); - else - BIO_free_all(ctx->_.file.file); - } else { - /* - * Because file_attach() called file_find_type(), we know that a - * BIO_f_buffer() has been pushed on top of the regular BIO. - */ - BIO *buff = ctx->_.file.file; - - /* Detach buff */ - (void)BIO_pop(ctx->_.file.file); - /* Safety measure */ - ctx->_.file.file = NULL; - - BIO_free(buff); - } - OSSL_STORE_LOADER_CTX_free(ctx); - return 1; -} - -/*- - * ENGINE management - */ - -static const char *loader_attic_id = "loader_attic"; -static const char *loader_attic_name = "'file:' loader"; - -static OSSL_STORE_LOADER *loader_attic = NULL; - -static int loader_attic_init(ENGINE *e) -{ - return 1; -} - - -static int loader_attic_finish(ENGINE *e) -{ - return 1; -} - - -static int loader_attic_destroy(ENGINE *e) -{ - OSSL_STORE_LOADER *loader = OSSL_STORE_unregister_loader("file"); - - if (loader == NULL) - return 0; - - ERR_unload_ATTIC_strings(); - OSSL_STORE_LOADER_free(loader); - return 1; -} - -static int bind_loader_attic(ENGINE *e) -{ - - /* Ensure the ATTIC error handling is set up on best effort basis */ - ERR_load_ATTIC_strings(); - - if (/* Create the OSSL_STORE_LOADER */ - (loader_attic = OSSL_STORE_LOADER_new(e, "file")) == NULL - || !OSSL_STORE_LOADER_set_open_ex(loader_attic, file_open_ex) - || !OSSL_STORE_LOADER_set_open(loader_attic, file_open) - || !OSSL_STORE_LOADER_set_attach(loader_attic, file_attach) - || !OSSL_STORE_LOADER_set_ctrl(loader_attic, file_ctrl) - || !OSSL_STORE_LOADER_set_expect(loader_attic, file_expect) - || !OSSL_STORE_LOADER_set_find(loader_attic, file_find) - || !OSSL_STORE_LOADER_set_load(loader_attic, file_load) - || !OSSL_STORE_LOADER_set_eof(loader_attic, file_eof) - || !OSSL_STORE_LOADER_set_error(loader_attic, file_error) - || !OSSL_STORE_LOADER_set_close(loader_attic, file_close) - /* Init the engine itself */ - || !ENGINE_set_id(e, loader_attic_id) - || !ENGINE_set_name(e, loader_attic_name) - || !ENGINE_set_destroy_function(e, loader_attic_destroy) - || !ENGINE_set_init_function(e, loader_attic_init) - || !ENGINE_set_finish_function(e, loader_attic_finish) - /* Finally, register the method with libcrypto */ - || !OSSL_STORE_register_loader(loader_attic)) { - OSSL_STORE_LOADER_free(loader_attic); - loader_attic = NULL; - ATTICerr(0, ATTIC_R_INIT_FAILED); - return 0; - } - - return 1; -} - -#ifdef OPENSSL_NO_DYNAMIC_ENGINE -# error "Only allowed as dynamically shared object" -#endif - -static int bind_helper(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, loader_attic_id) != 0)) - return 0; - if (!bind_loader_attic(e)) - return 0; - return 1; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) diff --git a/engines/e_loader_attic.ec b/engines/e_loader_attic.ec deleted file mode 100644 index 525a689fe58..00000000000 --- a/engines/e_loader_attic.ec +++ /dev/null @@ -1,3 +0,0 @@ -# The INPUT HEADER is scanned for declarations -# LIBNAME INPUT HEADER ERROR-TABLE FILE -L ATTIC e_loader_attic_err.h e_loader_attic_err.c diff --git a/engines/e_loader_attic.txt b/engines/e_loader_attic.txt deleted file mode 100644 index 4fb8fdf5e8a..00000000000 --- a/engines/e_loader_attic.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 1999-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 - -#Reason codes -ATTIC_R_AMBIGUOUS_CONTENT_TYPE:100:ambiguous content type -ATTIC_R_BAD_PASSWORD_READ:101:bad password read -ATTIC_R_ERROR_VERIFYING_PKCS12_MAC:102:error verifying pkcs12 mac -ATTIC_R_INIT_FAILED:103:init failed -ATTIC_R_PASSPHRASE_CALLBACK_ERROR:104:passphrase callback error -ATTIC_R_PATH_MUST_BE_ABSOLUTE:105:path must be absolute -ATTIC_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES:106:\ - search only supported for directories -ATTIC_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED:107:\ - ui process interrupted or cancelled -ATTIC_R_UNSUPPORTED_CONTENT_TYPE:108:unsupported content type -ATTIC_R_UNSUPPORTED_SEARCH_TYPE:109:unsupported search type -ATTIC_R_URI_AUTHORITY_UNSUPPORTED:110:uri authority unsupported diff --git a/engines/e_loader_attic_err.c b/engines/e_loader_attic_err.c deleted file mode 100644 index d7c71463d8c..00000000000 --- a/engines/e_loader_attic_err.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-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 "e_loader_attic_err.h" - -#ifndef OPENSSL_NO_ERR - -static ERR_STRING_DATA ATTIC_str_reasons[] = { - {ERR_PACK(0, 0, ATTIC_R_AMBIGUOUS_CONTENT_TYPE), "ambiguous content type"}, - {ERR_PACK(0, 0, ATTIC_R_BAD_PASSWORD_READ), "bad password read"}, - {ERR_PACK(0, 0, ATTIC_R_ERROR_VERIFYING_PKCS12_MAC), - "error verifying pkcs12 mac"}, - {ERR_PACK(0, 0, ATTIC_R_INIT_FAILED), "init failed"}, - {ERR_PACK(0, 0, ATTIC_R_PASSPHRASE_CALLBACK_ERROR), - "passphrase callback error"}, - {ERR_PACK(0, 0, ATTIC_R_PATH_MUST_BE_ABSOLUTE), "path must be absolute"}, - {ERR_PACK(0, 0, ATTIC_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES), - "search only supported for directories"}, - {ERR_PACK(0, 0, ATTIC_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED), - "ui process interrupted or cancelled"}, - {ERR_PACK(0, 0, ATTIC_R_UNSUPPORTED_CONTENT_TYPE), - "unsupported content type"}, - {ERR_PACK(0, 0, ATTIC_R_UNSUPPORTED_SEARCH_TYPE), - "unsupported search type"}, - {ERR_PACK(0, 0, ATTIC_R_URI_AUTHORITY_UNSUPPORTED), - "uri authority unsupported"}, - {0, NULL} -}; - -#endif - -static int lib_code = 0; -static int error_loaded = 0; - -static int ERR_load_ATTIC_strings(void) -{ - if (lib_code == 0) - lib_code = ERR_get_next_error_library(); - - if (!error_loaded) { -#ifndef OPENSSL_NO_ERR - ERR_load_strings(lib_code, ATTIC_str_reasons); -#endif - error_loaded = 1; - } - return 1; -} - -static void ERR_unload_ATTIC_strings(void) -{ - if (error_loaded) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(lib_code, ATTIC_str_reasons); -#endif - error_loaded = 0; - } -} - -static void ERR_ATTIC_error(int function, int reason, const char *file, int line) -{ - if (lib_code == 0) - lib_code = ERR_get_next_error_library(); - ERR_raise(lib_code, reason); - ERR_set_debug(file, line, NULL); -} diff --git a/engines/e_loader_attic_err.h b/engines/e_loader_attic_err.h deleted file mode 100644 index b4a144f4cbc..00000000000 --- a/engines/e_loader_attic_err.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-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 - */ - -#ifndef OSSL_E_LOADER_ATTIC_ERR_H -# define OSSL_E_LOADER_ATTIC_ERR_H -# pragma once - -# include -# include - - -# define ATTICerr(f, r) ERR_ATTIC_error(0, (r), OPENSSL_FILE, OPENSSL_LINE) - - -/* - * ATTIC reason codes. - */ -# define ATTIC_R_AMBIGUOUS_CONTENT_TYPE 100 -# define ATTIC_R_BAD_PASSWORD_READ 101 -# define ATTIC_R_ERROR_VERIFYING_PKCS12_MAC 102 -# define ATTIC_R_INIT_FAILED 103 -# define ATTIC_R_PASSPHRASE_CALLBACK_ERROR 104 -# define ATTIC_R_PATH_MUST_BE_ABSOLUTE 105 -# define ATTIC_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES 106 -# define ATTIC_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED 107 -# define ATTIC_R_UNSUPPORTED_CONTENT_TYPE 108 -# define ATTIC_R_UNSUPPORTED_SEARCH_TYPE 109 -# define ATTIC_R_URI_AUTHORITY_UNSUPPORTED 110 - -#endif diff --git a/engines/e_ossltest.c b/engines/e_ossltest.c deleted file mode 100644 index 56c79ef2e6d..00000000000 --- a/engines/e_ossltest.c +++ /dev/null @@ -1,914 +0,0 @@ -/* - * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * This is the OSSLTEST engine. It provides deliberately crippled digest - * implementations for test purposes. It is highly insecure and must NOT be - * used for any purpose except testing - */ - -/* We need to use some engine deprecated APIs */ -#define OPENSSL_SUPPRESS_DEPRECATED - -/* - * SHA low level APIs are deprecated for public use, but still ok for - * internal use. Note, that due to symbols not being exported, only the - * #defines and type definitions can be accessed, function calls are not - * available. The digest lengths, block sizes and sizeof(CTX) are used herein - * for several different digests. - */ -#include "internal/deprecated.h" - -#include -#include -#include "internal/common.h" /* for CHECK_AND_SKIP_CASE_PREFIX */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* clang-format off */ -#include "e_ossltest_err.c" -/* clang-format on */ - -/* Engine Id and Name */ -static const char *engine_ossltest_id = "ossltest"; -static const char *engine_ossltest_name = "OpenSSL Test engine support"; - - -/* Engine Lifetime functions */ -static int ossltest_destroy(ENGINE *e); -static int ossltest_init(ENGINE *e); -static int ossltest_finish(ENGINE *e); -void ENGINE_load_ossltest(void); - - -/* Set up digests */ -static int ossltest_digests(ENGINE *e, const EVP_MD **digest, - const int **nids, int nid); -static const RAND_METHOD *ossltest_rand_method(void); - -/* MD5 */ -static int digest_md5_init(EVP_MD_CTX *ctx); -static int digest_md5_update(EVP_MD_CTX *ctx, const void *data, - size_t count); -static int digest_md5_final(EVP_MD_CTX *ctx, unsigned char *md); - -static EVP_MD *_hidden_md5_md = NULL; -static const EVP_MD *digest_md5(void) -{ - if (_hidden_md5_md == NULL) { - EVP_MD *md; - - if ((md = EVP_MD_meth_new(NID_md5, NID_md5WithRSAEncryption)) == NULL - || !EVP_MD_meth_set_result_size(md, MD5_DIGEST_LENGTH) - || !EVP_MD_meth_set_input_blocksize(md, MD5_CBLOCK) - || !EVP_MD_meth_set_app_datasize(md, - sizeof(EVP_MD *) + sizeof(MD5_CTX)) - || !EVP_MD_meth_set_flags(md, 0) - || !EVP_MD_meth_set_init(md, digest_md5_init) - || !EVP_MD_meth_set_update(md, digest_md5_update) - || !EVP_MD_meth_set_final(md, digest_md5_final)) { - EVP_MD_meth_free(md); - md = NULL; - } - _hidden_md5_md = md; - } - return _hidden_md5_md; -} - -/* SHA1 */ -static int digest_sha1_init(EVP_MD_CTX *ctx); -static int digest_sha1_update(EVP_MD_CTX *ctx, const void *data, - size_t count); -static int digest_sha1_final(EVP_MD_CTX *ctx, unsigned char *md); - -static EVP_MD *_hidden_sha1_md = NULL; -static const EVP_MD *digest_sha1(void) -{ - if (_hidden_sha1_md == NULL) { - EVP_MD *md; - - if ((md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption)) == NULL - || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH) - || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK) - || !EVP_MD_meth_set_app_datasize(md, - sizeof(EVP_MD *) + sizeof(SHA_CTX)) - || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT) - || !EVP_MD_meth_set_init(md, digest_sha1_init) - || !EVP_MD_meth_set_update(md, digest_sha1_update) - || !EVP_MD_meth_set_final(md, digest_sha1_final)) { - EVP_MD_meth_free(md); - md = NULL; - } - _hidden_sha1_md = md; - } - return _hidden_sha1_md; -} - -/* SHA256 */ -static int digest_sha256_init(EVP_MD_CTX *ctx); -static int digest_sha256_update(EVP_MD_CTX *ctx, const void *data, - size_t count); -static int digest_sha256_final(EVP_MD_CTX *ctx, unsigned char *md); - -static EVP_MD *_hidden_sha256_md = NULL; -static const EVP_MD *digest_sha256(void) -{ - if (_hidden_sha256_md == NULL) { - EVP_MD *md; - - if ((md = EVP_MD_meth_new(NID_sha256, NID_sha256WithRSAEncryption)) == NULL - || !EVP_MD_meth_set_result_size(md, SHA256_DIGEST_LENGTH) - || !EVP_MD_meth_set_input_blocksize(md, SHA256_CBLOCK) - || !EVP_MD_meth_set_app_datasize(md, - sizeof(EVP_MD *) + sizeof(SHA256_CTX)) - || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT) - || !EVP_MD_meth_set_init(md, digest_sha256_init) - || !EVP_MD_meth_set_update(md, digest_sha256_update) - || !EVP_MD_meth_set_final(md, digest_sha256_final)) { - EVP_MD_meth_free(md); - md = NULL; - } - _hidden_sha256_md = md; - } - return _hidden_sha256_md; -} - -/* SHA384/SHA512 */ -static int digest_sha384_init(EVP_MD_CTX *ctx); -static int digest_sha384_update(EVP_MD_CTX *ctx, const void *data, - size_t count); -static int digest_sha384_final(EVP_MD_CTX *ctx, unsigned char *md); - -static int digest_sha512_init(EVP_MD_CTX *ctx); -static int digest_sha512_update(EVP_MD_CTX *ctx, const void *data, - size_t count); -static int digest_sha512_final(EVP_MD_CTX *ctx, unsigned char *md); - -static EVP_MD *_hidden_sha384_md = NULL; -static const EVP_MD *digest_sha384(void) -{ - if (_hidden_sha384_md == NULL) { - EVP_MD *md; - - if ((md = EVP_MD_meth_new(NID_sha384, NID_sha384WithRSAEncryption)) == NULL - || !EVP_MD_meth_set_result_size(md, SHA384_DIGEST_LENGTH) - || !EVP_MD_meth_set_input_blocksize(md, SHA512_CBLOCK) - || !EVP_MD_meth_set_app_datasize(md, - sizeof(EVP_MD *) + sizeof(SHA512_CTX)) - || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT) - || !EVP_MD_meth_set_init(md, digest_sha384_init) - || !EVP_MD_meth_set_update(md, digest_sha384_update) - || !EVP_MD_meth_set_final(md, digest_sha384_final)) { - EVP_MD_meth_free(md); - md = NULL; - } - _hidden_sha384_md = md; - } - return _hidden_sha384_md; -} -static EVP_MD *_hidden_sha512_md = NULL; -static const EVP_MD *digest_sha512(void) -{ - if (_hidden_sha512_md == NULL) { - EVP_MD *md; - - if ((md = EVP_MD_meth_new(NID_sha512, NID_sha512WithRSAEncryption)) == NULL - || !EVP_MD_meth_set_result_size(md, SHA512_DIGEST_LENGTH) - || !EVP_MD_meth_set_input_blocksize(md, SHA512_CBLOCK) - || !EVP_MD_meth_set_app_datasize(md, - sizeof(EVP_MD *) + sizeof(SHA512_CTX)) - || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT) - || !EVP_MD_meth_set_init(md, digest_sha512_init) - || !EVP_MD_meth_set_update(md, digest_sha512_update) - || !EVP_MD_meth_set_final(md, digest_sha512_final)) { - EVP_MD_meth_free(md); - md = NULL; - } - _hidden_sha512_md = md; - } - return _hidden_sha512_md; -} -static void destroy_digests(void) -{ - EVP_MD_meth_free(_hidden_md5_md); - _hidden_md5_md = NULL; - EVP_MD_meth_free(_hidden_sha1_md); - _hidden_sha1_md = NULL; - EVP_MD_meth_free(_hidden_sha256_md); - _hidden_sha256_md = NULL; - EVP_MD_meth_free(_hidden_sha384_md); - _hidden_sha384_md = NULL; - EVP_MD_meth_free(_hidden_sha512_md); - _hidden_sha512_md = NULL; -} -static int ossltest_digest_nids(const int **nids) -{ - static int digest_nids[6] = { 0, 0, 0, 0, 0, 0 }; - static int pos = 0; - static int init = 0; - - if (!init) { - const EVP_MD *md; - if ((md = digest_md5()) != NULL) - digest_nids[pos++] = EVP_MD_get_type(md); - if ((md = digest_sha1()) != NULL) - digest_nids[pos++] = EVP_MD_get_type(md); - if ((md = digest_sha256()) != NULL) - digest_nids[pos++] = EVP_MD_get_type(md); - if ((md = digest_sha384()) != NULL) - digest_nids[pos++] = EVP_MD_get_type(md); - if ((md = digest_sha512()) != NULL) - digest_nids[pos++] = EVP_MD_get_type(md); - digest_nids[pos] = 0; - init = 1; - } - *nids = digest_nids; - return pos; -} - -/* Setup ciphers */ -static int ossltest_ciphers(ENGINE *, const EVP_CIPHER **, - const int **, int); - -static int ossltest_cipher_nids[] = { - NID_aes_128_cbc, NID_aes_128_gcm, - NID_aes_128_cbc_hmac_sha1, 0 -}; - -/* AES128 */ - -static int ossltest_aes128_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *key, - const unsigned char *iv, int enc); -static int ossltest_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl); -static int ossltest_aes128_gcm_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *key, - const unsigned char *iv, int enc); -static int ossltest_aes128_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl); -static int ossltest_aes128_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, - void *ptr); -static int ossltest_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *key, - const unsigned char *iv, - int enc); -static int ossltest_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, - unsigned char *out, - const unsigned char *in, - size_t inl); -static int ossltest_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, - int arg, void *ptr); - -typedef struct { - size_t payload_length; /* AAD length in decrypt case */ - unsigned int tls_ver; -} EVP_AES_HMAC_SHA1; - -static EVP_CIPHER *_hidden_aes_128_cbc = NULL; -static const EVP_CIPHER *ossltest_aes_128_cbc(void) -{ - if (_hidden_aes_128_cbc == NULL - && ((_hidden_aes_128_cbc = EVP_CIPHER_meth_new(NID_aes_128_cbc, - 16 /* block size */, - 16 /* key len */)) == NULL - || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc,16) - || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc, - EVP_CIPH_FLAG_DEFAULT_ASN1 - | EVP_CIPH_CBC_MODE) - || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc, - ossltest_aes128_init_key) - || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc, - ossltest_aes128_cbc_cipher) - || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc, - EVP_CIPHER_impl_ctx_size(EVP_aes_128_cbc())))) { - EVP_CIPHER_meth_free(_hidden_aes_128_cbc); - _hidden_aes_128_cbc = NULL; - } - return _hidden_aes_128_cbc; -} - -static EVP_CIPHER *_hidden_aes_128_gcm = NULL; - -#define AES_GCM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \ - | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ - | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ - | EVP_CIPH_CUSTOM_COPY |EVP_CIPH_FLAG_AEAD_CIPHER \ - | EVP_CIPH_GCM_MODE) - -static const EVP_CIPHER *ossltest_aes_128_gcm(void) -{ - if (_hidden_aes_128_gcm == NULL - && ((_hidden_aes_128_gcm = EVP_CIPHER_meth_new(NID_aes_128_gcm, - 1 /* block size */, - 16 /* key len */)) == NULL - || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_gcm,12) - || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_gcm, AES_GCM_FLAGS) - || !EVP_CIPHER_meth_set_init(_hidden_aes_128_gcm, - ossltest_aes128_gcm_init_key) - || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_gcm, - ossltest_aes128_gcm_cipher) - || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_gcm, - ossltest_aes128_gcm_ctrl) - || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_gcm, - EVP_CIPHER_impl_ctx_size(EVP_aes_128_gcm())))) { - EVP_CIPHER_meth_free(_hidden_aes_128_gcm); - _hidden_aes_128_gcm = NULL; - } - return _hidden_aes_128_gcm; -} - -static EVP_CIPHER *_hidden_aes_128_cbc_hmac_sha1 = NULL; - -static const EVP_CIPHER *ossltest_aes_128_cbc_hmac_sha1(void) -{ - if (_hidden_aes_128_cbc_hmac_sha1 == NULL - && ((_hidden_aes_128_cbc_hmac_sha1 - = EVP_CIPHER_meth_new(NID_aes_128_cbc_hmac_sha1, - 16 /* block size */, - 16 /* key len */)) == NULL - || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc_hmac_sha1,16) - || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc_hmac_sha1, - EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | - EVP_CIPH_FLAG_AEAD_CIPHER) - || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc_hmac_sha1, - ossltest_aes128_cbc_hmac_sha1_init_key) - || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc_hmac_sha1, - ossltest_aes128_cbc_hmac_sha1_cipher) - || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc_hmac_sha1, - ossltest_aes128_cbc_hmac_sha1_ctrl) - || !EVP_CIPHER_meth_set_set_asn1_params(_hidden_aes_128_cbc_hmac_sha1, - EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv) - || !EVP_CIPHER_meth_set_get_asn1_params(_hidden_aes_128_cbc_hmac_sha1, - EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv) - || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc_hmac_sha1, - sizeof(EVP_AES_HMAC_SHA1)))) { - EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1); - _hidden_aes_128_cbc_hmac_sha1 = NULL; - } - return _hidden_aes_128_cbc_hmac_sha1; -} - -static void destroy_ciphers(void) -{ - EVP_CIPHER_meth_free(_hidden_aes_128_cbc); - EVP_CIPHER_meth_free(_hidden_aes_128_gcm); - EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1); - _hidden_aes_128_cbc = NULL; - _hidden_aes_128_gcm = NULL; - _hidden_aes_128_cbc_hmac_sha1 = NULL; -} - -/* Key loading */ -static EVP_PKEY *load_key(ENGINE *eng, const char *key_id, int pub, - UI_METHOD *ui_method, void *ui_data) -{ - BIO *in; - EVP_PKEY *key; - - if (!CHECK_AND_SKIP_CASE_PREFIX(key_id, "ot:")) - return NULL; - - fprintf(stderr, "[ossltest]Loading %s key %s\n", - pub ? "Public" : "Private", key_id); - in = BIO_new_file(key_id, "r"); - if (!in) - return NULL; - if (pub) - key = PEM_read_bio_PUBKEY(in, NULL, 0, NULL); - else - key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL); - BIO_free(in); - return key; -} - -static EVP_PKEY *ossltest_load_privkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, void *ui_data) -{ - return load_key(eng, key_id, 0, ui_method, ui_data); -} - -static EVP_PKEY *ossltest_load_pubkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, void *ui_data) -{ - return load_key(eng, key_id, 1, ui_method, ui_data); -} - - -static int bind_ossltest(ENGINE *e) -{ - /* Ensure the ossltest error handling is set up */ - ERR_load_OSSLTEST_strings(); - - if (!ENGINE_set_id(e, engine_ossltest_id) - || !ENGINE_set_name(e, engine_ossltest_name) - || !ENGINE_set_digests(e, ossltest_digests) - || !ENGINE_set_ciphers(e, ossltest_ciphers) - || !ENGINE_set_RAND(e, ossltest_rand_method()) - || !ENGINE_set_destroy_function(e, ossltest_destroy) - || !ENGINE_set_load_privkey_function(e, ossltest_load_privkey) - || !ENGINE_set_load_pubkey_function(e, ossltest_load_pubkey) - || !ENGINE_set_init_function(e, ossltest_init) - || !ENGINE_set_finish_function(e, ossltest_finish)) { - OSSLTESTerr(OSSLTEST_F_BIND_OSSLTEST, OSSLTEST_R_INIT_FAILED); - return 0; - } - - return 1; -} - -static ENGINE *engine_ossltest(void) -{ - ENGINE *ret = ENGINE_new(); - if (ret == NULL) - return NULL; - if (!bind_ossltest(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_ossltest(void) -{ - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_ossltest(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); -} - - -static int ossltest_init(ENGINE *e) -{ - return 1; -} - - -static int ossltest_finish(ENGINE *e) -{ - return 1; -} - - -static int ossltest_destroy(ENGINE *e) -{ - destroy_digests(); - destroy_ciphers(); - ERR_unload_OSSLTEST_strings(); - return 1; -} - -static int ossltest_digests(ENGINE *e, const EVP_MD **digest, - const int **nids, int nid) -{ - int ok = 1; - if (!digest) { - /* We are returning a list of supported nids */ - return ossltest_digest_nids(nids); - } - /* We are being asked for a specific digest */ - switch (nid) { - case NID_md5: - *digest = digest_md5(); - break; - case NID_sha1: - *digest = digest_sha1(); - break; - case NID_sha256: - *digest = digest_sha256(); - break; - case NID_sha384: - *digest = digest_sha384(); - break; - case NID_sha512: - *digest = digest_sha512(); - break; - default: - ok = 0; - *digest = NULL; - break; - } - return ok; -} - -static int ossltest_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid) -{ - int ok = 1; - if (!cipher) { - /* We are returning a list of supported nids */ - *nids = ossltest_cipher_nids; - return (sizeof(ossltest_cipher_nids) - 1) - / sizeof(ossltest_cipher_nids[0]); - } - /* We are being asked for a specific cipher */ - switch (nid) { - case NID_aes_128_cbc: - *cipher = ossltest_aes_128_cbc(); - break; - case NID_aes_128_gcm: - *cipher = ossltest_aes_128_gcm(); - break; - case NID_aes_128_cbc_hmac_sha1: - *cipher = ossltest_aes_128_cbc_hmac_sha1(); - break; - default: - ok = 0; - *cipher = NULL; - break; - } - return ok; -} - -static void fill_known_data(unsigned char *md, unsigned int len) -{ - unsigned int i; - - for (i=0; i 0) { - fill_known_data(md, MD5_DIGEST_LENGTH); - } - return ret; -} - -/* - * SHA1 implementation. - */ -static int digest_sha1_init(EVP_MD_CTX *ctx) -{ - return EVP_MD_meth_get_init(EVP_sha1())(ctx); -} - -static int digest_sha1_update(EVP_MD_CTX *ctx, const void *data, - size_t count) -{ - return EVP_MD_meth_get_update(EVP_sha1())(ctx, data, count); -} - -static int digest_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) -{ - int ret = EVP_MD_meth_get_final(EVP_sha1())(ctx, md); - - if (ret > 0) { - fill_known_data(md, SHA_DIGEST_LENGTH); - } - return ret; -} - -/* - * SHA256 implementation. - */ -static int digest_sha256_init(EVP_MD_CTX *ctx) -{ - return EVP_MD_meth_get_init(EVP_sha256())(ctx); -} - -static int digest_sha256_update(EVP_MD_CTX *ctx, const void *data, - size_t count) -{ - return EVP_MD_meth_get_update(EVP_sha256())(ctx, data, count); -} - -static int digest_sha256_final(EVP_MD_CTX *ctx, unsigned char *md) -{ - int ret = EVP_MD_meth_get_final(EVP_sha256())(ctx, md); - - if (ret > 0) { - fill_known_data(md, SHA256_DIGEST_LENGTH); - } - return ret; -} - -/* - * SHA384 implementation. - */ -static int digest_sha384_init(EVP_MD_CTX *ctx) -{ - return EVP_MD_meth_get_init(EVP_sha384())(ctx); -} - -static int digest_sha384_update(EVP_MD_CTX *ctx, const void *data, - size_t count) -{ - return EVP_MD_meth_get_update(EVP_sha384())(ctx, data, count); -} - -static int digest_sha384_final(EVP_MD_CTX *ctx, unsigned char *md) -{ - int ret = EVP_MD_meth_get_final(EVP_sha384())(ctx, md); - - if (ret > 0) { - fill_known_data(md, SHA384_DIGEST_LENGTH); - } - return ret; -} - -/* - * SHA512 implementation. - */ -static int digest_sha512_init(EVP_MD_CTX *ctx) -{ - return EVP_MD_meth_get_init(EVP_sha512())(ctx); -} - -static int digest_sha512_update(EVP_MD_CTX *ctx, const void *data, - size_t count) -{ - return EVP_MD_meth_get_update(EVP_sha512())(ctx, data, count); -} - -static int digest_sha512_final(EVP_MD_CTX *ctx, unsigned char *md) -{ - int ret = EVP_MD_meth_get_final(EVP_sha512())(ctx, md); - - if (ret > 0) { - fill_known_data(md, SHA512_DIGEST_LENGTH); - } - return ret; -} - -/* - * AES128 Implementation - */ - -static int ossltest_aes128_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *key, - const unsigned char *iv, int enc) -{ - return EVP_CIPHER_meth_get_init(EVP_aes_128_cbc()) (ctx, key, iv, enc); -} - -static int ossltest_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - unsigned char *tmpbuf; - int ret; - - tmpbuf = OPENSSL_malloc(inl); - - /* OPENSSL_malloc will return NULL if inl == 0 */ - if (tmpbuf == NULL && inl > 0) - return -1; - - /* Remember what we were asked to encrypt */ - if (tmpbuf != NULL) - memcpy(tmpbuf, in, inl); - - /* Go through the motions of encrypting it */ - ret = EVP_CIPHER_meth_get_do_cipher(EVP_aes_128_cbc())(ctx, out, in, inl); - - /* Throw it all away and just use the plaintext as the output */ - if (tmpbuf != NULL) - memcpy(out, tmpbuf, inl); - OPENSSL_free(tmpbuf); - - return ret; -} - -static int ossltest_aes128_gcm_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *key, - const unsigned char *iv, int enc) -{ - return EVP_CIPHER_meth_get_init(EVP_aes_128_gcm()) (ctx, key, iv, enc); -} - -static int ossltest_aes128_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - unsigned char *tmpbuf = OPENSSL_malloc(inl); - - /* OPENSSL_malloc will return NULL if inl == 0 */ - if (tmpbuf == NULL && inl > 0) - return -1; - - /* Remember what we were asked to encrypt */ - if (tmpbuf != NULL) - memcpy(tmpbuf, in, inl); - - /* Go through the motions of encrypting it */ - EVP_CIPHER_meth_get_do_cipher(EVP_aes_128_gcm())(ctx, out, in, inl); - - /* Throw it all away and just use the plaintext as the output */ - if (tmpbuf != NULL && out != NULL) - memcpy(out, tmpbuf, inl); - OPENSSL_free(tmpbuf); - - return (int)inl; -} - -static int ossltest_aes128_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, - void *ptr) -{ - /* Pass the ctrl down */ - int ret = EVP_CIPHER_meth_get_ctrl(EVP_aes_128_gcm())(ctx, type, arg, ptr); - - if (ret <= 0) - return ret; - - switch (type) { - case EVP_CTRL_AEAD_GET_TAG: - /* Always give the same tag */ - memset(ptr, 0, EVP_GCM_TLS_TAG_LEN); - break; - - default: - break; - } - - return 1; -} - -#define NO_PAYLOAD_LENGTH ((size_t)-1) -# define data(ctx) ((EVP_AES_HMAC_SHA1 *)EVP_CIPHER_CTX_get_cipher_data(ctx)) - -static int ossltest_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *inkey, - const unsigned char *iv, - int enc) -{ - EVP_AES_HMAC_SHA1 *key = data(ctx); - key->payload_length = NO_PAYLOAD_LENGTH; - return 1; -} - -static int ossltest_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, - unsigned char *out, - const unsigned char *in, - size_t len) -{ - EVP_AES_HMAC_SHA1 *key = data(ctx); - unsigned int l; - size_t plen = key->payload_length; - - key->payload_length = NO_PAYLOAD_LENGTH; - - if (len % AES_BLOCK_SIZE) - return 0; - - if (EVP_CIPHER_CTX_is_encrypting(ctx)) { - if (plen == NO_PAYLOAD_LENGTH) - plen = len; - else if (len != - ((plen + SHA_DIGEST_LENGTH + - AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)) - return 0; - - memmove(out, in, plen); - - if (plen != len) { /* "TLS" mode of operation */ - /* calculate HMAC and append it to payload */ - fill_known_data(out + plen, SHA_DIGEST_LENGTH); - - /* pad the payload|hmac */ - plen += SHA_DIGEST_LENGTH; - for (l = (unsigned int)(len - plen - 1); plen < len; plen++) - out[plen] = l; - } - } else { - /* decrypt HMAC|padding at once */ - memmove(out, in, len); - - if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ - unsigned int maxpad, pad; - - if (key->tls_ver >= TLS1_1_VERSION) { - if (len < (AES_BLOCK_SIZE + SHA_DIGEST_LENGTH + 1)) - return 0; - - /* omit explicit iv */ - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - len -= AES_BLOCK_SIZE; - } else if (len < (SHA_DIGEST_LENGTH + 1)) - return 0; - - /* figure out payload length */ - pad = out[len - 1]; - maxpad = (unsigned int)(len - (SHA_DIGEST_LENGTH + 1)); - if (pad > maxpad) - return 0; - for (plen = len - pad - 1; plen < len; plen++) - if (out[plen] != pad) - return 0; - } - } - - return 1; -} - -static int ossltest_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, - int arg, void *ptr) -{ - EVP_AES_HMAC_SHA1 *key = data(ctx); - - switch (type) { - case EVP_CTRL_AEAD_SET_MAC_KEY: - return 1; - - case EVP_CTRL_AEAD_TLS1_AAD: - { - unsigned char *p = ptr; - unsigned int len; - - if (arg != EVP_AEAD_TLS1_AAD_LEN) - return -1; - - len = p[arg - 2] << 8 | p[arg - 1]; - key->tls_ver = p[arg - 4] << 8 | p[arg - 3]; - - if (EVP_CIPHER_CTX_is_encrypting(ctx)) { - key->payload_length = len; - if (key->tls_ver >= TLS1_1_VERSION) { - if (len < AES_BLOCK_SIZE) - return 0; - len -= AES_BLOCK_SIZE; - p[arg - 2] = len >> 8; - p[arg - 1] = len; - } - - return (int)(((len + SHA_DIGEST_LENGTH + - AES_BLOCK_SIZE) & -AES_BLOCK_SIZE) - - len); - } else { - key->payload_length = arg; - - return SHA_DIGEST_LENGTH; - } - } - default: - return -1; - } -} - -static int ossltest_rand_bytes(unsigned char *buf, int num) -{ - unsigned char val = 1; - - while (--num >= 0) - *buf++ = val++; - return 1; -} - -static int ossltest_rand_status(void) -{ - return 1; -} - -static const RAND_METHOD *ossltest_rand_method(void) -{ - - static RAND_METHOD osslt_rand_meth = { - NULL, - ossltest_rand_bytes, - NULL, - NULL, - ossltest_rand_bytes, - ossltest_rand_status - }; - - return &osslt_rand_meth; -} diff --git a/engines/e_ossltest.ec b/engines/e_ossltest.ec deleted file mode 100644 index a4a55ecb3f6..00000000000 --- a/engines/e_ossltest.ec +++ /dev/null @@ -1,3 +0,0 @@ -# The INPUT HEADER is scanned for declarations -# LIBNAME INPUT HEADER ERROR-TABLE FILE -L OSSLTEST e_ossltest_err.h e_ossltest_err.c diff --git a/engines/e_ossltest.txt b/engines/e_ossltest.txt deleted file mode 100644 index 645917fe3bb..00000000000 --- a/engines/e_ossltest.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright 1999-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 - -#Reason codes -OSSLTEST_R_INIT_FAILED:100:init failed diff --git a/engines/e_ossltest_err.c b/engines/e_ossltest_err.c deleted file mode 100644 index f229aeb4384..00000000000 --- a/engines/e_ossltest_err.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-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 "e_ossltest_err.h" - -#ifndef OPENSSL_NO_ERR - -static ERR_STRING_DATA OSSLTEST_str_reasons[] = { - {ERR_PACK(0, 0, OSSLTEST_R_INIT_FAILED), "init failed"}, - {0, NULL} -}; - -#endif - -static int lib_code = 0; -static int error_loaded = 0; - -static int ERR_load_OSSLTEST_strings(void) -{ - if (lib_code == 0) - lib_code = ERR_get_next_error_library(); - - if (!error_loaded) { -#ifndef OPENSSL_NO_ERR - ERR_load_strings(lib_code, OSSLTEST_str_reasons); -#endif - error_loaded = 1; - } - return 1; -} - -static void ERR_unload_OSSLTEST_strings(void) -{ - if (error_loaded) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(lib_code, OSSLTEST_str_reasons); -#endif - error_loaded = 0; - } -} - -static void ERR_OSSLTEST_error(int function, int reason, const char *file, int line) -{ - if (lib_code == 0) - lib_code = ERR_get_next_error_library(); - ERR_raise(lib_code, reason); - ERR_set_debug(file, line, NULL); -} diff --git a/engines/e_ossltest_err.h b/engines/e_ossltest_err.h deleted file mode 100644 index c89409079be..00000000000 --- a/engines/e_ossltest_err.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-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 - */ - -#ifndef OSSL_E_OSSLTEST_ERR_H -# define OSSL_E_OSSLTEST_ERR_H -# pragma once - -# include -# include - - -# define OSSLTESTerr(f, r) ERR_OSSLTEST_error(0, (r), OPENSSL_FILE, OPENSSL_LINE) - - -/* - * OSSLTEST reason codes. - */ -# define OSSLTEST_R_INIT_FAILED 100 - -#endif diff --git a/engines/e_padlock.c b/engines/e_padlock.c deleted file mode 100644 index 7430eeaae2e..00000000000 --- a/engines/e_padlock.c +++ /dev/null @@ -1,727 +0,0 @@ -/* - * Copyright 2004-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * This file uses the low level AES and engine functions (which are deprecated - * for non-internal use) in order to implement the padlock engine AES ciphers. - */ -#define OPENSSL_SUPPRESS_DEPRECATED - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef OPENSSL_NO_PADLOCKENG - -/* - * VIA PadLock AES is available *ONLY* on some x86 CPUs. Not only that it - * doesn't exist elsewhere, but it even can't be compiled on other platforms! - */ - -# undef COMPILE_PADLOCKENG -# if defined(PADLOCK_ASM) -# define COMPILE_PADLOCKENG -static ENGINE *ENGINE_padlock(void); -# endif - -void engine_load_padlock_int(void); -void engine_load_padlock_int(void) -{ -/* On non-x86 CPUs it just returns. */ -# ifdef COMPILE_PADLOCKENG - ENGINE *toadd = ENGINE_padlock(); - if (!toadd) - return; - ERR_set_mark(); - ENGINE_add(toadd); - /* - * If the "add" worked, it gets a structural reference. So either way, we - * release our just-created reference. - */ - ENGINE_free(toadd); - /* - * If the "add" didn't work, it was probably a conflict because it was - * already added (eg. someone calling ENGINE_load_blah then calling - * ENGINE_load_builtin_engines() perhaps). - */ - ERR_pop_to_mark(); -# endif -} - -# ifdef COMPILE_PADLOCKENG - -/* Function for ENGINE detection and control */ -static int padlock_available(void); -static int padlock_init(ENGINE *e); - -/* RNG Stuff */ -static RAND_METHOD padlock_rand; - -/* Cipher Stuff */ -static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid); - -/* Engine names */ -static const char *padlock_id = "padlock"; -static char padlock_name[100]; - -/* Available features */ -static int padlock_use_ace = 0; /* Advanced Cryptography Engine */ -static int padlock_use_rng = 0; /* Random Number Generator */ - -/* ===== Engine "management" functions ===== */ - -/* Prepare the ENGINE structure for registration */ -static int padlock_bind_helper(ENGINE *e) -{ - /* Check available features */ - padlock_available(); - - /* - * RNG is currently disabled for reasons discussed in commentary just - * before padlock_rand_bytes function. - */ - padlock_use_rng = 0; - - /* Generate a nice engine name with available features */ - BIO_snprintf(padlock_name, sizeof(padlock_name), - "VIA PadLock (%s, %s)", - padlock_use_rng ? "RNG" : "no-RNG", - padlock_use_ace ? "ACE" : "no-ACE"); - - /* Register everything or return with an error */ - if (!ENGINE_set_id(e, padlock_id) || - !ENGINE_set_name(e, padlock_name) || - !ENGINE_set_init_function(e, padlock_init) || - (padlock_use_ace && !ENGINE_set_ciphers(e, padlock_ciphers)) || - (padlock_use_rng && !ENGINE_set_RAND(e, &padlock_rand))) { - return 0; - } - - /* Everything looks good */ - return 1; -} - -/* Constructor */ -static ENGINE *ENGINE_padlock(void) -{ - ENGINE *eng = ENGINE_new(); - - if (eng == NULL) { - return NULL; - } - - if (!padlock_bind_helper(eng)) { - ENGINE_free(eng); - return NULL; - } - - return eng; -} - -/* Check availability of the engine */ -static int padlock_init(ENGINE *e) -{ - return (padlock_use_rng || padlock_use_ace); -} - -# ifndef AES_ASM -static int padlock_aes_set_encrypt_key(const unsigned char *userKey, - const int bits, - AES_KEY *key); -static int padlock_aes_set_decrypt_key(const unsigned char *userKey, - const int bits, - AES_KEY *key); -# define AES_ASM -# define AES_set_encrypt_key padlock_aes_set_encrypt_key -# define AES_set_decrypt_key padlock_aes_set_decrypt_key -/* clang-format off */ -# include "../crypto/aes/aes_core.c" -/* clang-format on */ -# endif - -/* - * This stuff is needed if this ENGINE is being compiled into a - * self-contained shared-library. - */ -/* ===== Here comes the "real" engine ===== */ - -/* Some AES-related constants */ -# define AES_BLOCK_SIZE 16 -# define AES_KEY_SIZE_128 16 -# define AES_KEY_SIZE_192 24 -# define AES_KEY_SIZE_256 32 - /* - * Here we store the status information relevant to the current context. - */ - /* - * BIG FAT WARNING: Inline assembler in PADLOCK_XCRYPT_ASM() depends on - * the order of items in this structure. Don't blindly modify, reorder, - * etc! - */ -struct padlock_cipher_data { - unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */ - union { - unsigned int pad[4]; - struct { - int rounds:4; - int dgst:1; /* n/a in C3 */ - int align:1; /* n/a in C3 */ - int cipher:1; /* n/a in C3 */ - unsigned int keygen:1; - int intern:1; - unsigned int encdec:1; - int ksize:2; - } b; - } cword; /* Control word */ - AES_KEY ks; /* Encryption key */ -}; - -/* Interface to assembler module */ -unsigned int padlock_capability(void); -void padlock_key_bswap(AES_KEY *key); -void padlock_verify_context(struct padlock_cipher_data *ctx); -void padlock_reload_key(void); -void padlock_aes_block(void *out, const void *inp, - struct padlock_cipher_data *ctx); -int padlock_ecb_encrypt(void *out, const void *inp, - struct padlock_cipher_data *ctx, size_t len); -int padlock_cbc_encrypt(void *out, const void *inp, - struct padlock_cipher_data *ctx, size_t len); -int padlock_cfb_encrypt(void *out, const void *inp, - struct padlock_cipher_data *ctx, size_t len); -int padlock_ofb_encrypt(void *out, const void *inp, - struct padlock_cipher_data *ctx, size_t len); -int padlock_ctr32_encrypt(void *out, const void *inp, - struct padlock_cipher_data *ctx, size_t len); -int padlock_xstore(void *out, int edx); -void padlock_sha1_oneshot(void *ctx, const void *inp, size_t len); -void padlock_sha1(void *ctx, const void *inp, size_t len); -void padlock_sha256_oneshot(void *ctx, const void *inp, size_t len); -void padlock_sha256(void *ctx, const void *inp, size_t len); - -/* - * Load supported features of the CPU to see if the PadLock is available. - */ -static int padlock_available(void) -{ - unsigned int edx = padlock_capability(); - - /* Fill up some flags */ - padlock_use_ace = ((edx & (0x3 << 6)) == (0x3 << 6)); - padlock_use_rng = ((edx & (0x3 << 2)) == (0x3 << 2)); - - return padlock_use_ace + padlock_use_rng; -} - -/* ===== AES encryption/decryption ===== */ - -# if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb) -# define NID_aes_128_cfb NID_aes_128_cfb128 -# endif - -# if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb) -# define NID_aes_128_ofb NID_aes_128_ofb128 -# endif - -# if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb) -# define NID_aes_192_cfb NID_aes_192_cfb128 -# endif - -# if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb) -# define NID_aes_192_ofb NID_aes_192_ofb128 -# endif - -# if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb) -# define NID_aes_256_cfb NID_aes_256_cfb128 -# endif - -# if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb) -# define NID_aes_256_ofb NID_aes_256_ofb128 -# endif - -/* List of supported ciphers. */ -static const int padlock_cipher_nids[] = { - NID_aes_128_ecb, - NID_aes_128_cbc, - NID_aes_128_cfb, - NID_aes_128_ofb, - NID_aes_128_ctr, - - NID_aes_192_ecb, - NID_aes_192_cbc, - NID_aes_192_cfb, - NID_aes_192_ofb, - NID_aes_192_ctr, - - NID_aes_256_ecb, - NID_aes_256_cbc, - NID_aes_256_cfb, - NID_aes_256_ofb, - NID_aes_256_ctr -}; - -static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids) / - sizeof(padlock_cipher_nids[0])); - -/* Function prototypes ... */ -static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); - -# define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \ - ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) ) -# define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\ - NEAREST_ALIGNED(EVP_CIPHER_CTX_get_cipher_data(ctx))) - -static int -padlock_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, - const unsigned char *in_arg, size_t nbytes) -{ - return padlock_ecb_encrypt(out_arg, in_arg, - ALIGNED_CIPHER_DATA(ctx), nbytes); -} - -static int -padlock_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, - const unsigned char *in_arg, size_t nbytes) -{ - struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx); - int ret; - - memcpy(cdata->iv, EVP_CIPHER_CTX_iv(ctx), AES_BLOCK_SIZE); - if ((ret = padlock_cbc_encrypt(out_arg, in_arg, cdata, nbytes))) - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), cdata->iv, AES_BLOCK_SIZE); - return ret; -} - -static int -padlock_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, - const unsigned char *in_arg, size_t nbytes) -{ - struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx); - size_t chunk; - - if ((chunk = EVP_CIPHER_CTX_get_num(ctx))) { /* borrow chunk variable */ - unsigned char *ivp = EVP_CIPHER_CTX_iv_noconst(ctx); - - if (chunk >= AES_BLOCK_SIZE) - return 0; /* bogus value */ - - if (EVP_CIPHER_CTX_is_encrypting(ctx)) - while (chunk < AES_BLOCK_SIZE && nbytes != 0) { - ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk]; - chunk++, nbytes--; - } else - while (chunk < AES_BLOCK_SIZE && nbytes != 0) { - unsigned char c = *(in_arg++); - *(out_arg++) = c ^ ivp[chunk]; - ivp[chunk++] = c, nbytes--; - } - - EVP_CIPHER_CTX_set_num(ctx, chunk % AES_BLOCK_SIZE); - } - - if (nbytes == 0) - return 1; - - memcpy(cdata->iv, EVP_CIPHER_CTX_iv(ctx), AES_BLOCK_SIZE); - - if ((chunk = nbytes & ~(AES_BLOCK_SIZE - 1))) { - if (!padlock_cfb_encrypt(out_arg, in_arg, cdata, chunk)) - return 0; - nbytes -= chunk; - } - - if (nbytes) { - unsigned char *ivp = cdata->iv; - - out_arg += chunk; - in_arg += chunk; - EVP_CIPHER_CTX_set_num(ctx, (int)nbytes); - if (cdata->cword.b.encdec) { - cdata->cword.b.encdec = 0; - padlock_reload_key(); - padlock_aes_block(ivp, ivp, cdata); - cdata->cword.b.encdec = 1; - padlock_reload_key(); - while (nbytes) { - unsigned char c = *(in_arg++); - *(out_arg++) = c ^ *ivp; - *(ivp++) = c, nbytes--; - } - } else { - padlock_reload_key(); - padlock_aes_block(ivp, ivp, cdata); - padlock_reload_key(); - while (nbytes) { - *ivp = *(out_arg++) = *(in_arg++) ^ *ivp; - ivp++, nbytes--; - } - } - } - - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), cdata->iv, AES_BLOCK_SIZE); - - return 1; -} - -static int -padlock_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, - const unsigned char *in_arg, size_t nbytes) -{ - struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx); - size_t chunk; - - /* - * ctx->num is maintained in byte-oriented modes, such as CFB and OFB... - */ - if ((chunk = EVP_CIPHER_CTX_get_num(ctx))) { /* borrow chunk variable */ - unsigned char *ivp = EVP_CIPHER_CTX_iv_noconst(ctx); - - if (chunk >= AES_BLOCK_SIZE) - return 0; /* bogus value */ - - while (chunk < AES_BLOCK_SIZE && nbytes != 0) { - *(out_arg++) = *(in_arg++) ^ ivp[chunk]; - chunk++, nbytes--; - } - - EVP_CIPHER_CTX_set_num(ctx, chunk % AES_BLOCK_SIZE); - } - - if (nbytes == 0) - return 1; - - memcpy(cdata->iv, EVP_CIPHER_CTX_iv(ctx), AES_BLOCK_SIZE); - - if ((chunk = nbytes & ~(AES_BLOCK_SIZE - 1))) { - if (!padlock_ofb_encrypt(out_arg, in_arg, cdata, chunk)) - return 0; - nbytes -= chunk; - } - - if (nbytes) { - unsigned char *ivp = cdata->iv; - - out_arg += chunk; - in_arg += chunk; - EVP_CIPHER_CTX_set_num(ctx, (int)nbytes); - padlock_reload_key(); /* empirically found */ - padlock_aes_block(ivp, ivp, cdata); - padlock_reload_key(); /* empirically found */ - while (nbytes) { - *(out_arg++) = *(in_arg++) ^ *ivp; - ivp++, nbytes--; - } - } - - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), cdata->iv, AES_BLOCK_SIZE); - - return 1; -} - -static void padlock_ctr32_encrypt_glue(const unsigned char *in, - unsigned char *out, size_t blocks, - struct padlock_cipher_data *ctx, - const unsigned char *ivec) -{ - memcpy(ctx->iv, ivec, AES_BLOCK_SIZE); - padlock_ctr32_encrypt(out, in, ctx, AES_BLOCK_SIZE * blocks); -} - -static int -padlock_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, - const unsigned char *in_arg, size_t nbytes) -{ - struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx); - int n = EVP_CIPHER_CTX_get_num(ctx); - unsigned int num; - - if (n < 0) - return 0; - num = (unsigned int)n; - - CRYPTO_ctr128_encrypt_ctr32(in_arg, out_arg, nbytes, - cdata, EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_buf_noconst(ctx), &num, - (ctr128_f) padlock_ctr32_encrypt_glue); - - EVP_CIPHER_CTX_set_num(ctx, (size_t)num); - return 1; -} - -# define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE -# define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE -# define EVP_CIPHER_block_size_OFB 1 -# define EVP_CIPHER_block_size_CFB 1 -# define EVP_CIPHER_block_size_CTR 1 - -/* - * Declaring so many ciphers by hand would be a pain. Instead introduce a bit - * of preprocessor magic :-) - */ -# define DECLARE_AES_EVP(ksize,lmode,umode) \ -static EVP_CIPHER *_hidden_aes_##ksize##_##lmode = NULL; \ -static const EVP_CIPHER *padlock_aes_##ksize##_##lmode(void) \ -{ \ - if (_hidden_aes_##ksize##_##lmode == NULL \ - && ((_hidden_aes_##ksize##_##lmode = \ - EVP_CIPHER_meth_new(NID_aes_##ksize##_##lmode, \ - EVP_CIPHER_block_size_##umode, \ - AES_KEY_SIZE_##ksize)) == NULL \ - || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_##ksize##_##lmode, \ - AES_BLOCK_SIZE) \ - || !EVP_CIPHER_meth_set_flags(_hidden_aes_##ksize##_##lmode, \ - 0 | EVP_CIPH_##umode##_MODE) \ - || !EVP_CIPHER_meth_set_init(_hidden_aes_##ksize##_##lmode, \ - padlock_aes_init_key) \ - || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_##ksize##_##lmode, \ - padlock_##lmode##_cipher) \ - || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_##ksize##_##lmode, \ - sizeof(struct padlock_cipher_data) + 16) \ - || !EVP_CIPHER_meth_set_set_asn1_params(_hidden_aes_##ksize##_##lmode, \ - EVP_CIPHER_set_asn1_iv) \ - || !EVP_CIPHER_meth_set_get_asn1_params(_hidden_aes_##ksize##_##lmode, \ - EVP_CIPHER_get_asn1_iv))) { \ - EVP_CIPHER_meth_free(_hidden_aes_##ksize##_##lmode); \ - _hidden_aes_##ksize##_##lmode = NULL; \ - } \ - return _hidden_aes_##ksize##_##lmode; \ -} - -DECLARE_AES_EVP(128, ecb, ECB) -DECLARE_AES_EVP(128, cbc, CBC) -DECLARE_AES_EVP(128, cfb, CFB) -DECLARE_AES_EVP(128, ofb, OFB) -DECLARE_AES_EVP(128, ctr, CTR) - -DECLARE_AES_EVP(192, ecb, ECB) -DECLARE_AES_EVP(192, cbc, CBC) -DECLARE_AES_EVP(192, cfb, CFB) -DECLARE_AES_EVP(192, ofb, OFB) -DECLARE_AES_EVP(192, ctr, CTR) - -DECLARE_AES_EVP(256, ecb, ECB) -DECLARE_AES_EVP(256, cbc, CBC) -DECLARE_AES_EVP(256, cfb, CFB) -DECLARE_AES_EVP(256, ofb, OFB) -DECLARE_AES_EVP(256, ctr, CTR) - -static int -padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, - int nid) -{ - /* No specific cipher => return a list of supported nids ... */ - if (!cipher) { - *nids = padlock_cipher_nids; - return padlock_cipher_nids_num; - } - - /* ... or the requested "cipher" otherwise */ - switch (nid) { - case NID_aes_128_ecb: - *cipher = padlock_aes_128_ecb(); - break; - case NID_aes_128_cbc: - *cipher = padlock_aes_128_cbc(); - break; - case NID_aes_128_cfb: - *cipher = padlock_aes_128_cfb(); - break; - case NID_aes_128_ofb: - *cipher = padlock_aes_128_ofb(); - break; - case NID_aes_128_ctr: - *cipher = padlock_aes_128_ctr(); - break; - - case NID_aes_192_ecb: - *cipher = padlock_aes_192_ecb(); - break; - case NID_aes_192_cbc: - *cipher = padlock_aes_192_cbc(); - break; - case NID_aes_192_cfb: - *cipher = padlock_aes_192_cfb(); - break; - case NID_aes_192_ofb: - *cipher = padlock_aes_192_ofb(); - break; - case NID_aes_192_ctr: - *cipher = padlock_aes_192_ctr(); - break; - - case NID_aes_256_ecb: - *cipher = padlock_aes_256_ecb(); - break; - case NID_aes_256_cbc: - *cipher = padlock_aes_256_cbc(); - break; - case NID_aes_256_cfb: - *cipher = padlock_aes_256_cfb(); - break; - case NID_aes_256_ofb: - *cipher = padlock_aes_256_ofb(); - break; - case NID_aes_256_ctr: - *cipher = padlock_aes_256_ctr(); - break; - - default: - /* Sorry, we don't support this NID */ - *cipher = NULL; - return 0; - } - - return 1; -} - -/* Prepare the encryption key for PadLock usage */ -static int -padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - struct padlock_cipher_data *cdata; - int key_len = EVP_CIPHER_CTX_get_key_length(ctx) * 8; - unsigned long mode = EVP_CIPHER_CTX_get_mode(ctx); - - if (key == NULL) - return 0; /* ERROR */ - - cdata = ALIGNED_CIPHER_DATA(ctx); - memset(cdata, 0, sizeof(*cdata)); - - /* Prepare Control word. */ - if (mode == EVP_CIPH_OFB_MODE || mode == EVP_CIPH_CTR_MODE) - cdata->cword.b.encdec = 0; - else - cdata->cword.b.encdec = (EVP_CIPHER_CTX_is_encrypting(ctx) == 0); - cdata->cword.b.rounds = 10 + (key_len - 128) / 32; - cdata->cword.b.ksize = (key_len - 128) / 64; - - switch (key_len) { - case 128: - /* - * PadLock can generate an extended key for AES128 in hardware - */ - memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128); - cdata->cword.b.keygen = 0; - break; - - case 192: - case 256: - /* - * Generate an extended AES key in software. Needed for AES192/AES256 - */ - /* - * Well, the above applies to Stepping 8 CPUs and is listed as - * hardware errata. They most likely will fix it at some point and - * then a check for stepping would be due here. - */ - if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) - && !enc) - AES_set_decrypt_key(key, key_len, &cdata->ks); - else - AES_set_encrypt_key(key, key_len, &cdata->ks); - /* - * OpenSSL C functions use byte-swapped extended key. - */ - padlock_key_bswap(&cdata->ks); - cdata->cword.b.keygen = 1; - break; - - default: - /* ERROR */ - return 0; - } - - /* - * This is done to cover for cases when user reuses the - * context for new key. The catch is that if we don't do - * this, padlock_eas_cipher might proceed with old key... - */ - padlock_reload_key(); - - return 1; -} - -/* ===== Random Number Generator ===== */ -/* - * This code is not engaged. The reason is that it does not comply - * with recommendations for VIA RNG usage for secure applications - * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it - * provide meaningful error control... - */ -/* - * Wrapper that provides an interface between the API and the raw PadLock - * RNG - */ -static int padlock_rand_bytes(unsigned char *output, int count) -{ - unsigned int eax, buf; - - while (count >= 8) { - eax = padlock_xstore(output, 0); - if (!(eax & (1 << 6))) - return 0; /* RNG disabled */ - /* this ---vv--- covers DC bias, Raw Bits and String Filter */ - if (eax & (0x1F << 10)) - return 0; - if ((eax & 0x1F) == 0) - continue; /* no data, retry... */ - if ((eax & 0x1F) != 8) - return 0; /* fatal failure... */ - output += 8; - count -= 8; - } - while (count > 0) { - eax = padlock_xstore(&buf, 3); - if (!(eax & (1 << 6))) - return 0; /* RNG disabled */ - /* this ---vv--- covers DC bias, Raw Bits and String Filter */ - if (eax & (0x1F << 10)) - return 0; - if ((eax & 0x1F) == 0) - continue; /* no data, retry... */ - if ((eax & 0x1F) != 1) - return 0; /* fatal failure... */ - *output++ = (unsigned char)buf; - count--; - } - OPENSSL_cleanse(&buf, sizeof(buf)); - - return 1; -} - -/* Dummy but necessary function */ -static int padlock_rand_status(void) -{ - return 1; -} - -/* Prepare structure for registration */ -static RAND_METHOD padlock_rand = { - NULL, /* seed */ - padlock_rand_bytes, /* bytes */ - NULL, /* cleanup */ - NULL, /* add */ - padlock_rand_bytes, /* pseudorand */ - padlock_rand_status, /* rand status */ -}; - -# endif /* COMPILE_PADLOCKENG */ -#endif /* !OPENSSL_NO_PADLOCKENG */ -- 2.47.3