Latest update
This commit is contained in:
@@ -9,6 +9,24 @@
|
||||
|
||||
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
|
||||
the attacked described in "Efficient Instantiations of Tweakable
|
||||
Blockciphers and Refinements to Modes OCB and PMAC" by Phillip Rogaway.
|
||||
|
||||
@@ -24,7 +24,12 @@
|
||||
|
||||
my $ndk = $ENV{ANDROID_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);
|
||||
|
||||
my $ndkver = undef;
|
||||
@@ -40,10 +45,18 @@
|
||||
close $fh;
|
||||
}
|
||||
|
||||
my $sysroot;
|
||||
my ($sysroot, $api, $arch);
|
||||
|
||||
if (!($sysroot = $ENV{CROSS_SYSROOT})) {
|
||||
my $api = "*";
|
||||
$config{target} =~ m|[^-]+-([^-]+)$|; # split on dash
|
||||
$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
|
||||
foreach (@{$useradd{CPPDEFINES}}, @{$user{CPPFLAGS}}) {
|
||||
@@ -59,19 +72,17 @@
|
||||
} glob("$ndk/platforms/android-$api");
|
||||
die "no $ndk/platforms/android-$api" if ($#platforms < 0);
|
||||
|
||||
$config{target} =~ m|[^-]+-([^-]+)$|; # split on dash
|
||||
$sysroot = "@platforms[$#platforms]/arch-$1";
|
||||
$sysroot = "@platforms[$#platforms]/arch-$arch";
|
||||
$sysroot =~ m|/android-([0-9]+)/arch-$arch|;
|
||||
$api = $1;
|
||||
}
|
||||
die "no sysroot=$sysroot" if (!-d $sysroot);
|
||||
|
||||
$sysroot =~ m|/android-([0-9]+)/arch-(\w+)/?$|;
|
||||
my ($api, $arch) = ($1, $2);
|
||||
|
||||
my $triarch = $triplet{$arch};
|
||||
my $cflags;
|
||||
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/([^/]+)/|) {
|
||||
my $host=$1;
|
||||
# harmonize with gcc default
|
||||
@@ -83,6 +94,23 @@
|
||||
. "/$tritools-4.9/prebuilt/$host";
|
||||
$user{CC} = "clang" if ($user{CC} !~ m|clang|);
|
||||
$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") {
|
||||
die "no NDK clang on \$PATH";
|
||||
} else {
|
||||
|
||||
+10
-12
@@ -6,31 +6,31 @@
|
||||
# work...
|
||||
#
|
||||
my %targets = (
|
||||
"ios-common" => {
|
||||
template => 1,
|
||||
inherit_from => [ "darwin-common" ],
|
||||
sys_id => "iOS",
|
||||
disable => [ "engine", "async" ],
|
||||
},
|
||||
"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,
|
||||
# thus targeting iPhone pre-3GS, but it's assumed to be irrelevant
|
||||
# at this point.
|
||||
CC => "xcrun -sdk iphoneos cc",
|
||||
cflags => add("-arch armv7 -mios-version-min=6.0.0 -fno-common"),
|
||||
sys_id => "iOS",
|
||||
perlasm_scheme => "ios32",
|
||||
disable => [ "engine" ],
|
||||
},
|
||||
"ios64-xcrun" => {
|
||||
inherit_from => [ "darwin-common", asm("aarch64_asm") ],
|
||||
inherit_from => [ "ios-common", asm("aarch64_asm") ],
|
||||
CC => "xcrun -sdk iphoneos cc",
|
||||
cflags => add("-arch arm64 -mios-version-min=7.0.0 -fno-common"),
|
||||
sys_id => "iOS",
|
||||
bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
|
||||
perlasm_scheme => "ios64",
|
||||
disable => [ "engine" ],
|
||||
},
|
||||
"iossimulator-xcrun" => {
|
||||
inherit_from => [ "darwin-common" ],
|
||||
inherit_from => [ "ios-common" ],
|
||||
CC => "xcrun -sdk iphonesimulator cc",
|
||||
sys_id => "iOS",
|
||||
disable => [ "engine" ],
|
||||
},
|
||||
# It takes three prior-set environment variables to make it work:
|
||||
#
|
||||
@@ -46,10 +46,8 @@ my %targets = (
|
||||
# CROSS_SDK=iPhoneOS.sdk
|
||||
#
|
||||
"iphoneos-cross" => {
|
||||
inherit_from => [ "darwin-common" ],
|
||||
inherit_from => [ "ios-common" ],
|
||||
cflags => add("-isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common"),
|
||||
sys_id => "iOS",
|
||||
disable => [ "engine" ],
|
||||
},
|
||||
"ios-cross" => {
|
||||
inherit_from => [ "ios-xcrun" ],
|
||||
|
||||
@@ -210,47 +210,6 @@
|
||||
# Start with populating the cache with all the 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
|
||||
foreach (@{$unified_info{depends}->{""}}) { dogenerate($_); }
|
||||
|
||||
|
||||
@@ -499,11 +499,11 @@ install_dev:
|
||||
@[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1)
|
||||
@$(ECHO) "*** Installing development files"
|
||||
@$(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"
|
||||
@cp $(SRCDIR)/ms/applink.c $(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 \
|
||||
$(BLDDIR)/include/openssl/*.h; do \
|
||||
fn=`basename $$i`; \
|
||||
@@ -574,10 +574,10 @@ install_dev:
|
||||
|
||||
uninstall_dev:
|
||||
@$(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"
|
||||
@$(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 \
|
||||
$(BLDDIR)/include/openssl/*.h; do \
|
||||
fn=`basename $$i`; \
|
||||
@@ -1134,9 +1134,7 @@ EOF
|
||||
}
|
||||
return $recipe;
|
||||
}
|
||||
# On Unix, we build shlibs from static libs, so we're ignoring the
|
||||
# object file array. We *know* this routine is only called when we've
|
||||
# configure 'shared'.
|
||||
# We *know* this routine is only called when we've configure 'shared'.
|
||||
sub obj2shlib {
|
||||
my %args = @_;
|
||||
my $lib = $args{lib};
|
||||
@@ -1163,26 +1161,20 @@ EOF
|
||||
die "More than one exported symbol map" if scalar @defs > 1;
|
||||
my $objs = join(" ", @objs);
|
||||
my $deps = join(" ", @objs, @defs, @deps);
|
||||
my $target = shlib_simple($lib);
|
||||
my $target_full = shlib($lib);
|
||||
my $simple = shlib_simple($lib);
|
||||
my $full = shlib($lib);
|
||||
my $target = "$simple $full";
|
||||
my $shared_soname = "";
|
||||
$shared_soname .= ' '.$target{shared_sonameflag}.basename($target_full)
|
||||
$shared_soname .= ' '.$target{shared_sonameflag}.basename($full)
|
||||
if defined $target{shared_sonameflag};
|
||||
my $shared_imp = "";
|
||||
$shared_imp .= ' '.$target{shared_impflag}.basename($target)
|
||||
$shared_imp .= ' '.$target{shared_impflag}.basename($simple)
|
||||
if defined $target{shared_impflag};
|
||||
my $shared_def = join("", map { ' '.$target{shared_defflag}.$_ } @defs);
|
||||
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
|
||||
\$(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)
|
||||
EOF
|
||||
if (windowsdll()) {
|
||||
@@ -1196,14 +1188,14 @@ EOF
|
||||
EOF
|
||||
} elsif (sharedaix()) {
|
||||
$recipe .= <<"EOF";
|
||||
rm -f $target && \\
|
||||
\$(AR) r $target $target_full
|
||||
rm -f $simple && \\
|
||||
\$(AR) r $simple $full
|
||||
EOF
|
||||
} else {
|
||||
$recipe .= <<"EOF";
|
||||
if [ '$target' != '$target_full' ]; then \\
|
||||
rm -f $target; \\
|
||||
ln -s $target_full $target; \\
|
||||
if [ '$simple' != '$full' ]; then \\
|
||||
rm -f $simple; \\
|
||||
ln -s $full $simple; \\
|
||||
fi
|
||||
EOF
|
||||
}
|
||||
@@ -1311,6 +1303,10 @@ EOF
|
||||
lib => $libext,
|
||||
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")) {
|
||||
next unless defined($unified_info{dirinfo}->{$dir}->{products}->{$type});
|
||||
# For lib object files, we could update the library. However, it
|
||||
@@ -1331,7 +1327,7 @@ EOF
|
||||
my $deps = join(" ", @deps);
|
||||
my $actions = join("\n", "", @actions);
|
||||
return <<"EOF";
|
||||
$args{dir} $args{dir}/: $deps$actions
|
||||
$dir $dir/: $deps$actions
|
||||
EOF
|
||||
}
|
||||
"" # Important! This becomes part of the template result.
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
|
||||
sub lib {
|
||||
(my $lib = shift) =~ s/\.a$//;
|
||||
$lib .= '_static'
|
||||
if (defined $unified_info{sharednames}->{$lib});
|
||||
return $lib . $libext;
|
||||
}
|
||||
|
||||
@@ -75,7 +77,7 @@ MINOR={- $config{minor} -}
|
||||
|
||||
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}}) -}
|
||||
SHLIBPDBS={- join(" ", map { local $shlibext = ".pdb"; shlib($_) } @{$unified_info{libraries}}) -}
|
||||
ENGINES={- join(" ", map { dso($_) } @{$unified_info{engines}}) -}
|
||||
@@ -96,7 +98,7 @@ GENERATED={- # common0.tmpl provides @generated
|
||||
$x }
|
||||
@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_SHLIBPDBS={- join(" ", map { local $shlibext = ".pdb"; quotify_l(shlib($_)) } @{$unified_info{install}->{libraries}}) -}
|
||||
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 )
|
||||
@$(ECHO) "*** Installing development files"
|
||||
@"$(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" \
|
||||
"$(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_" \
|
||||
"$(SRCDIR)\include\openssl\*.h" \
|
||||
"$(INSTALLTOP)\include\openssl"
|
||||
@@ -490,11 +492,6 @@ reconfigure reconf:
|
||||
if ($disabled{shared}) {
|
||||
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($_) } @_;
|
||||
}
|
||||
|
||||
@@ -618,25 +615,22 @@ $obj$objext: $deps
|
||||
\$(CC) /EP /D__ASSEMBLER__ $cflags $srcs > \$@.asm && \$(AS) $asflags \$(ASOUTFLAG)\$\@ \$@.asm
|
||||
EOF
|
||||
}
|
||||
return <<"EOF" if (!$disabled{makedepend});
|
||||
$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});
|
||||
my $recipe = <<"EOF";
|
||||
$obj$objext: $deps
|
||||
\$(CC) $cflags -c \$(COUTFLAG)\$\@ $srcs
|
||||
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
|
||||
# object file array. We *know* this routine is only called when we've
|
||||
# configure 'shared'.
|
||||
# We *know* this routine is only called when we've configure 'shared'.
|
||||
# Also, note that even though the import library built here looks like
|
||||
# a static library, it really isn't.
|
||||
sub obj2shlib {
|
||||
my %args = @_;
|
||||
my $lib = $args{lib};
|
||||
my $shlib = $args{shlib};
|
||||
my @objs = map { (my $x = $_) =~ s|\.o$|$objext|; $x }
|
||||
grep { $_ =~ m/\.(?:o|res)$/ }
|
||||
@{$args{objs}};
|
||||
@@ -648,25 +642,30 @@ EOF
|
||||
my $linklibs = join("", map { "$_\n" } @deps);
|
||||
my $objs = join("\n", @objs);
|
||||
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);
|
||||
return <<"EOF"
|
||||
$target: $deps
|
||||
IF EXIST $shlib$shlibext.manifest DEL /F /Q $shlib$shlibext.manifest
|
||||
# The import library may look like a static library, but it is not.
|
||||
# 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 \$@
|
||||
\$(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
|
||||
$linklibs\$(LIB_EX_LIBS)
|
||||
<<
|
||||
IF EXIST $shlib$shlibext.manifest \\
|
||||
\$(MT) \$(MTFLAGS) \$(MTINFLAG)$shlib$shlibext.manifest \$(MTOUTFLAG)$shlib$shlibext
|
||||
IF EXIST apps\\$shlib$shlibext DEL /Q /F apps\\$shlib$shlibext
|
||||
IF EXIST test\\$shlib$shlibext DEL /Q /F test\\$shlib$shlibext
|
||||
IF EXIST fuzz\\$shlib$shlibext DEL /Q /F fuzz\\$shlib$shlibext
|
||||
COPY $shlib$shlibext apps
|
||||
COPY $shlib$shlibext test
|
||||
COPY $shlib$shlibext fuzz
|
||||
IF EXIST $dll.manifest \\
|
||||
\$(MT) \$(MTFLAGS) \$(MTINFLAG)$dll.manifest \$(MTOUTFLAG)$dll
|
||||
IF EXIST apps\\$dll DEL /Q /F apps\\$dll
|
||||
IF EXIST test\\$dll DEL /Q /F test\\$dll
|
||||
IF EXIST fuzz\\$dll DEL /Q /F fuzz\\$dll
|
||||
COPY $dll apps
|
||||
COPY $dll test
|
||||
COPY $dll fuzz
|
||||
EOF
|
||||
}
|
||||
sub obj2dso {
|
||||
@@ -698,20 +697,13 @@ EOF
|
||||
}
|
||||
sub obj2lib {
|
||||
my %args = @_;
|
||||
my $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 $lib = lib($args{lib});
|
||||
my @objs = map { (my $x = $_) =~ s|\.o$|$objext|; $x } @{$args{objs}};
|
||||
my $objs = join("\n", @objs);
|
||||
my $deps = join(" ", @objs);
|
||||
return <<"EOF";
|
||||
$lib$libext: $deps
|
||||
\$(AR) \$(ARFLAGS) \$(AROUTFLAG)$lib$libext @<<
|
||||
$lib: $deps
|
||||
\$(AR) \$(ARFLAGS) \$(AROUTFLAG)$lib @<<
|
||||
$objs
|
||||
<<
|
||||
EOF
|
||||
@@ -758,6 +750,10 @@ EOF
|
||||
lib => $libext,
|
||||
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")) {
|
||||
next unless defined($unified_info{dirinfo}->{$dir}->{products}->{$type});
|
||||
# For lib object files, we could update the library. However,
|
||||
@@ -775,7 +771,7 @@ EOF
|
||||
my $deps = join(" ", @deps);
|
||||
my $actions = join("\n", "", @actions);
|
||||
return <<"EOF";
|
||||
$args{dir} $args{dir}\\ : $deps$actions
|
||||
$dir $dir\\ : $deps$actions
|
||||
EOF
|
||||
}
|
||||
"" # Important! This becomes part of the template result.
|
||||
|
||||
@@ -1013,13 +1013,18 @@ if (scalar(@seed_sources) == 0) {
|
||||
if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) {
|
||||
die "Cannot seed with none and anything else" 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
|
||||
instructions and the RAND_DRBG(7) manual page for more details.
|
||||
============================== WARNING ===============================
|
||||
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}},
|
||||
@@ -2325,6 +2330,42 @@ EOF
|
||||
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
|
||||
@@ -2799,11 +2840,17 @@ print <<"EOF";
|
||||
|
||||
**********************************************************************
|
||||
*** ***
|
||||
*** If you want to report a building issue, please include the ***
|
||||
*** output from this command: ***
|
||||
*** OpenSSL has been successfully configured ***
|
||||
*** ***
|
||||
*** 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
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
|
||||
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]
|
||||
|
||||
|
||||
+13
-5
@@ -24,16 +24,18 @@
|
||||
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
|
||||
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
|
||||
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
|
||||
target platform version. For example, to compile for ICS on ARM with
|
||||
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
|
||||
./Configure android-arm -D__ANDROID_API__=14
|
||||
make
|
||||
|
||||
Caveat lector! Earlier OpenSSL versions relied on additional CROSS_SYSROOT
|
||||
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
|
||||
CROSS_SYSROOT-less setup is recommended.
|
||||
|
||||
One can engage clang by adjusting PATH to cover NDK's clang. Just keep
|
||||
in mind that if you miss it, Configure will try to use gcc... Also,
|
||||
PATH would need even further adjustment to cover unprefixed, yet
|
||||
One can engage clang by adjusting PATH to cover same NDK's clang. Just
|
||||
keep in mind that if you miss it, Configure will try to use gcc...
|
||||
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
|
||||
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)
|
||||
------------------------
|
||||
|
||||
|
||||
@@ -976,7 +976,7 @@ end_of_options:
|
||||
BIO_printf(bio_err, "Write out database with %d new entries\n",
|
||||
sk_X509_num(cert_sk));
|
||||
|
||||
if (!rand_ser
|
||||
if (serialfile != NULL
|
||||
&& !save_serial(serialfile, "new", serial, NULL))
|
||||
goto end;
|
||||
|
||||
@@ -1044,7 +1044,8 @@ end_of_options:
|
||||
|
||||
if (sk_X509_num(cert_sk)) {
|
||||
/* Rename the database and the serial file */
|
||||
if (!rotate_serial(serialfile, "new", "old"))
|
||||
if (serialfile != NULL
|
||||
&& !rotate_serial(serialfile, "new", "old"))
|
||||
goto end;
|
||||
|
||||
if (!rotate_index(dbfile, "new", "old"))
|
||||
@@ -1177,8 +1178,7 @@ end_of_options:
|
||||
}
|
||||
|
||||
/* we have a CRL number that need updating */
|
||||
if (crlnumberfile != NULL)
|
||||
if (!rand_ser
|
||||
if (crlnumberfile != NULL
|
||||
&& !save_serial(crlnumberfile, "new", crlnumber, NULL))
|
||||
goto end;
|
||||
|
||||
@@ -1195,8 +1195,9 @@ end_of_options:
|
||||
|
||||
PEM_write_bio_X509_CRL(Sout, crl);
|
||||
|
||||
if (crlnumberfile != NULL) /* Rename the crlnumber file */
|
||||
if (!rotate_serial(crlnumberfile, "new", "old"))
|
||||
/* Rename the crlnumber file */
|
||||
if (crlnumberfile != NULL
|
||||
&& !rotate_serial(crlnumberfile, "new", "old"))
|
||||
goto end;
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
||||
+2
-3
@@ -193,9 +193,8 @@ static int psk_find_session_cb(SSL *ssl, const unsigned char *identity,
|
||||
|
||||
if (strlen(psk_identity) != identity_len
|
||||
|| memcmp(psk_identity, identity, identity_len) != 0) {
|
||||
BIO_printf(bio_s_out,
|
||||
"PSK warning: client identity not what we expected"
|
||||
" (got '%s' expected '%s')\n", identity, psk_identity);
|
||||
*sess = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (psksess != NULL) {
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
|
||||
# include <unistd.h>
|
||||
|
||||
# if _POSIX_VERSION >= 200112L
|
||||
# if _POSIX_VERSION >= 200112L \
|
||||
&& (_POSIX_VERSION < 200809L || defined(__GLIBC__))
|
||||
|
||||
# include <pthread.h>
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
* EM (and likely other) side-channel attacks like One&Done
|
||||
* (for details see "One&Done: A Single-Decryption EM-Based
|
||||
* Attack on OpenSSL’s 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
|
||||
* M. Prvulovic, in USENIX Security'18)
|
||||
*/
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=cmac.c cm_ameth.c cm_pmeth.c
|
||||
SOURCE[../../libcrypto]=cmac.c cm_ameth.c cm_meth.c
|
||||
@@ -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
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/cmac.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)
|
||||
{
|
||||
CMAC_CTX *cmctx = EVP_PKEY_get0(pkey);
|
||||
CMAC_CTX_free(cmctx);
|
||||
EVP_MAC_CTX *cmctx = EVP_PKEY_get0(pkey);
|
||||
EVP_MAC_CTX_free(cmctx);
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = {
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -327,6 +327,12 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
|
||||
if (mctx == NULL)
|
||||
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 (N == 160)
|
||||
evpmd = EVP_sha1();
|
||||
|
||||
+45
-13
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/bn_int.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/sha.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);
|
||||
static int dsa_init(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 = {
|
||||
"OpenSSL DSA method",
|
||||
@@ -178,9 +181,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
|
||||
{
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *k, *kinv = NULL, *r = *rp;
|
||||
BIGNUM *l, *m;
|
||||
BIGNUM *l;
|
||||
int ret = 0;
|
||||
int q_bits;
|
||||
int q_bits, q_words;
|
||||
|
||||
if (!dsa->p || !dsa->q || !dsa->g) {
|
||||
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();
|
||||
l = BN_new();
|
||||
m = BN_new();
|
||||
if (k == NULL || l == NULL || m == NULL)
|
||||
if (k == NULL || l == NULL)
|
||||
goto err;
|
||||
|
||||
if (ctx_in == NULL) {
|
||||
@@ -201,9 +203,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
|
||||
|
||||
/* Preallocate space */
|
||||
q_bits = BN_num_bits(dsa->q);
|
||||
if (!BN_set_bit(k, q_bits)
|
||||
|| !BN_set_bit(l, q_bits)
|
||||
|| !BN_set_bit(m, q_bits))
|
||||
q_words = bn_get_top(dsa->q);
|
||||
if (!bn_wexpand(k, q_words + 2)
|
||||
|| !bn_wexpand(l, q_words + 2))
|
||||
goto err;
|
||||
|
||||
/* 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
|
||||
* one bit longer than the modulus.
|
||||
*
|
||||
* TODO: revisit the BN_copy aiming for a memory access agnostic
|
||||
* conditional copy.
|
||||
* There are some concerns about the efficacy of doing this. More
|
||||
* 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)
|
||||
|| !BN_add(m, l, dsa->q)
|
||||
|| !BN_copy(k, BN_num_bits(l) > q_bits ? l : m))
|
||||
|| !BN_add(k, l, dsa->q))
|
||||
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(dsa, r, dsa->g, k, dsa->p, ctx,
|
||||
dsa->method_mont_p))
|
||||
@@ -259,7 +264,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
|
||||
goto err;
|
||||
|
||||
/* 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;
|
||||
|
||||
BN_clear_free(*kinvp);
|
||||
@@ -273,7 +278,6 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
|
||||
BN_CTX_free(ctx);
|
||||
BN_clear_free(k);
|
||||
BN_clear_free(l);
|
||||
BN_clear_free(m);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -393,3 +397,31 @@ static int dsa_finish(DSA *dsa)
|
||||
BN_MONT_CTX_free(dsa->method_mont_p);
|
||||
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;
|
||||
}
|
||||
@@ -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)
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
goto err;
|
||||
} else
|
||||
|
||||
+3
-3
@@ -206,8 +206,8 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
|
||||
*/
|
||||
cardinality_bits = BN_num_bits(cardinality);
|
||||
group_top = bn_get_top(cardinality);
|
||||
if ((bn_wexpand(k, group_top + 1) == NULL)
|
||||
|| (bn_wexpand(lambda, group_top + 1) == NULL)) {
|
||||
if ((bn_wexpand(k, group_top + 2) == NULL)
|
||||
|| (bn_wexpand(lambda, group_top + 2) == NULL)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -244,7 +244,7 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
|
||||
* k := scalar + 2*cardinality
|
||||
*/
|
||||
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);
|
||||
if ((bn_wexpand(s->X, group_top) == NULL)
|
||||
|
||||
@@ -209,7 +209,7 @@ static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
|
||||
if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
|
||||
goto err;
|
||||
/* 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))
|
||||
goto err;
|
||||
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:
|
||||
if (p1 == -2)
|
||||
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;
|
||||
dctx->kdf_type = p1;
|
||||
return 1;
|
||||
|
||||
+18
-3
@@ -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
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -10,12 +10,13 @@
|
||||
#include <string.h>
|
||||
#include <openssl/ec.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 */
|
||||
#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 *sinfo, size_t sinfolen,
|
||||
const EVP_MD *md)
|
||||
@@ -66,3 +67,17 @@ int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
|
||||
EVP_MD_CTX_free(mctx);
|
||||
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
|
||||
@@ -740,6 +740,11 @@ EVP_F_EVP_DIGESTFINALXOF:174:EVP_DigestFinalXOF
|
||||
EVP_F_EVP_DIGESTINIT_EX:128:EVP_DigestInit_ex
|
||||
EVP_F_EVP_ENCRYPTFINAL_EX:127:EVP_EncryptFinal_ex
|
||||
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_SIZE:162:EVP_MD_size
|
||||
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_PBKDF2_KEYIVGEN:164:PKCS5_v2_PBKDF2_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_RC2_MAGIC_TO_METH:109:rc2_magic_to_meth
|
||||
EVP_F_RC5_CTRL:125:rc5_ctrl
|
||||
|
||||
@@ -12,7 +12,8 @@ SOURCE[../../libcrypto]=\
|
||||
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_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_cbc_hmac_sha1.o]=../modes
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -54,6 +54,11 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0),
|
||||
"EVP_EncryptFinal_ex"},
|
||||
{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_SIZE, 0), "EVP_MD_size"},
|
||||
{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"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, 0),
|
||||
"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_RC2_MAGIC_TO_METH, 0), "rc2_magic_to_meth"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_RC5_CTRL, 0), "rc5_ctrl"},
|
||||
|
||||
@@ -526,3 +526,30 @@ int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int 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;
|
||||
}
|
||||
@@ -41,6 +41,11 @@ struct evp_cipher_ctx_st {
|
||||
unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */
|
||||
} /* 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 passlen, ASN1_TYPE *param,
|
||||
const EVP_CIPHER *c, const EVP_MD *md,
|
||||
|
||||
@@ -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
@@ -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
|
||||
* 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;
|
||||
}
|
||||
|
||||
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 *cp;
|
||||
@@ -77,8 +93,20 @@ const EVP_MD *EVP_get_digestbyname(const char *name)
|
||||
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)
|
||||
{
|
||||
OBJ_NAME_cleanup(OBJ_NAME_TYPE_MAC_METH);
|
||||
OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_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;
|
||||
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
@@ -319,7 +319,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
{
|
||||
#ifndef OPENSSL_NO_CMAC
|
||||
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
|
||||
|| cmctx == NULL
|
||||
@@ -328,7 +328,9 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
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);
|
||||
goto err;
|
||||
}
|
||||
@@ -338,7 +340,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
|
||||
err:
|
||||
EVP_PKEY_free(ret);
|
||||
CMAC_CTX_free(cmctx);
|
||||
EVP_MAC_CTX_free(cmctx);
|
||||
return NULL;
|
||||
#else
|
||||
EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
|
||||
|
||||
@@ -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,3 +1,3 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
hmac.c hm_ameth.c hm_pmeth.c
|
||||
hmac.c hm_ameth.c hm_meth.c
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -41,5 +41,13 @@
|
||||
__owur int ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res,
|
||||
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
|
||||
@@ -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 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 {
|
||||
int type;
|
||||
int pkey_type;
|
||||
@@ -423,6 +452,7 @@ struct evp_pkey_st {
|
||||
|
||||
void openssl_add_all_ciphers_int(void);
|
||||
void openssl_add_all_digests_int(void);
|
||||
void openssl_add_all_macs_int(void);
|
||||
void evp_cleanup_int(void);
|
||||
void evp_app_cleanup_int(void);
|
||||
|
||||
|
||||
@@ -235,6 +235,23 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
|
||||
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)
|
||||
{
|
||||
/* 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))
|
||||
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)
|
||||
&& !openssl_init_fork_handlers())
|
||||
return 0;
|
||||
|
||||
+13
-1
@@ -175,6 +175,18 @@ static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
|
||||
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,
|
||||
size_t *keylen)
|
||||
{
|
||||
@@ -236,7 +248,7 @@ const EVP_PKEY_METHOD hkdf_pkey_meth = {
|
||||
|
||||
0, 0,
|
||||
|
||||
0,
|
||||
pkey_hkdf_derive_init,
|
||||
pkey_hkdf_derive,
|
||||
pkey_hkdf_ctrl,
|
||||
pkey_hkdf_ctrl_str
|
||||
|
||||
+100
-37
@@ -374,6 +374,13 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
|
||||
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)
|
||||
entropylen = drbg->get_entropy(drbg, &entropy, min_entropy,
|
||||
min_entropylen, max_entropylen, 0);
|
||||
@@ -401,27 +408,13 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
|
||||
drbg->state = DRBG_READY;
|
||||
drbg->reseed_gen_counter = 1;
|
||||
drbg->reseed_time = time(NULL);
|
||||
if (drbg->reseed_prop_counter > 0) {
|
||||
if (drbg->parent == NULL)
|
||||
drbg->reseed_prop_counter++;
|
||||
else
|
||||
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
|
||||
}
|
||||
tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
|
||||
|
||||
end:
|
||||
if (entropy != NULL && drbg->cleanup_entropy != NULL)
|
||||
drbg->cleanup_entropy(drbg, entropy, entropylen);
|
||||
if (nonce != NULL && drbg->cleanup_nonce != NULL)
|
||||
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)
|
||||
return 1;
|
||||
return 0;
|
||||
@@ -498,6 +491,14 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
|
||||
}
|
||||
|
||||
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)
|
||||
entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength,
|
||||
drbg->min_entropylen,
|
||||
@@ -515,12 +516,7 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
|
||||
drbg->state = DRBG_READY;
|
||||
drbg->reseed_gen_counter = 1;
|
||||
drbg->reseed_time = time(NULL);
|
||||
if (drbg->reseed_prop_counter > 0) {
|
||||
if (drbg->parent == NULL)
|
||||
drbg->reseed_prop_counter++;
|
||||
else
|
||||
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
|
||||
}
|
||||
tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
|
||||
|
||||
end:
|
||||
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 */
|
||||
if (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;
|
||||
}
|
||||
@@ -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)
|
||||
reseed_required = 1;
|
||||
}
|
||||
if (drbg->reseed_prop_counter > 0 && drbg->parent != NULL) {
|
||||
if (drbg->reseed_prop_counter != drbg->parent->reseed_prop_counter)
|
||||
if (drbg->parent != NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -764,7 +757,8 @@ int RAND_DRBG_set_callbacks(RAND_DRBG *drbg,
|
||||
RAND_DRBG_get_nonce_fn get_nonce,
|
||||
RAND_DRBG_cleanup_nonce_fn cleanup_nonce)
|
||||
{
|
||||
if (drbg->state != DRBG_UNINITIALISED)
|
||||
if (drbg->state != DRBG_UNINITIALISED
|
||||
|| drbg->parent != NULL)
|
||||
return 0;
|
||||
drbg->get_entropy = get_entropy;
|
||||
drbg->cleanup_entropy = cleanup_entropy;
|
||||
@@ -942,7 +936,7 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent, int drbg_type)
|
||||
goto err;
|
||||
|
||||
/* enable seed propagation */
|
||||
drbg->reseed_prop_counter = 1;
|
||||
tsan_store(&drbg->reseed_prop_counter, 1);
|
||||
|
||||
/*
|
||||
* Ignore instantiation error to support just-in-time instantiation.
|
||||
@@ -1031,11 +1025,53 @@ static int drbg_bytes(unsigned char *out, int count)
|
||||
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 */
|
||||
static int drbg_add(const void *buf, int num, double randomness)
|
||||
{
|
||||
int ret = 0;
|
||||
RAND_DRBG *drbg = RAND_DRBG_get0_master();
|
||||
size_t buflen;
|
||||
size_t seedlen;
|
||||
|
||||
if (drbg == NULL)
|
||||
return 0;
|
||||
@@ -1043,7 +1079,37 @@ static int drbg_add(const void *buf, int num, double randomness)
|
||||
if (num < 0 || randomness < 0.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
|
||||
* 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
|
||||
* security strength.
|
||||
*/
|
||||
randomness = (double)RAND_DRBG_STRENGTH;
|
||||
randomness = (double)seedlen;
|
||||
}
|
||||
|
||||
rand_drbg_lock(drbg);
|
||||
ret = rand_drbg_restart(drbg, buf,
|
||||
(size_t)(unsigned int)num,
|
||||
(size_t)(8*randomness));
|
||||
ret = rand_drbg_restart(drbg, buf, buflen, (size_t)(8 * randomness));
|
||||
rand_drbg_unlock(drbg);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
# include <openssl/hmac.h>
|
||||
# include <openssl/ec.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. */
|
||||
# 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
|
||||
* 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;
|
||||
DRBG_STATUS state;
|
||||
|
||||
@@ -151,6 +151,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
||||
pool->entropy_requested = entropy;
|
||||
} else {
|
||||
pool = rand_pool_new(entropy, min_len, max_len);
|
||||
if (pool == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (drbg->parent) {
|
||||
@@ -172,6 +174,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
||||
prediction_resistance,
|
||||
NULL, 0) != 0)
|
||||
bytes = bytes_needed;
|
||||
drbg->reseed_next_counter
|
||||
= tsan_load(&drbg->parent->reseed_prop_counter);
|
||||
rand_drbg_unlock(drbg->parent);
|
||||
|
||||
rand_pool_add_end(pool, bytes, 8 * bytes);
|
||||
@@ -200,6 +204,7 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
||||
}
|
||||
|
||||
err:
|
||||
if (drbg->pool == NULL)
|
||||
rand_pool_free(pool);
|
||||
return ret;
|
||||
}
|
||||
@@ -213,8 +218,6 @@ void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
|
||||
{
|
||||
if (drbg->pool == NULL)
|
||||
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;
|
||||
pool->buffer = NULL;
|
||||
pool->len = 0;
|
||||
pool->entropy = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+29
-9
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/rand_drbg.h>
|
||||
#include <openssl/buffer.h>
|
||||
|
||||
#ifdef OPENSSL_SYS_VMS
|
||||
@@ -48,7 +49,7 @@
|
||||
# define S_ISREG(m) ((m) & S_IFREG)
|
||||
# endif
|
||||
|
||||
#define RAND_FILE_SIZE 1024
|
||||
#define RAND_BUF_SIZE 1024
|
||||
#define RFILE ".rnd"
|
||||
|
||||
#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)
|
||||
{
|
||||
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
|
||||
struct stat sb;
|
||||
#endif
|
||||
@@ -98,8 +108,12 @@ int RAND_load_file(const char *file, long bytes)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!S_ISREG(sb.st_mode) && bytes < 0)
|
||||
bytes = 256;
|
||||
if (bytes < 0) {
|
||||
if (S_ISREG(sb.st_mode))
|
||||
bytes = sb.st_size;
|
||||
else
|
||||
bytes = RAND_DRBG_STRENGTH;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* 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 ( ; ; ) {
|
||||
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
|
||||
n = RAND_FILE_SIZE;
|
||||
n = RAND_LOAD_BUF_SIZE;
|
||||
i = fread(buf, 1, n, in);
|
||||
#ifdef EINTR
|
||||
if (ferror(in) && errno == EINTR){
|
||||
@@ -148,12 +162,18 @@ int RAND_load_file(const char *file, long bytes)
|
||||
|
||||
OPENSSL_cleanse(buf, sizeof(buf));
|
||||
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;
|
||||
}
|
||||
|
||||
int RAND_write_file(const char *file)
|
||||
{
|
||||
unsigned char buf[RAND_FILE_SIZE];
|
||||
unsigned char buf[RAND_BUF_SIZE];
|
||||
int ret = -1;
|
||||
FILE *out = NULL;
|
||||
#ifndef OPENSSL_NO_POSIX_IO
|
||||
@@ -222,9 +242,9 @@ int RAND_write_file(const char *file)
|
||||
chmod(file, 0600);
|
||||
#endif
|
||||
|
||||
ret = fwrite(buf, 1, RAND_FILE_SIZE, out);
|
||||
ret = fwrite(buf, 1, RAND_BUF_SIZE, out);
|
||||
fclose(out);
|
||||
OPENSSL_cleanse(buf, RAND_FILE_SIZE);
|
||||
OPENSSL_cleanse(buf, RAND_BUF_SIZE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+128
-1
@@ -163,6 +163,133 @@ void *RSA_get_ex_data(const RSA *r, int 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 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))
|
||||
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)
|
||||
|
||||
+20
-3
@@ -49,6 +49,9 @@ struct OPENSSL_s390xcap_st {
|
||||
|
||||
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 */
|
||||
# define S390X_CAPBIT(i) (1ULL << (63 - (i) % 64))
|
||||
|
||||
@@ -68,9 +71,15 @@ extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
|
||||
# define S390X_KMA 0xb0
|
||||
|
||||
/* Facility Bit Numbers */
|
||||
# define S390X_VX 129
|
||||
# define S390X_VXD 134
|
||||
# define S390X_VXE 135
|
||||
# define S390X_MSA 17 /* message-security-assist */
|
||||
# define S390X_STCKF 25 /* store-clock-fast */
|
||||
# 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 */
|
||||
|
||||
@@ -78,6 +87,9 @@ extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
|
||||
# define S390X_QUERY 0
|
||||
|
||||
/* 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_256 33
|
||||
# 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_256 20
|
||||
|
||||
/* km */
|
||||
# define S390X_XTS_AES_128 50
|
||||
# define S390X_XTS_AES_256 52
|
||||
|
||||
/* prno */
|
||||
# define S390X_SHA_512_DRNG 3
|
||||
# define S390X_TRNG 114
|
||||
|
||||
/* Register 0 Flags */
|
||||
|
||||
@@ -13,15 +13,51 @@
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/ctype.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 void ill_handler(int 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_functions(void);
|
||||
void OPENSSL_vx_probe(void);
|
||||
|
||||
struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
|
||||
@@ -30,6 +66,7 @@ void OPENSSL_cpuid_setup(void)
|
||||
{
|
||||
sigset_t oset;
|
||||
struct sigaction ill_act, oact;
|
||||
struct OPENSSL_s390xcap_st cap;
|
||||
|
||||
if (OPENSSL_s390xcap_P.stfle[0])
|
||||
return;
|
||||
@@ -37,6 +74,12 @@ void OPENSSL_cpuid_setup(void)
|
||||
/* set a bit that will not be tested later */
|
||||
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));
|
||||
ill_act.sa_handler = ill_handler;
|
||||
sigfillset(&ill_act.sa_mask);
|
||||
@@ -51,6 +94,12 @@ void OPENSSL_cpuid_setup(void)
|
||||
if (sigsetjmp(ill_jmp, 1) == 0)
|
||||
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 */
|
||||
if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX))
|
||||
&& (sigsetjmp(ill_jmp, 1) == 0)) {
|
||||
@@ -64,4 +113,470 @@ void OPENSSL_cpuid_setup(void)
|
||||
sigaction(SIGFPE, &oact, NULL);
|
||||
sigaction(SIGILL, &oact, 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
@@ -38,7 +38,26 @@ OPENSSL_s390x_facilities:
|
||||
stg %r0,S390X_STFLE+8(%r4) # wipe capability vectors
|
||||
stg %r0,S390X_STFLE+16(%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_KLMD(%r4)
|
||||
stg %r0,S390X_KLMD+8(%r4)
|
||||
@@ -59,14 +78,6 @@ OPENSSL_s390x_facilities:
|
||||
stg %r0,S390X_KMA(%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)
|
||||
tmhl %r2,0x4000 # check for message-security-assist
|
||||
jz .Lret
|
||||
@@ -123,7 +134,7 @@ OPENSSL_s390x_facilities:
|
||||
|
||||
.Lret:
|
||||
br $ra
|
||||
.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities
|
||||
.size OPENSSL_s390x_functions,.-OPENSSL_s390x_functions
|
||||
|
||||
.globl OPENSSL_rdtsc
|
||||
.type OPENSSL_rdtsc,\@function
|
||||
|
||||
@@ -533,30 +533,28 @@ my @A = map([ "v".$_.".16b", "v".($_+1).".16b", "v".($_+2).".16b",
|
||||
(0, 5, 10, 15, 20));
|
||||
|
||||
my @C = map("v$_.16b", (25..31));
|
||||
my @D = @C[4,5,6,2,3];
|
||||
|
||||
$code.=<<___;
|
||||
.type KeccakF1600_ce,%function
|
||||
.align 5
|
||||
KeccakF1600_ce:
|
||||
mov x9,#12
|
||||
mov x9,#24
|
||||
adr x10,iotas
|
||||
b .Loop_ce
|
||||
.align 4
|
||||
.Loop_ce:
|
||||
___
|
||||
for($i=0; $i<2; $i++) {
|
||||
$code.=<<___;
|
||||
////////////////////////////////////////////////// Theta
|
||||
eor3 $C[0],$A[0][0],$A[1][0],$A[2][0]
|
||||
eor3 $C[1],$A[0][1],$A[1][1],$A[2][1]
|
||||
eor3 $C[2],$A[0][2],$A[1][2],$A[2][2]
|
||||
eor3 $C[3],$A[0][3],$A[1][3],$A[2][3]
|
||||
eor3 $C[4],$A[0][4],$A[1][4],$A[2][4]
|
||||
eor3 $C[0],$C[0], $A[3][0],$A[4][0]
|
||||
eor3 $C[1],$C[1], $A[3][1],$A[4][1]
|
||||
eor3 $C[2],$C[2], $A[3][2],$A[4][2]
|
||||
eor3 $C[3],$C[3], $A[3][3],$A[4][3]
|
||||
eor3 $C[4],$C[4], $A[3][4],$A[4][4]
|
||||
eor3 $C[0],$A[4][0],$A[3][0],$A[2][0]
|
||||
eor3 $C[1],$A[4][1],$A[3][1],$A[2][1]
|
||||
eor3 $C[2],$A[4][2],$A[3][2],$A[2][2]
|
||||
eor3 $C[3],$A[4][3],$A[3][3],$A[2][3]
|
||||
eor3 $C[4],$A[4][4],$A[3][4],$A[2][4]
|
||||
eor3 $C[0],$C[0], $A[1][0],$A[0][0]
|
||||
eor3 $C[1],$C[1], $A[1][1],$A[0][1]
|
||||
eor3 $C[2],$C[2], $A[1][2],$A[0][2]
|
||||
eor3 $C[3],$C[3], $A[1][3],$A[0][3]
|
||||
eor3 $C[4],$C[4], $A[1][4],$A[0][4]
|
||||
|
||||
rax1 $C[5],$C[0],$C[2] // D[1]
|
||||
rax1 $C[6],$C[1],$C[3] // D[2]
|
||||
@@ -565,81 +563,75 @@ $code.=<<___;
|
||||
rax1 $C[4],$C[4],$C[1] // D[0]
|
||||
|
||||
////////////////////////////////////////////////// Theta+Rho+Pi
|
||||
xar $C[0], $A[1][1],$C[5],#64-$rhotates[1][1] // C[0]=A[0][1]
|
||||
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 $C[0], $A[0][1],$D[1],#64-$rhotates[0][1] // C[0]=A[2][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 $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 $C[1], $A[0][2],$D[2],#64-$rhotates[0][2] // C[1]=A[4][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]
|
||||
ldr x11,[x10],#8
|
||||
xar $A[3][0],$A[0][4],$D[4],#64-$rhotates[0][4]
|
||||
|
||||
xar $C[1], $A[3][3],$C[2],#64-$rhotates[3][3] // C[1]=A[0][3]
|
||||
xar $A[3][3],$A[3][2],$C[6],#64-$rhotates[3][2]
|
||||
xar $A[3][2],$A[2][1],$C[5],#64-$rhotates[2][1]
|
||||
xar $A[2][1],$A[1][2],$C[6],#64-$rhotates[1][2]
|
||||
xar $A[1][2],$A[2][0],$C[4],#64-$rhotates[2][0]
|
||||
xar $D[4], $A[4][4],$D[4],#64-$rhotates[4][4] // D[4]=A[0][4]
|
||||
xar $A[4][4],$A[4][1],$D[1],#64-$rhotates[4][1]
|
||||
xar $A[1][3],$A[1][3],$D[3],#64-$rhotates[1][3] // A[1][3]=A[4][1]
|
||||
xar $A[0][4],$A[3][1],$D[1],#64-$rhotates[3][1] // A[0][4]=A[1][3]
|
||||
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]
|
||||
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]
|
||||
eor $A[0][0],$A[0][0],$D[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
|
||||
dup $C[6],x11 // borrow C[6]
|
||||
bcax $C[3], $A[0][0],$A[0][2],$C[0] // *
|
||||
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][0],$C[1], $A[4][2],$A[1][3] // A[1][3]=A[4][1]
|
||||
bcax $A[4][1],$A[1][3],$A[4][3],$A[4][2] // A[1][3]=A[4][1]
|
||||
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][4],$A[4][4],$A[4][1],$A[4][0]
|
||||
___
|
||||
( $A[1][1], $C[0]) = ( $C[0], $A[1][1]);
|
||||
($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]);
|
||||
($A[4][0],$A[4][1], $C[5],$C[6]) = ($C[5],$C[6], $A[4][0],$A[4][1]);
|
||||
}
|
||||
$code.=<<___;
|
||||
bcax $A[4][3],$A[4][3],$C[1], $A[4][4]
|
||||
bcax $A[4][4],$A[4][4],$A[1][3],$C[1] // A[1][3]=A[4][1]
|
||||
|
||||
ld1r {$C[1]},[x10],#8
|
||||
|
||||
bcax $A[3][2],$D[1], $A[3][4],$A[0][3] // A[0][3]=A[3][3]
|
||||
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]
|
||||
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
|
||||
bne .Loop_ce
|
||||
|
||||
@@ -857,7 +849,7 @@ foreach(split("\n",$code)) {
|
||||
|
||||
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;
|
||||
|
||||
print $_,"\n";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
siphash.c \
|
||||
siphash_pmeth.c \
|
||||
siphash_meth.c \
|
||||
siphash_ameth.c
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "internal/sm2.h"
|
||||
#include "internal/sm2err.h"
|
||||
#include "internal/ec_int.h" /* ecdh_KDF_X9_63() */
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.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 */
|
||||
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)) {
|
||||
SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EVP_LIB);
|
||||
goto done;
|
||||
@@ -344,7 +345,7 @@ int sm2_decrypt(const EC_KEY *key,
|
||||
|
||||
if (BN_bn2binpad(x2, x2y2, 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)) {
|
||||
SM2err(SM2_F_SM2_DECRYPT, ERR_R_INTERNAL_ERROR);
|
||||
goto done;
|
||||
|
||||
@@ -517,15 +517,14 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
|
||||
/* check_purpose() makes the callback as needed */
|
||||
if (purpose > 0 && !check_purpose(ctx, x, purpose, i, must_be_ca))
|
||||
return 0;
|
||||
/* Check pathlen if not self issued */
|
||||
if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
|
||||
&& (x->ex_pathlen != -1)
|
||||
&& (plen > (x->ex_pathlen + proxy_path_length + 1))) {
|
||||
/* Check pathlen */
|
||||
if ((i > 1) && (x->ex_pathlen != -1)
|
||||
&& (plen > (x->ex_pathlen + proxy_path_length))) {
|
||||
if (!verify_cb_cert(ctx, x, i, X509_V_ERR_PATH_LENGTH_EXCEEDED))
|
||||
return 0;
|
||||
}
|
||||
/* Increment path length if not self issued */
|
||||
if (!(x->ex_flags & EXFLAG_SI))
|
||||
/* Increment path length if not a self issued intermediate CA */
|
||||
if (i > 0 && (x->ex_flags & EXFLAG_SI) == 0)
|
||||
plen++;
|
||||
/*
|
||||
* If this certificate is a proxy certificate, the next certificate
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include "internal/x509_int.h"
|
||||
#include "ext_dat.h"
|
||||
@@ -435,6 +436,27 @@ int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc)
|
||||
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)
|
||||
{
|
||||
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);
|
||||
if (gen->type != sub->base->type)
|
||||
continue;
|
||||
if (sub->minimum || sub->maximum)
|
||||
if (!nc_minmax_valid(sub))
|
||||
return X509_V_ERR_SUBTREE_MINMAX;
|
||||
/* If we already have a match don't bother trying any more */
|
||||
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);
|
||||
if (gen->type != sub->base->type)
|
||||
continue;
|
||||
if (sub->minimum || sub->maximum)
|
||||
if (!nc_minmax_valid(sub))
|
||||
return X509_V_ERR_SUBTREE_MINMAX;
|
||||
|
||||
r = nc_match_single(gen, sub->base);
|
||||
|
||||
@@ -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
@@ -4,20 +4,55 @@
|
||||
|
||||
EVP_PKEY_CTX_ctrl,
|
||||
EVP_PKEY_CTX_ctrl_str,
|
||||
EVP_PKEY_CTX_ctrl_uint64,
|
||||
EVP_PKEY_CTX_md,
|
||||
EVP_PKEY_CTX_set_signature_md,
|
||||
EVP_PKEY_CTX_get_signature_md,
|
||||
EVP_PKEY_CTX_set_mac_key,
|
||||
EVP_PKEY_CTX_set_rsa_padding,
|
||||
EVP_PKEY_CTX_get_rsa_padding,
|
||||
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_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_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_type,
|
||||
EVP_PKEY_CTX_set_dh_rfc5114,
|
||||
EVP_PKEY_CTX_set_dhx_rfc5114,
|
||||
EVP_PKEY_CTX_set_dh_pad,
|
||||
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_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
|
||||
- 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 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,
|
||||
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_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>
|
||||
|
||||
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_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_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>
|
||||
|
||||
int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits);
|
||||
|
||||
#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_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_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_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>
|
||||
|
||||
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_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_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
|
||||
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
|
||||
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
|
||||
@@ -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
|
||||
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.
|
||||
|
||||
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
|
||||
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>.
|
||||
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,
|
||||
RSA_PKCS1_OAEP_PADDING for OAEP padding (encrypt and decrypt only),
|
||||
RSA_X931_PADDING for X9.31 padding (signature operations only) and
|
||||
RSA_PKCS1_PSS_PADDING (sign and verify only).
|
||||
=head2 RSA parameters
|
||||
|
||||
The EVP_PKEY_CTX_set_rsa_padding() macro sets the RSA padding mode for B<ctx>.
|
||||
The B<pad> parameter can take the value B<RSA_PKCS1_PADDING> for PKCS#1
|
||||
padding, B<RSA_SSLV23_PADDING> for SSLv23 padding, B<RSA_NO_PADDING> for
|
||||
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()
|
||||
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
|
||||
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
|
||||
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
|
||||
digest length, RSA_PSS_SALTLEN_MAX sets the salt length to the maximum
|
||||
permissible value. When verifying RSA_PSS_SALTLEN_AUTO causes the salt length
|
||||
B<len>. As its name implies it is only supported for PSS padding. Three special
|
||||
values are supported: B<RSA_PSS_SALTLEN_DIGEST> sets the salt length to the
|
||||
digest length, B<RSA_PSS_SALTLEN_MAX> sets the salt length to the maximum
|
||||
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
|
||||
macro is not called maximum salt length is used when signing and auto detection
|
||||
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
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
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>
|
||||
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
|
||||
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.
|
||||
|
||||
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_ffdhe4096>, B<NID_ffdhe6144> or B<NID_ffdhe8192>. This macro can be
|
||||
called during parameter or key generation.
|
||||
B<nid> as defined in RFC7919. The B<nid> parameter must be B<NID_ffdhe2048>,
|
||||
B<NID_ffdhe3072>, B<NID_ffdhe4096>, B<NID_ffdhe6144>, B<NID_ffdhe8192>
|
||||
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
|
||||
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
|
||||
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<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.
|
||||
@@ -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
|
||||
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()
|
||||
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
|
||||
@@ -191,7 +434,7 @@ L<EVP_PKEY_decrypt(3)>,
|
||||
L<EVP_PKEY_sign(3)>,
|
||||
L<EVP_PKEY_verify(3)>,
|
||||
L<EVP_PKEY_verify_recover(3)>,
|
||||
L<EVP_PKEY_derive(3)>
|
||||
L<EVP_PKEY_derive(3)>,
|
||||
L<EVP_PKEY_keygen(3)>
|
||||
|
||||
=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
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||
they have exactly the same meaning as for the RSA algorithm.
|
||||
|
||||
|
||||
@@ -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_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_EC_KEY, EVP_PKEY_get0_hmac, EVP_PKEY_type, EVP_PKEY_id,
|
||||
EVP_PKEY_base_id, EVP_PKEY_set_alias_type, EVP_PKEY_set1_engine - EVP_PKEY assignment functions
|
||||
EVP_PKEY_assign_EC_KEY, EVP_PKEY_assign_POLY1305, EVP_PKEY_assign_SIPHASH,
|
||||
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
|
||||
|
||||
@@ -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);
|
||||
|
||||
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);
|
||||
DSA *EVP_PKEY_get0_DSA(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_DH(EVP_PKEY *pkey, DH *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_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
|
||||
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_DH() and EVP_PKEY_get0_EC_KEY() also return the
|
||||
referenced key in B<pkey> or B<NULL> if the key is not of the
|
||||
correct type but the reference count of the returned key is
|
||||
B<not> incremented and so must not be freed up after use.
|
||||
EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305(), EVP_PKEY_get0_siphash(),
|
||||
EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(), EVP_PKEY_get0_DH()
|
||||
and EVP_PKEY_get0_EC_KEY() also return the referenced key in B<pkey> or B<NULL>
|
||||
if the key is not of the correct type but the reference count of the
|
||||
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()
|
||||
and EVP_PKEY_assign_EC_KEY() also set the referenced key to B<key>
|
||||
EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH(),
|
||||
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>
|
||||
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
|
||||
freed as well as B<pkey>.
|
||||
|
||||
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_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH(),
|
||||
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
|
||||
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
|
||||
an error occurred.
|
||||
|
||||
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_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH(),
|
||||
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
|
||||
type or B<NID_undef> (equivalently B<EVP_PKEY_NONE>) on error.
|
||||
|
||||
@@ -14,6 +14,9 @@ EVP_aes_256_cfb1,
|
||||
EVP_aes_128_cfb8,
|
||||
EVP_aes_192_cfb8,
|
||||
EVP_aes_256_cfb8,
|
||||
EVP_aes_128_cfb128,
|
||||
EVP_aes_192_cfb128,
|
||||
EVP_aes_256_cfb128,
|
||||
EVP_aes_128_ctr,
|
||||
EVP_aes_192_ctr,
|
||||
EVP_aes_256_ctr,
|
||||
@@ -75,6 +78,9 @@ EVP_aes_256_cfb1(),
|
||||
EVP_aes_128_cfb8(),
|
||||
EVP_aes_192_cfb8(),
|
||||
EVP_aes_256_cfb8(),
|
||||
EVP_aes_128_cfb128(),
|
||||
EVP_aes_192_cfb128(),
|
||||
EVP_aes_256_cfb128(),
|
||||
EVP_aes_128_ctr(),
|
||||
EVP_aes_192_ctr(),
|
||||
EVP_aes_256_ctr(),
|
||||
|
||||
@@ -14,6 +14,9 @@ EVP_aria_256_cfb1,
|
||||
EVP_aria_128_cfb8,
|
||||
EVP_aria_192_cfb8,
|
||||
EVP_aria_256_cfb8,
|
||||
EVP_aria_128_cfb128,
|
||||
EVP_aria_192_cfb128,
|
||||
EVP_aria_256_cfb128,
|
||||
EVP_aria_128_ctr,
|
||||
EVP_aria_192_ctr,
|
||||
EVP_aria_256_ctr,
|
||||
@@ -60,6 +63,9 @@ EVP_aria_256_cfb1(),
|
||||
EVP_aria_128_cfb8(),
|
||||
EVP_aria_192_cfb8(),
|
||||
EVP_aria_256_cfb8(),
|
||||
EVP_aria_128_cfb128(),
|
||||
EVP_aria_192_cfb128(),
|
||||
EVP_aria_256_cfb128(),
|
||||
EVP_aria_128_ctr(),
|
||||
EVP_aria_192_ctr(),
|
||||
EVP_aria_256_ctr(),
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
EVP_bf_cbc,
|
||||
EVP_bf_cfb,
|
||||
EVP_bf_cfb64,
|
||||
EVP_bf_ecb,
|
||||
EVP_bf_ofb
|
||||
- EVP Blowfish cipher
|
||||
@@ -14,6 +15,7 @@ EVP_bf_ofb
|
||||
|
||||
const EVP_CIPHER *EVP_bf_cbc(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_ofb(void)
|
||||
|
||||
@@ -27,6 +29,7 @@ This is a variable key length cipher.
|
||||
|
||||
=item EVP_bf_cbc(),
|
||||
EVP_bf_cfb(),
|
||||
EVP_bf_cfb64(),
|
||||
EVP_bf_ecb(),
|
||||
EVP_bf_ofb()
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@ EVP_camellia_256_cfb1,
|
||||
EVP_camellia_128_cfb8,
|
||||
EVP_camellia_192_cfb8,
|
||||
EVP_camellia_256_cfb8,
|
||||
EVP_camellia_128_cfb128,
|
||||
EVP_camellia_192_cfb128,
|
||||
EVP_camellia_256_cfb128,
|
||||
EVP_camellia_128_ctr,
|
||||
EVP_camellia_192_ctr,
|
||||
EVP_camellia_256_ctr,
|
||||
@@ -54,6 +57,9 @@ EVP_camellia_256_cfb1(),
|
||||
EVP_camellia_128_cfb8(),
|
||||
EVP_camellia_192_cfb8(),
|
||||
EVP_camellia_256_cfb8(),
|
||||
EVP_camellia_128_cfb128(),
|
||||
EVP_camellia_192_cfb128(),
|
||||
EVP_camellia_256_cfb128(),
|
||||
EVP_camellia_128_ctr(),
|
||||
EVP_camellia_192_ctr(),
|
||||
EVP_camellia_256_ctr(),
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
EVP_cast5_cbc,
|
||||
EVP_cast5_cfb,
|
||||
EVP_cast5_cfb64,
|
||||
EVP_cast5_ecb,
|
||||
EVP_cast5_ofb
|
||||
- EVP CAST cipher
|
||||
@@ -14,6 +15,7 @@ EVP_cast5_ofb
|
||||
|
||||
const EVP_CIPHER *EVP_cast5_cbc(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_ofb(void)
|
||||
|
||||
@@ -28,6 +30,7 @@ This is a variable key length cipher.
|
||||
=item EVP_cast5_cbc(),
|
||||
EVP_cast5_ecb(),
|
||||
EVP_cast5_cfb(),
|
||||
EVP_cast5_cfb64(),
|
||||
EVP_cast5_ofb()
|
||||
|
||||
CAST encryption algorithm in CBC, ECB, CFB and OFB modes respectively.
|
||||
|
||||
+22
-12
@@ -6,19 +6,24 @@ EVP_des_cbc,
|
||||
EVP_des_cfb,
|
||||
EVP_des_cfb1,
|
||||
EVP_des_cfb8,
|
||||
EVP_des_cfb64,
|
||||
EVP_des_ecb,
|
||||
EVP_des_ede,
|
||||
EVP_des_ede_cfb,
|
||||
EVP_des_ede_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_cbc,
|
||||
EVP_des_ede3_cfb,
|
||||
EVP_des_ede3_cfb1,
|
||||
EVP_des_ede3_cfb8,
|
||||
EVP_des_ede3_cfb64,
|
||||
EVP_des_ede3_ecb,
|
||||
EVP_des_ede3_ofb,
|
||||
EVP_des_ede3_wrap,
|
||||
EVP_des_ede_cbc
|
||||
EVP_des_ede3_wrap
|
||||
- EVP DES cipher
|
||||
|
||||
=head1 SYNOPSIS
|
||||
@@ -43,27 +48,32 @@ EVP_des_ecb(),
|
||||
EVP_des_cfb(),
|
||||
EVP_des_cfb1(),
|
||||
EVP_des_cfb8(),
|
||||
EVP_des_cfb64(),
|
||||
EVP_des_ofb()
|
||||
|
||||
DES in CBC, ECB, CFB with 128-bit shift, CFB with 1-bit shift, CFB with 8-bit
|
||||
shift and OFB modes respectively.
|
||||
DES in CBC, ECB, CFB with 64-bit shift, CFB with 1-bit shift, CFB with 8-bit
|
||||
shift and OFB modes.
|
||||
|
||||
=item EVP_des_ede(),
|
||||
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(),
|
||||
EVP_des_ede3_cbc(),
|
||||
EVP_des_ede3_cfb(),
|
||||
EVP_des_ede3_cfb1(),
|
||||
EVP_des_ede3_cfb8(),
|
||||
EVP_des_ede3_cfb64(),
|
||||
EVP_des_ede3_ecb(),
|
||||
EVP_des_ede3_ofb()
|
||||
|
||||
Three-key triple DES in ECB, CBC, CFB with 128-bit shift, CFB with 1-bit shift,
|
||||
CFB with 8-bit shift and OFB modes respectively.
|
||||
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.
|
||||
|
||||
=item EVP_des_ede3_wrap()
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
EVP_idea_cbc,
|
||||
EVP_idea_cfb,
|
||||
EVP_idea_cfb64,
|
||||
EVP_idea_ecb,
|
||||
EVP_idea_ofb
|
||||
- EVP IDEA cipher
|
||||
@@ -14,6 +15,7 @@ EVP_idea_ofb
|
||||
|
||||
const EVP_CIPHER *EVP_idea_cbc(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_ofb(void)
|
||||
|
||||
@@ -25,6 +27,7 @@ The IDEA encryption algorithm for EVP.
|
||||
|
||||
=item EVP_idea_cbc(),
|
||||
EVP_idea_cfb(),
|
||||
EVP_idea_cfb64(),
|
||||
EVP_idea_ecb(),
|
||||
EVP_idea_ofb()
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
EVP_md5
|
||||
EVP_md5,
|
||||
EVP_md5_sha1
|
||||
- MD5 For EVP
|
||||
|
||||
=head1 SYNOPSIS
|
||||
@@ -10,6 +11,7 @@ EVP_md5
|
||||
#include <openssl/evp.h>
|
||||
|
||||
const EVP_MD *EVP_md5(void);
|
||||
const EVP_MD *EVP_md5_sha1(void);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
EVP_rc2_cbc,
|
||||
EVP_rc2_cfb,
|
||||
EVP_rc2_cfb64,
|
||||
EVP_rc2_ecb,
|
||||
EVP_rc2_ofb,
|
||||
EVP_rc2_40_cbc,
|
||||
@@ -16,6 +17,7 @@ EVP_rc2_64_cbc
|
||||
|
||||
const EVP_CIPHER *EVP_rc2_cbc(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_ofb(void)
|
||||
const EVP_CIPHER *EVP_rc2_40_cbc(void)
|
||||
@@ -29,6 +31,7 @@ The RC2 encryption algorithm for EVP.
|
||||
|
||||
=item EVP_rc2_cbc(),
|
||||
EVP_rc2_cfb(),
|
||||
EVP_rc2_cfb64(),
|
||||
EVP_rc2_ecb(),
|
||||
EVP_rc2_ofb()
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
EVP_rc5_32_12_16_cbc,
|
||||
EVP_rc5_32_12_16_cfb,
|
||||
EVP_rc5_32_12_16_cfb64,
|
||||
EVP_rc5_32_12_16_ecb,
|
||||
EVP_rc5_32_12_16_ofb
|
||||
- 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_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_ofb(void)
|
||||
|
||||
@@ -25,6 +27,7 @@ The RC5 encryption algorithm for EVP.
|
||||
|
||||
=item EVP_rc5_32_12_16_cbc(),
|
||||
EVP_rc5_32_12_16_cfb(),
|
||||
EVP_rc5_32_12_16_cfb64(),
|
||||
EVP_rc5_32_12_16_ecb(),
|
||||
EVP_rc5_32_12_16_ofb()
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
EVP_seed_cbc,
|
||||
EVP_seed_cfb,
|
||||
EVP_seed_cfb128,
|
||||
EVP_seed_ecb,
|
||||
EVP_seed_ofb
|
||||
- EVP SEED cipher
|
||||
@@ -14,6 +15,7 @@ EVP_seed_ofb
|
||||
|
||||
const EVP_CIPHER *EVP_seed_cbc(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_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(),
|
||||
EVP_seed_cfb(),
|
||||
EVP_seed_cfb128(),
|
||||
EVP_seed_ecb(),
|
||||
EVP_seed_ofb()
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
EVP_sm4_cbc,
|
||||
EVP_sm4_ecb,
|
||||
EVP_sm4_cfb,
|
||||
EVP_sm4_cfb128,
|
||||
EVP_sm4_ofb,
|
||||
EVP_sm4_ctr
|
||||
- EVP SM4 cipher
|
||||
@@ -16,6 +17,7 @@ EVP_sm4_ctr
|
||||
const EVP_CIPHER *EVP_sm4_cbc(void);
|
||||
const EVP_CIPHER *EVP_sm4_ecb(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_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(),
|
||||
EVP_sm4_ecb(),
|
||||
EVP_sm4_cfb(),
|
||||
EVP_sm4_cfb128(),
|
||||
EVP_sm4_ofb(),
|
||||
EVP_sm4_ctr()
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -377,7 +377,14 @@ int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len);
|
||||
/* OPENSSL_INIT_ZLIB 0x00010000L */
|
||||
# define OPENSSL_INIT_ATFORK 0x00020000L
|
||||
/* 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 */
|
||||
|
||||
/* openssl and dasync not counted as builtin */
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
# include <openssl/symhacks.h>
|
||||
|
||||
int ERR_load_CRYPTO_strings(void);
|
||||
|
||||
/*
|
||||
|
||||
+14
-3
@@ -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);
|
||||
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 *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,
|
||||
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)
|
||||
/* KDF types */
|
||||
# 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
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#ifndef HEADER_ENVELOPE_H
|
||||
# define HEADER_ENVELOPE_H
|
||||
|
||||
# include <stdarg.h>
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
# include <openssl/ossl_typ.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 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,
|
||||
const unsigned char *enc_key, int enc_key_len,
|
||||
EVP_PKEY *private_key);
|
||||
@@ -1632,6 +1675,14 @@ void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth,
|
||||
EVP_MD_CTX *mctx));
|
||||
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
|
||||
}
|
||||
|
||||
@@ -50,6 +50,11 @@ int ERR_load_EVP_strings(void);
|
||||
# define EVP_F_EVP_DIGESTINIT_EX 128
|
||||
# define EVP_F_EVP_ENCRYPTFINAL_EX 127
|
||||
# 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_SIZE 162
|
||||
# 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_PBKDF2_KEYIVGEN 164
|
||||
# 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_RC2_MAGIC_TO_METH 109
|
||||
# define EVP_F_RC5_CTRL 125
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
# define OBJ_NAME_TYPE_CIPHER_METH 0x02
|
||||
# define OBJ_NAME_TYPE_PKEY_METH 0x03
|
||||
# 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
|
||||
|
||||
|
||||
@@ -90,6 +90,8 @@ typedef struct evp_cipher_st EVP_CIPHER;
|
||||
typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
|
||||
typedef struct evp_md_st EVP_MD;
|
||||
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_asn1_method_st EVP_PKEY_ASN1_METHOD;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
# include <time.h>
|
||||
# include <openssl/ossl_typ.h>
|
||||
# include <openssl/obj_mac.h>
|
||||
|
||||
/*
|
||||
* RAND_DRBG flags
|
||||
|
||||
+35
-54
@@ -445,15 +445,14 @@ static void get_current_time(struct timeval *t)
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
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 seq[SEQ_NUM_SIZE];
|
||||
const unsigned char *data;
|
||||
unsigned char *buf;
|
||||
size_t fragoff, fraglen, msglen;
|
||||
unsigned char *buf, *wbuf;
|
||||
size_t fragoff, fraglen, msglen, reclen, align = 0;
|
||||
unsigned int rectype, versmajor, msgseq, msgtype, clientvers, cookielen;
|
||||
BIO *rbio, *wbio;
|
||||
BUF_MEM *bufm;
|
||||
BIO_ADDR *tmpclient = NULL;
|
||||
PACKET pkt, msgpkt, msgpayload, session, cookiepkt;
|
||||
|
||||
@@ -476,13 +475,6 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
|
||||
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
|
||||
* requires the MAC to be calculated *including* the first ClientHello
|
||||
@@ -495,35 +487,32 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (s->init_buf == NULL) {
|
||||
if ((bufm = BUF_MEM_new()) == NULL) {
|
||||
SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE);
|
||||
if (!ssl3_setup_buffers(s)) {
|
||||
/* SSLerr already called */
|
||||
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 {
|
||||
/* Get a packet */
|
||||
|
||||
clear_sys_error();
|
||||
/*
|
||||
* Technically a ClientHello could be SSL3_RT_MAX_PLAIN_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);
|
||||
|
||||
n = BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH
|
||||
+ DTLS1_RT_HEADER_LENGTH);
|
||||
if (n <= 0) {
|
||||
if (BIO_should_retry(rbio)) {
|
||||
/* Non-blocking IO */
|
||||
@@ -532,9 +521,6 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
|
||||
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)) {
|
||||
SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
@@ -587,6 +573,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
|
||||
SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
|
||||
goto end;
|
||||
}
|
||||
reclen = PACKET_remaining(&msgpkt);
|
||||
/*
|
||||
* We allow data remaining at the end of the packet because there could
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
if (s->ctx->app_gen_cookie_cb == NULL ||
|
||||
s->ctx->app_gen_cookie_cb(s, cookie, &cookielen) == 0 ||
|
||||
@@ -732,7 +711,11 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
|
||||
: s->version;
|
||||
|
||||
/* 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_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
|
||||
* last 3 bytes of the message header
|
||||
*/
|
||||
memcpy(&buf[DTLS1_RT_HEADER_LENGTH + 1],
|
||||
&buf[DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH - 3],
|
||||
memcpy(&wbuf[DTLS1_RT_HEADER_LENGTH + 1],
|
||||
&wbuf[DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH - 3],
|
||||
3);
|
||||
|
||||
if (s->msg_callback)
|
||||
@@ -815,7 +798,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client)
|
||||
tmpclient = NULL;
|
||||
|
||||
/* 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)) {
|
||||
/*
|
||||
* 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)
|
||||
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;
|
||||
clearpkt = 0;
|
||||
end:
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -185,14 +185,11 @@ int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* insert should not fail, since duplicates are dropped */
|
||||
if (pqueue_insert(queue->q, item) == NULL) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_BUFFER_RECORD,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
/* Must be a duplicate so ignore it */
|
||||
OPENSSL_free(rdata->rbuf.buf);
|
||||
OPENSSL_free(rdata);
|
||||
pitem_free(item);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -188,6 +188,8 @@ typedef struct record_layer_st {
|
||||
((rl)->d->processed_rcds)
|
||||
#define DTLS_RECORD_LAYER_get_unprocessed_rcds(rl) \
|
||||
((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_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,
|
||||
size_t len, int create_empty_fragment, size_t *written);
|
||||
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);
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
/* 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_set_packet(rl, p) ((rl)->packet = (p))
|
||||
#define RECORD_LAYER_reset_packet_length(rl) ((rl)->packet_length = 0)
|
||||
|
||||
@@ -2030,3 +2030,28 @@ int dtls1_get_record(SSL *s)
|
||||
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
@@ -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
|
||||
* 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
|
||||
* 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
|
||||
* short and there obviously cannot be this many blocks then
|
||||
* 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
|
||||
* bytes of `header' before the start of the data (TLS) or 71/75 bytes
|
||||
|
||||
+2
-1
@@ -199,7 +199,8 @@ int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS * settings)
|
||||
| OPENSSL_INIT_LOAD_CONFIG
|
||||
#endif
|
||||
| OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS,
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_ADD_ALL_MACS,
|
||||
settings))
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
size_t hdatalen;
|
||||
long hdatalen_l;
|
||||
void *hdata;
|
||||
|
||||
hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
|
||||
if (hdatalen <= 0) {
|
||||
hdatalen = hdatalen_l =
|
||||
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,
|
||||
SSL_R_BAD_HANDSHAKE_LENGTH);
|
||||
goto err;
|
||||
|
||||
@@ -1095,6 +1095,7 @@ WORK_STATE ossl_statem_client_post_process_message(SSL *s, WORK_STATE wst)
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return WORK_ERROR;
|
||||
|
||||
case TLS_ST_CR_CERT_VRFY:
|
||||
case TLS_ST_CR_CERT_REQ:
|
||||
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.... */
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
+14
-2
@@ -203,9 +203,10 @@ static int get_cert_verify_tbs_data(SSL *s, unsigned char *tls13tbs,
|
||||
*hdatalen = TLS13_TBS_PREAMBLE_SIZE + hashlen;
|
||||
} else {
|
||||
size_t retlen;
|
||||
long retlen_l;
|
||||
|
||||
retlen = BIO_get_mem_data(s->s3->handshake_buffer, hdata);
|
||||
if (retlen <= 0) {
|
||||
retlen = retlen_l = BIO_get_mem_data(s->s3->handshake_buffer, hdata);
|
||||
if (retlen_l <= 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_GET_CERT_VERIFY_TBS_DATA,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
@@ -494,6 +495,17 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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:
|
||||
BIO_free(s->s3->handshake_buffer);
|
||||
|
||||
@@ -1519,10 +1519,12 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt)
|
||||
* So check cookie length...
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PACKET_get_length_prefixed_2(pkt, &clienthello->ciphersuites)) {
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO,
|
||||
@@ -3225,6 +3227,12 @@ static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt)
|
||||
SSL_R_LENGTH_MISMATCH);
|
||||
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();
|
||||
if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) <= 0) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE,
|
||||
|
||||
+2
-4
@@ -436,10 +436,8 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=main
|
||||
# available through the shared library (at least on Linux, Solaris, Windows
|
||||
# and VMS, where the exported symbols are those listed in util/*.num), these
|
||||
# programs are forcibly linked with the static libraries, where all symbols
|
||||
# are always available. This excludes linking these programs natively on
|
||||
# Windows when building shared libraries, since the static libraries share
|
||||
# names with the DLL import libraries.
|
||||
IF[{- $disabled{shared} || $target{build_scheme}->[1] ne 'windows' -}]
|
||||
# are always available.
|
||||
IF[1]
|
||||
PROGRAMS_NO_INST=asn1_internal_test modes_internal_test x509_internal_test \
|
||||
tls13encryptiontest wpackettest ctype_internal_test \
|
||||
rdrand_sanitytest
|
||||
|
||||
+85
-41
@@ -677,7 +677,7 @@ static int test_drbg_reseed(int expect_success,
|
||||
* setup correctly, in particular whether reseeding works
|
||||
* as designed.
|
||||
*/
|
||||
static int test_rand_reseed(void)
|
||||
static int test_rand_drbg_reseed(void)
|
||||
{
|
||||
RAND_DRBG *master, *public, *private;
|
||||
unsigned char rand_add_buf[256];
|
||||
@@ -884,64 +884,107 @@ static int test_multi_thread(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_RAND_SEED_NONE
|
||||
/*
|
||||
* This function only returns the entropy already added with RAND_add(),
|
||||
* and does not get entropy from the OS.
|
||||
* Calculates the minimum buffer length which needs to be
|
||||
* 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,
|
||||
unsigned char **pout,
|
||||
int entropy, size_t min_len, size_t max_len,
|
||||
int prediction_resistance)
|
||||
static size_t rand_drbg_seedlen(RAND_DRBG *drbg)
|
||||
{
|
||||
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)
|
||||
return 0;
|
||||
|
||||
*pout = drbg->pool->buffer;
|
||||
return drbg->pool->len;
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up the entropy that get_pool_entropy() returned.
|
||||
* Convert entropy requirement from bits to bytes
|
||||
* (dividing by 8 without rounding upwards, because
|
||||
* all entropy requirements are divisible by 8).
|
||||
*/
|
||||
static void cleanup_pool_entropy(RAND_DRBG *drbg, unsigned char *out, size_t outlen)
|
||||
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)
|
||||
{
|
||||
OPENSSL_free(drbg->pool);
|
||||
drbg->pool = NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that instantiating works when OS entropy is not available and that
|
||||
* RAND_add() is enough to reseed it.
|
||||
* Test that adding additional data with RAND_add() works as expected
|
||||
* when the master DRBG is instantiated (and below its reseed limit).
|
||||
*
|
||||
* This should succeed regardless of whether an os entropy source is
|
||||
* available or not.
|
||||
*/
|
||||
static int test_rand_add(void)
|
||||
{
|
||||
RAND_DRBG *master = RAND_DRBG_get0_master();
|
||||
RAND_DRBG_get_entropy_fn old_get_entropy = master->get_entropy;
|
||||
RAND_DRBG_cleanup_entropy_fn old_cleanup_entropy = master->cleanup_entropy;
|
||||
int rv = 0;
|
||||
unsigned char rand_add_buf[256];
|
||||
unsigned char rand_buf[256];
|
||||
size_t rand_buflen;
|
||||
|
||||
master->get_entropy = get_pool_entropy;
|
||||
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;
|
||||
memset(rand_buf, 0xCD, sizeof(rand_buf));
|
||||
|
||||
rv = 1;
|
||||
/* make sure it's instantiated */
|
||||
RAND_seed(rand_buf, sizeof(rand_buf));
|
||||
if (!TEST_true(RAND_status()))
|
||||
return 0;
|
||||
|
||||
error:
|
||||
master->get_entropy = old_get_entropy;
|
||||
master->cleanup_entropy = old_cleanup_entropy;
|
||||
return rv;
|
||||
for ( rand_buflen = 256 ; rand_buflen > 0 ; --rand_buflen ) {
|
||||
RAND_add(rand_buf, rand_buflen, 0.0);
|
||||
if (!TEST_true(RAND_status()))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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_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_multi_set);
|
||||
ADD_TEST(test_set_defaults);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/ssl.h>
|
||||
@@ -240,6 +241,89 @@ static int test_dtls_drop_records(int idx)
|
||||
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)
|
||||
{
|
||||
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_drop_records, TOTAL_RECORDS);
|
||||
ADD_TEST(test_cookie);
|
||||
ADD_TEST(test_dtls_duplicate_records);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include "testutil.h"
|
||||
#include "internal/nelem.h"
|
||||
#include "internal/evp_int.h"
|
||||
@@ -918,6 +919,50 @@ static int test_EVP_PKEY_check(int i)
|
||||
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)
|
||||
{
|
||||
ADD_TEST(test_EVP_DigestSignInit);
|
||||
@@ -941,5 +986,6 @@ int setup_tests(void)
|
||||
if (!TEST_int_eq(EVP_PKEY_meth_add0(custom_pmeth), 1))
|
||||
return 0;
|
||||
ADD_ALL_TESTS(test_EVP_PKEY_check, OSSL_NELEM(keycheckdata));
|
||||
ADD_TEST(test_HKDF);
|
||||
return 1;
|
||||
}
|
||||
+189
-15
@@ -73,8 +73,6 @@ static KEY_LIST *public_keys;
|
||||
static int find_key(EVP_PKEY **ppk, const char *name, KEY_LIST *lst);
|
||||
|
||||
static int parse_bin(const char *value, unsigned char **buf, size_t *buflen);
|
||||
static int pkey_test_ctrl(EVP_TEST *t, EVP_PKEY_CTX *pctx,
|
||||
const char *value);
|
||||
|
||||
/*
|
||||
* 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 {
|
||||
/* MAC type */
|
||||
int type;
|
||||
/* MAC type in one form or another */
|
||||
const EVP_MAC *mac; /* for mac_test_run_mac */
|
||||
int type; /* for mac_test_run_pkey */
|
||||
/* Algorithm string for this MAC */
|
||||
char *alg;
|
||||
/* MAC key */
|
||||
@@ -851,37 +850,63 @@ typedef struct mac_data_st {
|
||||
|
||||
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;
|
||||
|
||||
if (strcmp(alg, "HMAC") == 0) {
|
||||
if ((mac = EVP_get_macbyname(alg)) == NULL) {
|
||||
/*
|
||||
* 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 (strcmp(alg, "CMAC") == 0) {
|
||||
} else if (strncmp(alg, "CMAC", sz) == 0) {
|
||||
#ifndef OPENSSL_NO_CMAC
|
||||
type = EVP_PKEY_CMAC;
|
||||
#else
|
||||
t->skip = 1;
|
||||
return 1;
|
||||
#endif
|
||||
} else if (strcmp(alg, "Poly1305") == 0) {
|
||||
} else if (strncmp(alg, "Poly1305", sz) == 0) {
|
||||
#ifndef OPENSSL_NO_POLY1305
|
||||
type = EVP_PKEY_POLY1305;
|
||||
#else
|
||||
t->skip = 1;
|
||||
return 1;
|
||||
#endif
|
||||
} else if (strcmp(alg, "SipHash") == 0) {
|
||||
} else if (strncmp(alg, "SipHash", sz) == 0) {
|
||||
#ifndef OPENSSL_NO_SIPHASH
|
||||
type = EVP_PKEY_SIPHASH;
|
||||
#else
|
||||
t->skip = 1;
|
||||
return 1;
|
||||
#endif
|
||||
} else
|
||||
} else {
|
||||
/*
|
||||
* 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->type = type;
|
||||
mdat->mac = mac;
|
||||
mdat->controls = sk_OPENSSL_STRING_new_null();
|
||||
t->data = mdat;
|
||||
return 1;
|
||||
@@ -927,7 +952,29 @@ static int mac_test_parse(EVP_TEST *t,
|
||||
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;
|
||||
EVP_MD_CTX *mctx = NULL;
|
||||
@@ -938,6 +985,12 @@ static int mac_test_run(EVP_TEST *t)
|
||||
size_t got_len;
|
||||
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
|
||||
if (expected->alg != NULL && strstr(expected->alg, "DES") != NULL) {
|
||||
/* Skip DES */
|
||||
@@ -972,8 +1025,9 @@ static int mac_test_run(EVP_TEST *t)
|
||||
goto err;
|
||||
}
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(expected->controls); i++)
|
||||
if (!pkey_test_ctrl(t, pctx,
|
||||
sk_OPENSSL_STRING_value(expected->controls, i))) {
|
||||
if (!mac_test_ctrl_pkey(t, pctx,
|
||||
sk_OPENSSL_STRING_value(expected->controls,
|
||||
i))) {
|
||||
t->err = "EVPPKEYCTXCTRL_ERROR";
|
||||
goto err;
|
||||
}
|
||||
@@ -1005,6 +1059,126 @@ static int mac_test_run(EVP_TEST *t)
|
||||
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 = {
|
||||
"MAC",
|
||||
mac_test_init,
|
||||
@@ -2614,8 +2788,8 @@ top:
|
||||
return 0;
|
||||
}
|
||||
if (rv < 0) {
|
||||
TEST_info("Line %d: error processing keyword %s\n",
|
||||
t->s.curr, pp->key);
|
||||
TEST_info("Line %d: error processing keyword %s = %s\n",
|
||||
t->s.curr, pp->key, pp->value);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user