Latest update

This commit is contained in:
2018-11-01 00:59:10 +09:00
parent 95369e3f0a
commit 35dea6db7e
107 changed files with 4513 additions and 1163 deletions
+18
View File
@@ -9,6 +9,24 @@
Changes between 1.1.1 and 1.1.2 [xx XXX xxxx] Changes between 1.1.1 and 1.1.2 [xx XXX xxxx]
*) Ported the HMAC, CMAC and SipHash EVP_PKEY_METHODs to EVP_MAC.
[Richard Levitte]
*) Added EVP_MAC, an EVP layer MAC API, to simplify adding MAC
implementations. This includes a generic EVP_PKEY to EVP_MAC bridge,
to facilitate the continued use of MACs through raw private keys in
functionality such as EVP_DigestSign* and EVP_DigestVerify*.
[Richard Levitte]
*) Deprecate ECDH_KDF_X9_62() and mark its replacement as internal. Users
should use the EVP interface instead (EVP_PKEY_CTX_set_ecdh_kdf_type).
[Antoine Salon]
*) Added EVP_PKEY_ECDH_KDF_X9_63 and ecdh_KDF_X9_63() as replacements for
the EVP_PKEY_ECDH_KDF_X9_62 KDF type and ECDH_KDF_X9_62(). The old names
are retained for backwards compatibility.
[Antoine Salon]
*) AES-XTS mode now enforces that its two keys are different to mitigate *) AES-XTS mode now enforces that its two keys are different to mitigate
the attacked described in "Efficient Instantiations of Tweakable the attacked described in "Efficient Instantiations of Tweakable
Blockciphers and Refinements to Modes OCB and PMAC" by Phillip Rogaway. Blockciphers and Refinements to Modes OCB and PMAC" by Phillip Rogaway.
+38 -10
View File
@@ -24,7 +24,12 @@
my $ndk = $ENV{ANDROID_NDK}; my $ndk = $ENV{ANDROID_NDK};
die "\$ANDROID_NDK is not defined" if (!$ndk); die "\$ANDROID_NDK is not defined" if (!$ndk);
die "\$ANDROID_NDK=$ndk is invalid" if (!-d "$ndk/platforms"); if (!-d "$ndk/platforms" && !-f "$ndk/AndroidVersion.txt") {
# $ndk/platforms is traditional "all-inclusive" NDK, while
# $ndk/AndroidVersion.txt is so-called standalone toolchain
# tailored for specific target down to API level.
die "\$ANDROID_NDK=$ndk is invalid";
}
$ndk = canonpath($ndk); $ndk = canonpath($ndk);
my $ndkver = undef; my $ndkver = undef;
@@ -40,10 +45,18 @@
close $fh; close $fh;
} }
my $sysroot; my ($sysroot, $api, $arch);
if (!($sysroot = $ENV{CROSS_SYSROOT})) { $config{target} =~ m|[^-]+-([^-]+)$|; # split on dash
my $api = "*"; $arch = $1;
if ($sysroot = $ENV{CROSS_SYSROOT}) {
$sysroot =~ m|/android-([0-9]+)/arch-(\w+)/?$|;
($api, $arch) = ($1, $2);
} elsif (-f "$ndk/AndroidVersion.txt") {
$sysroot = "$ndk/sysroot";
} else {
$api = "*";
# see if user passed -D__ANDROID_API__=N # see if user passed -D__ANDROID_API__=N
foreach (@{$useradd{CPPDEFINES}}, @{$user{CPPFLAGS}}) { foreach (@{$useradd{CPPDEFINES}}, @{$user{CPPFLAGS}}) {
@@ -59,19 +72,17 @@
} glob("$ndk/platforms/android-$api"); } glob("$ndk/platforms/android-$api");
die "no $ndk/platforms/android-$api" if ($#platforms < 0); die "no $ndk/platforms/android-$api" if ($#platforms < 0);
$config{target} =~ m|[^-]+-([^-]+)$|; # split on dash $sysroot = "@platforms[$#platforms]/arch-$arch";
$sysroot = "@platforms[$#platforms]/arch-$1"; $sysroot =~ m|/android-([0-9]+)/arch-$arch|;
$api = $1;
} }
die "no sysroot=$sysroot" if (!-d $sysroot); die "no sysroot=$sysroot" if (!-d $sysroot);
$sysroot =~ m|/android-([0-9]+)/arch-(\w+)/?$|;
my ($api, $arch) = ($1, $2);
my $triarch = $triplet{$arch}; my $triarch = $triplet{$arch};
my $cflags; my $cflags;
my $cppflags; my $cppflags;
# see if there is NDK clang on $PATH # see if there is NDK clang on $PATH, "universal" or "standalone"
if (which("clang") =~ m|^$ndk/.*/prebuilt/([^/]+)/|) { if (which("clang") =~ m|^$ndk/.*/prebuilt/([^/]+)/|) {
my $host=$1; my $host=$1;
# harmonize with gcc default # harmonize with gcc default
@@ -83,6 +94,23 @@
. "/$tritools-4.9/prebuilt/$host"; . "/$tritools-4.9/prebuilt/$host";
$user{CC} = "clang" if ($user{CC} !~ m|clang|); $user{CC} = "clang" if ($user{CC} !~ m|clang|);
$user{CROSS_COMPILE} = undef; $user{CROSS_COMPILE} = undef;
if (which("llvm-ar") =~ m|^$ndk/.*/prebuilt/([^/]+)/|) {
$user{AR} = "llvm-ar";
$user{ARFLAGS} = [ "rs" ];
$user{RANLIB} = ":";
}
} elsif (-f "$ndk/AndroidVersion.txt") { #"standalone toolchain"
my $cc = $user{CC} // "clang";
# One can probably argue that both clang and gcc should be
# probed, but support for "standalone toolchain" was added
# *after* announcement that gcc is being phased out, so
# favouring clang is considered adequate. Those who insist
# have option to enforce test for gcc with CC=gcc.
if (which("$triarch-$cc") !~ m|^$ndk|) {
die "no NDK $triarch-$cc on \$PATH";
}
$user{CC} = $cc;
$user{CROSS_COMPILE} = "$triarch-";
} elsif ($user{CC} eq "clang") { } elsif ($user{CC} eq "clang") {
die "no NDK clang on \$PATH"; die "no NDK clang on \$PATH";
} else { } else {
+10 -12
View File
@@ -6,31 +6,31 @@
# work... # work...
# #
my %targets = ( my %targets = (
"ios-common" => {
template => 1,
inherit_from => [ "darwin-common" ],
sys_id => "iOS",
disable => [ "engine", "async" ],
},
"ios-xcrun" => { "ios-xcrun" => {
inherit_from => [ "darwin-common", asm("armv4_asm") ], inherit_from => [ "ios-common", asm("armv4_asm") ],
# It should be possible to go below iOS 6 and even add -arch armv6, # It should be possible to go below iOS 6 and even add -arch armv6,
# thus targeting iPhone pre-3GS, but it's assumed to be irrelevant # thus targeting iPhone pre-3GS, but it's assumed to be irrelevant
# at this point. # at this point.
CC => "xcrun -sdk iphoneos cc", CC => "xcrun -sdk iphoneos cc",
cflags => add("-arch armv7 -mios-version-min=6.0.0 -fno-common"), cflags => add("-arch armv7 -mios-version-min=6.0.0 -fno-common"),
sys_id => "iOS",
perlasm_scheme => "ios32", perlasm_scheme => "ios32",
disable => [ "engine" ],
}, },
"ios64-xcrun" => { "ios64-xcrun" => {
inherit_from => [ "darwin-common", asm("aarch64_asm") ], inherit_from => [ "ios-common", asm("aarch64_asm") ],
CC => "xcrun -sdk iphoneos cc", CC => "xcrun -sdk iphoneos cc",
cflags => add("-arch arm64 -mios-version-min=7.0.0 -fno-common"), cflags => add("-arch arm64 -mios-version-min=7.0.0 -fno-common"),
sys_id => "iOS",
bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR", bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
perlasm_scheme => "ios64", perlasm_scheme => "ios64",
disable => [ "engine" ],
}, },
"iossimulator-xcrun" => { "iossimulator-xcrun" => {
inherit_from => [ "darwin-common" ], inherit_from => [ "ios-common" ],
CC => "xcrun -sdk iphonesimulator cc", CC => "xcrun -sdk iphonesimulator cc",
sys_id => "iOS",
disable => [ "engine" ],
}, },
# It takes three prior-set environment variables to make it work: # It takes three prior-set environment variables to make it work:
# #
@@ -46,10 +46,8 @@ my %targets = (
# CROSS_SDK=iPhoneOS.sdk # CROSS_SDK=iPhoneOS.sdk
# #
"iphoneos-cross" => { "iphoneos-cross" => {
inherit_from => [ "darwin-common" ], inherit_from => [ "ios-common" ],
cflags => add("-isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common"), cflags => add("-isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common"),
sys_id => "iOS",
disable => [ "engine" ],
}, },
"ios-cross" => { "ios-cross" => {
inherit_from => [ "ios-xcrun" ], inherit_from => [ "ios-xcrun" ],
-41
View File
@@ -210,47 +210,6 @@
# Start with populating the cache with all the overrides # Start with populating the cache with all the overrides
%cache = map { $_ => 1 } @{$unified_info{overrides}}; %cache = map { $_ => 1 } @{$unified_info{overrides}};
# For convenience collect information regarding directories where
# files are generated, those generated files and the end product
# they end up in where applicable. Then, add build rules for those
# directories
if (exists &generatedir) {
my %loopinfo = ( "dso" => [ @{$unified_info{engines}} ],
"lib" => [ @{$unified_info{libraries}} ],
"bin" => [ @{$unified_info{programs}} ],
"script" => [ @{$unified_info{scripts}} ] );
foreach my $type (keys %loopinfo) {
foreach my $product (@{$loopinfo{$type}}) {
my %dirs = ();
my $pd = dirname($product);
# We already have a "test" target, and the current directory
# is just silly to make a target for
$dirs{$pd} = 1 unless $pd eq "test" || $pd eq ".";
foreach (@{$unified_info{sources}->{$product}}) {
my $d = dirname($_);
# We don't want to create targets for source directories
# when building out of source
next if ($config{sourcedir} ne $config{builddir}
&& $d =~ m|^\Q$config{sourcedir}\E|);
# We already have a "test" target, and the current directory
# is just silly to make a target for
next if $d eq "test" || $d eq ".";
$dirs{$d} = 1;
push @{$unified_info{dirinfo}->{$d}->{deps}}, $_
if $d ne $pd;
}
foreach (keys %dirs) {
push @{$unified_info{dirinfo}->{$_}->{products}->{$type}},
$product;
}
}
}
}
# Build mandatory generated headers # Build mandatory generated headers
foreach (@{$unified_info{depends}->{""}}) { dogenerate($_); } foreach (@{$unified_info{depends}->{""}}) { dogenerate($_); }
+21 -25
View File
@@ -499,11 +499,11 @@ install_dev:
@[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1) @[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1)
@$(ECHO) "*** Installing development files" @$(ECHO) "*** Installing development files"
@$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(INSTALLTOP)/include/openssl @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(INSTALLTOP)/include/openssl
@ : {- output_off() unless grep { $_ eq "OPENSSL_USE_APPLINK" } @{$target{defines}}; "" -} @ : {- output_off() unless grep { $_ eq "OPENSSL_USE_APPLINK" } (@{$target{defines}}, @{$config{defines}}); "" -}
@$(ECHO) "install $(SRCDIR)/ms/applink.c -> $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c" @$(ECHO) "install $(SRCDIR)/ms/applink.c -> $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c"
@cp $(SRCDIR)/ms/applink.c $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c @cp $(SRCDIR)/ms/applink.c $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c
@chmod 644 $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c @chmod 644 $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c
@ : {- output_on() unless grep { $_ eq "OPENSSL_USE_APPLINK" } @{$target{defines}}; "" -} @ : {- output_on() unless grep { $_ eq "OPENSSL_USE_APPLINK" } (@{$target{defines}}, @{$config{defines}}); "" -}
@set -e; for i in $(SRCDIR)/include/openssl/*.h \ @set -e; for i in $(SRCDIR)/include/openssl/*.h \
$(BLDDIR)/include/openssl/*.h; do \ $(BLDDIR)/include/openssl/*.h; do \
fn=`basename $$i`; \ fn=`basename $$i`; \
@@ -574,10 +574,10 @@ install_dev:
uninstall_dev: uninstall_dev:
@$(ECHO) "*** Uninstalling development files" @$(ECHO) "*** Uninstalling development files"
@ : {- output_off() unless grep { $_ eq "OPENSSL_USE_APPLINK" } @{$target{defines}}; "" -} @ : {- output_off() unless grep { $_ eq "OPENSSL_USE_APPLINK" } (@{$target{defines}}, @{$config{defines}}); "" -}
@$(ECHO) "$(RM) $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c" @$(ECHO) "$(RM) $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c"
@$(RM) $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c @$(RM) $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c
@ : {- output_on() unless grep { $_ eq "OPENSSL_USE_APPLINK" } @{$target{defines}}; "" -} @ : {- output_on() unless grep { $_ eq "OPENSSL_USE_APPLINK" } (@{$target{defines}}, @{$config{defines}}); "" -}
@set -e; for i in $(SRCDIR)/include/openssl/*.h \ @set -e; for i in $(SRCDIR)/include/openssl/*.h \
$(BLDDIR)/include/openssl/*.h; do \ $(BLDDIR)/include/openssl/*.h; do \
fn=`basename $$i`; \ fn=`basename $$i`; \
@@ -1134,9 +1134,7 @@ EOF
} }
return $recipe; return $recipe;
} }
# On Unix, we build shlibs from static libs, so we're ignoring the # We *know* this routine is only called when we've configure 'shared'.
# object file array. We *know* this routine is only called when we've
# configure 'shared'.
sub obj2shlib { sub obj2shlib {
my %args = @_; my %args = @_;
my $lib = $args{lib}; my $lib = $args{lib};
@@ -1163,26 +1161,20 @@ EOF
die "More than one exported symbol map" if scalar @defs > 1; die "More than one exported symbol map" if scalar @defs > 1;
my $objs = join(" ", @objs); my $objs = join(" ", @objs);
my $deps = join(" ", @objs, @defs, @deps); my $deps = join(" ", @objs, @defs, @deps);
my $target = shlib_simple($lib); my $simple = shlib_simple($lib);
my $target_full = shlib($lib); my $full = shlib($lib);
my $target = "$simple $full";
my $shared_soname = ""; my $shared_soname = "";
$shared_soname .= ' '.$target{shared_sonameflag}.basename($target_full) $shared_soname .= ' '.$target{shared_sonameflag}.basename($full)
if defined $target{shared_sonameflag}; if defined $target{shared_sonameflag};
my $shared_imp = ""; my $shared_imp = "";
$shared_imp .= ' '.$target{shared_impflag}.basename($target) $shared_imp .= ' '.$target{shared_impflag}.basename($simple)
if defined $target{shared_impflag}; if defined $target{shared_impflag};
my $shared_def = join("", map { ' '.$target{shared_defflag}.$_ } @defs); my $shared_def = join("", map { ' '.$target{shared_defflag}.$_ } @defs);
my $recipe = <<"EOF"; my $recipe = <<"EOF";
# When building on a Windows POSIX layer (Cygwin or Mingw), we know for a fact
# that two files get produced, {shlibname}.dll and {libname}.dll.a.
# With all other Unix platforms, we often build a shared library with the
# SO version built into the file name and a symlink without the SO version
# It's not necessary to have both as targets. The choice falls on the
# simplest, {libname}\$(SHLIB_EXT_IMPORT) for Windows POSIX layers and
# {libname}\$(SHLIB_EXT_SIMPLE) for the Unix platforms.
$target: $deps $target: $deps
\$(CC) \$(LIB_CFLAGS) $linkflags\$(LIB_LDFLAGS)$shared_soname$shared_imp \\ \$(CC) \$(LIB_CFLAGS) $linkflags\$(LIB_LDFLAGS)$shared_soname$shared_imp \\
-o $target_full$shared_def $objs \\ -o $full$shared_def $objs \\
$linklibs \$(LIB_EX_LIBS) $linklibs \$(LIB_EX_LIBS)
EOF EOF
if (windowsdll()) { if (windowsdll()) {
@@ -1196,14 +1188,14 @@ EOF
EOF EOF
} elsif (sharedaix()) { } elsif (sharedaix()) {
$recipe .= <<"EOF"; $recipe .= <<"EOF";
rm -f $target && \\ rm -f $simple && \\
\$(AR) r $target $target_full \$(AR) r $simple $full
EOF EOF
} else { } else {
$recipe .= <<"EOF"; $recipe .= <<"EOF";
if [ '$target' != '$target_full' ]; then \\ if [ '$simple' != '$full' ]; then \\
rm -f $target; \\ rm -f $simple; \\
ln -s $target_full $target; \\ ln -s $full $simple; \\
fi fi
EOF EOF
} }
@@ -1311,6 +1303,10 @@ EOF
lib => $libext, lib => $libext,
bin => $exeext ); bin => $exeext );
# We already have a 'test' target, and the top directory is just plain
# silly
return if $dir eq "test" || $dir eq ".";
foreach my $type (("dso", "lib", "bin", "script")) { foreach my $type (("dso", "lib", "bin", "script")) {
next unless defined($unified_info{dirinfo}->{$dir}->{products}->{$type}); next unless defined($unified_info{dirinfo}->{$dir}->{products}->{$type});
# For lib object files, we could update the library. However, it # For lib object files, we could update the library. However, it
@@ -1331,7 +1327,7 @@ EOF
my $deps = join(" ", @deps); my $deps = join(" ", @deps);
my $actions = join("\n", "", @actions); my $actions = join("\n", "", @actions);
return <<"EOF"; return <<"EOF";
$args{dir} $args{dir}/: $deps$actions $dir $dir/: $deps$actions
EOF EOF
} }
"" # Important! This becomes part of the template result. "" # Important! This becomes part of the template result.
+39 -43
View File
@@ -41,6 +41,8 @@
sub lib { sub lib {
(my $lib = shift) =~ s/\.a$//; (my $lib = shift) =~ s/\.a$//;
$lib .= '_static'
if (defined $unified_info{sharednames}->{$lib});
return $lib . $libext; return $lib . $libext;
} }
@@ -75,7 +77,7 @@ MINOR={- $config{minor} -}
SHLIB_VERSION_NUMBER={- $config{shlib_version_number} -} SHLIB_VERSION_NUMBER={- $config{shlib_version_number} -}
LIBS={- join(" ", map { lib($_) } @{$unified_info{libraries}}) -} LIBS={- join(" ", map { ( shlib_import($_), lib($_) ) } @{$unified_info{libraries}}) -}
SHLIBS={- join(" ", map { shlib($_) } @{$unified_info{libraries}}) -} SHLIBS={- join(" ", map { shlib($_) } @{$unified_info{libraries}}) -}
SHLIBPDBS={- join(" ", map { local $shlibext = ".pdb"; shlib($_) } @{$unified_info{libraries}}) -} SHLIBPDBS={- join(" ", map { local $shlibext = ".pdb"; shlib($_) } @{$unified_info{libraries}}) -}
ENGINES={- join(" ", map { dso($_) } @{$unified_info{engines}}) -} ENGINES={- join(" ", map { dso($_) } @{$unified_info{engines}}) -}
@@ -96,7 +98,7 @@ GENERATED={- # common0.tmpl provides @generated
$x } $x }
@generated) -} @generated) -}
INSTALL_LIBS={- join(" ", map { quotify1(lib($_)) } @{$unified_info{install}->{libraries}}) -} INSTALL_LIBS={- join(" ", map { quotify1(shlib_import($_) or lib($_)) } @{$unified_info{install}->{libraries}}) -}
INSTALL_SHLIBS={- join(" ", map { quotify_l(shlib($_)) } @{$unified_info{install}->{libraries}}) -} INSTALL_SHLIBS={- join(" ", map { quotify_l(shlib($_)) } @{$unified_info{install}->{libraries}}) -}
INSTALL_SHLIBPDBS={- join(" ", map { local $shlibext = ".pdb"; quotify_l(shlib($_)) } @{$unified_info{install}->{libraries}}) -} INSTALL_SHLIBPDBS={- join(" ", map { local $shlibext = ".pdb"; quotify_l(shlib($_)) } @{$unified_info{install}->{libraries}}) -}
INSTALL_ENGINES={- join(" ", map { quotify1(dso($_)) } @{$unified_info{install}->{engines}}) -} INSTALL_ENGINES={- join(" ", map { quotify1(dso($_)) } @{$unified_info{install}->{engines}}) -}
@@ -414,10 +416,10 @@ install_dev:
@if "$(INSTALLTOP)"=="" ( $(ECHO) "INSTALLTOP should not be empty" & exit 1 ) @if "$(INSTALLTOP)"=="" ( $(ECHO) "INSTALLTOP should not be empty" & exit 1 )
@$(ECHO) "*** Installing development files" @$(ECHO) "*** Installing development files"
@"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(INSTALLTOP)\include\openssl" @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(INSTALLTOP)\include\openssl"
@{- output_off() unless grep { $_ eq "OPENSSL_USE_APPLINK" } @{$config{defines}}; "" -} @{- output_off() unless grep { $_ eq "OPENSSL_USE_APPLINK" } (@{$target{defines}}, @{$config{defines}}); "" -}
@"$(PERL)" "$(SRCDIR)\util\copy.pl" "$(SRCDIR)\ms\applink.c" \ @"$(PERL)" "$(SRCDIR)\util\copy.pl" "$(SRCDIR)\ms\applink.c" \
"$(INSTALLTOP)\include\openssl" "$(INSTALLTOP)\include\openssl"
@{- output_on() unless grep { $_ eq "OPENSSL_USE_APPLINK" } @{$config{defines}}; "" -} @{- output_on() unless grep { $_ eq "OPENSSL_USE_APPLINK" } (@{$target{defines}}, @{$config{defines}}); "" -}
@"$(PERL)" "$(SRCDIR)\util\copy.pl" "-exclude_re=/__DECC_" \ @"$(PERL)" "$(SRCDIR)\util\copy.pl" "-exclude_re=/__DECC_" \
"$(SRCDIR)\include\openssl\*.h" \ "$(SRCDIR)\include\openssl\*.h" \
"$(INSTALLTOP)\include\openssl" "$(INSTALLTOP)\include\openssl"
@@ -490,11 +492,6 @@ reconfigure reconf:
if ($disabled{shared}) { if ($disabled{shared}) {
return map { lib($_) } @_; return map { lib($_) } @_;
} }
foreach (@_) {
(my $l = $_) =~ s/\.a$//;
die "Linking with static variants of shared libraries is not supported in this configuration\n"
if $l ne $_ && shlib($l);
}
return map { shlib_import($_) or lib($_) } @_; return map { shlib_import($_) or lib($_) } @_;
} }
@@ -618,25 +615,22 @@ $obj$objext: $deps
\$(CC) /EP /D__ASSEMBLER__ $cflags $srcs > \$@.asm && \$(AS) $asflags \$(ASOUTFLAG)\$\@ \$@.asm \$(CC) /EP /D__ASSEMBLER__ $cflags $srcs > \$@.asm && \$(AS) $asflags \$(ASOUTFLAG)\$\@ \$@.asm
EOF EOF
} }
return <<"EOF" if (!$disabled{makedepend}); my $recipe = <<"EOF";
$obj$depext: $deps
\$(CC) $cflags /Zs /showIncludes $srcs 2>&1 > $obj$depext
$obj$objext: $obj$depext
\$(CC) $cflags -c \$(COUTFLAG)\$\@ $srcs
EOF
return <<"EOF" if ($disabled{makedepend});
$obj$objext: $deps $obj$objext: $deps
\$(CC) $cflags -c \$(COUTFLAG)\$\@ $srcs \$(CC) $cflags -c \$(COUTFLAG)\$\@ $srcs
EOF EOF
$recipe .= <<"EOF" unless $disabled{makedepend};
\$(CC) $cflags /Zs /showIncludes $srcs 2>&1 > $obj$depext
EOF
return $recipe;
} }
# On Unix, we build shlibs from static libs, so we're ignoring the # We *know* this routine is only called when we've configure 'shared'.
# object file array. We *know* this routine is only called when we've # Also, note that even though the import library built here looks like
# configure 'shared'. # a static library, it really isn't.
sub obj2shlib { sub obj2shlib {
my %args = @_; my %args = @_;
my $lib = $args{lib}; my $lib = $args{lib};
my $shlib = $args{shlib};
my @objs = map { (my $x = $_) =~ s|\.o$|$objext|; $x } my @objs = map { (my $x = $_) =~ s|\.o$|$objext|; $x }
grep { $_ =~ m/\.(?:o|res)$/ } grep { $_ =~ m/\.(?:o|res)$/ }
@{$args{objs}}; @{$args{objs}};
@@ -648,25 +642,30 @@ EOF
my $linklibs = join("", map { "$_\n" } @deps); my $linklibs = join("", map { "$_\n" } @deps);
my $objs = join("\n", @objs); my $objs = join("\n", @objs);
my $deps = join(" ", @objs, @defs, @deps); my $deps = join(" ", @objs, @defs, @deps);
my $target = shlib_import($lib); my $import = shlib_import($lib);
my $dll = shlib($lib);
my $shared_def = join("", map { " /def:$_" } @defs); my $shared_def = join("", map { " /def:$_" } @defs);
return <<"EOF" return <<"EOF"
$target: $deps # The import library may look like a static library, but it is not.
IF EXIST $shlib$shlibext.manifest DEL /F /Q $shlib$shlibext.manifest # We MUST make the import library depend on the DLL, in case someone
# mistakenly removes the latter.
$import: $dll
$dll: $deps
IF EXIST $full.manifest DEL /F /Q $full.manifest
IF EXIST \$@ DEL /F /Q \$@ IF EXIST \$@ DEL /F /Q \$@
\$(LD) \$(LDFLAGS) \$(LIB_LDFLAGS) \\ \$(LD) \$(LDFLAGS) \$(LIB_LDFLAGS) \\
/implib:\$@ \$(LDOUTFLAG)$shlib$shlibext$shared_def @<< || (DEL /Q \$(\@B).* $shlib.* && EXIT 1) /implib:$import \$(LDOUTFLAG)$dll$shared_def @<< || (DEL /Q \$(\@B).* $import && EXIT 1)
$objs $objs
$linklibs\$(LIB_EX_LIBS) $linklibs\$(LIB_EX_LIBS)
<< <<
IF EXIST $shlib$shlibext.manifest \\ IF EXIST $dll.manifest \\
\$(MT) \$(MTFLAGS) \$(MTINFLAG)$shlib$shlibext.manifest \$(MTOUTFLAG)$shlib$shlibext \$(MT) \$(MTFLAGS) \$(MTINFLAG)$dll.manifest \$(MTOUTFLAG)$dll
IF EXIST apps\\$shlib$shlibext DEL /Q /F apps\\$shlib$shlibext IF EXIST apps\\$dll DEL /Q /F apps\\$dll
IF EXIST test\\$shlib$shlibext DEL /Q /F test\\$shlib$shlibext IF EXIST test\\$dll DEL /Q /F test\\$dll
IF EXIST fuzz\\$shlib$shlibext DEL /Q /F fuzz\\$shlib$shlibext IF EXIST fuzz\\$dll DEL /Q /F fuzz\\$dll
COPY $shlib$shlibext apps COPY $dll apps
COPY $shlib$shlibext test COPY $dll test
COPY $shlib$shlibext fuzz COPY $dll fuzz
EOF EOF
} }
sub obj2dso { sub obj2dso {
@@ -698,20 +697,13 @@ EOF
} }
sub obj2lib { sub obj2lib {
my %args = @_; my %args = @_;
my $lib = $args{lib}; my $lib = lib($args{lib});
# Because static libs and import libs are both named the same in native
# Windows, we can't have both. We skip the static lib in that case,
# as the shared libs are what we use anyway.
return "" unless $disabled{"shared"} || $lib =~ /\.a$/;
$lib =~ s/\.a$//;
my @objs = map { (my $x = $_) =~ s|\.o$|$objext|; $x } @{$args{objs}}; my @objs = map { (my $x = $_) =~ s|\.o$|$objext|; $x } @{$args{objs}};
my $objs = join("\n", @objs); my $objs = join("\n", @objs);
my $deps = join(" ", @objs); my $deps = join(" ", @objs);
return <<"EOF"; return <<"EOF";
$lib$libext: $deps $lib: $deps
\$(AR) \$(ARFLAGS) \$(AROUTFLAG)$lib$libext @<< \$(AR) \$(ARFLAGS) \$(AROUTFLAG)$lib @<<
$objs $objs
<< <<
EOF EOF
@@ -758,6 +750,10 @@ EOF
lib => $libext, lib => $libext,
bin => $exeext ); bin => $exeext );
# We already have a 'test' target, and the top directory is just plain
# silly
return if $dir eq "test" || $dir eq ".";
foreach my $type (("dso", "lib", "bin", "script")) { foreach my $type (("dso", "lib", "bin", "script")) {
next unless defined($unified_info{dirinfo}->{$dir}->{products}->{$type}); next unless defined($unified_info{dirinfo}->{$dir}->{products}->{$type});
# For lib object files, we could update the library. However, # For lib object files, we could update the library. However,
@@ -775,7 +771,7 @@ EOF
my $deps = join(" ", @deps); my $deps = join(" ", @deps);
my $actions = join("\n", "", @actions); my $actions = join("\n", "", @actions);
return <<"EOF"; return <<"EOF";
$args{dir} $args{dir}\\ : $deps$actions $dir $dir\\ : $deps$actions
EOF EOF
} }
"" # Important! This becomes part of the template result. "" # Important! This becomes part of the template result.
+56 -9
View File
@@ -1013,13 +1013,18 @@ if (scalar(@seed_sources) == 0) {
if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) { if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) {
die "Cannot seed with none and anything else" if scalar(@seed_sources) > 1; die "Cannot seed with none and anything else" if scalar(@seed_sources) > 1;
warn <<_____ if scalar(@seed_sources) == 1; warn <<_____ if scalar(@seed_sources) == 1;
You have selected the --with-rand-seed=none option, which effectively disables
automatic reseeding of the OpenSSL random generator. All operations depending
on the random generator such as creating keys will not work unless the random
generator is seeded manually by the application.
Please read the 'Note on random number generation' section in the INSTALL ============================== WARNING ===============================
instructions and the RAND_DRBG(7) manual page for more details. You have selected the --with-rand-seed=none option, which effectively
disables automatic reseeding of the OpenSSL random generator.
All operations depending on the random generator such as creating keys
will not work unless the random generator is seeded manually by the
application.
Please read the 'Note on random number generation' section in the
INSTALL instructions and the RAND_DRBG(7) manual page for more details.
============================== WARNING ===============================
_____ _____
} }
push @{$config{openssl_other_defines}}, push @{$config{openssl_other_defines}},
@@ -2325,6 +2330,42 @@ EOF
delete $unified_info{includes}->{$dest}; delete $unified_info{includes}->{$dest};
} }
} }
# For convenience collect information regarding directories where
# files are generated, those generated files and the end product
# they end up in where applicable. Then, add build rules for those
# directories
my %loopinfo = ( "lib" => [ @{$unified_info{libraries}} ],
"dso" => [ @{$unified_info{engines}} ],
"bin" => [ @{$unified_info{programs}} ],
"script" => [ @{$unified_info{scripts}} ] );
foreach my $type (keys %loopinfo) {
foreach my $product (@{$loopinfo{$type}}) {
my %dirs = ();
my $pd = dirname($product);
foreach (@{$unified_info{sources}->{$product}},
@{$unified_info{shared_sources}->{$product} // []}) {
my $d = dirname($_);
# We don't want to create targets for source directories
# when building out of source
next if ($config{sourcedir} ne $config{builddir}
&& $d =~ m|^\Q$config{sourcedir}\E|);
# We already have a "test" target, and the current directory
# is just silly to make a target for
next if $d eq "test" || $d eq ".";
$dirs{$d} = 1;
push @{$unified_info{dirinfo}->{$d}->{deps}}, $_
if $d ne $pd;
}
foreach (keys %dirs) {
push @{$unified_info{dirinfo}->{$_}->{products}->{$type}},
$product;
}
}
}
} }
# For the schemes that need it, we provide the old *_obj configs # For the schemes that need it, we provide the old *_obj configs
@@ -2799,10 +2840,16 @@ print <<"EOF";
********************************************************************** **********************************************************************
*** *** *** ***
*** If you want to report a building issue, please include the *** *** OpenSSL has been successfully configured ***
*** output from this command: ***
*** *** *** ***
*** perl configdata.pm --dump *** *** If you encounter a problem while building, please open an ***
*** issue on GitHub <https://github.com/openssl/openssl/issues> ***
*** and include the output from the following command: ***
*** ***
*** perl configdata.pm --dump ***
*** ***
*** (If you are new to OpenSSL, you might want to consult the ***
*** 'Troubleshooting' section in the INSTALL file first) ***
*** *** *** ***
********************************************************************** **********************************************************************
EOF EOF
+2 -1
View File
@@ -7,7 +7,8 @@
Major changes between OpenSSL 1.1.1 and OpenSSL 1.1.2 [under development] Major changes between OpenSSL 1.1.1 and OpenSSL 1.1.2 [under development]
o o Added EVP_MAC, an EVP layer MAC API, and a generic EVP_PKEY to EVP_MAC
bridge.
Major changes between OpenSSL 1.1.0i and OpenSSL 1.1.1 [11 Sep 2018] Major changes between OpenSSL 1.1.0i and OpenSSL 1.1.1 [11 Sep 2018]
+13 -5
View File
@@ -24,16 +24,18 @@
in order to invoke $(CROSS_COMPILE)gcc and company. (Configure will fail in order to invoke $(CROSS_COMPILE)gcc and company. (Configure will fail
and give you a hint if you get it wrong.) Apart from PATH adjustment and give you a hint if you get it wrong.) Apart from PATH adjustment
you need to set ANDROID_NDK environment to point at NDK directory you need to set ANDROID_NDK environment to point at NDK directory
as /some/where/android-ndk-<ver>. NDK customarily supports multiple as /some/where/android-ndk-<ver>. Both variables are significant at both
configuration and compilation times. NDK customarily supports multiple
Android API levels, e.g. android-14, android-21, etc. By default latest Android API levels, e.g. android-14, android-21, etc. By default latest
one available is chosen. If you need to target older platform, pass one available is chosen. If you need to target older platform, pass
additional -D__ANDROID_API__=N to Configure. N is numeric value of the additional -D__ANDROID_API__=N to Configure. N is numeric value of the
target platform version. For example, to compile for ICS on ARM with target platform version. For example, to compile for ICS on ARM with
NDK 10d: NDK 10d:
ANDROID_NDK=/some/where/android-ndk-10d export ANDROID_NDK=/some/where/android-ndk-10d
PATH=$ANDROID_NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin:$PATH PATH=$ANDROID_NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin:$PATH
./Configure android-arm -D__ANDROID_API__=14 ./Configure android-arm -D__ANDROID_API__=14
make
Caveat lector! Earlier OpenSSL versions relied on additional CROSS_SYSROOT Caveat lector! Earlier OpenSSL versions relied on additional CROSS_SYSROOT
variable set to $ANDROID_NDK/platforms/android-<api>/arch-<arch> to variable set to $ANDROID_NDK/platforms/android-<api>/arch-<arch> to
@@ -43,12 +45,18 @@
conflict, and mixing the two is therefore not supported. Migration to conflict, and mixing the two is therefore not supported. Migration to
CROSS_SYSROOT-less setup is recommended. CROSS_SYSROOT-less setup is recommended.
One can engage clang by adjusting PATH to cover NDK's clang. Just keep One can engage clang by adjusting PATH to cover same NDK's clang. Just
in mind that if you miss it, Configure will try to use gcc... Also, keep in mind that if you miss it, Configure will try to use gcc...
PATH would need even further adjustment to cover unprefixed, yet Also, PATH would need even further adjustment to cover unprefixed, yet
target-specific, ar and ranlib. It's possible that you don't need to target-specific, ar and ranlib. It's possible that you don't need to
bother, if binutils-multiarch is installed on your Linux system. bother, if binutils-multiarch is installed on your Linux system.
Another option is to create so called "standalone toolchain" tailored
for single specific platform including Android API level, and assign its
location to ANDROID_NDK. In such case you have to pass matching target
name to Configure and shouldn't use -D__ANDROID_API__=N. PATH adjusment
becomes simpler, $ANDROID_NDK/bin:$PATH suffices.
Running tests (on Linux) Running tests (on Linux)
------------------------ ------------------------
+10 -9
View File
@@ -976,7 +976,7 @@ end_of_options:
BIO_printf(bio_err, "Write out database with %d new entries\n", BIO_printf(bio_err, "Write out database with %d new entries\n",
sk_X509_num(cert_sk)); sk_X509_num(cert_sk));
if (!rand_ser if (serialfile != NULL
&& !save_serial(serialfile, "new", serial, NULL)) && !save_serial(serialfile, "new", serial, NULL))
goto end; goto end;
@@ -1044,7 +1044,8 @@ end_of_options:
if (sk_X509_num(cert_sk)) { if (sk_X509_num(cert_sk)) {
/* Rename the database and the serial file */ /* Rename the database and the serial file */
if (!rotate_serial(serialfile, "new", "old")) if (serialfile != NULL
&& !rotate_serial(serialfile, "new", "old"))
goto end; goto end;
if (!rotate_index(dbfile, "new", "old")) if (!rotate_index(dbfile, "new", "old"))
@@ -1177,10 +1178,9 @@ end_of_options:
} }
/* we have a CRL number that need updating */ /* we have a CRL number that need updating */
if (crlnumberfile != NULL) if (crlnumberfile != NULL
if (!rand_ser && !save_serial(crlnumberfile, "new", crlnumber, NULL))
&& !save_serial(crlnumberfile, "new", crlnumber, NULL)) goto end;
goto end;
BN_free(crlnumber); BN_free(crlnumber);
crlnumber = NULL; crlnumber = NULL;
@@ -1195,9 +1195,10 @@ end_of_options:
PEM_write_bio_X509_CRL(Sout, crl); PEM_write_bio_X509_CRL(Sout, crl);
if (crlnumberfile != NULL) /* Rename the crlnumber file */ /* Rename the crlnumber file */
if (!rotate_serial(crlnumberfile, "new", "old")) if (crlnumberfile != NULL
goto end; && !rotate_serial(crlnumberfile, "new", "old"))
goto end;
} }
/*****************************************************************/ /*****************************************************************/
+1 -1
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2013-2014 Timo Teräs <timo.teras@gmail.com> * Copyright (c) 2013-2014 Timo Teräs <timo.teras@gmail.com>
* *
* Licensed under the OpenSSL license (the "License"). You may not use * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * this file except in compliance with the License. You can obtain a copy
+2 -3
View File
@@ -193,9 +193,8 @@ static int psk_find_session_cb(SSL *ssl, const unsigned char *identity,
if (strlen(psk_identity) != identity_len if (strlen(psk_identity) != identity_len
|| memcmp(psk_identity, identity, identity_len) != 0) { || memcmp(psk_identity, identity, identity_len) != 0) {
BIO_printf(bio_s_out, *sess = NULL;
"PSK warning: client identity not what we expected" return 1;
" (got '%s' expected '%s')\n", identity, psk_identity);
} }
if (psksess != NULL) { if (psksess != NULL) {
+2 -1
View File
@@ -17,7 +17,8 @@
# include <unistd.h> # include <unistd.h>
# if _POSIX_VERSION >= 200112L # if _POSIX_VERSION >= 200112L \
&& (_POSIX_VERSION < 200809L || defined(__GLIBC__))
# include <pthread.h> # include <pthread.h>
+1 -1
View File
@@ -1077,7 +1077,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
* is not only slower but also makes each bit vulnerable to * is not only slower but also makes each bit vulnerable to
* EM (and likely other) side-channel attacks like One&Done * EM (and likely other) side-channel attacks like One&Done
* (for details see "One&Done: A Single-Decryption EM-Based * (for details see "One&Done: A Single-Decryption EM-Based
* Attack on OpenSSLs Constant-Time Blinded RSA" by M. Alam, * Attack on OpenSSL's Constant-Time Blinded RSA" by M. Alam,
* H. Khan, M. Dey, N. Sinha, R. Callan, A. Zajic, and * H. Khan, M. Dey, N. Sinha, R. Callan, A. Zajic, and
* M. Prvulovic, in USENIX Security'18) * M. Prvulovic, in USENIX Security'18)
*/ */
+1 -1
View File
@@ -1,2 +1,2 @@
LIBS=../../libcrypto LIBS=../../libcrypto
SOURCE[../../libcrypto]=cmac.c cm_ameth.c cm_pmeth.c SOURCE[../../libcrypto]=cmac.c cm_ameth.c cm_meth.c
+3 -4
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2010-2018 The OpenSSL Project Authors. All Rights Reserved.
* *
* Licensed under the OpenSSL license (the "License"). You may not use * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * this file except in compliance with the License. You can obtain a copy
@@ -10,7 +10,6 @@
#include <stdio.h> #include <stdio.h>
#include "internal/cryptlib.h" #include "internal/cryptlib.h"
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/cmac.h>
#include "internal/asn1_int.h" #include "internal/asn1_int.h"
/* /*
@@ -25,8 +24,8 @@ static int cmac_size(const EVP_PKEY *pkey)
static void cmac_key_free(EVP_PKEY *pkey) static void cmac_key_free(EVP_PKEY *pkey)
{ {
CMAC_CTX *cmctx = EVP_PKEY_get0(pkey); EVP_MAC_CTX *cmctx = EVP_PKEY_get0(pkey);
CMAC_CTX_free(cmctx); EVP_MAC_CTX_free(cmctx);
} }
const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = { const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = {
+164
View File
@@ -0,0 +1,164 @@
/*
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/evp.h>
#include <openssl/cmac.h>
#include "internal/evp_int.h"
/* local CMAC pkey structure */
/* typedef EVP_MAC_IMPL */
struct evp_mac_impl_st {
/* tmpcipher and tmpengine are set to NULL after a CMAC_Init call */
const EVP_CIPHER *tmpcipher; /* cached CMAC cipher */
const ENGINE *tmpengine; /* cached CMAC cipher engine */
CMAC_CTX *ctx;
};
static EVP_MAC_IMPL *cmac_new(void)
{
EVP_MAC_IMPL *cctx;
if ((cctx = OPENSSL_zalloc(sizeof(*cctx))) == NULL
|| (cctx->ctx = CMAC_CTX_new()) == NULL) {
OPENSSL_free(cctx);
cctx = NULL;
}
return cctx;
}
static void cmac_free(EVP_MAC_IMPL *cctx)
{
if (cctx != NULL) {
CMAC_CTX_free(cctx->ctx);
OPENSSL_free(cctx);
}
}
static int cmac_copy(EVP_MAC_IMPL *cdst, EVP_MAC_IMPL *csrc)
{
if (!CMAC_CTX_copy(cdst->ctx, csrc->ctx))
return 0;
cdst->tmpengine = csrc->tmpengine;
cdst->tmpcipher = csrc->tmpcipher;
return 1;
}
static size_t cmac_size(EVP_MAC_IMPL *cctx)
{
return EVP_CIPHER_CTX_block_size(CMAC_CTX_get0_cipher_ctx(cctx->ctx));
}
static int cmac_init(EVP_MAC_IMPL *cctx)
{
int rv = CMAC_Init(cctx->ctx, NULL, 0, cctx->tmpcipher,
(ENGINE *)cctx->tmpengine);
cctx->tmpcipher = NULL;
cctx->tmpengine = NULL;
return rv;
}
static int cmac_update(EVP_MAC_IMPL *cctx, const unsigned char *data,
size_t datalen)
{
return CMAC_Update(cctx->ctx, data, datalen);
}
static int cmac_final(EVP_MAC_IMPL *cctx, unsigned char *out)
{
size_t hlen;
return CMAC_Final(cctx->ctx, out, &hlen);
}
static int cmac_ctrl(EVP_MAC_IMPL *cctx, int cmd, va_list args)
{
switch (cmd) {
case EVP_MAC_CTRL_SET_KEY:
{
const unsigned char *key = va_arg(args, const unsigned char *);
size_t keylen = va_arg(args, size_t);
int rv = CMAC_Init(cctx->ctx, key, keylen, cctx->tmpcipher,
(ENGINE *)cctx->tmpengine);
cctx->tmpcipher = NULL;
cctx->tmpengine = NULL;
return rv;
}
break;
case EVP_MAC_CTRL_SET_CIPHER:
cctx->tmpcipher = va_arg(args, const EVP_CIPHER *);
break;
case EVP_MAC_CTRL_SET_ENGINE:
cctx->tmpengine = va_arg(args, const ENGINE *);
break;
default:
return -2;
}
return 1;
}
static int cmac_ctrl_int(EVP_MAC_IMPL *hctx, int cmd, ...)
{
int rv;
va_list args;
va_start(args, cmd);
rv = cmac_ctrl(hctx, cmd, args);
va_end(args);
return rv;
}
static int cmac_ctrl_str_cb(void *hctx, int cmd, void *buf, size_t buflen)
{
return cmac_ctrl_int(hctx, cmd, buf, buflen);
}
static int cmac_ctrl_str(EVP_MAC_IMPL *cctx, const char *type,
const char *value)
{
if (!value)
return 0;
if (strcmp(type, "cipher") == 0) {
const EVP_CIPHER *c = EVP_get_cipherbyname(value);
if (c == NULL)
return 0;
return cmac_ctrl_int(cctx, EVP_MAC_CTRL_SET_CIPHER, c);
}
if (strcmp(type, "key") == 0)
return EVP_str2ctrl(cmac_ctrl_str_cb, cctx, EVP_MAC_CTRL_SET_KEY,
value);
if (strcmp(type, "hexkey") == 0)
return EVP_hex2ctrl(cmac_ctrl_str_cb, cctx, EVP_MAC_CTRL_SET_KEY,
value);
return -2;
}
const EVP_MAC cmac_meth = {
EVP_MAC_CMAC,
cmac_new,
cmac_copy,
cmac_free,
cmac_size,
cmac_init,
cmac_update,
cmac_final,
cmac_ctrl,
cmac_ctrl_str
};
-161
View File
@@ -1,161 +0,0 @@
/*
* Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/evp.h>
#include <openssl/cmac.h>
#include "internal/evp_int.h"
/* The context structure and "key" is simply a CMAC_CTX */
static int pkey_cmac_init(EVP_PKEY_CTX *ctx)
{
ctx->data = CMAC_CTX_new();
if (ctx->data == NULL)
return 0;
ctx->keygen_info_count = 0;
return 1;
}
static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
{
if (!pkey_cmac_init(dst))
return 0;
if (!CMAC_CTX_copy(dst->data, src->data))
return 0;
return 1;
}
static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx)
{
CMAC_CTX_free(ctx->data);
}
static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
CMAC_CTX *cmkey = CMAC_CTX_new();
CMAC_CTX *cmctx = ctx->data;
if (cmkey == NULL)
return 0;
if (!CMAC_CTX_copy(cmkey, cmctx)) {
CMAC_CTX_free(cmkey);
return 0;
}
EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey);
return 1;
}
static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
if (!CMAC_Update(EVP_MD_CTX_pkey_ctx(ctx)->data, data, count))
return 0;
return 1;
}
static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
{
EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
EVP_MD_CTX_set_update_fn(mctx, int_update);
return 1;
}
static int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
EVP_MD_CTX *mctx)
{
return CMAC_Final(ctx->data, sig, siglen);
}
static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
CMAC_CTX *cmctx = ctx->data;
switch (type) {
case EVP_PKEY_CTRL_SET_MAC_KEY:
if (!p2 || p1 < 0)
return 0;
if (!CMAC_Init(cmctx, p2, p1, NULL, NULL))
return 0;
break;
case EVP_PKEY_CTRL_CIPHER:
if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine))
return 0;
break;
case EVP_PKEY_CTRL_MD:
if (ctx->pkey && !CMAC_CTX_copy(ctx->data,
(CMAC_CTX *)ctx->pkey->pkey.ptr))
return 0;
if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL))
return 0;
break;
default:
return -2;
}
return 1;
}
static int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx,
const char *type, const char *value)
{
if (!value) {
return 0;
}
if (strcmp(type, "cipher") == 0) {
const EVP_CIPHER *c;
c = EVP_get_cipherbyname(value);
if (!c)
return 0;
return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c);
}
if (strcmp(type, "key") == 0)
return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
if (strcmp(type, "hexkey") == 0)
return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
return -2;
}
const EVP_PKEY_METHOD cmac_pkey_meth = {
EVP_PKEY_CMAC,
EVP_PKEY_FLAG_SIGCTX_CUSTOM,
pkey_cmac_init,
pkey_cmac_copy,
pkey_cmac_cleanup,
0, 0,
0,
pkey_cmac_keygen,
0, 0,
0, 0,
0, 0,
cmac_signctx_init,
cmac_signctx,
0, 0,
0, 0,
0, 0,
0, 0,
pkey_cmac_ctrl,
pkey_cmac_ctrl_str
};
+6
View File
@@ -327,6 +327,12 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
if (mctx == NULL) if (mctx == NULL)
goto err; goto err;
/* make sure L > N, otherwise we'll get trapped in an infinite loop */
if (L <= N) {
DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
goto err;
}
if (evpmd == NULL) { if (evpmd == NULL) {
if (N == 160) if (N == 160)
evpmd = EVP_sha1(); evpmd = EVP_sha1();
+46 -14
View File
@@ -9,6 +9,7 @@
#include <stdio.h> #include <stdio.h>
#include "internal/cryptlib.h" #include "internal/cryptlib.h"
#include "internal/bn_int.h"
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include "dsa_locl.h" #include "dsa_locl.h"
@@ -23,6 +24,8 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
DSA_SIG *sig, DSA *dsa); DSA_SIG *sig, DSA *dsa);
static int dsa_init(DSA *dsa); static int dsa_init(DSA *dsa);
static int dsa_finish(DSA *dsa); static int dsa_finish(DSA *dsa);
static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q,
BN_CTX *ctx);
static DSA_METHOD openssl_dsa_meth = { static DSA_METHOD openssl_dsa_meth = {
"OpenSSL DSA method", "OpenSSL DSA method",
@@ -178,9 +181,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
{ {
BN_CTX *ctx = NULL; BN_CTX *ctx = NULL;
BIGNUM *k, *kinv = NULL, *r = *rp; BIGNUM *k, *kinv = NULL, *r = *rp;
BIGNUM *l, *m; BIGNUM *l;
int ret = 0; int ret = 0;
int q_bits; int q_bits, q_words;
if (!dsa->p || !dsa->q || !dsa->g) { if (!dsa->p || !dsa->q || !dsa->g) {
DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS); DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS);
@@ -189,8 +192,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
k = BN_new(); k = BN_new();
l = BN_new(); l = BN_new();
m = BN_new(); if (k == NULL || l == NULL)
if (k == NULL || l == NULL || m == NULL)
goto err; goto err;
if (ctx_in == NULL) { if (ctx_in == NULL) {
@@ -201,9 +203,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
/* Preallocate space */ /* Preallocate space */
q_bits = BN_num_bits(dsa->q); q_bits = BN_num_bits(dsa->q);
if (!BN_set_bit(k, q_bits) q_words = bn_get_top(dsa->q);
|| !BN_set_bit(l, q_bits) if (!bn_wexpand(k, q_words + 2)
|| !BN_set_bit(m, q_bits)) || !bn_wexpand(l, q_words + 2))
goto err; goto err;
/* Get random k */ /* Get random k */
@@ -238,14 +240,17 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
* small timing information leakage. We then choose the sum that is * small timing information leakage. We then choose the sum that is
* one bit longer than the modulus. * one bit longer than the modulus.
* *
* TODO: revisit the BN_copy aiming for a memory access agnostic * There are some concerns about the efficacy of doing this. More
* conditional copy. * specificly refer to the discussion starting with:
* https://github.com/openssl/openssl/pull/7486#discussion_r228323705
* The fix is to rework BN so these gymnastics aren't required.
*/ */
if (!BN_add(l, k, dsa->q) if (!BN_add(l, k, dsa->q)
|| !BN_add(m, l, dsa->q) || !BN_add(k, l, dsa->q))
|| !BN_copy(k, BN_num_bits(l) > q_bits ? l : m))
goto err; goto err;
BN_consttime_swap(BN_is_bit_set(l, q_bits), k, l, q_words + 2);
if ((dsa)->meth->bn_mod_exp != NULL) { if ((dsa)->meth->bn_mod_exp != NULL) {
if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, k, dsa->p, ctx, if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, k, dsa->p, ctx,
dsa->method_mont_p)) dsa->method_mont_p))
@@ -258,8 +263,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
if (!BN_mod(r, r, dsa->q, ctx)) if (!BN_mod(r, r, dsa->q, ctx))
goto err; goto err;
/* Compute part of 's = inv(k) (m + xr) mod q' */ /* Compute part of 's = inv(k) (m + xr) mod q' */
if ((kinv = BN_mod_inverse(NULL, k, dsa->q, ctx)) == NULL) if ((kinv = dsa_mod_inverse_fermat(k, dsa->q, ctx)) == NULL)
goto err; goto err;
BN_clear_free(*kinvp); BN_clear_free(*kinvp);
@@ -273,7 +278,6 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
BN_CTX_free(ctx); BN_CTX_free(ctx);
BN_clear_free(k); BN_clear_free(k);
BN_clear_free(l); BN_clear_free(l);
BN_clear_free(m);
return ret; return ret;
} }
@@ -393,3 +397,31 @@ static int dsa_finish(DSA *dsa)
BN_MONT_CTX_free(dsa->method_mont_p); BN_MONT_CTX_free(dsa->method_mont_p);
return 1; return 1;
} }
/*
* Compute the inverse of k modulo q.
* Since q is prime, Fermat's Little Theorem applies, which reduces this to
* mod-exp operation. Both the exponent and modulus are public information
* so a mod-exp that doesn't leak the base is sufficient. A newly allocated
* BIGNUM is returned which the caller must free.
*/
static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q,
BN_CTX *ctx)
{
BIGNUM *res = NULL;
BIGNUM *r, *e;
if ((r = BN_new()) == NULL)
return NULL;
BN_CTX_start(ctx);
if ((e = BN_CTX_get(ctx)) != NULL
&& BN_set_word(r, 2)
&& BN_sub(e, q, r)
&& BN_mod_exp_mont(r, k, e, q, ctx, NULL))
res = r;
else
BN_free(r);
BN_CTX_end(ctx);
return res;
}
+2 -2
View File
@@ -699,7 +699,7 @@ static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0) if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
return 0; return 0;
if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_62) <= 0) if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0)
return 0; return 0;
kdf_md = EVP_get_digestbynid(kdfmd_nid); kdf_md = EVP_get_digestbynid(kdfmd_nid);
@@ -864,7 +864,7 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
ecdh_nid = NID_dh_cofactor_kdf; ecdh_nid = NID_dh_cofactor_kdf;
if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) { if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
kdf_type = EVP_PKEY_ECDH_KDF_X9_62; kdf_type = EVP_PKEY_ECDH_KDF_X9_63;
if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0) if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
goto err; goto err;
} else } else
+3 -3
View File
@@ -206,8 +206,8 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
*/ */
cardinality_bits = BN_num_bits(cardinality); cardinality_bits = BN_num_bits(cardinality);
group_top = bn_get_top(cardinality); group_top = bn_get_top(cardinality);
if ((bn_wexpand(k, group_top + 1) == NULL) if ((bn_wexpand(k, group_top + 2) == NULL)
|| (bn_wexpand(lambda, group_top + 1) == NULL)) { || (bn_wexpand(lambda, group_top + 2) == NULL)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB); ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
goto err; goto err;
} }
@@ -244,7 +244,7 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
* k := scalar + 2*cardinality * k := scalar + 2*cardinality
*/ */
kbit = BN_is_bit_set(lambda, cardinality_bits); kbit = BN_is_bit_set(lambda, cardinality_bits);
BN_consttime_swap(kbit, k, lambda, group_top + 1); BN_consttime_swap(kbit, k, lambda, group_top + 2);
group_top = bn_get_top(group->field); group_top = bn_get_top(group->field);
if ((bn_wexpand(s->X, group_top) == NULL) if ((bn_wexpand(s->X, group_top) == NULL)
+2 -2
View File
@@ -209,7 +209,7 @@ static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
if (!pkey_ec_derive(ctx, ktmp, &ktmplen)) if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
goto err; goto err;
/* Do KDF stuff */ /* Do KDF stuff */
if (!ECDH_KDF_X9_62(key, *keylen, ktmp, ktmplen, if (!ecdh_KDF_X9_63(key, *keylen, ktmp, ktmplen,
dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
goto err; goto err;
rv = 1; rv = 1;
@@ -281,7 +281,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
case EVP_PKEY_CTRL_EC_KDF_TYPE: case EVP_PKEY_CTRL_EC_KDF_TYPE:
if (p1 == -2) if (p1 == -2)
return dctx->kdf_type; return dctx->kdf_type;
if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_62) if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_63)
return -2; return -2;
dctx->kdf_type = p1; dctx->kdf_type = p1;
return 1; return 1;
+18 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
* *
* Licensed under the OpenSSL license (the "License"). You may not use * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * this file except in compliance with the License. You can obtain a copy
@@ -10,12 +10,13 @@
#include <string.h> #include <string.h>
#include <openssl/ec.h> #include <openssl/ec.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#include "ec_lcl.h"
/* Key derivation function from X9.62/SECG */ /* Key derivation function from X9.63/SECG */
/* Way more than we will ever need */ /* Way more than we will ever need */
#define ECDH_KDF_MAX (1 << 30) #define ECDH_KDF_MAX (1 << 30)
int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
const unsigned char *Z, size_t Zlen, const unsigned char *Z, size_t Zlen,
const unsigned char *sinfo, size_t sinfolen, const unsigned char *sinfo, size_t sinfolen,
const EVP_MD *md) const EVP_MD *md)
@@ -66,3 +67,17 @@ int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
EVP_MD_CTX_free(mctx); EVP_MD_CTX_free(mctx);
return rv; return rv;
} }
/*-
* The old name for ecdh_KDF_X9_63
* Retained for ABI compatibility
*/
#if OPENSSL_API_COMPAT < 0x10200000L
int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
const unsigned char *Z, size_t Zlen,
const unsigned char *sinfo, size_t sinfolen,
const EVP_MD *md)
{
return ecdh_KDF_X9_63(out, outlen, Z, Zlen, sinfo, sinfolen, md);
}
#endif
+6
View File
@@ -740,6 +740,11 @@ EVP_F_EVP_DIGESTFINALXOF:174:EVP_DigestFinalXOF
EVP_F_EVP_DIGESTINIT_EX:128:EVP_DigestInit_ex EVP_F_EVP_DIGESTINIT_EX:128:EVP_DigestInit_ex
EVP_F_EVP_ENCRYPTFINAL_EX:127:EVP_EncryptFinal_ex EVP_F_EVP_ENCRYPTFINAL_EX:127:EVP_EncryptFinal_ex
EVP_F_EVP_ENCRYPTUPDATE:167:EVP_EncryptUpdate EVP_F_EVP_ENCRYPTUPDATE:167:EVP_EncryptUpdate
EVP_F_EVP_MAC_CTRL:209:EVP_MAC_ctrl
EVP_F_EVP_MAC_CTRL_STR:210:EVP_MAC_ctrl_str
EVP_F_EVP_MAC_CTX_COPY:211:EVP_MAC_CTX_copy
EVP_F_EVP_MAC_CTX_NEW:213:EVP_MAC_CTX_new
EVP_F_EVP_MAC_INIT:212:EVP_MAC_init
EVP_F_EVP_MD_CTX_COPY_EX:110:EVP_MD_CTX_copy_ex EVP_F_EVP_MD_CTX_COPY_EX:110:EVP_MD_CTX_copy_ex
EVP_F_EVP_MD_SIZE:162:EVP_MD_size EVP_F_EVP_MD_SIZE:162:EVP_MD_size
EVP_F_EVP_OPENINIT:102:EVP_OpenInit EVP_F_EVP_OPENINIT:102:EVP_OpenInit
@@ -802,6 +807,7 @@ EVP_F_PKCS5_PBE_KEYIVGEN:117:PKCS5_PBE_keyivgen
EVP_F_PKCS5_V2_PBE_KEYIVGEN:118:PKCS5_v2_PBE_keyivgen EVP_F_PKCS5_V2_PBE_KEYIVGEN:118:PKCS5_v2_PBE_keyivgen
EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN:164:PKCS5_v2_PBKDF2_keyivgen EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN:164:PKCS5_v2_PBKDF2_keyivgen
EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN:180:PKCS5_v2_scrypt_keyivgen EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN:180:PKCS5_v2_scrypt_keyivgen
EVP_F_PKEY_MAC_INIT:214:pkey_mac_init
EVP_F_PKEY_SET_TYPE:158:pkey_set_type EVP_F_PKEY_SET_TYPE:158:pkey_set_type
EVP_F_RC2_MAGIC_TO_METH:109:rc2_magic_to_meth EVP_F_RC2_MAGIC_TO_METH:109:rc2_magic_to_meth
EVP_F_RC5_CTRL:125:rc5_ctrl EVP_F_RC5_CTRL:125:rc5_ctrl
+2 -1
View File
@@ -12,7 +12,8 @@ SOURCE[../../libcrypto]=\
evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \ evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \
e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \ e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \
e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \ e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
e_chacha20_poly1305.c cmeth_lib.c e_chacha20_poly1305.c cmeth_lib.c \
mac_lib.c c_allm.c pkey_mac.c
INCLUDE[e_aes.o]=.. ../modes INCLUDE[e_aes.o]=.. ../modes
INCLUDE[e_aes_cbc_hmac_sha1.o]=../modes INCLUDE[e_aes_cbc_hmac_sha1.o]=../modes
+22
View File
@@ -0,0 +1,22 @@
/*
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 <openssl/evp.h>
#include "internal/evp_int.h"
void openssl_add_all_macs_int(void)
{
#ifndef OPENSSL_NO_CMAC
EVP_add_mac(&cmac_meth);
#endif
EVP_add_mac(&hmac_meth);
#ifndef OPENSSL_NO_SIPHASH
EVP_add_mac(&siphash_meth);
#endif
}
+6
View File
@@ -54,6 +54,11 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0), {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0),
"EVP_EncryptFinal_ex"}, "EVP_EncryptFinal_ex"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTUPDATE, 0), "EVP_EncryptUpdate"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTUPDATE, 0), "EVP_EncryptUpdate"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL, 0), "EVP_MAC_ctrl"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL_STR, 0), "EVP_MAC_ctrl_str"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_COPY, 0), "EVP_MAC_CTX_copy"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_NEW, 0), "EVP_MAC_CTX_new"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_INIT, 0), "EVP_MAC_init"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_CTX_COPY_EX, 0), "EVP_MD_CTX_copy_ex"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_CTX_COPY_EX, 0), "EVP_MD_CTX_copy_ex"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_SIZE, 0), "EVP_MD_size"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_SIZE, 0), "EVP_MD_size"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_OPENINIT, 0), "EVP_OpenInit"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_OPENINIT, 0), "EVP_OpenInit"},
@@ -145,6 +150,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
"PKCS5_v2_PBKDF2_keyivgen"}, "PKCS5_v2_PBKDF2_keyivgen"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, 0), {ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, 0),
"PKCS5_v2_scrypt_keyivgen"}, "PKCS5_v2_scrypt_keyivgen"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_MAC_INIT, 0), "pkey_mac_init"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_SET_TYPE, 0), "pkey_set_type"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_SET_TYPE, 0), "pkey_set_type"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_RC2_MAGIC_TO_METH, 0), "rc2_magic_to_meth"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_RC2_MAGIC_TO_METH, 0), "rc2_magic_to_meth"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_RC5_CTRL, 0), "rc5_ctrl"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_RC5_CTRL, 0), "rc5_ctrl"},
+27
View File
@@ -526,3 +526,30 @@ int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
{ {
return (ctx->flags & flags); return (ctx->flags & flags);
} }
int EVP_str2ctrl(int (*cb)(void *ctx, int cmd, void *buf, size_t buflen),
void *ctx, int cmd, const char *value)
{
size_t len;
len = strlen(value);
if (len > INT_MAX)
return -1;
return cb(ctx, cmd, (void *)value, len);
}
int EVP_hex2ctrl(int (*cb)(void *ctx, int cmd, void *buf, size_t buflen),
void *ctx, int cmd, const char *hex)
{
unsigned char *bin;
long binlen;
int rv = -1;
bin = OPENSSL_hexstr2buf(hex, &binlen);
if (bin == NULL)
return 0;
if (binlen <= INT_MAX)
rv = cb(ctx, cmd, bin, binlen);
OPENSSL_free(bin);
return rv;
}
+5
View File
@@ -41,6 +41,11 @@ struct evp_cipher_ctx_st {
unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */ unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */
} /* EVP_CIPHER_CTX */ ; } /* EVP_CIPHER_CTX */ ;
struct evp_mac_ctx_st {
const EVP_MAC *meth; /* Method structure */
void *data; /* Individual method data */
} /* EVP_MAC_CTX */;
int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param, int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md, const EVP_CIPHER *c, const EVP_MD *md,
+185
View File
@@ -0,0 +1,185 @@
/*
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 <string.h>
#include <stdarg.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/ossl_typ.h>
#include "internal/nelem.h"
#include "internal/evp_int.h"
#include "evp_locl.h"
EVP_MAC_CTX *EVP_MAC_CTX_new_id(int id)
{
const EVP_MAC *mac = EVP_get_macbynid(id);
if (mac == NULL)
return NULL;
return EVP_MAC_CTX_new(mac);
}
EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac)
{
EVP_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(EVP_MAC_CTX));
if (ctx == NULL || (ctx->data = mac->new()) == NULL) {
EVPerr(EVP_F_EVP_MAC_CTX_NEW, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ctx);
ctx = NULL;
} else {
ctx->meth = mac;
}
return ctx;
}
void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx)
{
if (ctx != NULL && ctx->data != NULL) {
ctx->meth->free(ctx->data);
ctx->data = NULL;
}
OPENSSL_free(ctx);
}
int EVP_MAC_CTX_copy(EVP_MAC_CTX *dst, EVP_MAC_CTX *src)
{
EVP_MAC_IMPL *macdata;
if (src->data != NULL && !dst->meth->copy(dst->data, src->data))
return 0;
macdata = dst->data;
*dst = *src;
dst->data = macdata;
return 1;
}
const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx)
{
return ctx->meth;
}
size_t EVP_MAC_size(EVP_MAC_CTX *ctx)
{
if (ctx->data != NULL)
return ctx->meth->size(ctx->data);
/* If the MAC hasn't been initialized yet, we return zero */
return 0;
}
int EVP_MAC_init(EVP_MAC_CTX *ctx)
{
return ctx->meth->init(ctx->data);
}
int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen)
{
return ctx->meth->update(ctx->data, data, datalen);
}
int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *poutlen)
{
int l = ctx->meth->size(ctx->data);
if (l < 0)
return 0;
if (poutlen != NULL)
*poutlen = l;
if (out == NULL)
return 1;
return ctx->meth->final(ctx->data, out);
}
int EVP_MAC_ctrl(EVP_MAC_CTX *ctx, int cmd, ...)
{
int ok = -1;
va_list args;
va_start(args, cmd);
ok = EVP_MAC_vctrl(ctx, cmd, args);
va_end(args);
if (ok == -2)
EVPerr(EVP_F_EVP_MAC_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
return ok;
}
int EVP_MAC_vctrl(EVP_MAC_CTX *ctx, int cmd, va_list args)
{
int ok = 1;
if (ctx == NULL || ctx->meth == NULL)
return -2;
switch (cmd) {
#if 0
case ...:
/* code */
ok = 1;
break;
#endif
default:
if (ctx->meth->ctrl != NULL)
ok = ctx->meth->ctrl(ctx->data, cmd, args);
else
ok = -2;
break;
}
return ok;
}
int EVP_MAC_ctrl_str(EVP_MAC_CTX *ctx, const char *type, const char *value)
{
int ok = 1;
if (ctx == NULL || ctx->meth == NULL || ctx->meth->ctrl_str == NULL) {
EVPerr(EVP_F_EVP_MAC_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
return -2;
}
ok = ctx->meth->ctrl_str(ctx->data, type, value);
if (ok == -2)
EVPerr(EVP_F_EVP_MAC_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
return ok;
}
int EVP_MAC_str2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value)
{
size_t len;
len = strlen(value);
if (len > INT_MAX)
return -1;
return EVP_MAC_ctrl(ctx, cmd, value, len);
}
int EVP_MAC_hex2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *hex)
{
unsigned char *bin;
long binlen;
int rv = -1;
bin = OPENSSL_hexstr2buf(hex, &binlen);
if (bin == NULL)
return 0;
if (binlen <= INT_MAX)
rv = EVP_MAC_ctrl(ctx, cmd, bin, (size_t)binlen);
OPENSSL_free(bin);
return rv;
}
int EVP_MAC_nid(const EVP_MAC *mac)
{
return mac->type;
}
+74 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
* *
* Licensed under the OpenSSL license (the "License"). You may not use * Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy * this file except in compliance with the License. You can obtain a copy
@@ -55,6 +55,22 @@ int EVP_add_digest(const EVP_MD *md)
return r; return r;
} }
int EVP_add_mac(const EVP_MAC *m)
{
int r;
if (m == NULL)
return 0;
r = OBJ_NAME_add(OBJ_nid2sn(m->type), OBJ_NAME_TYPE_MAC_METH,
(const char *)m);
if (r == 0)
return 0;
r = OBJ_NAME_add(OBJ_nid2ln(m->type), OBJ_NAME_TYPE_MAC_METH,
(const char *)m);
return r;
}
const EVP_CIPHER *EVP_get_cipherbyname(const char *name) const EVP_CIPHER *EVP_get_cipherbyname(const char *name)
{ {
const EVP_CIPHER *cp; const EVP_CIPHER *cp;
@@ -77,8 +93,20 @@ const EVP_MD *EVP_get_digestbyname(const char *name)
return cp; return cp;
} }
const EVP_MAC *EVP_get_macbyname(const char *name)
{
const EVP_MAC *mp;
if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL))
return NULL;
mp = (const EVP_MAC *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MAC_METH);
return mp;
}
void evp_cleanup_int(void) void evp_cleanup_int(void)
{ {
OBJ_NAME_cleanup(OBJ_NAME_TYPE_MAC_METH);
OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH); OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH); OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
/* /*
@@ -178,3 +206,48 @@ void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md,
dc.arg = arg; dc.arg = arg;
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
} }
struct doall_mac {
void *arg;
void (*fn) (const EVP_MAC *ciph,
const char *from, const char *to, void *arg);
};
static void do_all_mac_fn(const OBJ_NAME *nm, void *arg)
{
struct doall_mac *dc = arg;
if (nm->alias)
dc->fn(NULL, nm->name, nm->data, dc->arg);
else
dc->fn((const EVP_MAC *)nm->data, nm->name, NULL, dc->arg);
}
void EVP_MAC_do_all(void (*fn)
(const EVP_MAC *ciph, const char *from, const char *to,
void *x), void *arg)
{
struct doall_mac dc;
/* Ignore errors */
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL);
dc.fn = fn;
dc.arg = arg;
OBJ_NAME_do_all(OBJ_NAME_TYPE_MAC_METH, do_all_mac_fn, &dc);
}
void EVP_MAC_do_all_sorted(void (*fn)
(const EVP_MAC *ciph, const char *from,
const char *to, void *x), void *arg)
{
struct doall_mac dc;
/* Ignore errors */
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL);
dc.fn = fn;
dc.arg = arg;
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MAC_METH, do_all_mac_fn, &dc);
}
+5 -3
View File
@@ -319,7 +319,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
{ {
#ifndef OPENSSL_NO_CMAC #ifndef OPENSSL_NO_CMAC
EVP_PKEY *ret = EVP_PKEY_new(); EVP_PKEY *ret = EVP_PKEY_new();
CMAC_CTX *cmctx = CMAC_CTX_new(); EVP_MAC_CTX *cmctx = EVP_MAC_CTX_new_id(EVP_MAC_CMAC);
if (ret == NULL if (ret == NULL
|| cmctx == NULL || cmctx == NULL
@@ -328,7 +328,9 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
goto err; goto err;
} }
if (!CMAC_Init(cmctx, priv, len, cipher, e)) { if (EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_ENGINE, e) <= 0
|| EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_CIPHER, cipher) <= 0
|| EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_KEY, priv, len) <= 0) {
EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED); EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED);
goto err; goto err;
} }
@@ -338,7 +340,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
err: err:
EVP_PKEY_free(ret); EVP_PKEY_free(ret);
CMAC_CTX_free(cmctx); EVP_MAC_CTX_free(cmctx);
return NULL; return NULL;
#else #else
EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
+427
View File
@@ -0,0 +1,427 @@
/*
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 <openssl/err.h>
#include <openssl/evp.h>
#include "internal/evp_int.h"
/* MAC PKEY context structure */
typedef struct {
EVP_MAC_CTX *ctx;
/*
* We know of two MAC types:
*
* 1. those who take a secret in raw form, i.e. raw data as a
* ASN1_OCTET_STRING embedded in a EVP_PKEY. So far, that's
* all of them but CMAC.
* 2. those who take a secret with associated cipher in very generic
* form, i.e. a complete EVP_MAC_CTX embedded in a PKEY. So far,
* only CMAC does this.
*
* (one might wonder why the second form isn't used for all)
*/
#define MAC_TYPE_RAW 1 /* HMAC like MAC type (all but CMAC so far) */
#define MAC_TYPE_MAC 2 /* CMAC like MAC type (only CMAC known so far) */
int type;
/* The following is only used for MAC_TYPE_RAW implementations */
struct {
const EVP_MD *md; /* temp storage of MD */
ASN1_OCTET_STRING ktmp; /* temp storage for key */
} raw_data;
} MAC_PKEY_CTX;
static int pkey_mac_init(EVP_PKEY_CTX *ctx)
{
MAC_PKEY_CTX *hctx;
int nid = ctx->pmeth->pkey_id;
if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
return 0;
}
/* We're being smart and using the same base NIDs for PKEY and for MAC */
hctx->ctx = EVP_MAC_CTX_new_id(nid);
if (hctx->ctx == NULL) {
OPENSSL_free(hctx);
return 0;
}
if (nid == EVP_PKEY_CMAC) {
hctx->type = MAC_TYPE_MAC;
} else {
hctx->type = MAC_TYPE_RAW;
hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING;
}
EVP_PKEY_CTX_set_data(ctx, hctx);
ctx->keygen_info_count = 0;
return 1;
}
static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
static int pkey_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
{
MAC_PKEY_CTX *sctx, *dctx;
if (!pkey_mac_init(dst))
return 0;
sctx = EVP_PKEY_CTX_get_data(src);
dctx = EVP_PKEY_CTX_get_data(dst);
if (!EVP_MAC_CTX_copy(dctx->ctx, sctx->ctx))
goto err;
switch (dctx->type) {
case MAC_TYPE_RAW:
dctx->raw_data.md = sctx->raw_data.md;
if (ASN1_STRING_get0_data(&sctx->raw_data.ktmp) != NULL &&
!ASN1_STRING_copy(&dctx->raw_data.ktmp, &sctx->raw_data.ktmp))
goto err;
break;
case MAC_TYPE_MAC:
/* Nothing more to do */
break;
default:
/* This should be dead code */
return 0;
}
return 1;
err:
pkey_mac_cleanup (dst);
return 0;
}
static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
{
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
if (hctx != NULL) {
switch (hctx->type) {
case MAC_TYPE_RAW:
OPENSSL_clear_free(hctx->raw_data.ktmp.data,
hctx->raw_data.ktmp.length);
break;
}
EVP_MAC_CTX_free(hctx->ctx);
OPENSSL_free(hctx);
EVP_PKEY_CTX_set_data(ctx, NULL);
}
}
static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
int nid = ctx->pmeth->pkey_id;
switch (hctx->type) {
case MAC_TYPE_RAW:
{
ASN1_OCTET_STRING *hkey = NULL;
if (!hctx->raw_data.ktmp.data)
return 0;
hkey = ASN1_OCTET_STRING_dup(&hctx->raw_data.ktmp);
if (!hkey)
return 0;
EVP_PKEY_assign(pkey, nid, hkey);
}
break;
case MAC_TYPE_MAC:
{
EVP_MAC_CTX *cmkey = EVP_MAC_CTX_new_id(nid);
if (cmkey == NULL)
return 0;
if (!EVP_MAC_CTX_copy(cmkey, hctx->ctx)) {
EVP_MAC_CTX_free(cmkey);
return 0;
}
EVP_PKEY_assign(pkey, nid, cmkey);
}
break;
default:
/* This should be dead code */
return 0;
}
return 1;
}
static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
if (!EVP_MAC_update(hctx->ctx, data, count))
return 0;
return 1;
}
static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
{
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
ASN1_OCTET_STRING *key = NULL;
int rv = 1;
/*
* For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that
* gets the key passed as an ASN.1 OCTET STRING, we set the key here,
* as this may be only time it's set during a DigestSign.
*
* MACs that pass around the key in form of EVP_MAC_CTX are setting
* the key through other mechanisms. (this is only CMAC for now)
*/
int set_key =
hctx->type == MAC_TYPE_RAW
&& (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
if (set_key) {
if (EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))
!= EVP_MAC_nid(EVP_MAC_CTX_mac(hctx->ctx)))
return 0;
key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
if (key == NULL)
return 0;
}
/* Some MACs don't support this control... that's fine */
EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_FLAGS,
EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT));
EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
EVP_MD_CTX_set_update_fn(mctx, int_update);
if (set_key)
rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, key->data,
key->length);
return rv > 0;
}
static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
size_t *siglen, EVP_MD_CTX *mctx)
{
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
return EVP_MAC_final(hctx->ctx, sig, siglen);
}
static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
switch (type) {
case EVP_PKEY_CTRL_CIPHER:
switch (hctx->type) {
case MAC_TYPE_RAW:
return -2; /* The raw types don't support ciphers */
case MAC_TYPE_MAC:
{
int rv;
if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
ctx->engine)) < 0
|| (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_CIPHER,
p2)) < 0
|| !(rv = EVP_MAC_init(hctx->ctx)))
return rv;
}
break;
default:
/* This should be dead code */
return 0;
}
break;
case EVP_PKEY_CTRL_MD:
switch (hctx->type) {
case MAC_TYPE_RAW:
hctx->raw_data.md = p2;
break;
case MAC_TYPE_MAC:
if (ctx->pkey != NULL
&& !EVP_MAC_CTX_copy(hctx->ctx,
(EVP_MAC_CTX *)ctx->pkey->pkey.ptr))
return 0;
if (!EVP_MAC_init(hctx->ctx))
return 0;
break;
default:
/* This should be dead code */
return 0;
}
break;
case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
return EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_SIZE, (size_t)p1);
case EVP_PKEY_CTRL_SET_MAC_KEY:
switch (hctx->type) {
case MAC_TYPE_RAW:
if ((!p2 && p1 > 0) || (p1 < -1))
return 0;
if (!ASN1_OCTET_STRING_set(&hctx->raw_data.ktmp, p2, p1))
return 0;
break;
case MAC_TYPE_MAC:
if (!EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, p2, p1))
return 0;
break;
default:
/* This should be dead code */
return 0;
}
break;
case EVP_PKEY_CTRL_DIGESTINIT:
switch (hctx->type) {
case MAC_TYPE_RAW:
/* Ensure that we have attached the implementation */
if (!EVP_MAC_init(hctx->ctx))
return 0;
{
int rv;
ASN1_OCTET_STRING *key =
(ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
ctx->engine)) < 0
|| (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_MD,
hctx->raw_data.md)) < 0
|| (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY,
key->data, key->length)) < 0)
return rv;
}
break;
case MAC_TYPE_MAC:
return -2; /* The mac types don't support ciphers */
default:
/* This should be dead code */
return 0;
}
break;
default:
return -2;
}
return 1;
}
static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
const char *type, const char *value)
{
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
return EVP_MAC_ctrl_str(hctx->ctx, type, value);
}
const EVP_PKEY_METHOD cmac_pkey_meth = {
EVP_PKEY_CMAC,
EVP_PKEY_FLAG_SIGCTX_CUSTOM,
pkey_mac_init,
pkey_mac_copy,
pkey_mac_cleanup,
0, 0,
0,
pkey_mac_keygen,
0, 0,
0, 0,
0, 0,
pkey_mac_signctx_init,
pkey_mac_signctx,
0, 0,
0, 0,
0, 0,
0, 0,
pkey_mac_ctrl,
pkey_mac_ctrl_str
};
const EVP_PKEY_METHOD hmac_pkey_meth = {
EVP_PKEY_HMAC,
0,
pkey_mac_init,
pkey_mac_copy,
pkey_mac_cleanup,
0, 0,
0,
pkey_mac_keygen,
0, 0,
0, 0,
0, 0,
pkey_mac_signctx_init,
pkey_mac_signctx,
0, 0,
0, 0,
0, 0,
0, 0,
pkey_mac_ctrl,
pkey_mac_ctrl_str
};
const EVP_PKEY_METHOD siphash_pkey_meth = {
EVP_PKEY_SIPHASH,
EVP_PKEY_FLAG_SIGCTX_CUSTOM,
pkey_mac_init,
pkey_mac_copy,
pkey_mac_cleanup,
0, 0,
0,
pkey_mac_keygen,
0, 0,
0, 0,
0, 0,
pkey_mac_signctx_init,
pkey_mac_signctx,
0, 0,
0, 0,
0, 0,
0, 0,
pkey_mac_ctrl,
pkey_mac_ctrl_str
};
+1 -1
View File
@@ -1,3 +1,3 @@
LIBS=../../libcrypto LIBS=../../libcrypto
SOURCE[../../libcrypto]=\ SOURCE[../../libcrypto]=\
hmac.c hm_ameth.c hm_pmeth.c hmac.c hm_ameth.c hm_meth.c
+173
View File
@@ -0,0 +1,173 @@
/*
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 <string.h>
#include <openssl/err.h>
#include <openssl/ossl_typ.h>
#include <openssl/asn1.h>
#include <openssl/hmac.h>
#include "internal/evp_int.h"
/* local HMAC context structure */
/* typedef EVP_MAC_IMPL */
struct evp_mac_impl_st {
/* tmpmd and tmpengine are set to NULL after a CMAC_Init call */
const EVP_MD *tmpmd; /* HMAC digest */
const ENGINE *tmpengine; /* HMAC digest engine */
HMAC_CTX *ctx; /* HMAC context */
};
static EVP_MAC_IMPL *hmac_new(void)
{
EVP_MAC_IMPL *hctx;
if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL
|| (hctx->ctx = HMAC_CTX_new()) == NULL) {
OPENSSL_free(hctx);
return NULL;
}
return hctx;
}
static void hmac_free(EVP_MAC_IMPL *hctx)
{
if (hctx != NULL) {
HMAC_CTX_free(hctx->ctx);
OPENSSL_free(hctx);
}
}
static int hmac_copy(EVP_MAC_IMPL *hdst, EVP_MAC_IMPL *hsrc)
{
if (!HMAC_CTX_copy(hdst->ctx, hsrc->ctx))
return 0;
hdst->tmpengine = hsrc->tmpengine;
hdst->tmpmd = hsrc->tmpmd;
return 1;
}
static size_t hmac_size(EVP_MAC_IMPL *hctx)
{
return HMAC_size(hctx->ctx);
}
static int hmac_init(EVP_MAC_IMPL *hctx)
{
int rv = 1;
/* HMAC_Init_ex doesn't tolerate all zero params, so we must be careful */
if (hctx->tmpmd != NULL)
rv = HMAC_Init_ex(hctx->ctx, NULL, 0, hctx->tmpmd,
(ENGINE * )hctx->tmpengine);
hctx->tmpengine = NULL;
hctx->tmpmd = NULL;
return rv;
}
static int hmac_update(EVP_MAC_IMPL *hctx, const unsigned char *data,
size_t datalen)
{
return HMAC_Update(hctx->ctx, data, datalen);
}
static int hmac_final(EVP_MAC_IMPL *hctx, unsigned char *out)
{
unsigned int hlen;
return HMAC_Final(hctx->ctx, out, &hlen);
}
static int hmac_ctrl(EVP_MAC_IMPL *hctx, int cmd, va_list args)
{
switch (cmd) {
case EVP_MAC_CTRL_SET_FLAGS:
{
unsigned long flags = va_arg(args, unsigned long);
HMAC_CTX_set_flags(hctx->ctx, flags);
}
break;
case EVP_MAC_CTRL_SET_KEY:
{
const unsigned char *key = va_arg(args, const unsigned char *);
size_t keylen = va_arg(args, size_t);
int rv = HMAC_Init_ex(hctx->ctx, key, keylen, hctx->tmpmd,
(ENGINE *)hctx->tmpengine);
hctx->tmpengine = NULL;
hctx->tmpmd = NULL;
return rv;
}
break;
case EVP_MAC_CTRL_SET_MD:
hctx->tmpmd = va_arg(args, const EVP_MD *);
break;
case EVP_MAC_CTRL_SET_ENGINE:
hctx->tmpengine = va_arg(args, const ENGINE *);
break;
default:
return -2;
}
return 1;
}
static int hmac_ctrl_int(EVP_MAC_IMPL *hctx, int cmd, ...)
{
int rv;
va_list args;
va_start(args, cmd);
rv = hmac_ctrl(hctx, cmd, args);
va_end(args);
return rv;
}
static int hmac_ctrl_str_cb(void *hctx, int cmd, void *buf, size_t buflen)
{
return hmac_ctrl_int(hctx, cmd, buf, buflen);
}
static int hmac_ctrl_str(EVP_MAC_IMPL *hctx, const char *type,
const char *value)
{
if (!value)
return 0;
if (strcmp(type, "digest") == 0) {
const EVP_MD *d = EVP_get_digestbyname(value);
if (d == NULL)
return 0;
return hmac_ctrl_int(hctx, EVP_MAC_CTRL_SET_MD, d);
}
if (strcmp(type, "key") == 0)
return EVP_str2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY,
value);
if (strcmp(type, "hexkey") == 0)
return EVP_hex2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY,
value);
return -2;
}
const EVP_MAC hmac_meth = {
EVP_MAC_HMAC,
hmac_new,
hmac_copy,
hmac_free,
hmac_size,
hmac_init,
hmac_update,
hmac_final,
hmac_ctrl,
hmac_ctrl_str
};
-212
View File
@@ -1,212 +0,0 @@
/*
* Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/err.h>
#include "internal/evp_int.h"
/* HMAC pkey context structure */
typedef struct {
const EVP_MD *md; /* MD for HMAC use */
ASN1_OCTET_STRING ktmp; /* Temp storage for key */
HMAC_CTX *ctx;
} HMAC_PKEY_CTX;
static int pkey_hmac_init(EVP_PKEY_CTX *ctx)
{
HMAC_PKEY_CTX *hctx;
if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
CRYPTOerr(CRYPTO_F_PKEY_HMAC_INIT, ERR_R_MALLOC_FAILURE);
return 0;
}
hctx->ktmp.type = V_ASN1_OCTET_STRING;
hctx->ctx = HMAC_CTX_new();
if (hctx->ctx == NULL) {
OPENSSL_free(hctx);
return 0;
}
ctx->data = hctx;
ctx->keygen_info_count = 0;
return 1;
}
static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx);
static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
{
HMAC_PKEY_CTX *sctx, *dctx;
/* allocate memory for dst->data and a new HMAC_CTX in dst->data->ctx */
if (!pkey_hmac_init(dst))
return 0;
sctx = EVP_PKEY_CTX_get_data(src);
dctx = EVP_PKEY_CTX_get_data(dst);
dctx->md = sctx->md;
if (!HMAC_CTX_copy(dctx->ctx, sctx->ctx))
goto err;
if (sctx->ktmp.data) {
if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
sctx->ktmp.data, sctx->ktmp.length))
goto err;
}
return 1;
err:
/* release HMAC_CTX in dst->data->ctx and memory allocated for dst->data */
pkey_hmac_cleanup (dst);
return 0;
}
static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx)
{
HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
if (hctx != NULL) {
HMAC_CTX_free(hctx->ctx);
OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length);
OPENSSL_free(hctx);
EVP_PKEY_CTX_set_data(ctx, NULL);
}
}
static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
ASN1_OCTET_STRING *hkey = NULL;
HMAC_PKEY_CTX *hctx = ctx->data;
if (!hctx->ktmp.data)
return 0;
hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
if (!hkey)
return 0;
EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
return 1;
}
static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
HMAC_PKEY_CTX *hctx = EVP_MD_CTX_pkey_ctx(ctx)->data;
if (!HMAC_Update(hctx->ctx, data, count))
return 0;
return 1;
}
static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
{
HMAC_PKEY_CTX *hctx = ctx->data;
HMAC_CTX_set_flags(hctx->ctx,
EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT));
EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
EVP_MD_CTX_set_update_fn(mctx, int_update);
return 1;
}
static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
EVP_MD_CTX *mctx)
{
unsigned int hlen;
HMAC_PKEY_CTX *hctx = ctx->data;
int l = EVP_MD_CTX_size(mctx);
if (l < 0)
return 0;
*siglen = l;
if (!sig)
return 1;
if (!HMAC_Final(hctx->ctx, sig, &hlen))
return 0;
*siglen = (size_t)hlen;
return 1;
}
static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
HMAC_PKEY_CTX *hctx = ctx->data;
ASN1_OCTET_STRING *key;
switch (type) {
case EVP_PKEY_CTRL_SET_MAC_KEY:
if ((!p2 && p1 > 0) || (p1 < -1))
return 0;
if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
return 0;
break;
case EVP_PKEY_CTRL_MD:
hctx->md = p2;
break;
case EVP_PKEY_CTRL_DIGESTINIT:
key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
if (!HMAC_Init_ex(hctx->ctx, key->data, key->length, hctx->md,
ctx->engine))
return 0;
break;
default:
return -2;
}
return 1;
}
static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
const char *type, const char *value)
{
if (!value) {
return 0;
}
if (strcmp(type, "key") == 0)
return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
if (strcmp(type, "hexkey") == 0)
return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
return -2;
}
const EVP_PKEY_METHOD hmac_pkey_meth = {
EVP_PKEY_HMAC,
0,
pkey_hmac_init,
pkey_hmac_copy,
pkey_hmac_cleanup,
0, 0,
0,
pkey_hmac_keygen,
0, 0,
0, 0,
0, 0,
hmac_signctx_init,
hmac_signctx,
0, 0,
0, 0,
0, 0,
0, 0,
pkey_hmac_ctrl,
pkey_hmac_ctrl_str
};
+8
View File
@@ -41,5 +41,13 @@
__owur int ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res, __owur int ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res,
const BIGNUM *x, BN_CTX *ctx); const BIGNUM *x, BN_CTX *ctx);
/*-
* ECDH Key Derivation Function as defined in ANSI X9.63
*/
int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
const unsigned char *Z, size_t Zlen,
const unsigned char *sinfo, size_t sinfolen,
const EVP_MD *md);
# endif /* OPENSSL_NO_EC */ # endif /* OPENSSL_NO_EC */
#endif #endif
+30
View File
@@ -112,6 +112,35 @@ extern const EVP_PKEY_METHOD hkdf_pkey_meth;
extern const EVP_PKEY_METHOD poly1305_pkey_meth; extern const EVP_PKEY_METHOD poly1305_pkey_meth;
extern const EVP_PKEY_METHOD siphash_pkey_meth; extern const EVP_PKEY_METHOD siphash_pkey_meth;
/* struct evp_mac_impl_st is defined by the implementation */
typedef struct evp_mac_impl_st EVP_MAC_IMPL;
struct evp_mac_st {
int type;
EVP_MAC_IMPL *(*new) (void);
int (*copy) (EVP_MAC_IMPL *macdst, EVP_MAC_IMPL *macsrc);
void (*free) (EVP_MAC_IMPL *macctx);
size_t (*size) (EVP_MAC_IMPL *macctx);
int (*init) (EVP_MAC_IMPL *macctx);
int (*update) (EVP_MAC_IMPL *macctx, const unsigned char *data,
size_t datalen);
int (*final) (EVP_MAC_IMPL *macctx, unsigned char *out);
int (*ctrl) (EVP_MAC_IMPL *macctx, int cmd, va_list args);
int (*ctrl_str) (EVP_MAC_IMPL *macctx, const char *type, const char *value);
};
extern const EVP_MAC cmac_meth;
extern const EVP_MAC hmac_meth;
extern const EVP_MAC siphash_meth;
/*
* This function is internal for now, but can be made external when needed.
* The documentation would read:
*
* EVP_add_mac() adds the MAC implementation C<mac> to the internal
* object database.
*/
int EVP_add_mac(const EVP_MAC *mac);
struct evp_md_st { struct evp_md_st {
int type; int type;
int pkey_type; int pkey_type;
@@ -423,6 +452,7 @@ struct evp_pkey_st {
void openssl_add_all_ciphers_int(void); void openssl_add_all_ciphers_int(void);
void openssl_add_all_digests_int(void); void openssl_add_all_digests_int(void);
void openssl_add_all_macs_int(void);
void evp_cleanup_int(void); void evp_cleanup_int(void);
void evp_app_cleanup_int(void); void evp_app_cleanup_int(void);
+25
View File
@@ -235,6 +235,23 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
return 1; return 1;
} }
static CRYPTO_ONCE add_all_macs = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_macs)
{
/*
* OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
* pulling in all the macs during static linking
*/
#ifndef OPENSSL_NO_AUTOALGINIT
# ifdef OPENSSL_INIT_DEBUG
fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_macs: "
"openssl_add_all_macs_int()\n");
# endif
openssl_add_all_macs_int();
#endif
return 1;
}
DEFINE_RUN_ONCE_STATIC(ossl_init_no_add_algs) DEFINE_RUN_ONCE_STATIC(ossl_init_no_add_algs)
{ {
/* Do nothing */ /* Do nothing */
@@ -619,6 +636,14 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
&& !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests)) && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
return 0; return 0;
if ((opts & OPENSSL_INIT_NO_ADD_ALL_MACS)
&& !RUN_ONCE(&add_all_macs, ossl_init_no_add_algs))
return 0;
if ((opts & OPENSSL_INIT_ADD_ALL_MACS)
&& !RUN_ONCE(&add_all_macs, ossl_init_add_all_macs))
return 0;
if ((opts & OPENSSL_INIT_ATFORK) if ((opts & OPENSSL_INIT_ATFORK)
&& !openssl_init_fork_handlers()) && !openssl_init_fork_handlers())
return 0; return 0;
+13 -1
View File
@@ -175,6 +175,18 @@ static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
return -2; return -2;
} }
static int pkey_hkdf_derive_init(EVP_PKEY_CTX *ctx)
{
HKDF_PKEY_CTX *kctx = ctx->data;
OPENSSL_clear_free(kctx->key, kctx->key_len);
OPENSSL_clear_free(kctx->salt, kctx->salt_len);
OPENSSL_cleanse(kctx->info, kctx->info_len);
memset(kctx, 0, sizeof(*kctx));
return 1;
}
static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
size_t *keylen) size_t *keylen)
{ {
@@ -236,7 +248,7 @@ const EVP_PKEY_METHOD hkdf_pkey_meth = {
0, 0, 0, 0,
0, pkey_hkdf_derive_init,
pkey_hkdf_derive, pkey_hkdf_derive,
pkey_hkdf_ctrl, pkey_hkdf_ctrl,
pkey_hkdf_ctrl_str pkey_hkdf_ctrl_str
+102 -39
View File
@@ -374,6 +374,13 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
max_entropylen += drbg->max_noncelen; max_entropylen += drbg->max_noncelen;
} }
drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter);
if (drbg->reseed_next_counter) {
drbg->reseed_next_counter++;
if(!drbg->reseed_next_counter)
drbg->reseed_next_counter = 1;
}
if (drbg->get_entropy != NULL) if (drbg->get_entropy != NULL)
entropylen = drbg->get_entropy(drbg, &entropy, min_entropy, entropylen = drbg->get_entropy(drbg, &entropy, min_entropy,
min_entropylen, max_entropylen, 0); min_entropylen, max_entropylen, 0);
@@ -401,27 +408,13 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
drbg->state = DRBG_READY; drbg->state = DRBG_READY;
drbg->reseed_gen_counter = 1; drbg->reseed_gen_counter = 1;
drbg->reseed_time = time(NULL); drbg->reseed_time = time(NULL);
if (drbg->reseed_prop_counter > 0) { tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
if (drbg->parent == NULL)
drbg->reseed_prop_counter++;
else
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
}
end: end:
if (entropy != NULL && drbg->cleanup_entropy != NULL) if (entropy != NULL && drbg->cleanup_entropy != NULL)
drbg->cleanup_entropy(drbg, entropy, entropylen); drbg->cleanup_entropy(drbg, entropy, entropylen);
if (nonce != NULL && drbg->cleanup_nonce != NULL) if (nonce != NULL && drbg->cleanup_nonce != NULL)
drbg->cleanup_nonce(drbg, nonce, noncelen); drbg->cleanup_nonce(drbg, nonce, noncelen);
if (drbg->pool != NULL) {
if (drbg->state == DRBG_READY) {
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED);
drbg->state = DRBG_ERROR;
}
rand_pool_free(drbg->pool);
drbg->pool = NULL;
}
if (drbg->state == DRBG_READY) if (drbg->state == DRBG_READY)
return 1; return 1;
return 0; return 0;
@@ -498,6 +491,14 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
} }
drbg->state = DRBG_ERROR; drbg->state = DRBG_ERROR;
drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter);
if (drbg->reseed_next_counter) {
drbg->reseed_next_counter++;
if(!drbg->reseed_next_counter)
drbg->reseed_next_counter = 1;
}
if (drbg->get_entropy != NULL) if (drbg->get_entropy != NULL)
entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength, entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength,
drbg->min_entropylen, drbg->min_entropylen,
@@ -515,12 +516,7 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
drbg->state = DRBG_READY; drbg->state = DRBG_READY;
drbg->reseed_gen_counter = 1; drbg->reseed_gen_counter = 1;
drbg->reseed_time = time(NULL); drbg->reseed_time = time(NULL);
if (drbg->reseed_prop_counter > 0) { tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
if (drbg->parent == NULL)
drbg->reseed_prop_counter++;
else
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
}
end: end:
if (entropy != NULL && drbg->cleanup_entropy != NULL) if (entropy != NULL && drbg->cleanup_entropy != NULL)
@@ -625,14 +621,8 @@ int rand_drbg_restart(RAND_DRBG *drbg,
} }
} }
/* check whether a given entropy pool was cleared properly during reseed */ rand_pool_free(drbg->pool);
if (drbg->pool != NULL) { drbg->pool = NULL;
drbg->state = DRBG_ERROR;
RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR);
rand_pool_free(drbg->pool);
drbg->pool = NULL;
return 0;
}
return drbg->state == DRBG_READY; return drbg->state == DRBG_READY;
} }
@@ -691,8 +681,11 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
|| now - drbg->reseed_time >= drbg->reseed_time_interval) || now - drbg->reseed_time >= drbg->reseed_time_interval)
reseed_required = 1; reseed_required = 1;
} }
if (drbg->reseed_prop_counter > 0 && drbg->parent != NULL) { if (drbg->parent != NULL) {
if (drbg->reseed_prop_counter != drbg->parent->reseed_prop_counter) unsigned int reseed_counter = tsan_load(&drbg->reseed_prop_counter);
if (reseed_counter > 0
&& tsan_load(&drbg->parent->reseed_prop_counter)
!= reseed_counter)
reseed_required = 1; reseed_required = 1;
} }
@@ -764,7 +757,8 @@ int RAND_DRBG_set_callbacks(RAND_DRBG *drbg,
RAND_DRBG_get_nonce_fn get_nonce, RAND_DRBG_get_nonce_fn get_nonce,
RAND_DRBG_cleanup_nonce_fn cleanup_nonce) RAND_DRBG_cleanup_nonce_fn cleanup_nonce)
{ {
if (drbg->state != DRBG_UNINITIALISED) if (drbg->state != DRBG_UNINITIALISED
|| drbg->parent != NULL)
return 0; return 0;
drbg->get_entropy = get_entropy; drbg->get_entropy = get_entropy;
drbg->cleanup_entropy = cleanup_entropy; drbg->cleanup_entropy = cleanup_entropy;
@@ -942,7 +936,7 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent, int drbg_type)
goto err; goto err;
/* enable seed propagation */ /* enable seed propagation */
drbg->reseed_prop_counter = 1; tsan_store(&drbg->reseed_prop_counter, 1);
/* /*
* Ignore instantiation error to support just-in-time instantiation. * Ignore instantiation error to support just-in-time instantiation.
@@ -1031,11 +1025,53 @@ static int drbg_bytes(unsigned char *out, int count)
return ret; return ret;
} }
/*
* Calculates the minimum length of a full entropy buffer
* which is necessary to seed (i.e. instantiate) the DRBG
* successfully.
*
* NOTE: There is a copy of this function in drbgtest.c.
* If you change anything here, you need to update
* the copy accordingly.
*/
static size_t rand_drbg_seedlen(RAND_DRBG *drbg)
{
/*
* If no os entropy source is available then RAND_seed(buffer, bufsize)
* is expected to succeed if and only if the buffer length satisfies
* the following requirements, which follow from the calculations
* in RAND_DRBG_instantiate().
*/
size_t min_entropy = drbg->strength;
size_t min_entropylen = drbg->min_entropylen;
/*
* Extra entropy for the random nonce in the absence of a
* get_nonce callback, see comment in RAND_DRBG_instantiate().
*/
if (drbg->min_noncelen > 0 && drbg->get_nonce == NULL) {
min_entropy += drbg->strength / 2;
min_entropylen += drbg->min_noncelen;
}
/*
* Convert entropy requirement from bits to bytes
* (dividing by 8 without rounding upwards, because
* all entropy requirements are divisible by 8).
*/
min_entropy >>= 3;
/* Return a value that satisfies both requirements */
return min_entropy > min_entropylen ? min_entropy : min_entropylen;
}
/* Implements the default OpenSSL RAND_add() method */ /* Implements the default OpenSSL RAND_add() method */
static int drbg_add(const void *buf, int num, double randomness) static int drbg_add(const void *buf, int num, double randomness)
{ {
int ret = 0; int ret = 0;
RAND_DRBG *drbg = RAND_DRBG_get0_master(); RAND_DRBG *drbg = RAND_DRBG_get0_master();
size_t buflen;
size_t seedlen;
if (drbg == NULL) if (drbg == NULL)
return 0; return 0;
@@ -1043,7 +1079,37 @@ static int drbg_add(const void *buf, int num, double randomness)
if (num < 0 || randomness < 0.0) if (num < 0 || randomness < 0.0)
return 0; return 0;
if (randomness > (double)RAND_DRBG_STRENGTH) { rand_drbg_lock(drbg);
seedlen = rand_drbg_seedlen(drbg);
buflen = (size_t)num;
if (buflen < seedlen || randomness < (double) seedlen) {
#if defined(OPENSSL_RAND_SEED_NONE)
/*
* If no os entropy source is available, a reseeding will fail
* inevitably. So we use a trick to mix the buffer contents into
* the DRBG state without forcing a reseeding: we generate a
* dummy random byte, using the buffer content as additional data.
* Note: This won't work with RAND_DRBG_FLAG_CTR_NO_DF.
*/
unsigned char dummy[1];
ret = RAND_DRBG_generate(drbg, dummy, sizeof(dummy), 0, buf, buflen);
rand_drbg_unlock(drbg);
return ret;
#else
/*
* If an os entropy source is avaible then we declare the buffer content
* as additional data by setting randomness to zero and trigger a regular
* reseeding.
*/
randomness = 0.0;
#endif
}
if (randomness > (double)seedlen) {
/* /*
* The purpose of this check is to bound |randomness| by a * The purpose of this check is to bound |randomness| by a
* relatively small value in order to prevent an integer * relatively small value in order to prevent an integer
@@ -1052,13 +1118,10 @@ static int drbg_add(const void *buf, int num, double randomness)
* not bits, so this value corresponds to eight times the * not bits, so this value corresponds to eight times the
* security strength. * security strength.
*/ */
randomness = (double)RAND_DRBG_STRENGTH; randomness = (double)seedlen;
} }
rand_drbg_lock(drbg); ret = rand_drbg_restart(drbg, buf, buflen, (size_t)(8 * randomness));
ret = rand_drbg_restart(drbg, buf,
(size_t)(unsigned int)num,
(size_t)(8*randomness));
rand_drbg_unlock(drbg); rand_drbg_unlock(drbg);
return ret; return ret;
+5 -1
View File
@@ -16,6 +16,9 @@
# include <openssl/hmac.h> # include <openssl/hmac.h>
# include <openssl/ec.h> # include <openssl/ec.h>
# include <openssl/rand_drbg.h> # include <openssl/rand_drbg.h>
# include "internal/tsan_assist.h"
# include "internal/numbers.h"
/* How many times to read the TSC as a randomness source. */ /* How many times to read the TSC as a randomness source. */
# define TSC_READ_COUNT 4 # define TSC_READ_COUNT 4
@@ -256,7 +259,8 @@ struct rand_drbg_st {
* is added by RAND_add() or RAND_seed() will have an immediate effect on * is added by RAND_add() or RAND_seed() will have an immediate effect on
* the output of RAND_bytes() resp. RAND_priv_bytes(). * the output of RAND_bytes() resp. RAND_priv_bytes().
*/ */
unsigned int reseed_prop_counter; TSAN_QUALIFIER unsigned int reseed_prop_counter;
unsigned int reseed_next_counter;
size_t seedlen; size_t seedlen;
DRBG_STATUS state; DRBG_STATUS state;
+8 -3
View File
@@ -151,6 +151,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
pool->entropy_requested = entropy; pool->entropy_requested = entropy;
} else { } else {
pool = rand_pool_new(entropy, min_len, max_len); pool = rand_pool_new(entropy, min_len, max_len);
if (pool == NULL)
return 0;
} }
if (drbg->parent) { if (drbg->parent) {
@@ -172,6 +174,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
prediction_resistance, prediction_resistance,
NULL, 0) != 0) NULL, 0) != 0)
bytes = bytes_needed; bytes = bytes_needed;
drbg->reseed_next_counter
= tsan_load(&drbg->parent->reseed_prop_counter);
rand_drbg_unlock(drbg->parent); rand_drbg_unlock(drbg->parent);
rand_pool_add_end(pool, bytes, 8 * bytes); rand_pool_add_end(pool, bytes, 8 * bytes);
@@ -200,7 +204,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
} }
err: err:
rand_pool_free(pool); if (drbg->pool == NULL)
rand_pool_free(pool);
return ret; return ret;
} }
@@ -213,8 +218,6 @@ void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
{ {
if (drbg->pool == NULL) if (drbg->pool == NULL)
OPENSSL_secure_clear_free(out, outlen); OPENSSL_secure_clear_free(out, outlen);
else
drbg->pool = NULL;
} }
@@ -539,6 +542,8 @@ unsigned char *rand_pool_detach(RAND_POOL *pool)
{ {
unsigned char *ret = pool->buffer; unsigned char *ret = pool->buffer;
pool->buffer = NULL; pool->buffer = NULL;
pool->len = 0;
pool->entropy = 0;
return ret; return ret;
} }
+29 -9
View File
@@ -16,6 +16,7 @@
#include <openssl/crypto.h> #include <openssl/crypto.h>
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/rand_drbg.h>
#include <openssl/buffer.h> #include <openssl/buffer.h>
#ifdef OPENSSL_SYS_VMS #ifdef OPENSSL_SYS_VMS
@@ -48,7 +49,7 @@
# define S_ISREG(m) ((m) & S_IFREG) # define S_ISREG(m) ((m) & S_IFREG)
# endif # endif
#define RAND_FILE_SIZE 1024 #define RAND_BUF_SIZE 1024
#define RFILE ".rnd" #define RFILE ".rnd"
#ifdef OPENSSL_SYS_VMS #ifdef OPENSSL_SYS_VMS
@@ -74,7 +75,16 @@ static __FILE_ptr32 (*const vms_fopen)(const char *, const char *, ...) =
*/ */
int RAND_load_file(const char *file, long bytes) int RAND_load_file(const char *file, long bytes)
{ {
unsigned char buf[RAND_FILE_SIZE]; /*
* The load buffer size exceeds the chunk size by the comfortable amount
* of 'RAND_DRBG_STRENGTH' bytes (not bits!). This is done on purpose
* to avoid calling RAND_add() with a small final chunk. Instead, such
* a small final chunk will be added together with the previous chunk
* (unless it's the only one).
*/
#define RAND_LOAD_BUF_SIZE (RAND_BUF_SIZE + RAND_DRBG_STRENGTH)
unsigned char buf[RAND_LOAD_BUF_SIZE];
#ifndef OPENSSL_NO_POSIX_IO #ifndef OPENSSL_NO_POSIX_IO
struct stat sb; struct stat sb;
#endif #endif
@@ -98,8 +108,12 @@ int RAND_load_file(const char *file, long bytes)
return -1; return -1;
} }
if (!S_ISREG(sb.st_mode) && bytes < 0) if (bytes < 0) {
bytes = 256; if (S_ISREG(sb.st_mode))
bytes = sb.st_size;
else
bytes = RAND_DRBG_STRENGTH;
}
#endif #endif
/* /*
* On VMS, setbuf() will only take 32-bit pointers, and a compilation * On VMS, setbuf() will only take 32-bit pointers, and a compilation
@@ -124,9 +138,9 @@ int RAND_load_file(const char *file, long bytes)
for ( ; ; ) { for ( ; ; ) {
if (bytes > 0) if (bytes > 0)
n = (bytes < RAND_FILE_SIZE) ? (int)bytes : RAND_FILE_SIZE; n = (bytes <= RAND_LOAD_BUF_SIZE) ? (int)bytes : RAND_BUF_SIZE;
else else
n = RAND_FILE_SIZE; n = RAND_LOAD_BUF_SIZE;
i = fread(buf, 1, n, in); i = fread(buf, 1, n, in);
#ifdef EINTR #ifdef EINTR
if (ferror(in) && errno == EINTR){ if (ferror(in) && errno == EINTR){
@@ -148,12 +162,18 @@ int RAND_load_file(const char *file, long bytes)
OPENSSL_cleanse(buf, sizeof(buf)); OPENSSL_cleanse(buf, sizeof(buf));
fclose(in); fclose(in);
if (!RAND_status()) {
RANDerr(RAND_F_RAND_LOAD_FILE, RAND_R_RESEED_ERROR);
ERR_add_error_data(2, "Filename=", file);
return -1;
}
return ret; return ret;
} }
int RAND_write_file(const char *file) int RAND_write_file(const char *file)
{ {
unsigned char buf[RAND_FILE_SIZE]; unsigned char buf[RAND_BUF_SIZE];
int ret = -1; int ret = -1;
FILE *out = NULL; FILE *out = NULL;
#ifndef OPENSSL_NO_POSIX_IO #ifndef OPENSSL_NO_POSIX_IO
@@ -222,9 +242,9 @@ int RAND_write_file(const char *file)
chmod(file, 0600); chmod(file, 0600);
#endif #endif
ret = fwrite(buf, 1, RAND_FILE_SIZE, out); ret = fwrite(buf, 1, RAND_BUF_SIZE, out);
fclose(out); fclose(out);
OPENSSL_cleanse(buf, RAND_FILE_SIZE); OPENSSL_cleanse(buf, RAND_BUF_SIZE);
return ret; return ret;
} }
+128 -1
View File
@@ -163,6 +163,133 @@ void *RSA_get_ex_data(const RSA *r, int idx)
return CRYPTO_get_ex_data(&r->ex_data, idx); return CRYPTO_get_ex_data(&r->ex_data, idx);
} }
/*
* Define a scaling constant for our fixed point arithmetic.
* This value must be a power of two because the base two logarithm code
* makes this assumption. The exponent must also be a multiple of three so
* that the scale factor has an exact cube root. Finally, the scale factor
* should not be so large that a multiplication of two scaled numbers
* overflows a 64 bit unsigned integer.
*/
static const unsigned int scale = 1 << 18;
static const unsigned int cbrt_scale = 1 << (2 * 18 / 3);
/* Define some constants, none exceed 32 bits */
static const unsigned int log_2 = 0x02c5c8; /* scale * log(2) */
static const unsigned int log_e = 0x05c551; /* scale * log2(M_E) */
static const unsigned int c1_923 = 0x07b126; /* scale * 1.923 */
static const unsigned int c4_690 = 0x12c28f; /* scale * 4.690 */
/*
* Multiply two scale integers together and rescale the result.
*/
static ossl_inline uint64_t mul2(uint64_t a, uint64_t b)
{
return a * b / scale;
}
/*
* Calculate the cube root of a 64 bit scaled integer.
* Although the cube root of a 64 bit number does fit into a 32 bit unsigned
* integer, this is not guaranteed after scaling, so this function has a
* 64 bit return. This uses the shifting nth root algorithm with some
* algebraic simplifications.
*/
static uint64_t icbrt64(uint64_t x)
{
uint64_t r = 0;
uint64_t b;
int s;
for (s = 63; s >= 0; s -= 3) {
r <<= 1;
b = 3 * r * (r + 1) + 1;
if ((x >> s) >= b) {
x -= b << s;
r++;
}
}
return r * cbrt_scale;
}
/*
* Calculate the natural logarithm of a 64 bit scaled integer.
* This is done by calculating a base two logarithm and scaling.
* The maximum logarithm (base 2) is 64 and this reduces base e, so
* a 32 bit result should not overflow. The argument passed must be
* greater than unity so we don't need to handle negative results.
*/
static uint32_t ilog_e(uint64_t v)
{
uint32_t i, r = 0;
/*
* Scale down the value into the range 1 .. 2.
*
* If fractional numbers need to be processed, another loop needs
* to go here that checks v < scale and if so multiplies it by 2 and
* reduces r by scale. This also means making r signed.
*/
while (v >= 2 * scale) {
v >>= 1;
r += scale;
}
for (i = scale / 2; i != 0; i /= 2) {
v = mul2(v, v);
if (v >= 2 * scale) {
v >>= 1;
r += i;
}
}
r = (r * (uint64_t)scale) / log_e;
return r;
}
/*
* NIST SP 800-56B rev 2 Appendix D: Maximum Security Strength Estimates for IFC
* Modulus Lengths.
*
* E = \frac{1.923 \sqrt[3]{nBits \cdot log_e(2)}
* \cdot(log_e(nBits \cdot log_e(2))^{2/3} - 4.69}{log_e(2)}
* The two cube roots are merged together here.
*/
static uint16_t rsa_compute_security_bits(int n)
{
uint64_t x;
uint32_t lx;
uint16_t y;
/* Look for common values as listed in SP 800-56B rev 2 Appendix D */
switch (n) {
case 2048:
return 112;
case 3072:
return 128;
case 4096:
return 152;
case 6144:
return 176;
case 8192:
return 200;
}
/*
* The first incorrect result (i.e. not accurate or off by one low) occurs
* for n = 699668. The true value here is 1200. Instead of using this n
* as the check threshold, the smallest n such that the correct result is
* 1200 is used instead.
*/
if (n >= 687737)
return 1200;
if (n < 8)
return 0;
x = n * (uint64_t)log_2;
lx = ilog_e(x);
y = (uint16_t)((mul2(c1_923, icbrt64(mul2(mul2(x, lx), lx))) - c4_690)
/ log_2);
return (y + 4) & ~7;
}
int RSA_security_bits(const RSA *rsa) int RSA_security_bits(const RSA *rsa)
{ {
int bits = BN_num_bits(rsa->n); int bits = BN_num_bits(rsa->n);
@@ -174,7 +301,7 @@ int RSA_security_bits(const RSA *rsa)
if (ex_primes <= 0 || (ex_primes + 2) > rsa_multip_cap(bits)) if (ex_primes <= 0 || (ex_primes + 2) > rsa_multip_cap(bits))
return 0; return 0;
} }
return BN_security_bits(bits, -1); return rsa_compute_security_bits(bits);
} }
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
+20 -3
View File
@@ -49,6 +49,9 @@ struct OPENSSL_s390xcap_st {
extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
/* Max number of 64-bit words currently returned by STFLE */
# define S390X_STFLE_MAX 3
/* convert facility bit number or function code to bit mask */ /* convert facility bit number or function code to bit mask */
# define S390X_CAPBIT(i) (1ULL << (63 - (i) % 64)) # define S390X_CAPBIT(i) (1ULL << (63 - (i) % 64))
@@ -68,9 +71,15 @@ extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
# define S390X_KMA 0xb0 # define S390X_KMA 0xb0
/* Facility Bit Numbers */ /* Facility Bit Numbers */
# define S390X_VX 129 # define S390X_MSA 17 /* message-security-assist */
# define S390X_VXD 134 # define S390X_STCKF 25 /* store-clock-fast */
# define S390X_VXE 135 # define S390X_MSA5 57 /* message-security-assist-ext. 5 */
# define S390X_MSA3 76 /* message-security-assist-ext. 3 */
# define S390X_MSA4 77 /* message-security-assist-ext. 4 */
# define S390X_VX 129 /* vector */
# define S390X_VXD 134 /* vector packed decimal */
# define S390X_VXE 135 /* vector enhancements 1 */
# define S390X_MSA8 146 /* message-security-assist-ext. 8 */
/* Function Codes */ /* Function Codes */
@@ -78,6 +87,9 @@ extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
# define S390X_QUERY 0 # define S390X_QUERY 0
/* kimd/klmd */ /* kimd/klmd */
# define S390X_SHA_1 1
# define S390X_SHA_256 2
# define S390X_SHA_512 3
# define S390X_SHA3_224 32 # define S390X_SHA3_224 32
# define S390X_SHA3_256 33 # define S390X_SHA3_256 33
# define S390X_SHA3_384 34 # define S390X_SHA3_384 34
@@ -91,7 +103,12 @@ extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
# define S390X_AES_192 19 # define S390X_AES_192 19
# define S390X_AES_256 20 # define S390X_AES_256 20
/* km */
# define S390X_XTS_AES_128 50
# define S390X_XTS_AES_256 52
/* prno */ /* prno */
# define S390X_SHA_512_DRNG 3
# define S390X_TRNG 114 # define S390X_TRNG 114
/* Register 0 Flags */ /* Register 0 Flags */
+515
View File
@@ -13,15 +13,51 @@
#include <setjmp.h> #include <setjmp.h>
#include <signal.h> #include <signal.h>
#include "internal/cryptlib.h" #include "internal/cryptlib.h"
#include "internal/ctype.h"
#include "s390x_arch.h" #include "s390x_arch.h"
#define LEN 128
#define STR_(S) #S
#define STR(S) STR_(S)
#define TOK_FUNC(NAME) \
(sscanf(tok_begin, \
" " STR(NAME) " : %" STR(LEN) "[^:] : " \
"%" STR(LEN) "s %" STR(LEN) "s ", \
tok[0], tok[1], tok[2]) == 2) { \
\
off = (tok[0][0] == '~') ? 1 : 0; \
if (sscanf(tok[0] + off, "%llx", &cap->NAME[0]) != 1) \
goto ret; \
if (off) \
cap->NAME[0] = ~cap->NAME[0]; \
\
off = (tok[1][0] == '~') ? 1 : 0; \
if (sscanf(tok[1] + off, "%llx", &cap->NAME[1]) != 1) \
goto ret; \
if (off) \
cap->NAME[1] = ~cap->NAME[1]; \
}
#define TOK_CPU(NAME) \
(sscanf(tok_begin, \
" %" STR(LEN) "s %" STR(LEN) "s ", \
tok[0], tok[1]) == 1 \
&& !strcmp(tok[0], #NAME)) { \
memcpy(cap, &NAME, sizeof(*cap)); \
}
static sigjmp_buf ill_jmp; static sigjmp_buf ill_jmp;
static void ill_handler(int sig) static void ill_handler(int sig)
{ {
siglongjmp(ill_jmp, sig); siglongjmp(ill_jmp, sig);
} }
static const char *env;
static int parse_env(struct OPENSSL_s390xcap_st *cap);
void OPENSSL_s390x_facilities(void); void OPENSSL_s390x_facilities(void);
void OPENSSL_s390x_functions(void);
void OPENSSL_vx_probe(void); void OPENSSL_vx_probe(void);
struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
@@ -30,6 +66,7 @@ void OPENSSL_cpuid_setup(void)
{ {
sigset_t oset; sigset_t oset;
struct sigaction ill_act, oact; struct sigaction ill_act, oact;
struct OPENSSL_s390xcap_st cap;
if (OPENSSL_s390xcap_P.stfle[0]) if (OPENSSL_s390xcap_P.stfle[0])
return; return;
@@ -37,6 +74,12 @@ void OPENSSL_cpuid_setup(void)
/* set a bit that will not be tested later */ /* set a bit that will not be tested later */
OPENSSL_s390xcap_P.stfle[0] |= S390X_CAPBIT(0); OPENSSL_s390xcap_P.stfle[0] |= S390X_CAPBIT(0);
env = getenv("OPENSSL_s390xcap");
if (env != NULL) {
if (!parse_env(&cap))
env = NULL;
}
memset(&ill_act, 0, sizeof(ill_act)); memset(&ill_act, 0, sizeof(ill_act));
ill_act.sa_handler = ill_handler; ill_act.sa_handler = ill_handler;
sigfillset(&ill_act.sa_mask); sigfillset(&ill_act.sa_mask);
@@ -51,6 +94,12 @@ void OPENSSL_cpuid_setup(void)
if (sigsetjmp(ill_jmp, 1) == 0) if (sigsetjmp(ill_jmp, 1) == 0)
OPENSSL_s390x_facilities(); OPENSSL_s390x_facilities();
if (env != NULL) {
OPENSSL_s390xcap_P.stfle[0] &= cap.stfle[0];
OPENSSL_s390xcap_P.stfle[1] &= cap.stfle[1];
OPENSSL_s390xcap_P.stfle[2] &= cap.stfle[2];
}
/* protection against disabled vector facility */ /* protection against disabled vector facility */
if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX)) if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX))
&& (sigsetjmp(ill_jmp, 1) == 0)) { && (sigsetjmp(ill_jmp, 1) == 0)) {
@@ -64,4 +113,470 @@ void OPENSSL_cpuid_setup(void)
sigaction(SIGFPE, &oact, NULL); sigaction(SIGFPE, &oact, NULL);
sigaction(SIGILL, &oact, NULL); sigaction(SIGILL, &oact, NULL);
sigprocmask(SIG_SETMASK, &oset, NULL); sigprocmask(SIG_SETMASK, &oset, NULL);
OPENSSL_s390x_functions();
if (env != NULL) {
OPENSSL_s390xcap_P.kimd[0] &= cap.kimd[0];
OPENSSL_s390xcap_P.kimd[1] &= cap.kimd[1];
OPENSSL_s390xcap_P.klmd[0] &= cap.klmd[0];
OPENSSL_s390xcap_P.klmd[1] &= cap.klmd[1];
OPENSSL_s390xcap_P.km[0] &= cap.km[0];
OPENSSL_s390xcap_P.km[1] &= cap.km[1];
OPENSSL_s390xcap_P.kmc[0] &= cap.kmc[0];
OPENSSL_s390xcap_P.kmc[1] &= cap.kmc[1];
OPENSSL_s390xcap_P.kmac[0] &= cap.kmac[0];
OPENSSL_s390xcap_P.kmac[1] &= cap.kmac[1];
OPENSSL_s390xcap_P.kmctr[0] &= cap.kmctr[0];
OPENSSL_s390xcap_P.kmctr[1] &= cap.kmctr[1];
OPENSSL_s390xcap_P.kmo[0] &= cap.kmo[0];
OPENSSL_s390xcap_P.kmo[1] &= cap.kmo[1];
OPENSSL_s390xcap_P.kmf[0] &= cap.kmf[0];
OPENSSL_s390xcap_P.kmf[1] &= cap.kmf[1];
OPENSSL_s390xcap_P.prno[0] &= cap.prno[0];
OPENSSL_s390xcap_P.prno[1] &= cap.prno[1];
OPENSSL_s390xcap_P.kma[0] &= cap.kma[0];
OPENSSL_s390xcap_P.kma[1] &= cap.kma[1];
}
}
static int parse_env(struct OPENSSL_s390xcap_st *cap)
{
/*-
* CPU model data
* (only the STFLE- and QUERY-bits relevant to libcrypto are set)
*/
/*-
* z900 (2000) - z/Architecture POP SA22-7832-00
* Facility detection would fail on real hw (no STFLE).
*/
static const struct OPENSSL_s390xcap_st z900 = {
.stfle = {0ULL, 0ULL, 0ULL, 0ULL},
.kimd = {0ULL, 0ULL},
.klmd = {0ULL, 0ULL},
.km = {0ULL, 0ULL},
.kmc = {0ULL, 0ULL},
.kmac = {0ULL, 0ULL},
.kmctr = {0ULL, 0ULL},
.kmo = {0ULL, 0ULL},
.kmf = {0ULL, 0ULL},
.prno = {0ULL, 0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* z990 (2003) - z/Architecture POP SA22-7832-02
* Implements MSA. Facility detection would fail on real hw (no STFLE).
*/
static const struct OPENSSL_s390xcap_st z990 = {
.stfle = {S390X_CAPBIT(S390X_MSA),
0ULL, 0ULL, 0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1),
0ULL},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY),
0ULL},
.kmctr = {0ULL, 0ULL},
.kmo = {0ULL, 0ULL},
.kmf = {0ULL, 0ULL},
.prno = {0ULL, 0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* z9 (2005) - z/Architecture POP SA22-7832-04
* Implements MSA and MSA1.
*/
static const struct OPENSSL_s390xcap_st z9 = {
.stfle = {S390X_CAPBIT(S390X_MSA)
| S390X_CAPBIT(S390X_STCKF),
0ULL, 0ULL, 0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256),
0ULL},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY),
0ULL},
.kmctr = {0ULL, 0ULL},
.kmo = {0ULL, 0ULL},
.kmf = {0ULL, 0ULL},
.prno = {0ULL, 0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* z10 (2008) - z/Architecture POP SA22-7832-06
* Implements MSA and MSA1-2.
*/
static const struct OPENSSL_s390xcap_st z10 = {
.stfle = {S390X_CAPBIT(S390X_MSA)
| S390X_CAPBIT(S390X_STCKF),
0ULL, 0ULL, 0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
0ULL},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY),
0ULL},
.kmctr = {0ULL, 0ULL},
.kmo = {0ULL, 0ULL},
.kmf = {0ULL, 0ULL},
.prno = {0ULL, 0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* z196 (2010) - z/Architecture POP SA22-7832-08
* Implements MSA and MSA1-4.
*/
static const struct OPENSSL_s390xcap_st z196 = {
.stfle = {S390X_CAPBIT(S390X_MSA)
| S390X_CAPBIT(S390X_STCKF),
S390X_CAPBIT(S390X_MSA3)
| S390X_CAPBIT(S390X_MSA4),
0ULL, 0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
S390X_CAPBIT(S390X_GHASH)},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256)
| S390X_CAPBIT(S390X_XTS_AES_128)
| S390X_CAPBIT(S390X_XTS_AES_256),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmctr = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmo = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmf = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.prno = {0ULL, 0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* zEC12 (2012) - z/Architecture POP SA22-7832-09
* Implements MSA and MSA1-4.
*/
static const struct OPENSSL_s390xcap_st zEC12 = {
.stfle = {S390X_CAPBIT(S390X_MSA)
| S390X_CAPBIT(S390X_STCKF),
S390X_CAPBIT(S390X_MSA3)
| S390X_CAPBIT(S390X_MSA4),
0ULL, 0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
S390X_CAPBIT(S390X_GHASH)},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256)
| S390X_CAPBIT(S390X_XTS_AES_128)
| S390X_CAPBIT(S390X_XTS_AES_256),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmctr = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmo = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmf = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.prno = {0ULL, 0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* z13 (2015) - z/Architecture POP SA22-7832-10
* Implements MSA and MSA1-5.
*/
static const struct OPENSSL_s390xcap_st z13 = {
.stfle = {S390X_CAPBIT(S390X_MSA)
| S390X_CAPBIT(S390X_STCKF)
| S390X_CAPBIT(S390X_MSA5),
S390X_CAPBIT(S390X_MSA3)
| S390X_CAPBIT(S390X_MSA4),
S390X_CAPBIT(S390X_VX),
0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
S390X_CAPBIT(S390X_GHASH)},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256)
| S390X_CAPBIT(S390X_XTS_AES_128)
| S390X_CAPBIT(S390X_XTS_AES_256),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmctr = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmo = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmf = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.prno = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_512_DRNG),
0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* z14 (2017) - z/Architecture POP SA22-7832-11
* Implements MSA and MSA1-8.
*/
static const struct OPENSSL_s390xcap_st z14 = {
.stfle = {S390X_CAPBIT(S390X_MSA)
| S390X_CAPBIT(S390X_STCKF)
| S390X_CAPBIT(S390X_MSA5),
S390X_CAPBIT(S390X_MSA3)
| S390X_CAPBIT(S390X_MSA4),
S390X_CAPBIT(S390X_VX)
| S390X_CAPBIT(S390X_VXD)
| S390X_CAPBIT(S390X_VXE)
| S390X_CAPBIT(S390X_MSA8),
0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512)
| S390X_CAPBIT(S390X_SHA3_224)
| S390X_CAPBIT(S390X_SHA3_256)
| S390X_CAPBIT(S390X_SHA3_384)
| S390X_CAPBIT(S390X_SHA3_512)
| S390X_CAPBIT(S390X_SHAKE_128)
| S390X_CAPBIT(S390X_SHAKE_256),
S390X_CAPBIT(S390X_GHASH)},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512)
| S390X_CAPBIT(S390X_SHA3_224)
| S390X_CAPBIT(S390X_SHA3_256)
| S390X_CAPBIT(S390X_SHA3_384)
| S390X_CAPBIT(S390X_SHA3_512)
| S390X_CAPBIT(S390X_SHAKE_128)
| S390X_CAPBIT(S390X_SHAKE_256),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256)
| S390X_CAPBIT(S390X_XTS_AES_128)
| S390X_CAPBIT(S390X_XTS_AES_256),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmctr = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmo = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmf = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.prno = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_512_DRNG),
S390X_CAPBIT(S390X_TRNG)},
.kma = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
};
char *tok_begin, *tok_end, *buff, tok[S390X_STFLE_MAX][LEN + 1];
int rc, off, i, n;
buff = malloc(strlen(env) + 1);
if (buff == NULL)
return 0;
rc = 0;
memset(cap, ~0, sizeof(*cap));
strcpy(buff, env);
tok_begin = buff + strspn(buff, ";");
strtok(tok_begin, ";");
tok_end = strtok(NULL, ";");
while (tok_begin != NULL) {
/* stfle token */
if ((n = sscanf(tok_begin,
" stfle : %" STR(LEN) "[^:] : "
"%" STR(LEN) "[^:] : %" STR(LEN) "s ",
tok[0], tok[1], tok[2]))) {
for (i = 0; i < n; i++) {
off = (tok[i][0] == '~') ? 1 : 0;
if (sscanf(tok[i] + off, "%llx", &cap->stfle[i]) != 1)
goto ret;
if (off)
cap->stfle[i] = ~cap->stfle[i];
}
}
/* query function tokens */
else if TOK_FUNC(kimd)
else if TOK_FUNC(klmd)
else if TOK_FUNC(km)
else if TOK_FUNC(kmc)
else if TOK_FUNC(kmac)
else if TOK_FUNC(kmctr)
else if TOK_FUNC(kmo)
else if TOK_FUNC(kmf)
else if TOK_FUNC(prno)
else if TOK_FUNC(kma)
/* CPU model tokens */
else if TOK_CPU(z900)
else if TOK_CPU(z990)
else if TOK_CPU(z9)
else if TOK_CPU(z10)
else if TOK_CPU(z196)
else if TOK_CPU(zEC12)
else if TOK_CPU(z13)
else if TOK_CPU(z14)
/* whitespace(ignored) or invalid tokens */
else {
while (*tok_begin != '\0') {
if (!ossl_isspace(*tok_begin))
goto ret;
tok_begin++;
}
}
tok_begin = tok_end;
tok_end = strtok(NULL, ";");
}
rc = 1;
ret:
free(buff);
return rc;
} }
+21 -10
View File
@@ -38,7 +38,26 @@ OPENSSL_s390x_facilities:
stg %r0,S390X_STFLE+8(%r4) # wipe capability vectors stg %r0,S390X_STFLE+8(%r4) # wipe capability vectors
stg %r0,S390X_STFLE+16(%r4) stg %r0,S390X_STFLE+16(%r4)
stg %r0,S390X_STFLE+24(%r4) stg %r0,S390X_STFLE+24(%r4)
stg %r0,S390X_KIMD(%r4)
.long 0xb2b04000 # stfle 0(%r4)
brc 8,.Ldone
lghi %r0,1
.long 0xb2b04000 # stfle 0(%r4)
brc 8,.Ldone
lghi %r0,2
.long 0xb2b04000 # stfle 0(%r4)
.Ldone:
br $ra
.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities
.globl OPENSSL_s390x_functions
.type OPENSSL_s390x_functions,\@function
.align 16
OPENSSL_s390x_functions:
lghi %r0,0
larl %r4,OPENSSL_s390xcap_P
stg %r0,S390X_KIMD(%r4) # wipe capability vectors
stg %r0,S390X_KIMD+8(%r4) stg %r0,S390X_KIMD+8(%r4)
stg %r0,S390X_KLMD(%r4) stg %r0,S390X_KLMD(%r4)
stg %r0,S390X_KLMD+8(%r4) stg %r0,S390X_KLMD+8(%r4)
@@ -59,14 +78,6 @@ OPENSSL_s390x_facilities:
stg %r0,S390X_KMA(%r4) stg %r0,S390X_KMA(%r4)
stg %r0,S390X_KMA+8(%r4) stg %r0,S390X_KMA+8(%r4)
.long 0xb2b04000 # stfle 0(%r4)
brc 8,.Ldone
lghi %r0,1
.long 0xb2b04000 # stfle 0(%r4)
brc 8,.Ldone
lghi %r0,2
.long 0xb2b04000 # stfle 0(%r4)
.Ldone:
lmg %r2,%r3,S390X_STFLE(%r4) lmg %r2,%r3,S390X_STFLE(%r4)
tmhl %r2,0x4000 # check for message-security-assist tmhl %r2,0x4000 # check for message-security-assist
jz .Lret jz .Lret
@@ -123,7 +134,7 @@ OPENSSL_s390x_facilities:
.Lret: .Lret:
br $ra br $ra
.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities .size OPENSSL_s390x_functions,.-OPENSSL_s390x_functions
.globl OPENSSL_rdtsc .globl OPENSSL_rdtsc
.type OPENSSL_rdtsc,\@function .type OPENSSL_rdtsc,\@function
+71 -79
View File
@@ -533,30 +533,28 @@ my @A = map([ "v".$_.".16b", "v".($_+1).".16b", "v".($_+2).".16b",
(0, 5, 10, 15, 20)); (0, 5, 10, 15, 20));
my @C = map("v$_.16b", (25..31)); my @C = map("v$_.16b", (25..31));
my @D = @C[4,5,6,2,3];
$code.=<<___; $code.=<<___;
.type KeccakF1600_ce,%function .type KeccakF1600_ce,%function
.align 5 .align 5
KeccakF1600_ce: KeccakF1600_ce:
mov x9,#12 mov x9,#24
adr x10,iotas adr x10,iotas
b .Loop_ce b .Loop_ce
.align 4 .align 4
.Loop_ce: .Loop_ce:
___
for($i=0; $i<2; $i++) {
$code.=<<___;
////////////////////////////////////////////////// Theta ////////////////////////////////////////////////// Theta
eor3 $C[0],$A[0][0],$A[1][0],$A[2][0] eor3 $C[0],$A[4][0],$A[3][0],$A[2][0]
eor3 $C[1],$A[0][1],$A[1][1],$A[2][1] eor3 $C[1],$A[4][1],$A[3][1],$A[2][1]
eor3 $C[2],$A[0][2],$A[1][2],$A[2][2] eor3 $C[2],$A[4][2],$A[3][2],$A[2][2]
eor3 $C[3],$A[0][3],$A[1][3],$A[2][3] eor3 $C[3],$A[4][3],$A[3][3],$A[2][3]
eor3 $C[4],$A[0][4],$A[1][4],$A[2][4] eor3 $C[4],$A[4][4],$A[3][4],$A[2][4]
eor3 $C[0],$C[0], $A[3][0],$A[4][0] eor3 $C[0],$C[0], $A[1][0],$A[0][0]
eor3 $C[1],$C[1], $A[3][1],$A[4][1] eor3 $C[1],$C[1], $A[1][1],$A[0][1]
eor3 $C[2],$C[2], $A[3][2],$A[4][2] eor3 $C[2],$C[2], $A[1][2],$A[0][2]
eor3 $C[3],$C[3], $A[3][3],$A[4][3] eor3 $C[3],$C[3], $A[1][3],$A[0][3]
eor3 $C[4],$C[4], $A[3][4],$A[4][4] eor3 $C[4],$C[4], $A[1][4],$A[0][4]
rax1 $C[5],$C[0],$C[2] // D[1] rax1 $C[5],$C[0],$C[2] // D[1]
rax1 $C[6],$C[1],$C[3] // D[2] rax1 $C[6],$C[1],$C[3] // D[2]
@@ -565,81 +563,75 @@ $code.=<<___;
rax1 $C[4],$C[4],$C[1] // D[0] rax1 $C[4],$C[4],$C[1] // D[0]
////////////////////////////////////////////////// Theta+Rho+Pi ////////////////////////////////////////////////// Theta+Rho+Pi
xar $C[0], $A[1][1],$C[5],#64-$rhotates[1][1] // C[0]=A[0][1] xar $C[0], $A[0][1],$D[1],#64-$rhotates[0][1] // C[0]=A[2][0]
xar $A[1][1],$A[1][4],$C[3],#64-$rhotates[1][4]
xar $A[1][4],$A[4][2],$C[6],#64-$rhotates[4][2]
xar $A[4][2],$A[2][4],$C[3],#64-$rhotates[2][4]
xar $A[2][4],$A[4][0],$C[4],#64-$rhotates[4][0]
xar $A[4][0],$A[0][2],$C[6],#64-$rhotates[0][2] xar $A[0][1],$A[1][1],$D[1],#64-$rhotates[1][1]
xar $A[1][1],$A[1][4],$D[4],#64-$rhotates[1][4]
xar $A[1][4],$A[4][2],$D[2],#64-$rhotates[4][2]
xar $A[4][2],$A[2][4],$D[4],#64-$rhotates[2][4]
xar $A[2][4],$A[4][0],$D[0],#64-$rhotates[4][0]
xar $A[0][2],$A[2][2],$C[6],#64-$rhotates[2][2] xar $C[1], $A[0][2],$D[2],#64-$rhotates[0][2] // C[1]=A[4][0]
xar $A[2][2],$A[2][3],$C[2],#64-$rhotates[2][3]
xar $A[2][3],$A[3][4],$C[3],#64-$rhotates[3][4]
xar $A[3][4],$A[4][3],$C[2],#64-$rhotates[4][3]
xar $A[4][3],$A[3][0],$C[4],#64-$rhotates[3][0]
xar $A[3][0],$A[0][4],$C[3],#64-$rhotates[0][4] xar $A[0][2],$A[2][2],$D[2],#64-$rhotates[2][2]
xar $A[2][2],$A[2][3],$D[3],#64-$rhotates[2][3]
xar $A[2][3],$A[3][4],$D[4],#64-$rhotates[3][4]
xar $A[3][4],$A[4][3],$D[3],#64-$rhotates[4][3]
xar $A[4][3],$A[3][0],$D[0],#64-$rhotates[3][0]
eor $A[0][0],$A[0][0],$C[4] xar $A[3][0],$A[0][4],$D[4],#64-$rhotates[0][4]
ldr x11,[x10],#8
xar $C[1], $A[3][3],$C[2],#64-$rhotates[3][3] // C[1]=A[0][3] xar $D[4], $A[4][4],$D[4],#64-$rhotates[4][4] // D[4]=A[0][4]
xar $A[3][3],$A[3][2],$C[6],#64-$rhotates[3][2] xar $A[4][4],$A[4][1],$D[1],#64-$rhotates[4][1]
xar $A[3][2],$A[2][1],$C[5],#64-$rhotates[2][1] xar $A[1][3],$A[1][3],$D[3],#64-$rhotates[1][3] // A[1][3]=A[4][1]
xar $A[2][1],$A[1][2],$C[6],#64-$rhotates[1][2] xar $A[0][4],$A[3][1],$D[1],#64-$rhotates[3][1] // A[0][4]=A[1][3]
xar $A[1][2],$A[2][0],$C[4],#64-$rhotates[2][0] xar $A[3][1],$A[1][0],$D[0],#64-$rhotates[1][0]
xar $A[2][0],$A[0][1],$C[5],#64-$rhotates[0][1] // * xar $A[1][0],$A[0][3],$D[3],#64-$rhotates[0][3]
xar $A[0][4],$A[4][4],$C[3],#64-$rhotates[4][4] eor $A[0][0],$A[0][0],$D[0]
xar $A[4][4],$A[4][1],$C[5],#64-$rhotates[4][1]
xar $A[4][1],$A[1][3],$C[2],#64-$rhotates[1][3]
xar $A[1][3],$A[3][1],$C[5],#64-$rhotates[3][1]
xar $A[3][1],$A[1][0],$C[4],#64-$rhotates[1][0]
xar $C[2], $A[0][3],$C[2],#64-$rhotates[0][3] // C[2]=A[1][0] xar $D[3], $A[3][3],$D[3],#64-$rhotates[3][3] // D[3]=A[0][3]
xar $A[0][3],$A[3][2],$D[2],#64-$rhotates[3][2] // A[0][3]=A[3][3]
xar $D[1], $A[2][1],$D[1],#64-$rhotates[2][1] // D[1]=A[3][2]
xar $D[2], $A[1][2],$D[2],#64-$rhotates[1][2] // D[2]=A[2][1]
xar $D[0], $A[2][0],$D[0],#64-$rhotates[2][0] // D[0]=A[1][2]
////////////////////////////////////////////////// Chi+Iota ////////////////////////////////////////////////// Chi+Iota
dup $C[6],x11 // borrow C[6] bcax $A[4][0],$C[1], $A[4][2],$A[1][3] // A[1][3]=A[4][1]
bcax $C[3], $A[0][0],$A[0][2],$C[0] // * bcax $A[4][1],$A[1][3],$A[4][3],$A[4][2] // A[1][3]=A[4][1]
bcax $A[0][1],$C[0], $C[1], $A[0][2] // *
bcax $A[0][2],$A[0][2],$A[0][4],$C[1]
bcax $A[0][3],$C[1], $A[0][0],$A[0][4]
bcax $A[0][4],$A[0][4],$C[0], $A[0][0]
bcax $A[1][0],$C[2], $A[1][2],$A[1][1] // *
bcax $C[0], $A[1][1],$A[1][3],$A[1][2] // *
bcax $A[1][2],$A[1][2],$A[1][4],$A[1][3]
bcax $A[1][3],$A[1][3],$C[2], $A[1][4]
bcax $A[1][4],$A[1][4],$A[1][1],$C[2]
eor $A[0][0],$C[3],$C[6] // Iota
bcax $C[1], $A[2][0],$A[2][2],$A[2][1] // *
bcax $C[2], $A[2][1],$A[2][3],$A[2][2] // *
bcax $A[2][2],$A[2][2],$A[2][4],$A[2][3]
bcax $A[2][3],$A[2][3],$A[2][0],$A[2][4]
bcax $A[2][4],$A[2][4],$A[2][1],$A[2][0]
bcax $C[3], $A[3][0],$A[3][2],$A[3][1] // *
bcax $C[4], $A[3][1],$A[3][3],$A[3][2] // *
bcax $A[3][2],$A[3][2],$A[3][4],$A[3][3]
bcax $A[3][3],$A[3][3],$A[3][0],$A[3][4]
bcax $A[3][4],$A[3][4],$A[3][1],$A[3][0]
bcax $C[5], $A[4][0],$A[4][2],$A[4][1] // *
bcax $C[6], $A[4][1],$A[4][3],$A[4][2] // *
bcax $A[4][2],$A[4][2],$A[4][4],$A[4][3] bcax $A[4][2],$A[4][2],$A[4][4],$A[4][3]
bcax $A[4][3],$A[4][3],$A[4][0],$A[4][4] bcax $A[4][3],$A[4][3],$C[1], $A[4][4]
bcax $A[4][4],$A[4][4],$A[4][1],$A[4][0] bcax $A[4][4],$A[4][4],$A[1][3],$C[1] // A[1][3]=A[4][1]
___
( $A[1][1], $C[0]) = ( $C[0], $A[1][1]); ld1r {$C[1]},[x10],#8
($A[2][0],$A[2][1], $C[1],$C[2]) = ($C[1],$C[2], $A[2][0],$A[2][1]);
($A[3][0],$A[3][1], $C[3],$C[4]) = ($C[3],$C[4], $A[3][0],$A[3][1]); bcax $A[3][2],$D[1], $A[3][4],$A[0][3] // A[0][3]=A[3][3]
($A[4][0],$A[4][1], $C[5],$C[6]) = ($C[5],$C[6], $A[4][0],$A[4][1]); bcax $A[3][3],$A[0][3],$A[3][0],$A[3][4] // A[0][3]=A[3][3]
} bcax $A[3][4],$A[3][4],$A[3][1],$A[3][0]
$code.=<<___; bcax $A[3][0],$A[3][0],$D[1], $A[3][1]
bcax $A[3][1],$A[3][1],$A[0][3],$D[1] // A[0][3]=A[3][3]
bcax $A[2][0],$C[0], $A[2][2],$D[2]
bcax $A[2][1],$D[2], $A[2][3],$A[2][2]
bcax $A[2][2],$A[2][2],$A[2][4],$A[2][3]
bcax $A[2][3],$A[2][3],$C[0], $A[2][4]
bcax $A[2][4],$A[2][4],$D[2], $C[0]
bcax $A[1][2],$D[0], $A[1][4],$A[0][4] // A[0][4]=A[1][3]
bcax $A[1][3],$A[0][4],$A[1][0],$A[1][4] // A[0][4]=A[1][3]
bcax $A[1][4],$A[1][4],$A[1][1],$A[1][0]
bcax $A[1][0],$A[1][0],$D[0], $A[1][1]
bcax $A[1][1],$A[1][1],$A[0][4],$D[0] // A[0][4]=A[1][3]
bcax $A[0][3],$D[3], $A[0][0],$D[4]
bcax $A[0][4],$D[4], $A[0][1],$A[0][0]
bcax $A[0][0],$A[0][0],$A[0][2],$A[0][1]
bcax $A[0][1],$A[0][1],$D[3], $A[0][2]
bcax $A[0][2],$A[0][2],$D[4], $D[3]
eor $A[0][0],$A[0][0],$C[1]
subs x9,x9,#1 subs x9,x9,#1
bne .Loop_ce bne .Loop_ce
@@ -857,7 +849,7 @@ foreach(split("\n",$code)) {
s/\`([^\`]*)\`/eval($1)/ge; s/\`([^\`]*)\`/eval($1)/ge;
m/\bdup\b/ and s/\.16b/.2d/g or m/\bld1r\b/ and s/\.16b/.2d/g or
s/\b(eor3|rax1|xar|bcax)\s+(v.*)/unsha3($1,$2)/ge; s/\b(eor3|rax1|xar|bcax)\s+(v.*)/unsha3($1,$2)/ge;
print $_,"\n"; print $_,"\n";
+1 -1
View File
@@ -1,5 +1,5 @@
LIBS=../../libcrypto LIBS=../../libcrypto
SOURCE[../../libcrypto]=\ SOURCE[../../libcrypto]=\
siphash.c \ siphash.c \
siphash_pmeth.c \ siphash_meth.c \
siphash_ameth.c siphash_ameth.c
+139
View File
@@ -0,0 +1,139 @@
/*
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 <stdarg.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include "internal/siphash.h"
#include "siphash_local.h"
#include "internal/evp_int.h"
/* local SIPHASH structure is actually a SIPHASH */
struct evp_mac_impl_st {
SIPHASH ctx;
};
static EVP_MAC_IMPL *siphash_new(void)
{
return OPENSSL_zalloc(sizeof(EVP_MAC_IMPL));
}
static void siphash_free(EVP_MAC_IMPL *sctx)
{
OPENSSL_free(sctx);
}
static int siphash_copy(EVP_MAC_IMPL *sdst, EVP_MAC_IMPL *ssrc)
{
*sdst = *ssrc;
return 1;
}
static size_t siphash_size(EVP_MAC_IMPL *sctx)
{
return SipHash_hash_size(&sctx->ctx);
}
static int siphash_init(EVP_MAC_IMPL *sctx)
{
/* Not much to do here, actual initialization happens through controls */
return 1;
}
static int siphash_update(EVP_MAC_IMPL *sctx, const unsigned char *data,
size_t datalen)
{
SipHash_Update(&sctx->ctx, data, datalen);
return 1;
}
static int siphash_final(EVP_MAC_IMPL *sctx, unsigned char *out)
{
size_t hlen = siphash_size(sctx);
return SipHash_Final(&sctx->ctx, out, hlen);
}
static int siphash_ctrl(EVP_MAC_IMPL *sctx, int cmd, va_list args)
{
switch (cmd) {
case EVP_MAC_CTRL_SET_SIZE:
{
size_t size = va_arg(args, size_t);
return SipHash_set_hash_size(&sctx->ctx, size);
}
break;
case EVP_MAC_CTRL_SET_KEY:
{
const unsigned char *key = va_arg(args, const unsigned char *);
size_t keylen = va_arg(args, size_t);
if (key == NULL || keylen != SIPHASH_KEY_SIZE)
return 0;
return SipHash_Init(&sctx->ctx, key, 0, 0);
}
break;
default:
return -2;
}
return 1;
}
static int siphash_ctrl_int(EVP_MAC_IMPL *sctx, int cmd, ...)
{
int rv;
va_list args;
va_start(args, cmd);
rv = siphash_ctrl(sctx, cmd, args);
va_end(args);
return rv;
}
static int siphash_ctrl_str_cb(void *ctx, int cmd, void *buf, size_t buflen)
{
return siphash_ctrl_int(ctx, cmd, buf, buflen);
}
static int siphash_ctrl_str(EVP_MAC_IMPL *ctx,
const char *type, const char *value)
{
if (value == NULL)
return 0;
if (strcmp(type, "digestsize") == 0) {
size_t hash_size = atoi(value);
return siphash_ctrl_int(ctx, EVP_MAC_CTRL_SET_SIZE, hash_size);
}
if (strcmp(type, "key") == 0)
return EVP_str2ctrl(siphash_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY,
value);
if (strcmp(type, "hexkey") == 0)
return EVP_hex2ctrl(siphash_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY,
value);
return -2;
}
const EVP_MAC siphash_meth = {
EVP_MAC_SIPHASH,
siphash_new,
siphash_copy,
siphash_free,
siphash_size,
siphash_init,
siphash_update,
siphash_final,
siphash_ctrl,
siphash_ctrl_str
};
-205
View File
@@ -1,205 +0,0 @@
/*
* Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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 <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include "internal/siphash.h"
#include "siphash_local.h"
#include "internal/evp_int.h"
/* SIPHASH pkey context structure */
typedef struct siphash_pkey_ctx_st {
ASN1_OCTET_STRING ktmp; /* Temp storage for key */
SIPHASH ctx;
} SIPHASH_PKEY_CTX;
static int pkey_siphash_init(EVP_PKEY_CTX *ctx)
{
SIPHASH_PKEY_CTX *pctx;
if ((pctx = OPENSSL_zalloc(sizeof(*pctx))) == NULL) {
CRYPTOerr(CRYPTO_F_PKEY_SIPHASH_INIT, ERR_R_MALLOC_FAILURE);
return 0;
}
pctx->ktmp.type = V_ASN1_OCTET_STRING;
EVP_PKEY_CTX_set_data(ctx, pctx);
EVP_PKEY_CTX_set0_keygen_info(ctx, NULL, 0);
return 1;
}
static void pkey_siphash_cleanup(EVP_PKEY_CTX *ctx)
{
SIPHASH_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx);
if (pctx != NULL) {
OPENSSL_clear_free(pctx->ktmp.data, pctx->ktmp.length);
OPENSSL_clear_free(pctx, sizeof(*pctx));
EVP_PKEY_CTX_set_data(ctx, NULL);
}
}
static int pkey_siphash_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
{
SIPHASH_PKEY_CTX *sctx, *dctx;
/* allocate memory for dst->data and a new SIPHASH_CTX in dst->data->ctx */
if (!pkey_siphash_init(dst))
return 0;
sctx = EVP_PKEY_CTX_get_data(src);
dctx = EVP_PKEY_CTX_get_data(dst);
if (ASN1_STRING_get0_data(&sctx->ktmp) != NULL &&
!ASN1_STRING_copy(&dctx->ktmp, &sctx->ktmp)) {
/* cleanup and free the SIPHASH_PKEY_CTX in dst->data */
pkey_siphash_cleanup(dst);
return 0;
}
memcpy(&dctx->ctx, &sctx->ctx, sizeof(SIPHASH));
return 1;
}
static int pkey_siphash_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
ASN1_OCTET_STRING *key;
SIPHASH_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx);
if (ASN1_STRING_get0_data(&pctx->ktmp) == NULL)
return 0;
key = ASN1_OCTET_STRING_dup(&pctx->ktmp);
if (key == NULL)
return 0;
return EVP_PKEY_assign_SIPHASH(pkey, key);
}
static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
SIPHASH_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
SipHash_Update(&pctx->ctx, data, count);
return 1;
}
static int siphash_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
{
SIPHASH_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx);
const unsigned char* key;
size_t len;
key = EVP_PKEY_get0_siphash(EVP_PKEY_CTX_get0_pkey(ctx), &len);
if (key == NULL || len != SIPHASH_KEY_SIZE)
return 0;
EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
EVP_MD_CTX_set_update_fn(mctx, int_update);
return SipHash_Init(&pctx->ctx, key, 0, 0);
}
static int siphash_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
EVP_MD_CTX *mctx)
{
SIPHASH_PKEY_CTX *pctx = ctx->data;
*siglen = SipHash_hash_size(&pctx->ctx);
if (sig != NULL)
return SipHash_Final(&pctx->ctx, sig, *siglen);
return 1;
}
static int pkey_siphash_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
SIPHASH_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx);
const unsigned char *key;
size_t len;
switch (type) {
case EVP_PKEY_CTRL_MD:
/* ignore */
break;
case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
return SipHash_set_hash_size(&pctx->ctx, p1);
case EVP_PKEY_CTRL_SET_MAC_KEY:
case EVP_PKEY_CTRL_DIGESTINIT:
if (type == EVP_PKEY_CTRL_SET_MAC_KEY) {
/* user explicitly setting the key */
key = p2;
len = p1;
} else {
/* user indirectly setting the key via EVP_DigestSignInit */
key = EVP_PKEY_get0_siphash(EVP_PKEY_CTX_get0_pkey(ctx), &len);
}
if (key == NULL || len != SIPHASH_KEY_SIZE ||
!ASN1_OCTET_STRING_set(&pctx->ktmp, key, len))
return 0;
/* use default rounds (2,4) */
return SipHash_Init(&pctx->ctx, ASN1_STRING_get0_data(&pctx->ktmp),
0, 0);
default:
return -2;
}
return 1;
}
static int pkey_siphash_ctrl_str(EVP_PKEY_CTX *ctx,
const char *type, const char *value)
{
if (value == NULL)
return 0;
if (strcmp(type, "digestsize") == 0) {
size_t hash_size = atoi(value);
return pkey_siphash_ctrl(ctx, EVP_PKEY_CTRL_SET_DIGEST_SIZE, hash_size,
NULL);
}
if (strcmp(type, "key") == 0)
return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
if (strcmp(type, "hexkey") == 0)
return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
return -2;
}
const EVP_PKEY_METHOD siphash_pkey_meth = {
EVP_PKEY_SIPHASH,
EVP_PKEY_FLAG_SIGCTX_CUSTOM, /* we don't deal with a separate MD */
pkey_siphash_init,
pkey_siphash_copy,
pkey_siphash_cleanup,
0, 0,
0,
pkey_siphash_keygen,
0, 0,
0, 0,
0, 0,
siphash_signctx_init,
siphash_signctx,
0, 0,
0, 0,
0, 0,
0, 0,
pkey_siphash_ctrl,
pkey_siphash_ctrl_str
};
+3 -2
View File
@@ -11,6 +11,7 @@
#include "internal/sm2.h" #include "internal/sm2.h"
#include "internal/sm2err.h" #include "internal/sm2err.h"
#include "internal/ec_int.h" /* ecdh_KDF_X9_63() */
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/bn.h> #include <openssl/bn.h>
@@ -203,7 +204,7 @@ int sm2_encrypt(const EC_KEY *key,
} }
/* X9.63 with no salt happens to match the KDF used in SM2 */ /* X9.63 with no salt happens to match the KDF used in SM2 */
if (!ECDH_KDF_X9_62(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, if (!ecdh_KDF_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0,
digest)) { digest)) {
SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EVP_LIB); SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EVP_LIB);
goto done; goto done;
@@ -344,7 +345,7 @@ int sm2_decrypt(const EC_KEY *key,
if (BN_bn2binpad(x2, x2y2, field_size) < 0 if (BN_bn2binpad(x2, x2y2, field_size) < 0
|| BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0 || BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0
|| !ECDH_KDF_X9_62(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, || !ecdh_KDF_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0,
digest)) { digest)) {
SM2err(SM2_F_SM2_DECRYPT, ERR_R_INTERNAL_ERROR); SM2err(SM2_F_SM2_DECRYPT, ERR_R_INTERNAL_ERROR);
goto done; goto done;
+5 -6
View File
@@ -517,15 +517,14 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
/* check_purpose() makes the callback as needed */ /* check_purpose() makes the callback as needed */
if (purpose > 0 && !check_purpose(ctx, x, purpose, i, must_be_ca)) if (purpose > 0 && !check_purpose(ctx, x, purpose, i, must_be_ca))
return 0; return 0;
/* Check pathlen if not self issued */ /* Check pathlen */
if ((i > 1) && !(x->ex_flags & EXFLAG_SI) if ((i > 1) && (x->ex_pathlen != -1)
&& (x->ex_pathlen != -1) && (plen > (x->ex_pathlen + proxy_path_length))) {
&& (plen > (x->ex_pathlen + proxy_path_length + 1))) {
if (!verify_cb_cert(ctx, x, i, X509_V_ERR_PATH_LENGTH_EXCEEDED)) if (!verify_cb_cert(ctx, x, i, X509_V_ERR_PATH_LENGTH_EXCEEDED))
return 0; return 0;
} }
/* Increment path length if not self issued */ /* Increment path length if not a self issued intermediate CA */
if (!(x->ex_flags & EXFLAG_SI)) if (i > 0 && (x->ex_flags & EXFLAG_SI) == 0)
plen++; plen++;
/* /*
* If this certificate is a proxy certificate, the next certificate * If this certificate is a proxy certificate, the next certificate
+24 -2
View File
@@ -14,6 +14,7 @@
#include <openssl/asn1t.h> #include <openssl/asn1t.h>
#include <openssl/conf.h> #include <openssl/conf.h>
#include <openssl/x509v3.h> #include <openssl/x509v3.h>
#include <openssl/bn.h>
#include "internal/x509_int.h" #include "internal/x509_int.h"
#include "ext_dat.h" #include "ext_dat.h"
@@ -435,6 +436,27 @@ int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc)
return X509_V_OK; return X509_V_OK;
} }
/*
* Return nonzero if the GeneralSubtree has valid 'minimum' field
* (must be absent or 0) and valid 'maximum' field (must be absent).
*/
static int nc_minmax_valid(GENERAL_SUBTREE *sub) {
BIGNUM *bn = NULL;
int ok = 1;
if (sub->maximum)
ok = 0;
if (sub->minimum) {
bn = ASN1_INTEGER_to_BN(sub->minimum, NULL);
if (bn == NULL || !BN_is_zero(bn))
ok = 0;
BN_free(bn);
}
return ok;
}
static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
{ {
GENERAL_SUBTREE *sub; GENERAL_SUBTREE *sub;
@@ -449,7 +471,7 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
if (gen->type != sub->base->type) if (gen->type != sub->base->type)
continue; continue;
if (sub->minimum || sub->maximum) if (!nc_minmax_valid(sub))
return X509_V_ERR_SUBTREE_MINMAX; return X509_V_ERR_SUBTREE_MINMAX;
/* If we already have a match don't bother trying any more */ /* If we already have a match don't bother trying any more */
if (match == 2) if (match == 2)
@@ -472,7 +494,7 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
if (gen->type != sub->base->type) if (gen->type != sub->base->type)
continue; continue;
if (sub->minimum || sub->maximum) if (!nc_minmax_valid(sub))
return X509_V_ERR_SUBTREE_MINMAX; return X509_V_ERR_SUBTREE_MINMAX;
r = nc_match_single(gen, sub->base); r = nc_match_single(gen, sub->base);
+342
View File
@@ -0,0 +1,342 @@
=pod
=head1 NAME
EVP_MAC, EVP_MAC_CTX, EVP_MAC_CTX_new, EVP_MAC_CTX_new_id, EVP_MAC_CTX_free,
EVP_MAC_CTX_copy, EVP_MAC_CTX_mac, EVP_MAC_size, EVP_MAC_init, EVP_MAC_update,
EVP_MAC_final, EVP_MAC_ctrl, EVP_MAC_vctrl, EVP_MAC_ctrl_str,
EVP_MAC_str2ctrl, EVP_MAC_hex2ctrl, EVP_MAC_nid, EVP_MAC_name,
EVP_get_macbyname, EVP_get_macbynid, EVP_get_macbyobj - EVP MAC routines
=head1 SYNOPSIS
#include <openssl/evp.h>
typedef struct evp_mac_st EVP_MAC;
typedef struct evp_mac_ctx_st EVP_MAC_CTX;
EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac);
EVP_MAC_CTX *EVP_MAC_CTX_new_id(int nid);
void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx);
int EVP_MAC_CTX_copy(EVP_MAC_CTX *dest, EVP_MAC_CTX *src);
const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx);
size_t EVP_MAC_size(EVP_MAC_CTX *ctx);
int EVP_MAC_init(EVP_MAC_CTX *ctx);
int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen);
int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *poutlen);
int EVP_MAC_ctrl(EVP_MAC_CTX *ctx, int cmd, ...);
int EVP_MAC_vctrl(EVP_MAC_CTX *ctx, int cmd, va_list args);
int EVP_MAC_ctrl_str(EVP_MAC_CTX *ctx, const char *type, const char *value);
int EVP_MAC_str2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value);
int EVP_MAC_hex2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value);
int EVP_MAC_nid(const EVP_MAC *mac);
const char *EVP_MAC_name(const EVP_MAC *mac);
const EVP_MAC *EVP_get_macbyname(const char *name);
const EVP_MAC *EVP_get_macbynid(int nid);
const EVP_MAC *EVP_get_macbyobj(const ASN1_OBJECT *o);
=head1 DESCRIPTION
These types and functions help the application to calculate MACs of
different types and with different underlying algorithms if there are
any.
MACs are a bit complex insofar that some of them use other algorithms
for actual computation. HMAC uses a digest, and CMAC uses a cipher.
Therefore, there are sometimes two contexts to keep track of, one for
the MAC algorithm itself and one for the underlying computation
algorithm if there is one.
To make things less ambiguous, this manual talks about a "context" or
"MAC context", which is to denote the MAC level context, and about a
"underlying context", or "computation context", which is to denote the
context for the underlying computation algorithm if there is one.
=head2 Types
B<EVP_MAC> is a type that holds the implementation of a MAC.
B<EVP_MAC_CTX> is a context type that holds internal MAC information
as well as a reference to a computation context, for those MACs that
rely on an underlying computation algorithm.
=head2 Context manipulation functions
EVP_MAC_CTX_new() creates a new context for the MAC type C<mac>.
EVP_MAC_CTX_new_id() creates a new context for the numerical MAC
identity <nid>.
The created context can then be used with most other functions
described here.
EVP_MAC_CTX_free() frees the contents of the context, including an
underlying context if there is one, as well as the context itself.
B<NULL> is a valid parameter, for which this function is a no-op.
EVP_MAC_CTX_copy() makes a deep copy of the C<src> context to the
C<dest> context.
The C<dest> context I<must> have been created before calling this
function.
EVP_MAC_CTX_mac() returns the B<EVP_MAC> associated with the context
C<ctx>.
=head2 Computing functions
EVP_MAC_init() sets up the underlying context with information given
through diverse controls.
This should be called before calling EVP_MAC_update() and
EVP_MAC_final().
EVP_MAC_reset() resets the computation for the given context.
This may not be supported by the MAC implementation.
EVP_MAC_update() adds C<datalen> bytes from C<data> to the MAC input.
EVP_MAC_final() does the final computation and stores the result in
the memory pointed at by C<out>, and sets its size in the B<size_t>
the C<poutlen> points at.
If C<out> is B<NULL>, then no computation is made.
To figure out what the output length will be and allocate space for it
dynamically, simply call with C<out> being B<NULL> and C<poutlen>
pointing at a valid location, then allocate space and make a second
call with C<out> pointing at the allocated space.
EVP_MAC_ctrl() is used to manipulate or get information on aspects of
the MAC which may vary depending on the MAC algorithm or its
implementation.
This includes the MAC key, and for MACs that use other algorithms to
do their computation, this is also the way to tell it which one to
use.
This functions takes variable arguments, the exact expected arguments
depend on C<cmd>.
EVP_MAC_ctrl() can be called both before and after EVP_MAC_init(), but
the effect will depend on what control is being use.
See </CONTROLS> below for a description of standard controls.
EVP_MAC_vctrl() is the variant of EVP_MAC_ctrl() that takes a
C<va_list> argument instead of variadic arguments.
EVP_MAC_ctrl_str() is an alternative to EVP_MAC_ctrl() to control the
MAC implementation as E<lt> C<type>, C<value> E<gt> pairs.
The MAC implementation documentation should specify what control type
strings are accepted.
EVP_MAC_str2ctrl() and EVP_MAC_hex2ctrl() are helper functions to
control the MAC implementation with raw strings or with strings
containing hexadecimal numbers.
The latter are decoded into bitstrings that are sent on to
EVP_MAC_ctrl().
=head2 Information functions
EVP_MAC_size() returns the MAC output size for the given context.
EVP_MAC_nid() returns the numeric identity of the given MAC implementation.
EVP_MAC_name() returns the name of the given MAC implementation.
=head2 Object database functions
EVP_get_macbyname() fetches a MAC implementation from the object
database by name.
EVP_get_macbynid() fetches a MAC implementation from the object
database by numeric identity.
EVP_get_macbyobj() fetches a MAC implementation from the object
database by ASN.1 OBJECT (i.e. an encoded OID).
=head1 CONTROLS
The standard controls are:
=over 4
=item B<EVP_MAC_CTRL_SET_KEY>
This control expects two arguments: C<unsigned char *key>, C<size_t keylen>
These will set the MAC key from the given string of the given length.
The string may be any bitstring, and can contain NUL bytes.
For MACs that use an underlying computation algorithm, the algorithm
I<must> be set first, see B<EVP_MAC_CTRL_SET_ENGINE>,
B<EVP_MAC_CTRL_SET_MD> and B<EVP_MAC_CTRL_SET_CIPHER> below.
=item B<EVP_MAC_CTRL_SET_FLAGS>
This control expects one arguments: C<unsigned long flags>
These will set the MAC flags to the given numbers.
Some MACs do not support this option.
=item B<EVP_MAC_CTRL_SET_ENGINE>
=item B<EVP_MAC_CTRL_SET_MD>
=item B<EVP_MAC_CTRL_SET_CIPHER>
For MAC implementations that use an underlying computation algorithm,
these controls set what the algorithm should be, and the engine that
implements the algorithm if needed.
B<EVP_MAC_CTRL_SET_ENGINE> takes one argument: C<ENGINE *>
B<EVP_MAC_CTRL_SET_MD> takes one argument: C<EVP_MD *>
B<EVP_MAC_CTRL_SET_CIPHER> takes one argument: C<EVP_CIPHER *>
=item B<EVP_MAC_CTRL_SET_SIZE>
For MAC implementations that support it, set the output size that
EVP_MAC_final() should produce.
The allowed sizes vary between MAC implementations.
=back
All these control should be used before the calls to any of
EVP_MAC_init(), EVP_MAC_update() and EVP_MAC_final() for a full
computation.
Anything else may give undefined results.
=head1 NOTES
EVP_get_macbynid(), EVP_get_macbyobj() and EVP_MAC_name() are
implemented as a macro.
=head1 RETURN VALUES
EVP_MAC_CTX_new() and EVP_MAC_CTX_new_id() return a pointer to a newly
created EVP_MAC_CTX, or NULL if allocation failed.
EVP_MAC_CTX_free() returns nothing at all.
EVP_MAC_CTX_copy(), EVP_MAC_reset(), EVP_MAC_init(), EVP_MAC_update(),
and EVP_MAC_final() return 1 on success, 0 on error.
EVP_MAC_ctrl(), EVP_MAC_ctrl_str(), EVP_MAC_str2ctrl() and
EVP_MAC_hex2ctrl() return 1 on success and 0 or a negative value on
error.
In particular, the value -2 indicates that the given control type
isn't supported by the MAC implementation.
EVP_MAC_size() returns the expected output size, or 0 if it isn't
set.
If it isn't set, a call to EVP_MAC_init() should get it set.
EVP_MAC_nid() returns the numeric identity for the given C<mac>.
EVP_MAC_name() returns the name for the given C<mac>, if it has been
added to the object database.
EVP_add_mac() returns 1 if the given C<mac> was successfully added to
the object database, otherwise 0.
EVP_get_macbyname(), EVP_get_macbynid() and EVP_get_macbyobj() return
the request MAC implementation, if it exists in the object database,
otherwise B<NULL>.
=head1 EXAMPLE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <openssl/evp.h>
#include <openssl/err.h>
int ctrl_ign_unsupported(EVP_MAC_CTX *ctx, int cmd, ...)
{
va_list args;
int rv;
va_start(args, cmd);
rv = EVP_MAC_vctrl(ctx, cmd, args);
va_end(args);
if (rv == -2)
rv = 1; /* Ignore unsupported, pretend it worked fine */
return rv;
}
int main() {
const EVP_MAC *mac =
EVP_get_macbyname(getenv("MY_MAC"));
const EVP_CIPHER *cipher =
EVP_get_cipherbyname(getenv("MY_MAC_CIPHER"));
const EVP_MD *digest =
EVP_get_digestbyname(getenv("MY_MAC_DIGEST"));
const char *key = getenv("MY_KEY");
EVP_MAC_CTX *ctx = NULL;
unsigned char buf[4096];
ssize_t read_l;
size_t final_l;
size_t i;
if (mac == NULL
|| key == NULL
|| (ctx = EVP_MAC_CTX_new(mac)) == NULL
|| (cipher != NULL
&& !ctrl_ign_unsupported(ctx, EVP_MAC_CTRL_SET_CIPHER, cipher))
|| (digest != NULL
&& !ctrl_ign_unsupported(ctx, EVP_MAC_CTRL_SET_MD, digest))
|| EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_KEY, key, strlen(key)) <= 0)
goto err;
if (!EVP_MAC_init(ctx))
goto err;
while ( (read_l = read(STDIN_FILENO, buf, sizeof(buf))) < 0) {
if (!EVP_MAC_update(ctx, buf, read_l))
goto err;
}
if (!EVP_MAC_final(ctx, buf, &final_l))
goto err;
printf("Result: ");
for (i = 0; i < final_l; i++)
printf("%02X", buf[i]);
printf("\n");
EVP_MAC_CTX_free(ctx);
exit(0);
err:
EVP_MAC_CTX_free(ctx);
fprintf(stderr, "Something went wrong\n");
ERR_print_errors_fp(stderr);
exit (1);
}
A run of this program, called with correct environment variables, can
look like this:
$ MY_MAC=cmac MY_KEY=secret0123456789 MY_MAC_CIPHER=aes-128-cbc \
LD_LIBRARY_PATH=. ./foo < foo.c
Result: ECCAAFF041B22A2299EB90A1B53B6D45
(in this example, that program was stored in F<foo.c> and compiled to
F<./foo>)
=head1 SEE ALSO
L<EVP_MAC_CMAC(7)>,
L<EVP_MAC_HMAC(7)>,
L<EVP_MAC_SIPHASH(7)>
=head1 COPYRIGHT
Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the OpenSSL license (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut
+263 -20
View File
@@ -4,20 +4,55 @@
EVP_PKEY_CTX_ctrl, EVP_PKEY_CTX_ctrl,
EVP_PKEY_CTX_ctrl_str, EVP_PKEY_CTX_ctrl_str,
EVP_PKEY_CTX_ctrl_uint64,
EVP_PKEY_CTX_md,
EVP_PKEY_CTX_set_signature_md, EVP_PKEY_CTX_set_signature_md,
EVP_PKEY_CTX_get_signature_md, EVP_PKEY_CTX_get_signature_md,
EVP_PKEY_CTX_set_mac_key, EVP_PKEY_CTX_set_mac_key,
EVP_PKEY_CTX_set_rsa_padding, EVP_PKEY_CTX_set_rsa_padding,
EVP_PKEY_CTX_get_rsa_padding,
EVP_PKEY_CTX_set_rsa_pss_saltlen, EVP_PKEY_CTX_set_rsa_pss_saltlen,
EVP_PKEY_CTX_get_rsa_pss_saltlen,
EVP_PKEY_CTX_set_rsa_keygen_bits, EVP_PKEY_CTX_set_rsa_keygen_bits,
EVP_PKEY_CTX_set_rsa_keygen_pubexp, EVP_PKEY_CTX_set_rsa_keygen_pubexp,
EVP_PKEY_CTX_set_rsa_keygen_primes,
EVP_PKEY_CTX_set_rsa_mgf1_md,
EVP_PKEY_CTX_get_rsa_mgf1_md,
EVP_PKEY_CTX_set_rsa_oaep_md,
EVP_PKEY_CTX_get_rsa_oaep_md,
EVP_PKEY_CTX_set0_rsa_oaep_label,
EVP_PKEY_CTX_get0_rsa_oaep_label,
EVP_PKEY_CTX_set_dsa_paramgen_bits, EVP_PKEY_CTX_set_dsa_paramgen_bits,
EVP_PKEY_CTX_set_dh_paramgen_prime_len, EVP_PKEY_CTX_set_dh_paramgen_prime_len,
EVP_PKEY_CTX_set_dh_paramgen_subprime_len,
EVP_PKEY_CTX_set_dh_paramgen_generator, EVP_PKEY_CTX_set_dh_paramgen_generator,
EVP_PKEY_CTX_set_dh_paramgen_type,
EVP_PKEY_CTX_set_dh_rfc5114,
EVP_PKEY_CTX_set_dhx_rfc5114,
EVP_PKEY_CTX_set_dh_pad, EVP_PKEY_CTX_set_dh_pad,
EVP_PKEY_CTX_set_dh_nid, EVP_PKEY_CTX_set_dh_nid,
EVP_PKEY_CTX_set_dh_kdf_type,
EVP_PKEY_CTX_get_dh_kdf_type,
EVP_PKEY_CTX_set0_dh_kdf_oid,
EVP_PKEY_CTX_get0_dh_kdf_oid,
EVP_PKEY_CTX_set_dh_kdf_md,
EVP_PKEY_CTX_get_dh_kdf_md,
EVP_PKEY_CTX_set_dh_kdf_outlen,
EVP_PKEY_CTX_get_dh_kdf_outlen,
EVP_PKEY_CTX_set0_dh_kdf_ukm,
EVP_PKEY_CTX_get0_dh_kdf_ukm,
EVP_PKEY_CTX_set_ec_paramgen_curve_nid, EVP_PKEY_CTX_set_ec_paramgen_curve_nid,
EVP_PKEY_CTX_set_ec_param_enc, EVP_PKEY_CTX_set_ec_param_enc,
EVP_PKEY_CTX_set_ecdh_cofactor_mode,
EVP_PKEY_CTX_get_ecdh_cofactor_mode,
EVP_PKEY_CTX_set_ecdh_kdf_type,
EVP_PKEY_CTX_get_ecdh_kdf_type,
EVP_PKEY_CTX_set_ecdh_kdf_md,
EVP_PKEY_CTX_get_ecdh_kdf_md,
EVP_PKEY_CTX_set_ecdh_kdf_outlen,
EVP_PKEY_CTX_get_ecdh_kdf_outlen,
EVP_PKEY_CTX_set0_ecdh_kdf_ukm,
EVP_PKEY_CTX_get0_ecdh_kdf_ukm,
EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
- algorithm specific control operations - algorithm specific control operations
@@ -27,9 +62,13 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
int cmd, int p1, void *p2); int cmd, int p1, void *p2);
int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
int cmd, uint64_t value);
int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
const char *value); const char *value);
int EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md);
int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd); int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd);
@@ -38,22 +77,58 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
#include <openssl/rsa.h> #include <openssl/rsa.h>
int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad); int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad);
int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad);
int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int len); int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int len);
int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *len);
int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int mbits); int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int mbits);
int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp); int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp);
int EVP_PKEY_CTX_set_rsa_keygen_primes(EVP_PKEY_CTX *ctx, int primes);
int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **md);
int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **md);
int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char *label, int len);
int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label);
#include <openssl/dsa.h> #include <openssl/dsa.h>
int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits); int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits);
#include <openssl/dh.h> #include <openssl/dh.h>
int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int len); int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int len);
int EVP_PKEY_CTX_set_dh_paramgen_subprime_len(EVP_PKEY_CTX *ctx, int len);
int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen); int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen);
int EVP_PKEY_CTX_set_dh_paramgen_type(EVP_PKEY_CTX *ctx, int type);
int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad); int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad);
int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid); int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid);
int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int rfc5114);
int EVP_PKEY_CTX_set_dhx_rfc5114(EVP_PKEY_CTX *ctx, int rfc5114);
int EVP_PKEY_CTX_set_dh_kdf_type(EVP_PKEY_CTX *ctx, int kdf);
int EVP_PKEY_CTX_get_dh_kdf_type(EVP_PKEY_CTX *ctx);
int EVP_PKEY_CTX_set0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT *oid);
int EVP_PKEY_CTX_get0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT **oid);
int EVP_PKEY_CTX_set_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
int EVP_PKEY_CTX_get_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **md);
int EVP_PKEY_CTX_set_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int len);
int EVP_PKEY_CTX_get_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int *len);
int EVP_PKEY_CTX_set0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len);
int EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **ukm);
#include <openssl/ec.h> #include <openssl/ec.h>
int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid); int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid);
int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc); int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc);
int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx, int cofactor_mode);
int EVP_PKEY_CTX_get_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx);
int EVP_PKEY_CTX_set_ecdh_kdf_type(EVP_PKEY_CTX *ctx, int kdf);
int EVP_PKEY_CTX_get_ecdh_kdf_type(EVP_PKEY_CTX *ctx);
int EVP_PKEY_CTX_set_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
int EVP_PKEY_CTX_get_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **md);
int EVP_PKEY_CTX_set_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int len);
int EVP_PKEY_CTX_get_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int *len);
int EVP_PKEY_CTX_set0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len);
int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **ukm);
int EVP_PKEY_CTX_set1_id(EVP_PKEY_CTX *ctx, void *id, size_t id_len); int EVP_PKEY_CTX_set1_id(EVP_PKEY_CTX *ctx, void *id, size_t id_len);
int EVP_PKEY_CTX_get1_id(EVP_PKEY_CTX *ctx, void *id); int EVP_PKEY_CTX_get1_id(EVP_PKEY_CTX *ctx, void *id);
@@ -73,6 +148,9 @@ and B<p2> is MAC key. This is used by Poly1305, SipHash, HMAC and CMAC.
Applications will not normally call EVP_PKEY_CTX_ctrl() directly but will Applications will not normally call EVP_PKEY_CTX_ctrl() directly but will
instead call one of the algorithm specific macros below. instead call one of the algorithm specific macros below.
The function EVP_PKEY_CTX_ctrl_uint64() is a wrapper that directly passes a
uint64 value as B<p2> to EVP_PKEY_CTX_ctrl().
The function EVP_PKEY_CTX_ctrl_str() allows an application to send an algorithm The function EVP_PKEY_CTX_ctrl_str() allows an application to send an algorithm
specific control operation to a context B<ctx> in string form. This is specific control operation to a context B<ctx> in string form. This is
intended to be used for options specified on the command line or in text intended to be used for options specified on the command line or in text
@@ -80,6 +158,9 @@ files. The commands supported are documented in the openssl utility
command line pages for the option B<-pkeyopt> which is supported by the command line pages for the option B<-pkeyopt> which is supported by the
B<pkeyutl>, B<genpkey> and B<req> commands. B<pkeyutl>, B<genpkey> and B<req> commands.
The function EVP_PKEY_CTX_md() sends a message digest control operation
to the context B<ctx>. The message digest is specified by its name B<md>.
All the remaining "functions" are implemented as macros. All the remaining "functions" are implemented as macros.
The EVP_PKEY_CTX_set_signature_md() macro sets the message digest type used The EVP_PKEY_CTX_set_signature_md() macro sets the message digest type used
@@ -99,12 +180,14 @@ L<EVP_PKEY_new_raw_private_key(3)> or similar functions instead of this macro.
The EVP_PKEY_CTX_set_mac_key() macro can be used with any of the algorithms The EVP_PKEY_CTX_set_mac_key() macro can be used with any of the algorithms
supported by the L<EVP_PKEY_new_raw_private_key(3)> function. supported by the L<EVP_PKEY_new_raw_private_key(3)> function.
The macro EVP_PKEY_CTX_set_rsa_padding() sets the RSA padding mode for B<ctx>. =head2 RSA parameters
The B<pad> parameter can take the value RSA_PKCS1_PADDING for PKCS#1 padding,
RSA_SSLV23_PADDING for SSLv23 padding, RSA_NO_PADDING for no padding, The EVP_PKEY_CTX_set_rsa_padding() macro sets the RSA padding mode for B<ctx>.
RSA_PKCS1_OAEP_PADDING for OAEP padding (encrypt and decrypt only), The B<pad> parameter can take the value B<RSA_PKCS1_PADDING> for PKCS#1
RSA_X931_PADDING for X9.31 padding (signature operations only) and padding, B<RSA_SSLV23_PADDING> for SSLv23 padding, B<RSA_NO_PADDING> for
RSA_PKCS1_PSS_PADDING (sign and verify only). no padding, B<RSA_PKCS1_OAEP_PADDING> for OAEP padding (encrypt and
decrypt only), B<RSA_X931_PADDING> for X9.31 padding (signature operations
only) and B<RSA_PKCS1_PSS_PADDING> (sign and verify only).
Two RSA padding modes behave differently if EVP_PKEY_CTX_set_signature_md() Two RSA padding modes behave differently if EVP_PKEY_CTX_set_signature_md()
is used. If this macro is called for PKCS#1 padding the plaintext buffer is is used. If this macro is called for PKCS#1 padding the plaintext buffer is
@@ -116,41 +199,154 @@ padding for RSA the algorithm identifier byte is added or checked and removed
if this control is called. If it is not called then the first byte of the plaintext if this control is called. If it is not called then the first byte of the plaintext
buffer is expected to be the algorithm identifier byte. buffer is expected to be the algorithm identifier byte.
The EVP_PKEY_CTX_get_rsa_padding() macro gets the RSA padding mode for B<ctx>.
The EVP_PKEY_CTX_set_rsa_pss_saltlen() macro sets the RSA PSS salt length to The EVP_PKEY_CTX_set_rsa_pss_saltlen() macro sets the RSA PSS salt length to
B<len> as its name implies it is only supported for PSS padding. Three special B<len>. As its name implies it is only supported for PSS padding. Three special
values are supported: RSA_PSS_SALTLEN_DIGEST sets the salt length to the values are supported: B<RSA_PSS_SALTLEN_DIGEST> sets the salt length to the
digest length, RSA_PSS_SALTLEN_MAX sets the salt length to the maximum digest length, B<RSA_PSS_SALTLEN_MAX> sets the salt length to the maximum
permissible value. When verifying RSA_PSS_SALTLEN_AUTO causes the salt length permissible value. When verifying B<RSA_PSS_SALTLEN_AUTO> causes the salt length
to be automatically determined based on the B<PSS> block structure. If this to be automatically determined based on the B<PSS> block structure. If this
macro is not called maximum salt length is used when signing and auto detection macro is not called maximum salt length is used when signing and auto detection
when verifying is used by default. when verifying is used by default.
The EVP_PKEY_CTX_get_rsa_pss_saltlen() macro gets the RSA PSS salt length
for B<ctx>. The padding mode must have been set to B<RSA_PKCS1_PSS_PADDING>.
The EVP_PKEY_CTX_set_rsa_keygen_bits() macro sets the RSA key length for The EVP_PKEY_CTX_set_rsa_keygen_bits() macro sets the RSA key length for
RSA key generation to B<bits>. If not specified 1024 bits is used. RSA key generation to B<bits>. If not specified 1024 bits is used.
The EVP_PKEY_CTX_set_rsa_keygen_pubexp() macro sets the public exponent value The EVP_PKEY_CTX_set_rsa_keygen_pubexp() macro sets the public exponent value
for RSA key generation to B<pubexp> currently it should be an odd integer. The for RSA key generation to B<pubexp>. Currently it should be an odd integer. The
B<pubexp> pointer is used internally by this function so it should not be B<pubexp> pointer is used internally by this function so it should not be
modified or free after the call. If this macro is not called then 65537 is used. modified or freed after the call. If not specified 65537 is used.
The macro EVP_PKEY_CTX_set_dsa_paramgen_bits() sets the number of bits used The EVP_PKEY_CTX_set_rsa_keygen_primes() macro sets the number of primes for
RSA key generation to B<primes>. If not specified 2 is used.
The EVP_PKEY_CTX_set_rsa_mgf1_md() macro sets the MGF1 digest for RSA padding
schemes to B<md>. If not explicitly set the signing digest is used. The
padding mode must have been set to B<RSA_PKCS1_OAEP_PADDING>
or B<RSA_PKCS1_PSS_PADDING>.
The EVP_PKEY_CTX_get_rsa_mgf1_md() macro gets the MGF1 digest for B<ctx>.
If not explicitly set the signing digest is used. The padding mode must have
been set to B<RSA_PKCS1_OAEP_PADDING> or B<RSA_PKCS1_PSS_PADDING>.
The EVP_PKEY_CTX_set_rsa_oaep_md() macro sets the message digest type used
in RSA OAEP to B<md>. The padding mode must have been set to
B<RSA_PKCS1_OAEP_PADDING>.
The EVP_PKEY_CTX_get_rsa_oaep_md() macro gets the message digest type used
in RSA OAEP to B<md>. The padding mode must have been set to
B<RSA_PKCS1_OAEP_PADDING>.
The EVP_PKEY_CTX_set0_rsa_oaep_label() macro sets the RSA OAEP label to
B<label> and its length to B<len>. If B<label> is NULL or B<len> is 0,
the label is cleared. The library takes ownership of the label so the
caller should not free the original memory pointed to by B<label>.
The padding mode must have been set to B<RSA_PKCS1_OAEP_PADDING>.
The EVP_PKEY_CTX_get0_rsa_oaep_label() macro gets the RSA OAEP label to
B<label>. The return value is the label length. The padding mode
must have been set to B<RSA_PKCS1_OAEP_PADDING>. The resulting pointer is owned
by the library and should not be freed by the caller.
=head2 DSA parameters
The EVP_PKEY_CTX_set_dsa_paramgen_bits() macro sets the number of bits used
for DSA parameter generation to B<bits>. If not specified 1024 is used. for DSA parameter generation to B<bits>. If not specified 1024 is used.
The macro EVP_PKEY_CTX_set_dh_paramgen_prime_len() sets the length of the DH =head2 DH parameters
The EVP_PKEY_CTX_set_dh_paramgen_prime_len() macro sets the length of the DH
prime parameter B<p> for DH parameter generation. If this macro is not called prime parameter B<p> for DH parameter generation. If this macro is not called
then 1024 is used. then 1024 is used. Only accepts lengths greater than or equal to 256.
The EVP_PKEY_CTX_set_dh_paramgen_subprime_len() macro sets the length of the DH
optional subprime parameter B<q> for DH parameter generation. The default is
256 if the prime is at least 2048 bits long or 160 otherwise. The DH
paramgen type must have been set to x9.42.
The EVP_PKEY_CTX_set_dh_paramgen_generator() macro sets DH generator to B<gen> The EVP_PKEY_CTX_set_dh_paramgen_generator() macro sets DH generator to B<gen>
for DH parameter generation. If not specified 2 is used. for DH parameter generation. If not specified 2 is used.
The EVP_PKEY_CTX_set_dh_paramgen_type() macro sets the key type for DH
parameter generation. Use 0 for PKCS#3 DH and 1 for X9.42 DH.
The default is 0.
The EVP_PKEY_CTX_set_dh_pad() macro sets the DH padding mode. If B<pad> is The EVP_PKEY_CTX_set_dh_pad() macro sets the DH padding mode. If B<pad> is
1 the shared secret is padded with zeroes up to the size of the DH prime B<p>. 1 the shared secret is padded with zeroes up to the size of the DH prime B<p>.
If B<pad> is zero (the default) then no padding is performed. If B<pad> is zero (the default) then no padding is performed.
EVP_PKEY_CTX_set_dh_nid() sets the DH parameters to values corresponding to EVP_PKEY_CTX_set_dh_nid() sets the DH parameters to values corresponding to
B<nid>. The B<nid> parameter must be B<NID_ffdhe2048>, B<NID_ffdhe3072>, B<nid> as defined in RFC7919. The B<nid> parameter must be B<NID_ffdhe2048>,
B<NID_ffdhe4096>, B<NID_ffdhe6144> or B<NID_ffdhe8192>. This macro can be B<NID_ffdhe3072>, B<NID_ffdhe4096>, B<NID_ffdhe6144>, B<NID_ffdhe8192>
called during parameter or key generation. or B<NID_undef> to clear the stored value. This macro can be called during
parameter or key generation.
The nid parameter and the rfc5114 parameter are mutually exclusive.
The EVP_PKEY_CTX_set_dh_rfc5114() and EVP_PKEY_CTX_set_dhx_rfc5114() macros are
synonymous. They set the DH parameters to the values defined in RFC5114. The
B<rfc5114> parameter must be 1, 2 or 3 corresponding to RFC5114 sections
2.1, 2.2 and 2.3. or 0 to clear the stored value. This macro can be called
during parameter generation. The B<ctx> must have a key type of
B<EVP_PKEY_DHX>.
The rfc5114 parameter and the nid parameter are mutually exclusive.
=head2 DH key derivation function parameters
Note that all of the following functions require that the B<ctx> parameter has
a private key type of B<EVP_PKEY_DHX>. When using key derivation, the output of
EVP_PKEY_derive() is the output of the KDF instead of the DH shared secret.
The KDF output is typically used as a Key Encryption Key (KEK) that in turn
encrypts a Content Encryption Key (CEK).
The EVP_PKEY_CTX_set_dh_kdf_type() macro sets the key derivation function type
to B<kdf> for DH key derivation. Possible values are B<EVP_PKEY_DH_KDF_NONE>
and B<EVP_PKEY_DH_KDF_X9_42> which uses the key derivation specified in RFC2631
(based on the keying algorithm described in X9.42). When using key derivation,
the B<kdf_oid>, B<kdf_md> and B<kdf_outlen> parameters must also be specified.
The EVP_PKEY_CTX_get_dh_kdf_type() macro gets the key derivation function type
for B<ctx> used for DH key derivation. Possible values are B<EVP_PKEY_DH_KDF_NONE>
and B<EVP_PKEY_DH_KDF_X9_42>.
The EVP_PKEY_CTX_set0_dh_kdf_oid() macro sets the key derivation function
object identifier to B<oid> for DH key derivation. This OID should identify
the algorithm to be used with the Content Encryption Key.
The library takes ownership of the object identifier so the caller should not
free the original memory pointed to by B<oid>.
The EVP_PKEY_CTX_get0_dh_kdf_oid() macro gets the key derivation function oid
for B<ctx> used for DH key derivation. The resulting pointer is owned by the
library and should not be freed by the caller.
The EVP_PKEY_CTX_set_dh_kdf_md() macro sets the key derivation function
message digest to B<md> for DH key derivation. Note that RFC2631 specifies
that this digest should be SHA1 but OpenSSL tolerates other digests.
The EVP_PKEY_CTX_get_dh_kdf_md() macro gets the key derivation function
message digest for B<ctx> used for DH key derivation.
The EVP_PKEY_CTX_set_dh_kdf_outlen() macro sets the key derivation function
output length to B<len> for DH key derivation.
The EVP_PKEY_CTX_get_dh_kdf_outlen() macro gets the key derivation function
output length for B<ctx> used for DH key derivation.
The EVP_PKEY_CTX_set0_dh_kdf_ukm() macro sets the user key material to
B<ukm> and its length to B<len> for DH key derivation. This parameter is optional
and corresponds to the partyAInfo field in RFC2631 terms. The specification
requires that it is 512 bits long but this is not enforced by OpenSSL.
The library takes ownership of the user key material so the caller should not
free the original memory pointed to by B<ukm>.
The EVP_PKEY_CTX_get0_dh_kdf_ukm() macro gets the user key material for B<ctx>.
The return value is the user key material length. The resulting pointer is owned
by the library and should not be freed by the caller.
=head2 EC parameters
The EVP_PKEY_CTX_set_ec_paramgen_curve_nid() sets the EC curve for EC parameter The EVP_PKEY_CTX_set_ec_paramgen_curve_nid() sets the EC curve for EC parameter
generation to B<nid>. For EC parameter generation this macro must be called generation to B<nid>. For EC parameter generation this macro must be called
@@ -158,7 +354,7 @@ or an error occurs because there is no default curve.
This function can also be called to set the curve explicitly when This function can also be called to set the curve explicitly when
generating an EC key. generating an EC key.
The EVP_PKEY_CTX_set_ec_param_enc() sets the EC parameter encoding to The EVP_PKEY_CTX_set_ec_param_enc() macro sets the EC parameter encoding to
B<param_enc> when generating EC parameters or an EC key. The encoding can be B<param_enc> when generating EC parameters or an EC key. The encoding can be
B<OPENSSL_EC_EXPLICIT_CURVE> for explicit parameters (the default in versions B<OPENSSL_EC_EXPLICIT_CURVE> for explicit parameters (the default in versions
of OpenSSL before 1.1.0) or B<OPENSSL_EC_NAMED_CURVE> to use named curve form. of OpenSSL before 1.1.0) or B<OPENSSL_EC_NAMED_CURVE> to use named curve form.
@@ -166,6 +362,53 @@ For maximum compatibility the named curve form should be used. Note: the
B<OPENSSL_EC_NAMED_CURVE> value was only added to OpenSSL 1.1.0; previous B<OPENSSL_EC_NAMED_CURVE> value was only added to OpenSSL 1.1.0; previous
versions should use 0 instead. versions should use 0 instead.
=head2 ECDH parameters
The EVP_PKEY_CTX_set_ecdh_cofactor_mode() macro sets the cofactor mode to
B<cofactor_mode> for ECDH key derivation. Possible values are 1 to enable
cofactor key derivation, 0 to disable it and -1 to clear the stored cofactor
mode and fallback to the private key cofactor mode.
The EVP_PKEY_CTX_get_ecdh_cofactor_mode() macro returns the cofactor mode for
B<ctx> used for ECDH key derivation. Possible values are 1 when cofactor key
derivation is enabled and 0 otherwise.
=head2 ECDH key derivation function parameters
The EVP_PKEY_CTX_set_ecdh_kdf_type() macro sets the key derivation function type
to B<kdf> for ECDH key derivation. Possible values are B<EVP_PKEY_ECDH_KDF_NONE>
and B<EVP_PKEY_ECDH_KDF_X9_63> which uses the key derivation specified in X9.63.
When using key derivation, the B<kdf_md> and B<kdf_outlen> parameters must
also be specified.
The EVP_PKEY_CTX_get_ecdh_kdf_type() macro returns the key derivation function
type for B<ctx> used for ECDH key derivation. Possible values are
B<EVP_PKEY_ECDH_KDF_NONE> and B<EVP_PKEY_ECDH_KDF_X9_63>.
The EVP_PKEY_CTX_set_ecdh_kdf_md() macro sets the key derivation function
message digest to B<md> for ECDH key derivation. Note that X9.63 specifies
that this digest should be SHA1 but OpenSSL tolerates other digests.
The EVP_PKEY_CTX_get_ecdh_kdf_md() macro gets the key derivation function
message digest for B<ctx> used for ECDH key derivation.
The EVP_PKEY_CTX_set_ecdh_kdf_outlen() macro sets the key derivation function
output length to B<len> for ECDH key derivation.
The EVP_PKEY_CTX_get_ecdh_kdf_outlen() macro gets the key derivation function
output length for B<ctx> used for ECDH key derivation.
The EVP_PKEY_CTX_set0_ecdh_kdf_ukm() macro sets the user key material to B<ukm>
for ECDH key derivation. This parameter is optional and corresponds to the
shared info in X9.63 terms. The library takes ownership of the user key material
so the caller should not free the original memory pointed to by B<ukm>.
The EVP_PKEY_CTX_get0_ecdh_kdf_ukm() macro gets the user key material for B<ctx>.
The return value is the user key material length. The resulting pointer is owned
by the library and should not be freed by the caller.
=head2 Other parameters
The EVP_PKEY_CTX_set1_id(), EVP_PKEY_CTX_get1_id() and EVP_PKEY_CTX_get1_id_len() The EVP_PKEY_CTX_set1_id(), EVP_PKEY_CTX_get1_id() and EVP_PKEY_CTX_get1_id_len()
macros are used to manipulate the special identifier field for specific signature macros are used to manipulate the special identifier field for specific signature
algorithms such as SM2. The EVP_PKEY_CTX_set1_id() sets an ID pointed by B<id> with algorithms such as SM2. The EVP_PKEY_CTX_set1_id() sets an ID pointed by B<id> with
@@ -191,7 +434,7 @@ L<EVP_PKEY_decrypt(3)>,
L<EVP_PKEY_sign(3)>, L<EVP_PKEY_sign(3)>,
L<EVP_PKEY_verify(3)>, L<EVP_PKEY_verify(3)>,
L<EVP_PKEY_verify_recover(3)>, L<EVP_PKEY_verify_recover(3)>,
L<EVP_PKEY_derive(3)> L<EVP_PKEY_derive(3)>,
L<EVP_PKEY_keygen(3)> L<EVP_PKEY_keygen(3)>
=head1 HISTORY =head1 HISTORY
@@ -32,7 +32,7 @@ The EVP_PKEY_CTX_set_rsa_pss_saltlen() macro is used to set the salt length.
If the key has usage restrictions then an error is returned if an attempt is If the key has usage restrictions then an error is returned if an attempt is
made to set the salt length below the minimum value. It is otherwise similar made to set the salt length below the minimum value. It is otherwise similar
to the B<RSA> operation except detection of the salt length (using to the B<RSA> operation except detection of the salt length (using
RSA_PSS_SALTLEN_AUTO is not supported for verification if the key has RSA_PSS_SALTLEN_AUTO) is not supported for verification if the key has
usage restrictions. usage restrictions.
The EVP_PKEY_CTX_set_signature_md() and EVP_PKEY_CTX_set_rsa_mgf1_md() macros The EVP_PKEY_CTX_set_signature_md() and EVP_PKEY_CTX_set_rsa_mgf1_md() macros
@@ -43,7 +43,7 @@ similar to the B<RSA> versions.
=head2 Key Generation =head2 Key Generation
As with RSA key generation the EVP_PKEY_CTX_set_rsa_rsa_keygen_bits() As with RSA key generation the EVP_PKEY_CTX_set_rsa_keygen_bits()
and EVP_PKEY_CTX_set_rsa_keygen_pubexp() macros are supported for RSA-PSS: and EVP_PKEY_CTX_set_rsa_keygen_pubexp() macros are supported for RSA-PSS:
they have exactly the same meaning as for the RSA algorithm. they have exactly the same meaning as for the RSA algorithm.
+22 -13
View File
@@ -6,8 +6,10 @@ EVP_PKEY_set1_RSA, EVP_PKEY_set1_DSA, EVP_PKEY_set1_DH, EVP_PKEY_set1_EC_KEY,
EVP_PKEY_get1_RSA, EVP_PKEY_get1_DSA, EVP_PKEY_get1_DH, EVP_PKEY_get1_EC_KEY, EVP_PKEY_get1_RSA, EVP_PKEY_get1_DSA, EVP_PKEY_get1_DH, EVP_PKEY_get1_EC_KEY,
EVP_PKEY_get0_RSA, EVP_PKEY_get0_DSA, EVP_PKEY_get0_DH, EVP_PKEY_get0_EC_KEY, EVP_PKEY_get0_RSA, EVP_PKEY_get0_DSA, EVP_PKEY_get0_DH, EVP_PKEY_get0_EC_KEY,
EVP_PKEY_assign_RSA, EVP_PKEY_assign_DSA, EVP_PKEY_assign_DH, EVP_PKEY_assign_RSA, EVP_PKEY_assign_DSA, EVP_PKEY_assign_DH,
EVP_PKEY_assign_EC_KEY, EVP_PKEY_get0_hmac, EVP_PKEY_type, EVP_PKEY_id, EVP_PKEY_assign_EC_KEY, EVP_PKEY_assign_POLY1305, EVP_PKEY_assign_SIPHASH,
EVP_PKEY_base_id, EVP_PKEY_set_alias_type, EVP_PKEY_set1_engine - EVP_PKEY assignment functions EVP_PKEY_get0_hmac, EVP_PKEY_get0_poly1305, EVP_PKEY_get0_siphash,
EVP_PKEY_type, EVP_PKEY_id, EVP_PKEY_base_id, EVP_PKEY_set_alias_type,
EVP_PKEY_set1_engine - EVP_PKEY assignment functions
=head1 SYNOPSIS =head1 SYNOPSIS
@@ -24,6 +26,8 @@ EVP_PKEY_base_id, EVP_PKEY_set_alias_type, EVP_PKEY_set1_engine - EVP_PKEY assig
EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len); const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len);
const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len);
const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len);
RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey);
DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey); DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey);
DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey); DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey);
@@ -33,6 +37,8 @@ EVP_PKEY_base_id, EVP_PKEY_set_alias_type, EVP_PKEY_set1_engine - EVP_PKEY assig
int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key); int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key);
int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key); int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key);
int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key);
int EVP_PKEY_assign_POLY1305(EVP_PKEY *pkey, ASN1_OCTET_STRING *key);
int EVP_PKEY_assign_SIPHASH(EVP_PKEY *pkey, ASN1_OCTET_STRING *key);
int EVP_PKEY_id(const EVP_PKEY *pkey); int EVP_PKEY_id(const EVP_PKEY *pkey);
int EVP_PKEY_base_id(const EVP_PKEY *pkey); int EVP_PKEY_base_id(const EVP_PKEY *pkey);
@@ -50,14 +56,15 @@ EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and
EVP_PKEY_get1_EC_KEY() return the referenced key in B<pkey> or EVP_PKEY_get1_EC_KEY() return the referenced key in B<pkey> or
B<NULL> if the key is not of the correct type. B<NULL> if the key is not of the correct type.
EVP_PKEY_get0_hmac(), EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(), EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305(), EVP_PKEY_get0_siphash(),
EVP_PKEY_get0_DH() and EVP_PKEY_get0_EC_KEY() also return the EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(), EVP_PKEY_get0_DH()
referenced key in B<pkey> or B<NULL> if the key is not of the and EVP_PKEY_get0_EC_KEY() also return the referenced key in B<pkey> or B<NULL>
correct type but the reference count of the returned key is if the key is not of the correct type but the reference count of the
B<not> incremented and so must not be freed up after use. returned key is B<not> incremented and so must not be freed up after use.
EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH() EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH(),
and EVP_PKEY_assign_EC_KEY() also set the referenced key to B<key> EVP_PKEY_assign_EC_KEY(), EVP_PKEY_assign_POLY1305() and
EVP_PKEY_assign_SIPHASH() also set the referenced key to B<key>
however these use the supplied B<key> internally and so B<key> however these use the supplied B<key> internally and so B<key>
will be freed when the parent B<pkey> is freed. will be freed when the parent B<pkey> is freed.
@@ -89,8 +96,9 @@ In accordance with the OpenSSL naming convention the key obtained
from or assigned to the B<pkey> using the B<1> functions must be from or assigned to the B<pkey> using the B<1> functions must be
freed as well as B<pkey>. freed as well as B<pkey>.
EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH() EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH(),
and EVP_PKEY_assign_EC_KEY() are implemented as macros. EVP_PKEY_assign_EC_KEY(), EVP_PKEY_assign_POLY1305()
and EVP_PKEY_assign_SIPHASH() are implemented as macros.
Most applications wishing to know a key type will simply call Most applications wishing to know a key type will simply call
EVP_PKEY_base_id() and will not care about the actual type: EVP_PKEY_base_id() and will not care about the actual type:
@@ -119,8 +127,9 @@ EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and
EVP_PKEY_get1_EC_KEY() return the referenced key or B<NULL> if EVP_PKEY_get1_EC_KEY() return the referenced key or B<NULL> if
an error occurred. an error occurred.
EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH() EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH(),
and EVP_PKEY_assign_EC_KEY() return 1 for success and 0 for failure. EVP_PKEY_assign_EC_KEY(), EVP_PKEY_assign_POLY1305()
and EVP_PKEY_assign_SIPHASH() return 1 for success and 0 for failure.
EVP_PKEY_base_id(), EVP_PKEY_id() and EVP_PKEY_type() return a key EVP_PKEY_base_id(), EVP_PKEY_id() and EVP_PKEY_type() return a key
type or B<NID_undef> (equivalently B<EVP_PKEY_NONE>) on error. type or B<NID_undef> (equivalently B<EVP_PKEY_NONE>) on error.
+6
View File
@@ -14,6 +14,9 @@ EVP_aes_256_cfb1,
EVP_aes_128_cfb8, EVP_aes_128_cfb8,
EVP_aes_192_cfb8, EVP_aes_192_cfb8,
EVP_aes_256_cfb8, EVP_aes_256_cfb8,
EVP_aes_128_cfb128,
EVP_aes_192_cfb128,
EVP_aes_256_cfb128,
EVP_aes_128_ctr, EVP_aes_128_ctr,
EVP_aes_192_ctr, EVP_aes_192_ctr,
EVP_aes_256_ctr, EVP_aes_256_ctr,
@@ -75,6 +78,9 @@ EVP_aes_256_cfb1(),
EVP_aes_128_cfb8(), EVP_aes_128_cfb8(),
EVP_aes_192_cfb8(), EVP_aes_192_cfb8(),
EVP_aes_256_cfb8(), EVP_aes_256_cfb8(),
EVP_aes_128_cfb128(),
EVP_aes_192_cfb128(),
EVP_aes_256_cfb128(),
EVP_aes_128_ctr(), EVP_aes_128_ctr(),
EVP_aes_192_ctr(), EVP_aes_192_ctr(),
EVP_aes_256_ctr(), EVP_aes_256_ctr(),
+6
View File
@@ -14,6 +14,9 @@ EVP_aria_256_cfb1,
EVP_aria_128_cfb8, EVP_aria_128_cfb8,
EVP_aria_192_cfb8, EVP_aria_192_cfb8,
EVP_aria_256_cfb8, EVP_aria_256_cfb8,
EVP_aria_128_cfb128,
EVP_aria_192_cfb128,
EVP_aria_256_cfb128,
EVP_aria_128_ctr, EVP_aria_128_ctr,
EVP_aria_192_ctr, EVP_aria_192_ctr,
EVP_aria_256_ctr, EVP_aria_256_ctr,
@@ -60,6 +63,9 @@ EVP_aria_256_cfb1(),
EVP_aria_128_cfb8(), EVP_aria_128_cfb8(),
EVP_aria_192_cfb8(), EVP_aria_192_cfb8(),
EVP_aria_256_cfb8(), EVP_aria_256_cfb8(),
EVP_aria_128_cfb128(),
EVP_aria_192_cfb128(),
EVP_aria_256_cfb128(),
EVP_aria_128_ctr(), EVP_aria_128_ctr(),
EVP_aria_192_ctr(), EVP_aria_192_ctr(),
EVP_aria_256_ctr(), EVP_aria_256_ctr(),
+3
View File
@@ -4,6 +4,7 @@
EVP_bf_cbc, EVP_bf_cbc,
EVP_bf_cfb, EVP_bf_cfb,
EVP_bf_cfb64,
EVP_bf_ecb, EVP_bf_ecb,
EVP_bf_ofb EVP_bf_ofb
- EVP Blowfish cipher - EVP Blowfish cipher
@@ -14,6 +15,7 @@ EVP_bf_ofb
const EVP_CIPHER *EVP_bf_cbc(void) const EVP_CIPHER *EVP_bf_cbc(void)
const EVP_CIPHER *EVP_bf_cfb(void) const EVP_CIPHER *EVP_bf_cfb(void)
const EVP_CIPHER *EVP_bf_cfb64(void)
const EVP_CIPHER *EVP_bf_ecb(void) const EVP_CIPHER *EVP_bf_ecb(void)
const EVP_CIPHER *EVP_bf_ofb(void) const EVP_CIPHER *EVP_bf_ofb(void)
@@ -27,6 +29,7 @@ This is a variable key length cipher.
=item EVP_bf_cbc(), =item EVP_bf_cbc(),
EVP_bf_cfb(), EVP_bf_cfb(),
EVP_bf_cfb64(),
EVP_bf_ecb(), EVP_bf_ecb(),
EVP_bf_ofb() EVP_bf_ofb()
+6
View File
@@ -14,6 +14,9 @@ EVP_camellia_256_cfb1,
EVP_camellia_128_cfb8, EVP_camellia_128_cfb8,
EVP_camellia_192_cfb8, EVP_camellia_192_cfb8,
EVP_camellia_256_cfb8, EVP_camellia_256_cfb8,
EVP_camellia_128_cfb128,
EVP_camellia_192_cfb128,
EVP_camellia_256_cfb128,
EVP_camellia_128_ctr, EVP_camellia_128_ctr,
EVP_camellia_192_ctr, EVP_camellia_192_ctr,
EVP_camellia_256_ctr, EVP_camellia_256_ctr,
@@ -54,6 +57,9 @@ EVP_camellia_256_cfb1(),
EVP_camellia_128_cfb8(), EVP_camellia_128_cfb8(),
EVP_camellia_192_cfb8(), EVP_camellia_192_cfb8(),
EVP_camellia_256_cfb8(), EVP_camellia_256_cfb8(),
EVP_camellia_128_cfb128(),
EVP_camellia_192_cfb128(),
EVP_camellia_256_cfb128(),
EVP_camellia_128_ctr(), EVP_camellia_128_ctr(),
EVP_camellia_192_ctr(), EVP_camellia_192_ctr(),
EVP_camellia_256_ctr(), EVP_camellia_256_ctr(),
+3
View File
@@ -4,6 +4,7 @@
EVP_cast5_cbc, EVP_cast5_cbc,
EVP_cast5_cfb, EVP_cast5_cfb,
EVP_cast5_cfb64,
EVP_cast5_ecb, EVP_cast5_ecb,
EVP_cast5_ofb EVP_cast5_ofb
- EVP CAST cipher - EVP CAST cipher
@@ -14,6 +15,7 @@ EVP_cast5_ofb
const EVP_CIPHER *EVP_cast5_cbc(void) const EVP_CIPHER *EVP_cast5_cbc(void)
const EVP_CIPHER *EVP_cast5_cfb(void) const EVP_CIPHER *EVP_cast5_cfb(void)
const EVP_CIPHER *EVP_cast5_cfb64(void)
const EVP_CIPHER *EVP_cast5_ecb(void) const EVP_CIPHER *EVP_cast5_ecb(void)
const EVP_CIPHER *EVP_cast5_ofb(void) const EVP_CIPHER *EVP_cast5_ofb(void)
@@ -28,6 +30,7 @@ This is a variable key length cipher.
=item EVP_cast5_cbc(), =item EVP_cast5_cbc(),
EVP_cast5_ecb(), EVP_cast5_ecb(),
EVP_cast5_cfb(), EVP_cast5_cfb(),
EVP_cast5_cfb64(),
EVP_cast5_ofb() EVP_cast5_ofb()
CAST encryption algorithm in CBC, ECB, CFB and OFB modes respectively. CAST encryption algorithm in CBC, ECB, CFB and OFB modes respectively.
+22 -12
View File
@@ -6,19 +6,24 @@ EVP_des_cbc,
EVP_des_cfb, EVP_des_cfb,
EVP_des_cfb1, EVP_des_cfb1,
EVP_des_cfb8, EVP_des_cfb8,
EVP_des_cfb64,
EVP_des_ecb, EVP_des_ecb,
EVP_des_ede,
EVP_des_ede_cfb,
EVP_des_ede_ofb,
EVP_des_ofb, EVP_des_ofb,
EVP_des_ede,
EVP_des_ede_cbc,
EVP_des_ede_cfb,
EVP_des_ede_cfb64,
EVP_des_ede_ecb,
EVP_des_ede_ofb,
EVP_des_ede3, EVP_des_ede3,
EVP_des_ede3_cbc, EVP_des_ede3_cbc,
EVP_des_ede3_cfb, EVP_des_ede3_cfb,
EVP_des_ede3_cfb1, EVP_des_ede3_cfb1,
EVP_des_ede3_cfb8, EVP_des_ede3_cfb8,
EVP_des_ede3_cfb64,
EVP_des_ede3_ecb,
EVP_des_ede3_ofb, EVP_des_ede3_ofb,
EVP_des_ede3_wrap, EVP_des_ede3_wrap
EVP_des_ede_cbc
- EVP DES cipher - EVP DES cipher
=head1 SYNOPSIS =head1 SYNOPSIS
@@ -43,27 +48,32 @@ EVP_des_ecb(),
EVP_des_cfb(), EVP_des_cfb(),
EVP_des_cfb1(), EVP_des_cfb1(),
EVP_des_cfb8(), EVP_des_cfb8(),
EVP_des_cfb64(),
EVP_des_ofb() EVP_des_ofb()
DES in CBC, ECB, CFB with 128-bit shift, CFB with 1-bit shift, CFB with 8-bit DES in CBC, ECB, CFB with 64-bit shift, CFB with 1-bit shift, CFB with 8-bit
shift and OFB modes respectively. shift and OFB modes.
=item EVP_des_ede(), =item EVP_des_ede(),
EVP_des_ede_cbc(), EVP_des_ede_cbc(),
EVP_des_ede_ofb(), EVP_des_ede_cfb(),
EVP_des_ede_cfb() EVP_des_ede_cfb64(),
EVP_des_ede_ecb(),
EVP_des_ede_ofb()
Two key triple DES in ECB, CBC, CFB and OFB modes respectively. Two key triple DES in ECB, CBC, CFB with 64-bit shift and OFB modes.
=item EVP_des_ede3(), =item EVP_des_ede3(),
EVP_des_ede3_cbc(), EVP_des_ede3_cbc(),
EVP_des_ede3_cfb(), EVP_des_ede3_cfb(),
EVP_des_ede3_cfb1(), EVP_des_ede3_cfb1(),
EVP_des_ede3_cfb8(), EVP_des_ede3_cfb8(),
EVP_des_ede3_cfb64(),
EVP_des_ede3_ecb(),
EVP_des_ede3_ofb() EVP_des_ede3_ofb()
Three-key triple DES in ECB, CBC, CFB with 128-bit shift, CFB with 1-bit shift, Three-key triple DES in ECB, CBC, CFB with 64-bit shift, CFB with 1-bit shift,
CFB with 8-bit shift and OFB modes respectively. CFB with 8-bit shift and OFB modes.
=item EVP_des_ede3_wrap() =item EVP_des_ede3_wrap()
+3
View File
@@ -4,6 +4,7 @@
EVP_idea_cbc, EVP_idea_cbc,
EVP_idea_cfb, EVP_idea_cfb,
EVP_idea_cfb64,
EVP_idea_ecb, EVP_idea_ecb,
EVP_idea_ofb EVP_idea_ofb
- EVP IDEA cipher - EVP IDEA cipher
@@ -14,6 +15,7 @@ EVP_idea_ofb
const EVP_CIPHER *EVP_idea_cbc(void) const EVP_CIPHER *EVP_idea_cbc(void)
const EVP_CIPHER *EVP_idea_cfb(void) const EVP_CIPHER *EVP_idea_cfb(void)
const EVP_CIPHER *EVP_idea_cfb64(void)
const EVP_CIPHER *EVP_idea_ecb(void) const EVP_CIPHER *EVP_idea_ecb(void)
const EVP_CIPHER *EVP_idea_ofb(void) const EVP_CIPHER *EVP_idea_ofb(void)
@@ -25,6 +27,7 @@ The IDEA encryption algorithm for EVP.
=item EVP_idea_cbc(), =item EVP_idea_cbc(),
EVP_idea_cfb(), EVP_idea_cfb(),
EVP_idea_cfb64(),
EVP_idea_ecb(), EVP_idea_ecb(),
EVP_idea_ofb() EVP_idea_ofb()
+3 -1
View File
@@ -2,7 +2,8 @@
=head1 NAME =head1 NAME
EVP_md5 EVP_md5,
EVP_md5_sha1
- MD5 For EVP - MD5 For EVP
=head1 SYNOPSIS =head1 SYNOPSIS
@@ -10,6 +11,7 @@ EVP_md5
#include <openssl/evp.h> #include <openssl/evp.h>
const EVP_MD *EVP_md5(void); const EVP_MD *EVP_md5(void);
const EVP_MD *EVP_md5_sha1(void);
=head1 DESCRIPTION =head1 DESCRIPTION
+3
View File
@@ -4,6 +4,7 @@
EVP_rc2_cbc, EVP_rc2_cbc,
EVP_rc2_cfb, EVP_rc2_cfb,
EVP_rc2_cfb64,
EVP_rc2_ecb, EVP_rc2_ecb,
EVP_rc2_ofb, EVP_rc2_ofb,
EVP_rc2_40_cbc, EVP_rc2_40_cbc,
@@ -16,6 +17,7 @@ EVP_rc2_64_cbc
const EVP_CIPHER *EVP_rc2_cbc(void) const EVP_CIPHER *EVP_rc2_cbc(void)
const EVP_CIPHER *EVP_rc2_cfb(void) const EVP_CIPHER *EVP_rc2_cfb(void)
const EVP_CIPHER *EVP_rc2_cfb64(void)
const EVP_CIPHER *EVP_rc2_ecb(void) const EVP_CIPHER *EVP_rc2_ecb(void)
const EVP_CIPHER *EVP_rc2_ofb(void) const EVP_CIPHER *EVP_rc2_ofb(void)
const EVP_CIPHER *EVP_rc2_40_cbc(void) const EVP_CIPHER *EVP_rc2_40_cbc(void)
@@ -29,6 +31,7 @@ The RC2 encryption algorithm for EVP.
=item EVP_rc2_cbc(), =item EVP_rc2_cbc(),
EVP_rc2_cfb(), EVP_rc2_cfb(),
EVP_rc2_cfb64(),
EVP_rc2_ecb(), EVP_rc2_ecb(),
EVP_rc2_ofb() EVP_rc2_ofb()
+3
View File
@@ -4,6 +4,7 @@
EVP_rc5_32_12_16_cbc, EVP_rc5_32_12_16_cbc,
EVP_rc5_32_12_16_cfb, EVP_rc5_32_12_16_cfb,
EVP_rc5_32_12_16_cfb64,
EVP_rc5_32_12_16_ecb, EVP_rc5_32_12_16_ecb,
EVP_rc5_32_12_16_ofb EVP_rc5_32_12_16_ofb
- EVP RC5 cipher - EVP RC5 cipher
@@ -14,6 +15,7 @@ EVP_rc5_32_12_16_ofb
const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void) const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void)
const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void) const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void)
const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void)
const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void) const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void)
const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void) const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void)
@@ -25,6 +27,7 @@ The RC5 encryption algorithm for EVP.
=item EVP_rc5_32_12_16_cbc(), =item EVP_rc5_32_12_16_cbc(),
EVP_rc5_32_12_16_cfb(), EVP_rc5_32_12_16_cfb(),
EVP_rc5_32_12_16_cfb64(),
EVP_rc5_32_12_16_ecb(), EVP_rc5_32_12_16_ecb(),
EVP_rc5_32_12_16_ofb() EVP_rc5_32_12_16_ofb()
+3
View File
@@ -4,6 +4,7 @@
EVP_seed_cbc, EVP_seed_cbc,
EVP_seed_cfb, EVP_seed_cfb,
EVP_seed_cfb128,
EVP_seed_ecb, EVP_seed_ecb,
EVP_seed_ofb EVP_seed_ofb
- EVP SEED cipher - EVP SEED cipher
@@ -14,6 +15,7 @@ EVP_seed_ofb
const EVP_CIPHER *EVP_seed_cbc(void) const EVP_CIPHER *EVP_seed_cbc(void)
const EVP_CIPHER *EVP_seed_cfb(void) const EVP_CIPHER *EVP_seed_cfb(void)
const EVP_CIPHER *EVP_seed_cfb128(void)
const EVP_CIPHER *EVP_seed_ecb(void) const EVP_CIPHER *EVP_seed_ecb(void)
const EVP_CIPHER *EVP_seed_ofb(void) const EVP_CIPHER *EVP_seed_ofb(void)
@@ -27,6 +29,7 @@ All modes below use a key length of 128 bits and acts on blocks of 128-bits.
=item EVP_seed_cbc(), =item EVP_seed_cbc(),
EVP_seed_cfb(), EVP_seed_cfb(),
EVP_seed_cfb128(),
EVP_seed_ecb(), EVP_seed_ecb(),
EVP_seed_ofb() EVP_seed_ofb()
+3
View File
@@ -5,6 +5,7 @@
EVP_sm4_cbc, EVP_sm4_cbc,
EVP_sm4_ecb, EVP_sm4_ecb,
EVP_sm4_cfb, EVP_sm4_cfb,
EVP_sm4_cfb128,
EVP_sm4_ofb, EVP_sm4_ofb,
EVP_sm4_ctr EVP_sm4_ctr
- EVP SM4 cipher - EVP SM4 cipher
@@ -16,6 +17,7 @@ EVP_sm4_ctr
const EVP_CIPHER *EVP_sm4_cbc(void); const EVP_CIPHER *EVP_sm4_cbc(void);
const EVP_CIPHER *EVP_sm4_ecb(void); const EVP_CIPHER *EVP_sm4_ecb(void);
const EVP_CIPHER *EVP_sm4_cfb(void); const EVP_CIPHER *EVP_sm4_cfb(void);
const EVP_CIPHER *EVP_sm4_cfb128(void);
const EVP_CIPHER *EVP_sm4_ofb(void); const EVP_CIPHER *EVP_sm4_ofb(void);
const EVP_CIPHER *EVP_sm4_ctr(void); const EVP_CIPHER *EVP_sm4_ctr(void);
@@ -30,6 +32,7 @@ All modes below use a key length of 128 bits and acts on blocks of 128 bits.
=item EVP_sm4_cbc(), =item EVP_sm4_cbc(),
EVP_sm4_ecb(), EVP_sm4_ecb(),
EVP_sm4_cfb(), EVP_sm4_cfb(),
EVP_sm4_cfb128(),
EVP_sm4_ofb(), EVP_sm4_ofb(),
EVP_sm4_ctr() EVP_sm4_ctr()
+173
View File
@@ -0,0 +1,173 @@
=pod
=head1 NAME
OPENSSL_s390xcap - the IBM z processor capabilities vector
=head1 SYNOPSIS
env OPENSSL_s390xcap=... <application>
=head1 DESCRIPTION
libcrypto supports z/Architecture instruction set extensions. These
extensions are denoted by individual bits in the capabilities vector.
When libcrypto is initialized, the bits returned by the STFLE instruction
and by the QUERY functions are stored in the vector.
To change the set of instructions available to an application, you can
set the OPENSSL_s390xcap environment variable before you start the
application. After initialization, the capability vector is ANDed bitwise
with a mask which is derived from the environment variable.
The environment variable is a semicolon-separated list of tokens which is
processed from left to right (whitespace is ignored):
OPENSSL_s390xcap="<tok1>;<tok2>;..."
There are three types of tokens:
=over 4
=item <string>
The name of a processor generation. A bit in the environment variable's
mask is set to one if and only if the specified processor generation
implements the corresponding instruction set extension. Possible values
are z900, z990, z9, z10, z196, zEC12, z13 and z14.
=item <string>:<mask>:<mask>
The name of an instruction followed by two 64-bit masks. The part of the
environment variable's mask corresponding to the specified instruction is
set to the specified 128-bit mask. Possible values are kimd, klmd, km, kmc,
kmac, kmctr, kmo, kmf, prno and kma.
=item stfle:<mask>:<mask>:<mask>
Store-facility-list-extended (stfle) followed by three 64-bit masks. The
part of the environment variable's mask corresponding to the stfle
instruction is set to the specified 192-bit mask.
=back
The 64-bit masks are specified in hexadecimal notation. The 0x prefix is
optional. Prefix a mask with a tilde (~) to denote a bitwise NOT operation.
The following is a list of significant bits for each instruction. Colon
rows separate the individual 64-bit masks. The bit numbers in the first
column are consistent with [1], that is, 0 denotes the leftmost bit and
the numbering is continuous across 64-bit mask boundaries.
Bit Mask Facility/Function
stfle:
# 17 1<<46 message-security assist
# 25 1<<38 store-clock-fast facility
:
# 76 1<<51 message-security assist extension 3
# 77 1<<50 message-security assist extension 4
:
#129 1<<62 vector facility
#134 1<<57 vector packed decimal facility
#135 1<<56 vector enhancements facility 1
#146 1<<45 message-security assist extension 8
kimd :
# 1 1<<62 KIMD-SHA-1
# 2 1<<61 KIMD-SHA-256
# 3 1<<60 KIMD-SHA-512
# 32 1<<31 KIMD-SHA3-224
# 33 1<<30 KIMD-SHA3-256
# 34 1<<29 KIMD-SHA3-384
# 35 1<<28 KIMD-SHA3-512
# 36 1<<27 KIMD-SHAKE-128
# 37 1<<26 KIMD-SHAKE-256
:
# 65 1<<62 KIMD-GHASH
klmd :
# 32 1<<31 KLMD-SHA3-224
# 33 1<<30 KLMD-SHA3-256
# 34 1<<29 KLMD-SHA3-384
# 35 1<<28 KLMD-SHA3-512
# 36 1<<27 KLMD-SHAKE-128
# 37 1<<26 KLMD-SHAKE-256
:
km :
# 18 1<<45 KM-AES-128
# 19 1<<44 KM-AES-192
# 20 1<<43 KM-AES-256
# 50 1<<13 KM-XTS-AES-128
# 52 1<<11 KM-XTS-AES-256
:
kmc :
# 18 1<<45 KMC-AES-128
# 19 1<<44 KMC-AES-192
# 20 1<<43 KMC-AES-256
:
kmac :
# 18 1<<45 KMAC-AES-128
# 19 1<<44 KMAC-AES-192
# 20 1<<43 KMAC-AES-256
:
kmctr:
:
kmo :
# 18 1<<45 KMO-AES-128
# 19 1<<44 KMO-AES-192
# 20 1<<43 KMO-AES-256
:
kmf :
# 18 1<<45 KMF-AES-128
# 19 1<<44 KMF-AES-192
# 20 1<<43 KMF-AES-256
:
prno :
:
kma :
# 18 1<<45 KMA-GCM-AES-128
# 19 1<<44 KMA-GCM-AES-192
# 20 1<<43 KMA-GCM-AES-256
:
=head1 EXAMPLES
Disables all instruction set extensions which the z196 processor does not implement:
OPENSSL_s390xcap="z196"
Disables the vector facility:
OPENSSL_s390xcap="stfle:~0:~0:~0x4000000000000000"
Disables the KM-XTS-AES and and the KIMD-SHAKE function codes:
OPENSSL_s390xcap="km:~0x2800:~0;kimd:~0xc000000:~0"
=head1 RETURN VALUES
Not available.
=head1 SEE ALSO
[1] z/Architecture Principles of Operation, SA22-7832-11
=head1 COPYRIGHT
Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the OpenSSL license (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut
+65
View File
@@ -0,0 +1,65 @@
=pod
=head1 NAME
EVP_MAC_CMAC - The CMAC EVP_MAC implementation
=head1 DESCRIPTION
Support for computing CMAC MACs through the B<EVP_MAC> API.
=head2 Numeric identity
B<EVP_MAC_CMAC> is the numeric identity for this implementation, and
can be used in functions like EVP_MAC_CTX_new_id() and
EVP_get_macbynid().
=head2 Supported controls
The supported controls are:
=over 4
=item B<EVP_MAC_CTRL_SET_KEY>
EVP_MAC_ctrl_str() takes to type string for this control:
=over 4
=item "key"
The value string is used as is.
=item "hexkey"
The value string is expected to be a hexadecimal number, which will be
decoded before passing on as control value.
=back
=item B<EVP_MAC_CTRL_SET_ENGINE>
=item B<EVP_MAC_CTRL_SET_CIPHER>
These work as described in L<EVP_MAC(3)/CONTROLS>.
EVP_MAC_ctrl_str() type string for B<EVP_MAC_CTRL_SET_CIPHER>: "cipher"
The value is expected to be the name of a cipher.
=back
=head1 SEE ALSO
L<EVP_MAC_ctrl(3)>, L<EVP_MAC(3)/CONTROLS>
=head1 COPYRIGHT
Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the OpenSSL license (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut
+71
View File
@@ -0,0 +1,71 @@
=pod
=head1 NAME
EVP_MAC_HMAC - The HMAC EVP_MAC implementation
=head1 DESCRIPTION
Support for computing HMAC MACs through the B<EVP_MAC> API.
=head2 Numeric identity
B<EVP_MAC_HMAC> is the numeric identity for this implementation, and
can be used in functions like EVP_MAC_CTX_new_id() and
EVP_get_macbynid().
=head2 Supported controls
The supported controls are:
=over 4
=item B<EVP_MAC_CTRL_SET_KEY>
EVP_MAC_ctrl_str() takes to type string for this control:
=over 4
=item "key"
The value string is used as is.
=item "hexkey"
The value string is expected to be a hexadecimal number, which will be
decoded before passing on as control value.
=back
=item B<EVP_MAC_CTRL_SET_FLAGS>
Sets HMAC flags. This is passed directly to HMAC_CTX_set_flags().
There are no corresponding string control types.
=item B<EVP_MAC_CTRL_SET_ENGINE>
=item B<EVP_MAC_CTRL_SET_MD>
These work as described in L<EVP_MAC(3)/CONTROLS>.
EVP_MAC_ctrl_str() type string for B<EVP_MAC_CTRL_SET_DIGEST>: "digest"
The value is expected to be the name of a cipher.
=back
=head1 SEE ALSO
L<EVP_MAC_ctrl(3)>, L<EVP_MAC(3)/CONTROLS>
=head1 COPYRIGHT
Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the OpenSSL license (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut
+61
View File
@@ -0,0 +1,61 @@
=pod
=head1 NAME
EVP_MAC_SIPHASH - The SipHash EVP_MAC implementation
=head1 DESCRIPTION
Support for computing SipHash MACs through the B<EVP_MAC> API.
=head2 Numeric identity
B<EVP_MAC_SIPHASH> is the numeric identity for this implementation,
and can be used in functions like EVP_MAC_CTX_new_id() and
EVP_get_macbynid().
=head2 Supported controls
The supported controls are:
=over 4
=item B<EVP_MAC_CTRL_SET_SIZE>
EVP_MAC_ctrl_str() type string: "digestsize"
The value string is expected to contain a decimal number.
=item B<EVP_MAC_CTRL_SET_KEY>
EVP_MAC_ctrl_str() takes to type string for this control:
=over 4
=item "key"
The value string is used as is.
=item "hexkey"
The value string is expected to be a hexadecimal number, which will be
decoded before passing on as control value.
=back
=back
=head1 SEE ALSO
L<EVP_MAC_ctrl(3)>, L<EVP_MAC(3)/CONTROLS>
=head1 COPYRIGHT
Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the OpenSSL license (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut
+8 -1
View File
@@ -377,7 +377,14 @@ int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len);
/* OPENSSL_INIT_ZLIB 0x00010000L */ /* OPENSSL_INIT_ZLIB 0x00010000L */
# define OPENSSL_INIT_ATFORK 0x00020000L # define OPENSSL_INIT_ATFORK 0x00020000L
/* OPENSSL_INIT_BASE_ONLY 0x00040000L */ /* OPENSSL_INIT_BASE_ONLY 0x00040000L */
/* OPENSSL_INIT flag range 0xfff00000 reserved for OPENSSL_init_ssl() */ /* FREE: 0x00080000L */
/* OPENSSL_INIT flag range 0x03f00000 reserved for OPENSSL_init_ssl() */
# define OPENSSL_INIT_NO_ADD_ALL_MACS 0x04000000L
# define OPENSSL_INIT_ADD_ALL_MACS 0x08000000L
/* FREE: 0x10000000L */
/* FREE: 0x20000000L */
/* FREE: 0x40000000L */
/* FREE: 0x80000000L */
/* Max OPENSSL_INIT flag value is 0x80000000 */ /* Max OPENSSL_INIT flag value is 0x80000000 */
/* openssl and dasync not counted as builtin */ /* openssl and dasync not counted as builtin */
+3
View File
@@ -14,6 +14,9 @@
# ifdef __cplusplus # ifdef __cplusplus
extern "C" extern "C"
# endif # endif
# include <openssl/symhacks.h>
int ERR_load_CRYPTO_strings(void); int ERR_load_CRYPTO_strings(void);
/* /*
+14 -3
View File
@@ -1107,10 +1107,15 @@ const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key);
int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth); int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth);
EC_KEY *EC_KEY_new_method(ENGINE *engine); EC_KEY *EC_KEY_new_method(ENGINE *engine);
int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, /** The old name for ecdh_KDF_X9_63
* The ECDH KDF specification has been mistakingly attributed to ANSI X9.62,
* it is actually specified in ANSI X9.63.
* This identifier is retained for backwards compatibility
*/
DEPRECATEDIN_1_2_0(int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
const unsigned char *Z, size_t Zlen, const unsigned char *Z, size_t Zlen,
const unsigned char *sinfo, size_t sinfolen, const unsigned char *sinfo, size_t sinfolen,
const EVP_MD *md); const EVP_MD *md))
int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
const EC_KEY *ecdh, const EC_KEY *ecdh,
@@ -1457,7 +1462,13 @@ void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth,
# define EVP_PKEY_CTRL_GET1_ID_LEN (EVP_PKEY_ALG_CTRL + 13) # define EVP_PKEY_CTRL_GET1_ID_LEN (EVP_PKEY_ALG_CTRL + 13)
/* KDF types */ /* KDF types */
# define EVP_PKEY_ECDH_KDF_NONE 1 # define EVP_PKEY_ECDH_KDF_NONE 1
# define EVP_PKEY_ECDH_KDF_X9_62 2 # define EVP_PKEY_ECDH_KDF_X9_63 2
/** The old name for EVP_PKEY_ECDH_KDF_X9_63
* The ECDH KDF specification has been mistakingly attributed to ANSI X9.62,
* it is actually specified in ANSI X9.63.
* This identifier is retained for backwards compatibility
*/
# define EVP_PKEY_ECDH_KDF_X9_62 EVP_PKEY_ECDH_KDF_X9_63
# ifdef __cplusplus # ifdef __cplusplus
+51
View File
@@ -10,6 +10,8 @@
#ifndef HEADER_ENVELOPE_H #ifndef HEADER_ENVELOPE_H
# define HEADER_ENVELOPE_H # define HEADER_ENVELOPE_H
# include <stdarg.h>
# include <openssl/opensslconf.h> # include <openssl/opensslconf.h>
# include <openssl/ossl_typ.h> # include <openssl/ossl_typ.h>
# include <openssl/symhacks.h> # include <openssl/symhacks.h>
@@ -984,6 +986,47 @@ void EVP_MD_do_all_sorted(void (*fn)
(const EVP_MD *ciph, const char *from, (const EVP_MD *ciph, const char *from,
const char *to, void *x), void *arg); const char *to, void *x), void *arg);
/* MAC stuff */
# define EVP_MAC_CMAC NID_cmac
# define EVP_MAC_HMAC NID_hmac
# define EVP_MAC_SIPHASH NID_siphash
EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac);
EVP_MAC_CTX *EVP_MAC_CTX_new_id(int nid);
void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx);
int EVP_MAC_CTX_copy(EVP_MAC_CTX *dest, EVP_MAC_CTX *src);
const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx);
size_t EVP_MAC_size(EVP_MAC_CTX *ctx);
int EVP_MAC_init(EVP_MAC_CTX *ctx);
int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen);
int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *poutlen);
int EVP_MAC_ctrl(EVP_MAC_CTX *ctx, int cmd, ...);
int EVP_MAC_vctrl(EVP_MAC_CTX *ctx, int cmd, va_list args);
int EVP_MAC_ctrl_str(EVP_MAC_CTX *ctx, const char *type, const char *value);
int EVP_MAC_str2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value);
int EVP_MAC_hex2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value);
int EVP_MAC_nid(const EVP_MAC *mac);
# define EVP_get_macbynid(a) EVP_get_macbyname(OBJ_nid2sn(a))
# define EVP_get_macbyobj(a) EVP_get_macbynid(OBJ_obj2nid(a))
# define EVP_MAC_name(o) OBJ_nid2sn(EVP_MAC_nid(o))
const EVP_MAC *EVP_get_macbyname(const char *name);
void EVP_MAC_do_all(void (*fn)
(const EVP_MAC *ciph, const char *from, const char *to,
void *x), void *arg);
void EVP_MAC_do_all_sorted(void (*fn)
(const EVP_MAC *ciph, const char *from,
const char *to, void *x), void *arg);
# define EVP_MAC_CTRL_SET_KEY 0x01 /* unsigned char *, size_t */
# define EVP_MAC_CTRL_SET_FLAGS 0x02 /* unsigned long */
# define EVP_MAC_CTRL_SET_ENGINE 0x03 /* ENGINE * */
# define EVP_MAC_CTRL_SET_MD 0x04 /* EVP_MD * */
# define EVP_MAC_CTRL_SET_CIPHER 0x04 /* EVP_CIPHER * */
# define EVP_MAC_CTRL_SET_SIZE 0x05 /* size_t */
/* PKEY stuff */
int EVP_PKEY_decrypt_old(unsigned char *dec_key, int EVP_PKEY_decrypt_old(unsigned char *dec_key,
const unsigned char *enc_key, int enc_key_len, const unsigned char *enc_key, int enc_key_len,
EVP_PKEY *private_key); EVP_PKEY *private_key);
@@ -1632,6 +1675,14 @@ void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth,
EVP_MD_CTX *mctx)); EVP_MD_CTX *mctx));
void EVP_add_alg_module(void); void EVP_add_alg_module(void);
/*
* Convenient helper functions to transfer string based controls.
* The callback gets called with the parsed value.
*/
int EVP_str2ctrl(int (*cb)(void *ctx, int cmd, void *buf, size_t buflen),
void *ctx, int cmd, const char *value);
int EVP_hex2ctrl(int (*cb)(void *ctx, int cmd, void *buf, size_t buflen),
void *ctx, int cmd, const char *hex);
# ifdef __cplusplus # ifdef __cplusplus
} }
+6
View File
@@ -50,6 +50,11 @@ int ERR_load_EVP_strings(void);
# define EVP_F_EVP_DIGESTINIT_EX 128 # define EVP_F_EVP_DIGESTINIT_EX 128
# define EVP_F_EVP_ENCRYPTFINAL_EX 127 # define EVP_F_EVP_ENCRYPTFINAL_EX 127
# define EVP_F_EVP_ENCRYPTUPDATE 167 # define EVP_F_EVP_ENCRYPTUPDATE 167
# define EVP_F_EVP_MAC_CTRL 209
# define EVP_F_EVP_MAC_CTRL_STR 210
# define EVP_F_EVP_MAC_CTX_COPY 211
# define EVP_F_EVP_MAC_CTX_NEW 213
# define EVP_F_EVP_MAC_INIT 212
# define EVP_F_EVP_MD_CTX_COPY_EX 110 # define EVP_F_EVP_MD_CTX_COPY_EX 110
# define EVP_F_EVP_MD_SIZE 162 # define EVP_F_EVP_MD_SIZE 162
# define EVP_F_EVP_OPENINIT 102 # define EVP_F_EVP_OPENINIT 102
@@ -112,6 +117,7 @@ int ERR_load_EVP_strings(void);
# define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 # define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118
# define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164 # define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164
# define EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN 180 # define EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN 180
# define EVP_F_PKEY_MAC_INIT 214
# define EVP_F_PKEY_SET_TYPE 158 # define EVP_F_PKEY_SET_TYPE 158
# define EVP_F_RC2_MAGIC_TO_METH 109 # define EVP_F_RC2_MAGIC_TO_METH 109
# define EVP_F_RC5_CTRL 125 # define EVP_F_RC5_CTRL 125
+2 -1
View File
@@ -20,7 +20,8 @@
# define OBJ_NAME_TYPE_CIPHER_METH 0x02 # define OBJ_NAME_TYPE_CIPHER_METH 0x02
# define OBJ_NAME_TYPE_PKEY_METH 0x03 # define OBJ_NAME_TYPE_PKEY_METH 0x03
# define OBJ_NAME_TYPE_COMP_METH 0x04 # define OBJ_NAME_TYPE_COMP_METH 0x04
# define OBJ_NAME_TYPE_NUM 0x05 # define OBJ_NAME_TYPE_MAC_METH 0x05
# define OBJ_NAME_TYPE_NUM 0x06
# define OBJ_NAME_ALIAS 0x8000 # define OBJ_NAME_ALIAS 0x8000
+2
View File
@@ -90,6 +90,8 @@ typedef struct evp_cipher_st EVP_CIPHER;
typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
typedef struct evp_md_st EVP_MD; typedef struct evp_md_st EVP_MD;
typedef struct evp_md_ctx_st EVP_MD_CTX; typedef struct evp_md_ctx_st EVP_MD_CTX;
typedef struct evp_mac_st EVP_MAC;
typedef struct evp_mac_ctx_st EVP_MAC_CTX;
typedef struct evp_pkey_st EVP_PKEY; typedef struct evp_pkey_st EVP_PKEY;
typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
+1
View File
@@ -12,6 +12,7 @@
# include <time.h> # include <time.h>
# include <openssl/ossl_typ.h> # include <openssl/ossl_typ.h>
# include <openssl/obj_mac.h>
/* /*
* RAND_DRBG flags * RAND_DRBG flags
+36 -55
View File
@@ -445,15 +445,14 @@ static void get_current_time(struct timeval *t)
#ifndef OPENSSL_NO_SOCK #ifndef OPENSSL_NO_SOCK
int DTLSv1_listen(SSL *s, BIO_ADDR *client) int DTLSv1_listen(SSL *s, BIO_ADDR *client)
{ {
int next, n, ret = 0, clearpkt = 0; int next, n, ret = 0;
unsigned char cookie[DTLS1_COOKIE_LENGTH]; unsigned char cookie[DTLS1_COOKIE_LENGTH];
unsigned char seq[SEQ_NUM_SIZE]; unsigned char seq[SEQ_NUM_SIZE];
const unsigned char *data; const unsigned char *data;
unsigned char *buf; unsigned char *buf, *wbuf;
size_t fragoff, fraglen, msglen; size_t fragoff, fraglen, msglen, reclen, align = 0;
unsigned int rectype, versmajor, msgseq, msgtype, clientvers, cookielen; unsigned int rectype, versmajor, msgseq, msgtype, clientvers, cookielen;
BIO *rbio, *wbio; BIO *rbio, *wbio;
BUF_MEM *bufm;
BIO_ADDR *tmpclient = NULL; BIO_ADDR *tmpclient = NULL;
PACKET pkt, msgpkt, msgpayload, session, cookiepkt; PACKET pkt, msgpkt, msgpayload, session, cookiepkt;
@@ -476,13 +475,6 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
return -1; return -1;
} }
/*
* We only peek at incoming ClientHello's until we're sure we are going to
* to respond with a HelloVerifyRequest. If its a ClientHello with a valid
* cookie then we leave it in the BIO for accept to handle.
*/
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL);
/* /*
* Note: This check deliberately excludes DTLS1_BAD_VER because that version * Note: This check deliberately excludes DTLS1_BAD_VER because that version
* requires the MAC to be calculated *including* the first ClientHello * requires the MAC to be calculated *including* the first ClientHello
@@ -495,35 +487,32 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
return -1; return -1;
} }
if (s->init_buf == NULL) { if (!ssl3_setup_buffers(s)) {
if ((bufm = BUF_MEM_new()) == NULL) { /* SSLerr already called */
SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE); return -1;
return -1;
}
if (!BUF_MEM_grow(bufm, SSL3_RT_MAX_PLAIN_LENGTH)) {
BUF_MEM_free(bufm);
SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE);
return -1;
}
s->init_buf = bufm;
} }
buf = (unsigned char *)s->init_buf->data; buf = RECORD_LAYER_get_rbuf(&s->rlayer)->buf;
wbuf = RECORD_LAYER_get_wbuf(&s->rlayer)[0].buf;
#if defined(SSL3_ALIGN_PAYLOAD)
# if SSL3_ALIGN_PAYLOAD != 0
/*
* Using SSL3_RT_HEADER_LENGTH here instead of DTLS1_RT_HEADER_LENGTH for
* consistency with ssl3_read_n. In practice it should make no difference
* for sensible values of SSL3_ALIGN_PAYLOAD because the difference between
* SSL3_RT_HEADER_LENGTH and DTLS1_RT_HEADER_LENGTH is exactly 8
*/
align = (size_t)buf + SSL3_RT_HEADER_LENGTH;
align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
# endif
#endif
buf += align;
do { do {
/* Get a packet */ /* Get a packet */
clear_sys_error(); clear_sys_error();
/* n = BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH
* Technically a ClientHello could be SSL3_RT_MAX_PLAIN_LENGTH + DTLS1_RT_HEADER_LENGTH);
* + DTLS1_RT_HEADER_LENGTH bytes long. Normally init_buf does not store
* the record header as well, but we do here. We've set up init_buf to
* be the standard size for simplicity. In practice we shouldn't ever
* receive a ClientHello as long as this. If we do it will get dropped
* in the record length check below.
*/
n = BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
if (n <= 0) { if (n <= 0) {
if (BIO_should_retry(rbio)) { if (BIO_should_retry(rbio)) {
/* Non-blocking IO */ /* Non-blocking IO */
@@ -532,9 +521,6 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
return -1; return -1;
} }
/* If we hit any problems we need to clear this packet from the BIO */
clearpkt = 1;
if (!PACKET_buf_init(&pkt, buf, n)) { if (!PACKET_buf_init(&pkt, buf, n)) {
SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR); SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR);
return -1; return -1;
@@ -587,6 +573,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH); SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
goto end; goto end;
} }
reclen = PACKET_remaining(&msgpkt);
/* /*
* We allow data remaining at the end of the packet because there could * We allow data remaining at the end of the packet because there could
* be a second record (but we ignore it) * be a second record (but we ignore it)
@@ -706,14 +693,6 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
* to resend, we just drop it. * to resend, we just drop it.
*/ */
/*
* Dump the read packet, we don't need it any more. Ignore return
* value
*/
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL);
BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL);
/* Generate the cookie */ /* Generate the cookie */
if (s->ctx->app_gen_cookie_cb == NULL || if (s->ctx->app_gen_cookie_cb == NULL ||
s->ctx->app_gen_cookie_cb(s, cookie, &cookielen) == 0 || s->ctx->app_gen_cookie_cb(s, cookie, &cookielen) == 0 ||
@@ -732,7 +711,11 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
: s->version; : s->version;
/* Construct the record and message headers */ /* Construct the record and message headers */
if (!WPACKET_init(&wpkt, s->init_buf) if (!WPACKET_init_static_len(&wpkt,
wbuf,
ssl_get_max_send_fragment(s)
+ DTLS1_RT_HEADER_LENGTH,
0)
|| !WPACKET_put_bytes_u8(&wpkt, SSL3_RT_HANDSHAKE) || !WPACKET_put_bytes_u8(&wpkt, SSL3_RT_HANDSHAKE)
|| !WPACKET_put_bytes_u16(&wpkt, version) || !WPACKET_put_bytes_u16(&wpkt, version)
/* /*
@@ -790,8 +773,8 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
* plus one byte for the message content type. The source is the * plus one byte for the message content type. The source is the
* last 3 bytes of the message header * last 3 bytes of the message header
*/ */
memcpy(&buf[DTLS1_RT_HEADER_LENGTH + 1], memcpy(&wbuf[DTLS1_RT_HEADER_LENGTH + 1],
&buf[DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH - 3], &wbuf[DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH - 3],
3); 3);
if (s->msg_callback) if (s->msg_callback)
@@ -815,7 +798,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
tmpclient = NULL; tmpclient = NULL;
/* TODO(size_t): convert this call */ /* TODO(size_t): convert this call */
if (BIO_write(wbio, buf, wreclen) < (int)wreclen) { if (BIO_write(wbio, wbuf, wreclen) < (int)wreclen) {
if (BIO_should_retry(wbio)) { if (BIO_should_retry(wbio)) {
/* /*
* Non-blocking IO...but we're stateless, so we're just * Non-blocking IO...but we're stateless, so we're just
@@ -865,15 +848,13 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
if (BIO_dgram_get_peer(rbio, client) <= 0) if (BIO_dgram_get_peer(rbio, client) <= 0)
BIO_ADDR_clear(client); BIO_ADDR_clear(client);
/* Buffer the record in the processed_rcds queue */
if (!dtls_buffer_listen_record(s, reclen, seq, align))
return -1;
ret = 1; ret = 1;
clearpkt = 0;
end: end:
BIO_ADDR_free(tmpclient); BIO_ADDR_free(tmpclient);
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL);
if (clearpkt) {
/* Dump this packet. Ignore return value */
BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
}
return ret; return ret;
} }
#endif #endif
+1 -4
View File
@@ -185,14 +185,11 @@ int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
return -1; return -1;
} }
/* insert should not fail, since duplicates are dropped */
if (pqueue_insert(queue->q, item) == NULL) { if (pqueue_insert(queue->q, item) == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_BUFFER_RECORD, /* Must be a duplicate so ignore it */
ERR_R_INTERNAL_ERROR);
OPENSSL_free(rdata->rbuf.buf); OPENSSL_free(rdata->rbuf.buf);
OPENSSL_free(rdata); OPENSSL_free(rdata);
pitem_free(item); pitem_free(item);
return -1;
} }
return 1; return 1;
+4
View File
@@ -188,6 +188,8 @@ typedef struct record_layer_st {
((rl)->d->processed_rcds) ((rl)->d->processed_rcds)
#define DTLS_RECORD_LAYER_get_unprocessed_rcds(rl) \ #define DTLS_RECORD_LAYER_get_unprocessed_rcds(rl) \
((rl)->d->unprocessed_rcds) ((rl)->d->unprocessed_rcds)
#define RECORD_LAYER_get_rbuf(rl) (&(rl)->rbuf)
#define RECORD_LAYER_get_wbuf(rl) ((rl)->wbuf)
void RECORD_LAYER_init(RECORD_LAYER *rl, SSL *s); void RECORD_LAYER_init(RECORD_LAYER *rl, SSL *s);
void RECORD_LAYER_clear(RECORD_LAYER *rl); void RECORD_LAYER_clear(RECORD_LAYER *rl);
@@ -230,3 +232,5 @@ __owur int dtls1_write_bytes(SSL *s, int type, const void *buf, size_t len,
int do_dtls1_write(SSL *s, int type, const unsigned char *buf, int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
size_t len, int create_empty_fragment, size_t *written); size_t len, int create_empty_fragment, size_t *written);
void dtls1_reset_seq_numbers(SSL *s, int rw); void dtls1_reset_seq_numbers(SSL *s, int rw);
int dtls_buffer_listen_record(SSL *s, size_t len, unsigned char *seq,
size_t off);
-2
View File
@@ -18,8 +18,6 @@
/* Functions/macros provided by the RECORD_LAYER component */ /* Functions/macros provided by the RECORD_LAYER component */
#define RECORD_LAYER_get_rbuf(rl) (&(rl)->rbuf)
#define RECORD_LAYER_get_wbuf(rl) ((rl)->wbuf)
#define RECORD_LAYER_get_rrec(rl) ((rl)->rrec) #define RECORD_LAYER_get_rrec(rl) ((rl)->rrec)
#define RECORD_LAYER_set_packet(rl, p) ((rl)->packet = (p)) #define RECORD_LAYER_set_packet(rl, p) ((rl)->packet = (p))
#define RECORD_LAYER_reset_packet_length(rl) ((rl)->packet_length = 0) #define RECORD_LAYER_reset_packet_length(rl) ((rl)->packet_length = 0)
+25
View File
@@ -2030,3 +2030,28 @@ int dtls1_get_record(SSL *s)
return 1; return 1;
} }
int dtls_buffer_listen_record(SSL *s, size_t len, unsigned char *seq, size_t off)
{
SSL3_RECORD *rr;
rr = RECORD_LAYER_get_rrec(&s->rlayer);
memset(rr, 0, sizeof(SSL3_RECORD));
rr->length = len;
rr->type = SSL3_RT_HANDSHAKE;
memcpy(rr->seq_num, seq, sizeof(rr->seq_num));
rr->off = off;
s->rlayer.packet = RECORD_LAYER_get_rbuf(&s->rlayer)->buf;
s->rlayer.packet_length = DTLS1_RT_HEADER_LENGTH + len;
rr->data = s->rlayer.packet + DTLS1_RT_HEADER_LENGTH;
if (dtls1_buffer_record(s, &(s->rlayer.d->processed_rcds),
SSL3_RECORD_get_seq_num(s->rlayer.rrec)) <= 0) {
/* SSLfatal() already called */
return 0;
}
return 1;
}
+3 -2
View File
@@ -256,12 +256,13 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
* of hash termination (0x80 + 64-bit length) don't fit in the final * of hash termination (0x80 + 64-bit length) don't fit in the final
* block, we say that the final two blocks can vary based on the padding. * block, we say that the final two blocks can vary based on the padding.
* TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
* required to be minimal. Therefore we say that the final six blocks can * required to be minimal. Therefore we say that the final |variance_blocks|
* blocks can
* vary based on the padding. Later in the function, if the message is * vary based on the padding. Later in the function, if the message is
* short and there obviously cannot be this many blocks then * short and there obviously cannot be this many blocks then
* variance_blocks can be reduced. * variance_blocks can be reduced.
*/ */
variance_blocks = is_sslv3 ? 2 : 6; variance_blocks = is_sslv3 ? 2 : ( ((255 + 1 + md_size + md_block_size - 1) / md_block_size) + 1);
/* /*
* From now on we're dealing with the MAC, which conceptually has 13 * From now on we're dealing with the MAC, which conceptually has 13
* bytes of `header' before the start of the data (TLS) or 71/75 bytes * bytes of `header' before the start of the data (TLS) or 71/75 bytes
+2 -1
View File
@@ -199,7 +199,8 @@ int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS * settings)
| OPENSSL_INIT_LOAD_CONFIG | OPENSSL_INIT_LOAD_CONFIG
#endif #endif
| OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS, | OPENSSL_INIT_ADD_ALL_DIGESTS
| OPENSSL_INIT_ADD_ALL_MACS,
settings)) settings))
return 0; return 0;
+4 -2
View File
@@ -1530,10 +1530,12 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart,
*/ */
if (s->hello_retry_request == SSL_HRR_PENDING) { if (s->hello_retry_request == SSL_HRR_PENDING) {
size_t hdatalen; size_t hdatalen;
long hdatalen_l;
void *hdata; void *hdata;
hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); hdatalen = hdatalen_l =
if (hdatalen <= 0) { BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
if (hdatalen_l <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER, SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER,
SSL_R_BAD_HANDSHAKE_LENGTH); SSL_R_BAD_HANDSHAKE_LENGTH);
goto err; goto err;
+12
View File
@@ -1095,6 +1095,7 @@ WORK_STATE ossl_statem_client_post_process_message(SSL *s, WORK_STATE wst)
ERR_R_INTERNAL_ERROR); ERR_R_INTERNAL_ERROR);
return WORK_ERROR; return WORK_ERROR;
case TLS_ST_CR_CERT_VRFY:
case TLS_ST_CR_CERT_REQ: case TLS_ST_CR_CERT_REQ:
return tls_prepare_client_certificate(s, wst); return tls_prepare_client_certificate(s, wst);
} }
@@ -2563,6 +2564,17 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
/* we should setup a certificate to return.... */ /* we should setup a certificate to return.... */
s->s3->tmp.cert_req = 1; s->s3->tmp.cert_req = 1;
/*
* In TLSv1.3 we don't prepare the client certificate yet. We wait until
* after the CertificateVerify message has been received. This is because
* in TLSv1.3 the CertificateRequest arrives before the Certificate message
* but in TLSv1.2 it is the other way around. We want to make sure that
* SSL_get_peer_certificate() returns something sensible in
* client_cert_cb.
*/
if (SSL_IS_TLS13(s) && s->post_handshake_auth != SSL_PHA_REQUESTED)
return MSG_PROCESS_CONTINUE_READING;
return MSG_PROCESS_CONTINUE_PROCESSING; return MSG_PROCESS_CONTINUE_PROCESSING;
} }
+15 -3
View File
@@ -203,9 +203,10 @@ static int get_cert_verify_tbs_data(SSL *s, unsigned char *tls13tbs,
*hdatalen = TLS13_TBS_PREAMBLE_SIZE + hashlen; *hdatalen = TLS13_TBS_PREAMBLE_SIZE + hashlen;
} else { } else {
size_t retlen; size_t retlen;
long retlen_l;
retlen = BIO_get_mem_data(s->s3->handshake_buffer, hdata); retlen = retlen_l = BIO_get_mem_data(s->s3->handshake_buffer, hdata);
if (retlen <= 0) { if (retlen_l <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_GET_CERT_VERIFY_TBS_DATA, SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_GET_CERT_VERIFY_TBS_DATA,
ERR_R_INTERNAL_ERROR); ERR_R_INTERNAL_ERROR);
return 0; return 0;
@@ -494,7 +495,18 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
} }
} }
ret = MSG_PROCESS_CONTINUE_READING; /*
* In TLSv1.3 on the client side we make sure we prepare the client
* certificate after the CertVerify instead of when we get the
* CertificateRequest. This is because in TLSv1.3 the CertificateRequest
* comes *before* the Certificate message. In TLSv1.2 it comes after. We
* want to make sure that SSL_get_peer_certificate() will return the actual
* server certificate from the client_cert_cb callback.
*/
if (!s->server && SSL_IS_TLS13(s) && s->s3->tmp.cert_req == 1)
ret = MSG_PROCESS_CONTINUE_PROCESSING;
else
ret = MSG_PROCESS_CONTINUE_READING;
err: err:
BIO_free(s->s3->handshake_buffer); BIO_free(s->s3->handshake_buffer);
s->s3->handshake_buffer = NULL; s->s3->handshake_buffer = NULL;
+9 -1
View File
@@ -1519,8 +1519,10 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt)
* So check cookie length... * So check cookie length...
*/ */
if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) {
if (clienthello->dtls_cookie_len == 0) if (clienthello->dtls_cookie_len == 0) {
OPENSSL_free(clienthello);
return MSG_PROCESS_FINISHED_READING; return MSG_PROCESS_FINISHED_READING;
}
} }
} }
@@ -3225,6 +3227,12 @@ static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt)
SSL_R_LENGTH_MISMATCH); SSL_R_LENGTH_MISMATCH);
goto err; goto err;
} }
if (skey == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE,
SSL_R_MISSING_TMP_ECDH_KEY);
goto err;
}
ckey = EVP_PKEY_new(); ckey = EVP_PKEY_new();
if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) <= 0) { if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE, SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE,
+2 -4
View File
@@ -436,10 +436,8 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=main
# available through the shared library (at least on Linux, Solaris, Windows # available through the shared library (at least on Linux, Solaris, Windows
# and VMS, where the exported symbols are those listed in util/*.num), these # and VMS, where the exported symbols are those listed in util/*.num), these
# programs are forcibly linked with the static libraries, where all symbols # programs are forcibly linked with the static libraries, where all symbols
# are always available. This excludes linking these programs natively on # are always available.
# Windows when building shared libraries, since the static libraries share IF[1]
# names with the DLL import libraries.
IF[{- $disabled{shared} || $target{build_scheme}->[1] ne 'windows' -}]
PROGRAMS_NO_INST=asn1_internal_test modes_internal_test x509_internal_test \ PROGRAMS_NO_INST=asn1_internal_test modes_internal_test x509_internal_test \
tls13encryptiontest wpackettest ctype_internal_test \ tls13encryptiontest wpackettest ctype_internal_test \
rdrand_sanitytest rdrand_sanitytest
+89 -45
View File
@@ -677,7 +677,7 @@ static int test_drbg_reseed(int expect_success,
* setup correctly, in particular whether reseeding works * setup correctly, in particular whether reseeding works
* as designed. * as designed.
*/ */
static int test_rand_reseed(void) static int test_rand_drbg_reseed(void)
{ {
RAND_DRBG *master, *public, *private; RAND_DRBG *master, *public, *private;
unsigned char rand_add_buf[256]; unsigned char rand_add_buf[256];
@@ -884,64 +884,107 @@ static int test_multi_thread(void)
} }
#endif #endif
#ifdef OPENSSL_RAND_SEED_NONE
/* /*
* This function only returns the entropy already added with RAND_add(), * Calculates the minimum buffer length which needs to be
* and does not get entropy from the OS. * provided to RAND_seed() in order to successfully
* instantiate the DRBG.
* *
* Returns 0 on failure and the size of the buffer on success. * Copied from rand_drbg_seedlen() in rand_drbg.c
*/ */
static size_t get_pool_entropy(RAND_DRBG *drbg, static size_t rand_drbg_seedlen(RAND_DRBG *drbg)
unsigned char **pout,
int entropy, size_t min_len, size_t max_len,
int prediction_resistance)
{ {
if (drbg->pool == NULL) /*
return 0; * If no os entropy source is available then RAND_seed(buffer, bufsize)
* is expected to succeed if and only if the buffer length satisfies
* the following requirements, which follow from the calculations
* in RAND_DRBG_instantiate().
*/
size_t min_entropy = drbg->strength;
size_t min_entropylen = drbg->min_entropylen;
if (drbg->pool->entropy < (size_t)entropy || drbg->pool->len < min_len /*
|| drbg->pool->len > max_len) * Extra entropy for the random nonce in the absence of a
return 0; * get_nonce callback, see comment in RAND_DRBG_instantiate().
*/
if (drbg->min_noncelen > 0 && drbg->get_nonce == NULL) {
min_entropy += drbg->strength / 2;
min_entropylen += drbg->min_noncelen;
}
*pout = drbg->pool->buffer; /*
return drbg->pool->len; * Convert entropy requirement from bits to bytes
* (dividing by 8 without rounding upwards, because
* all entropy requirements are divisible by 8).
*/
min_entropy >>= 3;
/* Return a value that satisfies both requirements */
return min_entropy > min_entropylen ? min_entropy : min_entropylen;
}
#endif /*OPENSSL_RAND_SEED_NONE*/
/*
* Test that instantiation with RAND_seed() works as expected
*
* If no os entropy source is available then RAND_seed(buffer, bufsize)
* is expected to succeed if and only if the buffer length is at least
* rand_drbg_seedlen(master) bytes.
*
* If an os entropy source is available then RAND_seed(buffer, bufsize)
* is expected to succeed always.
*/
static int test_rand_seed(void)
{
RAND_DRBG *master = RAND_DRBG_get0_master();
unsigned char rand_buf[256];
size_t rand_buflen;
#ifdef OPENSSL_RAND_SEED_NONE
size_t required_seed_buflen = rand_drbg_seedlen(master);
#else
size_t required_seed_buflen = 0;
#endif
memset(rand_buf, 0xCD, sizeof(rand_buf));
for ( rand_buflen = 256 ; rand_buflen > 0 ; --rand_buflen ) {
RAND_DRBG_uninstantiate(master);
RAND_seed(rand_buf, rand_buflen);
if (!TEST_int_eq(RAND_status(),
(rand_buflen >= required_seed_buflen)))
return 0;
}
return 1;
} }
/* /*
* Clean up the entropy that get_pool_entropy() returned. * Test that adding additional data with RAND_add() works as expected
*/ * when the master DRBG is instantiated (and below its reseed limit).
static void cleanup_pool_entropy(RAND_DRBG *drbg, unsigned char *out, size_t outlen) *
{ * This should succeed regardless of whether an os entropy source is
OPENSSL_free(drbg->pool); * available or not.
drbg->pool = NULL;
}
/*
* Test that instantiating works when OS entropy is not available and that
* RAND_add() is enough to reseed it.
*/ */
static int test_rand_add(void) static int test_rand_add(void)
{ {
RAND_DRBG *master = RAND_DRBG_get0_master(); unsigned char rand_buf[256];
RAND_DRBG_get_entropy_fn old_get_entropy = master->get_entropy; size_t rand_buflen;
RAND_DRBG_cleanup_entropy_fn old_cleanup_entropy = master->cleanup_entropy;
int rv = 0;
unsigned char rand_add_buf[256];
master->get_entropy = get_pool_entropy; memset(rand_buf, 0xCD, sizeof(rand_buf));
master->cleanup_entropy = cleanup_pool_entropy;
master->reseed_prop_counter++;
RAND_DRBG_uninstantiate(master);
memset(rand_add_buf, 0xCD, sizeof(rand_add_buf));
RAND_add(rand_add_buf, sizeof(rand_add_buf), sizeof(rand_add_buf));
if (!TEST_true(RAND_DRBG_instantiate(master, NULL, 0)))
goto error;
rv = 1; /* make sure it's instantiated */
RAND_seed(rand_buf, sizeof(rand_buf));
if (!TEST_true(RAND_status()))
return 0;
error: for ( rand_buflen = 256 ; rand_buflen > 0 ; --rand_buflen ) {
master->get_entropy = old_get_entropy; RAND_add(rand_buf, rand_buflen, 0.0);
master->cleanup_entropy = old_cleanup_entropy; if (!TEST_true(RAND_status()))
return rv; return 0;
}
return 1;
} }
static int test_multi_set(void) static int test_multi_set(void)
@@ -1067,7 +1110,8 @@ int setup_tests(void)
ADD_ALL_TESTS(test_kats, OSSL_NELEM(drbg_test)); ADD_ALL_TESTS(test_kats, OSSL_NELEM(drbg_test));
ADD_ALL_TESTS(test_error_checks, OSSL_NELEM(drbg_test)); ADD_ALL_TESTS(test_error_checks, OSSL_NELEM(drbg_test));
ADD_TEST(test_rand_reseed); ADD_TEST(test_rand_drbg_reseed);
ADD_TEST(test_rand_seed);
ADD_TEST(test_rand_add); ADD_TEST(test_rand_add);
ADD_TEST(test_multi_set); ADD_TEST(test_multi_set);
ADD_TEST(test_set_defaults); ADD_TEST(test_set_defaults);
+86
View File
@@ -7,6 +7,7 @@
* https://www.openssl.org/source/license.html * https://www.openssl.org/source/license.html
*/ */
#include <string.h>
#include <openssl/bio.h> #include <openssl/bio.h>
#include <openssl/crypto.h> #include <openssl/crypto.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
@@ -240,6 +241,89 @@ static int test_dtls_drop_records(int idx)
return testresult; return testresult;
} }
static const char dummy_cookie[] = "0123456";
static int generate_cookie_cb(SSL *ssl, unsigned char *cookie,
unsigned int *cookie_len)
{
memcpy(cookie, dummy_cookie, sizeof(dummy_cookie));
*cookie_len = sizeof(dummy_cookie);
return 1;
}
static int verify_cookie_cb(SSL *ssl, const unsigned char *cookie,
unsigned int cookie_len)
{
return TEST_mem_eq(cookie, cookie_len, dummy_cookie, sizeof(dummy_cookie));
}
static int test_cookie(void)
{
SSL_CTX *sctx = NULL, *cctx = NULL;
SSL *serverssl = NULL, *clientssl = NULL;
int testresult = 0;
if (!TEST_true(create_ssl_ctx_pair(DTLS_server_method(),
DTLS_client_method(),
DTLS1_VERSION, DTLS_MAX_VERSION,
&sctx, &cctx, cert, privkey)))
return 0;
SSL_CTX_set_options(sctx, SSL_OP_COOKIE_EXCHANGE);
SSL_CTX_set_cookie_generate_cb(sctx, generate_cookie_cb);
SSL_CTX_set_cookie_verify_cb(sctx, verify_cookie_cb);
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
NULL, NULL))
|| !TEST_true(create_ssl_connection(serverssl, clientssl,
SSL_ERROR_NONE)))
goto end;
testresult = 1;
end:
SSL_free(serverssl);
SSL_free(clientssl);
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
return testresult;
}
static int test_dtls_duplicate_records(void)
{
SSL_CTX *sctx = NULL, *cctx = NULL;
SSL *serverssl = NULL, *clientssl = NULL;
int testresult = 0;
if (!TEST_true(create_ssl_ctx_pair(DTLS_server_method(),
DTLS_client_method(),
DTLS1_VERSION, DTLS_MAX_VERSION,
&sctx, &cctx, cert, privkey)))
return 0;
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
NULL, NULL)))
goto end;
DTLS_set_timer_cb(clientssl, timer_cb);
DTLS_set_timer_cb(serverssl, timer_cb);
BIO_ctrl(SSL_get_wbio(clientssl), MEMPACKET_CTRL_SET_DUPLICATE_REC, 1, NULL);
BIO_ctrl(SSL_get_wbio(serverssl), MEMPACKET_CTRL_SET_DUPLICATE_REC, 1, NULL);
if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
goto end;
testresult = 1;
end:
SSL_free(serverssl);
SSL_free(clientssl);
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
return testresult;
}
int setup_tests(void) int setup_tests(void)
{ {
if (!TEST_ptr(cert = test_get_argument(0)) if (!TEST_ptr(cert = test_get_argument(0))
@@ -248,6 +332,8 @@ int setup_tests(void)
ADD_ALL_TESTS(test_dtls_unprocessed, NUM_TESTS); ADD_ALL_TESTS(test_dtls_unprocessed, NUM_TESTS);
ADD_ALL_TESTS(test_dtls_drop_records, TOTAL_RECORDS); ADD_ALL_TESTS(test_dtls_drop_records, TOTAL_RECORDS);
ADD_TEST(test_cookie);
ADD_TEST(test_dtls_duplicate_records);
return 1; return 1;
} }
+46
View File
@@ -17,6 +17,7 @@
#include <openssl/rsa.h> #include <openssl/rsa.h>
#include <openssl/x509.h> #include <openssl/x509.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/kdf.h>
#include "testutil.h" #include "testutil.h"
#include "internal/nelem.h" #include "internal/nelem.h"
#include "internal/evp_int.h" #include "internal/evp_int.h"
@@ -918,6 +919,50 @@ static int test_EVP_PKEY_check(int i)
return ret; return ret;
} }
static int test_HKDF(void)
{
EVP_PKEY_CTX *pctx;
unsigned char out[20];
size_t outlen;
int i, ret = 0;
unsigned char salt[] = "0123456789";
unsigned char key[] = "012345678901234567890123456789";
unsigned char info[] = "infostring";
const unsigned char expected[] = {
0xe5, 0x07, 0x70, 0x7f, 0xc6, 0x78, 0xd6, 0x54, 0x32, 0x5f, 0x7e, 0xc5,
0x7b, 0x59, 0x3e, 0xd8, 0x03, 0x6b, 0xed, 0xca
};
size_t expectedlen = sizeof(expected);
if (!TEST_ptr(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL)))
goto done;
/* We do this twice to test reuse of the EVP_PKEY_CTX */
for (i = 0; i < 2; i++) {
outlen = sizeof(out);
memset(out, 0, outlen);
if (!TEST_int_gt(EVP_PKEY_derive_init(pctx), 0)
|| !TEST_int_gt(EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()), 0)
|| !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt,
sizeof(salt) - 1), 0)
|| !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_key(pctx, key,
sizeof(key) - 1), 0)
|| !TEST_int_gt(EVP_PKEY_CTX_add1_hkdf_info(pctx, info,
sizeof(info) - 1), 0)
|| !TEST_int_gt(EVP_PKEY_derive(pctx, out, &outlen), 0)
|| !TEST_mem_eq(out, outlen, expected, expectedlen))
goto done;
}
ret = 1;
done:
EVP_PKEY_CTX_free(pctx);
return ret;
}
int setup_tests(void) int setup_tests(void)
{ {
ADD_TEST(test_EVP_DigestSignInit); ADD_TEST(test_EVP_DigestSignInit);
@@ -941,5 +986,6 @@ int setup_tests(void)
if (!TEST_int_eq(EVP_PKEY_meth_add0(custom_pmeth), 1)) if (!TEST_int_eq(EVP_PKEY_meth_add0(custom_pmeth), 1))
return 0; return 0;
ADD_ALL_TESTS(test_EVP_PKEY_check, OSSL_NELEM(keycheckdata)); ADD_ALL_TESTS(test_EVP_PKEY_check, OSSL_NELEM(keycheckdata));
ADD_TEST(test_HKDF);
return 1; return 1;
} }
+200 -26
View File
@@ -73,8 +73,6 @@ static KEY_LIST *public_keys;
static int find_key(EVP_PKEY **ppk, const char *name, KEY_LIST *lst); static int find_key(EVP_PKEY **ppk, const char *name, KEY_LIST *lst);
static int parse_bin(const char *value, unsigned char **buf, size_t *buflen); static int parse_bin(const char *value, unsigned char **buf, size_t *buflen);
static int pkey_test_ctrl(EVP_TEST *t, EVP_PKEY_CTX *pctx,
const char *value);
/* /*
* Compare two memory regions for equality, returning zero if they differ. * Compare two memory regions for equality, returning zero if they differ.
@@ -832,8 +830,9 @@ static const EVP_TEST_METHOD cipher_test_method = {
**/ **/
typedef struct mac_data_st { typedef struct mac_data_st {
/* MAC type */ /* MAC type in one form or another */
int type; const EVP_MAC *mac; /* for mac_test_run_mac */
int type; /* for mac_test_run_pkey */
/* Algorithm string for this MAC */ /* Algorithm string for this MAC */
char *alg; char *alg;
/* MAC key */ /* MAC key */
@@ -851,37 +850,63 @@ typedef struct mac_data_st {
static int mac_test_init(EVP_TEST *t, const char *alg) static int mac_test_init(EVP_TEST *t, const char *alg)
{ {
int type; const EVP_MAC *mac = NULL;
int type = NID_undef;
MAC_DATA *mdat; MAC_DATA *mdat;
if (strcmp(alg, "HMAC") == 0) { if ((mac = EVP_get_macbyname(alg)) == NULL) {
type = EVP_PKEY_HMAC; /*
} else if (strcmp(alg, "CMAC") == 0) { * Since we didn't find an EVP_MAC, we check for known EVP_PKEY methods
* For debugging purposes, we allow 'NNNN by EVP_PKEY' to force running
* the EVP_PKEY method.
*/
size_t sz = strlen(alg);
static const char epilogue[] = " by EVP_PKEY";
if (sz >= sizeof(epilogue)
&& strcmp(alg + sz - (sizeof(epilogue) - 1), epilogue) == 0)
sz -= sizeof(epilogue) - 1;
if (strncmp(alg, "HMAC", sz) == 0) {
type = EVP_PKEY_HMAC;
} else if (strncmp(alg, "CMAC", sz) == 0) {
#ifndef OPENSSL_NO_CMAC #ifndef OPENSSL_NO_CMAC
type = EVP_PKEY_CMAC; type = EVP_PKEY_CMAC;
#else #else
t->skip = 1; t->skip = 1;
return 1; return 1;
#endif #endif
} else if (strcmp(alg, "Poly1305") == 0) { } else if (strncmp(alg, "Poly1305", sz) == 0) {
#ifndef OPENSSL_NO_POLY1305 #ifndef OPENSSL_NO_POLY1305
type = EVP_PKEY_POLY1305; type = EVP_PKEY_POLY1305;
#else #else
t->skip = 1; t->skip = 1;
return 1; return 1;
#endif #endif
} else if (strcmp(alg, "SipHash") == 0) { } else if (strncmp(alg, "SipHash", sz) == 0) {
#ifndef OPENSSL_NO_SIPHASH #ifndef OPENSSL_NO_SIPHASH
type = EVP_PKEY_SIPHASH; type = EVP_PKEY_SIPHASH;
#else #else
t->skip = 1; t->skip = 1;
return 1; return 1;
#endif #endif
} else } else {
return 0; /*
* Not a known EVP_PKEY method either. If it's a known OID, then
* assume it's been disabled.
*/
if (OBJ_sn2nid(alg) != NID_undef || OBJ_ln2nid(alg) != NID_undef) {
t->skip = 1;
return 1;
}
return 0;
}
}
mdat = OPENSSL_zalloc(sizeof(*mdat)); mdat = OPENSSL_zalloc(sizeof(*mdat));
mdat->type = type; mdat->type = type;
mdat->mac = mac;
mdat->controls = sk_OPENSSL_STRING_new_null(); mdat->controls = sk_OPENSSL_STRING_new_null();
t->data = mdat; t->data = mdat;
return 1; return 1;
@@ -927,7 +952,29 @@ static int mac_test_parse(EVP_TEST *t,
return 0; return 0;
} }
static int mac_test_run(EVP_TEST *t) static int mac_test_ctrl_pkey(EVP_TEST *t, EVP_PKEY_CTX *pctx,
const char *value)
{
int rv;
char *p, *tmpval;
if (!TEST_ptr(tmpval = OPENSSL_strdup(value)))
return 0;
p = strchr(tmpval, ':');
if (p != NULL)
*p++ = '\0';
rv = EVP_PKEY_CTX_ctrl_str(pctx, tmpval, p);
if (rv == -2)
t->err = "PKEY_CTRL_INVALID";
else if (rv <= 0)
t->err = "PKEY_CTRL_ERROR";
else
rv = 1;
OPENSSL_free(tmpval);
return rv > 0;
}
static int mac_test_run_pkey(EVP_TEST *t)
{ {
MAC_DATA *expected = t->data; MAC_DATA *expected = t->data;
EVP_MD_CTX *mctx = NULL; EVP_MD_CTX *mctx = NULL;
@@ -938,6 +985,12 @@ static int mac_test_run(EVP_TEST *t)
size_t got_len; size_t got_len;
int i; int i;
if (expected->alg == NULL)
TEST_info("Trying the EVP_PKEY %s test", OBJ_nid2sn(expected->type));
else
TEST_info("Trying the EVP_PKEY %s test with %s",
OBJ_nid2sn(expected->type), expected->alg);
#ifdef OPENSSL_NO_DES #ifdef OPENSSL_NO_DES
if (expected->alg != NULL && strstr(expected->alg, "DES") != NULL) { if (expected->alg != NULL && strstr(expected->alg, "DES") != NULL) {
/* Skip DES */ /* Skip DES */
@@ -972,8 +1025,9 @@ static int mac_test_run(EVP_TEST *t)
goto err; goto err;
} }
for (i = 0; i < sk_OPENSSL_STRING_num(expected->controls); i++) for (i = 0; i < sk_OPENSSL_STRING_num(expected->controls); i++)
if (!pkey_test_ctrl(t, pctx, if (!mac_test_ctrl_pkey(t, pctx,
sk_OPENSSL_STRING_value(expected->controls, i))) { sk_OPENSSL_STRING_value(expected->controls,
i))) {
t->err = "EVPPKEYCTXCTRL_ERROR"; t->err = "EVPPKEYCTXCTRL_ERROR";
goto err; goto err;
} }
@@ -1005,6 +1059,126 @@ static int mac_test_run(EVP_TEST *t)
return 1; return 1;
} }
static int mac_test_run_mac(EVP_TEST *t)
{
MAC_DATA *expected = t->data;
EVP_MAC_CTX *ctx = NULL;
const void *algo = NULL;
int algo_ctrl = 0;
unsigned char *got = NULL;
size_t got_len;
int rv, i;
if (expected->alg == NULL)
TEST_info("Trying the EVP_MAC %s test", EVP_MAC_name(expected->mac));
else
TEST_info("Trying the EVP_MAC %s test with %s",
EVP_MAC_name(expected->mac), expected->alg);
#ifdef OPENSSL_NO_DES
if (expected->alg != NULL && strstr(expected->alg, "DES") != NULL) {
/* Skip DES */
t->err = NULL;
goto err;
}
#endif
if ((ctx = EVP_MAC_CTX_new(expected->mac)) == NULL) {
t->err = "MAC_CREATE_ERROR";
goto err;
}
if (expected->alg != NULL
&& ((algo_ctrl = EVP_MAC_CTRL_SET_CIPHER,
algo = EVP_get_cipherbyname(expected->alg)) == NULL
&& (algo_ctrl = EVP_MAC_CTRL_SET_MD,
algo = EVP_get_digestbyname(expected->alg)) == NULL)) {
t->err = "MAC_BAD_ALGORITHM";
goto err;
}
if (algo_ctrl != 0) {
rv = EVP_MAC_ctrl(ctx, algo_ctrl, algo);
if (rv == -2) {
t->err = "MAC_CTRL_INVALID";
goto err;
} else if (rv <= 0) {
t->err = "MAC_CTRL_ERROR";
goto err;
}
}
rv = EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_KEY,
expected->key, expected->key_len);
if (rv == -2) {
t->err = "MAC_CTRL_INVALID";
goto err;
} else if (rv <= 0) {
t->err = "MAC_CTRL_ERROR";
goto err;
}
if (!EVP_MAC_init(ctx)) {
t->err = "MAC_INIT_ERROR";
goto err;
}
for (i = 0; i < sk_OPENSSL_STRING_num(expected->controls); i++) {
char *p, *tmpval;
char *value = sk_OPENSSL_STRING_value(expected->controls, i);
if (!TEST_ptr(tmpval = OPENSSL_strdup(value))) {
t->err = "MAC_CTRL_ERROR";
goto err;
}
p = strchr(tmpval, ':');
if (p != NULL)
*p++ = '\0';
rv = EVP_MAC_ctrl_str(ctx, tmpval, p);
OPENSSL_free(tmpval);
if (rv == -2) {
t->err = "MAC_CTRL_INVALID";
goto err;
} else if (rv <= 0) {
t->err = "MAC_CTRL_ERROR";
goto err;
}
}
if (!EVP_MAC_update(ctx, expected->input, expected->input_len)) {
t->err = "MAC_UPDATE_ERROR";
goto err;
}
if (!EVP_MAC_final(ctx, NULL, &got_len)) {
t->err = "MAC_FINAL_LENGTH_ERROR";
goto err;
}
if (!TEST_ptr(got = OPENSSL_malloc(got_len))) {
t->err = "TEST_FAILURE";
goto err;
}
if (!EVP_MAC_final(ctx, got, &got_len)
|| !memory_err_compare(t, "TEST_MAC_ERR",
expected->output, expected->output_len,
got, got_len)) {
t->err = "TEST_MAC_ERR";
goto err;
}
t->err = NULL;
err:
EVP_MAC_CTX_free(ctx);
OPENSSL_free(got);
return 1;
}
static int mac_test_run(EVP_TEST *t)
{
MAC_DATA *expected = t->data;
if (expected->mac != NULL)
return mac_test_run_mac(t);
return mac_test_run_pkey(t);
}
static const EVP_TEST_METHOD mac_test_method = { static const EVP_TEST_METHOD mac_test_method = {
"MAC", "MAC",
mac_test_init, mac_test_init,
@@ -2614,8 +2788,8 @@ top:
return 0; return 0;
} }
if (rv < 0) { if (rv < 0) {
TEST_info("Line %d: error processing keyword %s\n", TEST_info("Line %d: error processing keyword %s = %s\n",
t->s.curr, pp->key); t->s.curr, pp->key, pp->value);
return 0; return 0;
} }
} }

Some files were not shown because too many files have changed in this diff Show More