Latest update

This commit is contained in:
2019-04-26 08:41:22 +09:00
parent 704c3822e0
commit a7bf77581f
91 changed files with 4677 additions and 389 deletions
+11
View File
@@ -9,6 +9,17 @@
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
*) Added command 'openssl kdf' that uses the EVP_KDF API.
[Shane Lontis]
*) Added command 'openssl mac' that uses the EVP_MAC API.
[Shane Lontis]
*) Added OPENSSL_info() to get diverse built-in OpenSSL data, such
as default directories. Also added the command 'openssl info'
for scripting purposes.
[Richard Levitte]
*) The functions AES_ige_encrypt() and AES_bi_ige_encrypt() have been
deprecated. These undocumented functions were never integrated into the EVP
layer and implement the AES Infinite Garble Extension (IGE) mode and AES
+4 -1
View File
@@ -32,7 +32,10 @@ my %shared_info;
return {
%{$shared_info{'gnu-shared'}},
shared_defflag => '-Wl,--version-script=',
dso_ldflags => '-z defs',
dso_ldflags =>
$disabled{asan} && $disabled{msan} && $disabled{ubsan}
? '-z defs'
: '',
};
},
'bsd-gcc-shared' => sub { return $shared_info{'linux-shared'}; },
+75 -40
View File
@@ -892,9 +892,6 @@ while (@argvcopy)
elsif (/^-static$/)
{
push @{$useradd{LDFLAGS}}, $_;
$disabled{"pic"} = "forced";
$disabled{"shared"} = "forced";
$disabled{"threads"} = "forced";
}
elsif (/^-D(.*)$/)
{
@@ -1006,20 +1003,30 @@ if (grep { /-rpath\b/ } ($user{LDFLAGS} ? @{$user{LDFLAGS}} : ())
"***** any of asan, msan or ubsan\n";
}
my @tocheckfor = (keys %disabled);
while (@tocheckfor) {
sub disable {
my $disable_type = shift;
for (@_) {
$disabled{$_} = $disable_type;
}
my @tocheckfor = (@_ ? @_ : keys %disabled);
while (@tocheckfor) {
my %new_tocheckfor = ();
my @cascade_copy = (@disable_cascades);
while (@cascade_copy) {
my ($test, $descendents) = (shift @cascade_copy, shift @cascade_copy);
my ($test, $descendents) =
(shift @cascade_copy, shift @cascade_copy);
if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
foreach(grep { !defined($disabled{$_}) } @$descendents) {
$new_tocheckfor{$_} = 1; $disabled{$_} = "forced";
foreach (grep { !defined($disabled{$_}) } @$descendents) {
$new_tocheckfor{$_} = 1; $disabled{$_} = "cascade";
}
}
}
@tocheckfor = (keys %new_tocheckfor);
}
}
disable(); # First cascade run
our $die = sub { die @_; };
if ($target eq "TABLE") {
@@ -1144,6 +1151,8 @@ $target{module_ldflags} = $target{shared_ldflag} unless defined $target{module_l
my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
$config{conf_files} = [ sort keys %conf_files ];
# Using sub disable within these loops may prove fragile, so we run
# a cascade afterwards
foreach my $feature (@{$target{disable}}) {
if (exists $deprecated_disablables{$feature}) {
warn "***** config $target disables deprecated feature $feature\n";
@@ -1162,6 +1171,7 @@ foreach my $feature (@{$target{enable}}) {
delete $disabled{$feature};
}
}
disable(); # Run a cascade now
$target{CXXFLAGS}//=$target{CFLAGS} if $target{CXX};
$target{cxxflags}//=$target{cflags} if $target{CXX};
@@ -1202,6 +1212,22 @@ foreach (keys %user) {
delete $config{$_} unless defined $config{$_};
}
# Finish up %config by appending things the user gave us on the command line
# apart from "make variables"
foreach (keys %useradd) {
# The must all be lists, so we assert that here
die "internal error: \$useradd{$_} isn't an ARRAY\n"
unless ref $useradd{$_} eq 'ARRAY';
if (defined $config{$_}) {
push @{$config{$_}}, @{$useradd{$_}};
} else {
$config{$_} = [ @{$useradd{$_}} ];
}
}
# At this point, we can forget everything about %user and %useradd,
# because it's now all been merged into the corresponding $config entry
# Allow overriding the build file name
$config{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile";
@@ -1281,8 +1307,7 @@ if ($target =~ /^mingw/ && `$config{CC} --target-help 2>&1` =~ m/-mno-cygwin/m)
}
if ($target =~ /linux.*-mips/ && !$disabled{asm}
&& !grep { $_ !~ /-m(ips|arch=)/ } (@{$user{CFLAGS}},
@{$useradd{CFLAGS}})) {
&& !grep { $_ !~ /-m(ips|arch=)/ } (@{$config{CFLAGS}})) {
# minimally required architecture flags for assembly modules
my $value;
$value = '-mips2' if ($target =~ /mips32/);
@@ -1296,7 +1321,7 @@ unless ($disabled{threads}) {
if ($auto_threads) {
# Enabled by default, disable it forcibly if unavailable
if ($target{thread_scheme} eq "(unknown)") {
$disabled{threads} = "unavailable";
disable("unavailable", 'threads');
}
} else {
# The user chose to enable threads explicitly, let's see
@@ -1307,8 +1332,7 @@ unless ($disabled{threads}) {
# system-dependent compiler options that are necessary. We
# can't truly check that the given options are correct, but
# we expect the user to know what [s]He is doing.
if (!@{$user{CFLAGS}} && !@{$useradd{CFLAGS}}
&& !@{$user{CPPDEFINES}} && !@{$useradd{CPPDEFINES}}) {
if (!@{$config{CFLAGS}} && !@{$config{CPPDEFINES}}) {
die "You asked for multi-threading support, but didn't\n"
,"provide any system-specific compiler options\n";
}
@@ -1316,6 +1340,27 @@ unless ($disabled{threads}) {
}
}
# Find out if clang's sanitizers have been enabled with -fsanitize
# flags and ensure that the corresponding %disabled elements area
# removed to reflect that the sanitizers are indeed enabled.
my %detected_sanitizers = ();
foreach (grep /^-fsanitize=/, @{$config{CFLAGS} || []}) {
(my $checks = $_) =~ s/^-fsanitize=//;
foreach (split /,/, $checks) {
my $d = { address => 'asan',
undefined => 'ubsan',
memory => 'msan' } -> {$_};
next unless defined $d;
$detected_sanitizers{$d} = 1;
if (defined $disabled{$d}) {
die "***** Conflict between disabling $d and enabling $_ sanitizer"
if $disabled{$d} ne "default";
delete $disabled{$d};
}
}
}
# If threads still aren't disabled, add a C macro to ensure the source
# code knows about it. Any other flag is taken care of by the configs.
unless($disabled{threads}) {
@@ -1332,8 +1377,7 @@ if ($target{shared_target} eq "")
{
$no_shared_warn = 1
if (!$disabled{shared} || !$disabled{"dynamic-engine"});
$disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} =
$disabled{module} = "no-shared-target";
disable('no-shared-target', 'pic');
}
if ($disabled{"dynamic-engine"}) {
@@ -1344,12 +1388,12 @@ if ($disabled{"dynamic-engine"}) {
$config{dynamic_engines} = 1;
}
unless ($disabled{asan}) {
unless ($disabled{asan} || defined $detected_sanitizers{asan}) {
push @{$config{cflags}}, "-fsanitize=address";
push @{$config{cxxflags}}, "-fsanitize=address" if $config{CXX};
}
unless ($disabled{ubsan}) {
unless ($disabled{ubsan} || defined $detected_sanitizers{ubsan}) {
# -DPEDANTIC or -fnosanitize=alignment may also be required on some
# platforms.
push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all";
@@ -1357,7 +1401,7 @@ unless ($disabled{ubsan}) {
if $config{CXX};
}
unless ($disabled{msan}) {
unless ($disabled{msan} || defined $detected_sanitizers{msan}) {
push @{$config{cflags}}, "-fsanitize=memory";
push @{$config{cxxflags}}, "-fsanitize=memory" if $config{CXX};
}
@@ -1482,7 +1526,7 @@ if (!$disabled{makedepend}) {
# In all other cases, we look for 'makedepend', and disable the
# capability if not found.
$config{makedepprog} = which('makedepend');
$disabled{makedepend} = "unavailable" unless $config{makedepprog};
disable('unavailable', 'makedepend') unless $config{makedepprog};
}
}
@@ -1569,12 +1613,17 @@ if ($strict_warnings)
@{$clang_devteam_warn{CXXFLAGS}}
if (defined($predefined_CXX{__clang__}));
}
if (grep { $_ eq '-static' } @{$config{LDFLAGS}}) {
disable('static', 'pic', 'threads');
}
foreach my $idx (qw(CFLAGS CXXFLAGS))
{
$useradd{$idx} = [ map { $_ eq '--ossl-strict-warnings'
$config{$idx} = [ map { $_ eq '--ossl-strict-warnings'
? @{$strict_warnings_collection{$idx}}
: ( $_ ) }
@{$useradd{$idx}} ];
@{$config{$idx}} ];
}
unless ($disabled{"crypto-mdebug-backtrace"})
@@ -1603,15 +1652,15 @@ unless ($disabled{afalgeng}) {
($mi2) = $mi2 =~ /(\d+)/;
my $ver = $ma*10000 + $mi1*100 + $mi2;
if ($ver < $minver) {
$disabled{afalgeng} = "too-old-kernel";
disable('too-old-kernel', 'afalgeng');
} else {
push @{$config{engdirs}}, "afalg";
}
} else {
$disabled{afalgeng} = "cross-compiling";
disable('cross-compiling', 'afalgeng');
}
} else {
$disabled{afalgeng} = "not-linux";
disable('not-linux', 'afalgeng');
}
}
@@ -1629,29 +1678,15 @@ unless ($disabled{ktls}) {
my @verstr = split(" ",`cat $usr/include/linux/version.h | grep LINUX_VERSION_CODE`);
if ($verstr[2] < $minver) {
$disabled{ktls} = "too-old-kernel";
disable('too-old-kernel', 'ktls');
}
} else {
$disabled{ktls} = "not-linux";
disable('not-linux', 'ktls');
}
}
push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
# Finish up %config by appending things the user gave us on the command line
# apart from "make variables"
foreach (keys %useradd) {
# The must all be lists, so we assert that here
die "internal error: \$useradd{$_} isn't an ARRAY\n"
unless ref $useradd{$_} eq 'ARRAY';
if (defined $config{$_}) {
push @{$config{$_}}, @{$useradd{$_}};
} else {
$config{$_} = [ @{$useradd{$_}} ];
}
}
# ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
# If we use the unified build, collect information from build.info files
+5
View File
@@ -7,6 +7,9 @@
Major changes between OpenSSL 1.1.1 and OpenSSL 3.0.0 [under development]
o Added 'openssl mac' that uses the EVP_MAC API.
o Added 'openssl kdf' that uses the EVP_KDF API.
o Add OPENSSL_info() and 'openssl info' to get built-in data.
o Add support for enabling instrumentation through trace and debug
output.
o Changed our version number scheme and set the next major release to
@@ -14,6 +17,8 @@
o Added EVP_MAC, an EVP layer MAC API, and a generic EVP_PKEY to EVP_MAC
bridge.
o Removed the heartbeat message in DTLS feature.
o Added EVP_KDF, an EVP layer KDF API, and a generic EVP_PKEY to EVP_KDF
bridge.
Major changes between OpenSSL 1.1.1 and OpenSSL 1.1.1a [20 Nov 2018]
+5 -7
View File
@@ -170,17 +170,17 @@ int asn1parse_main(int argc, char **argv)
if (derfile && (derout = bio_open_default(derfile, 'w', FORMAT_ASN1)) == NULL)
goto end;
if ((buf = BUF_MEM_new()) == NULL)
goto end;
if (strictpem) {
if (PEM_read_bio(in, &name, &header, &str, &num) !=
1) {
if (PEM_read_bio(in, &name, &header, &str, &num) != 1) {
BIO_printf(bio_err, "Error reading PEM file\n");
ERR_print_errors(bio_err);
goto end;
}
buf->data = (char *)str;
buf->length = buf->max = num;
} else {
if ((buf = BUF_MEM_new()) == NULL)
goto end;
if (!BUF_MEM_grow(buf, BUFSIZ * 8))
goto end; /* Pre-allocate :-) */
@@ -303,8 +303,6 @@ int asn1parse_main(int argc, char **argv)
BUF_MEM_free(buf);
OPENSSL_free(name);
OPENSSL_free(header);
if (strictpem)
OPENSSL_free(str);
ASN1_TYPE_free(at);
sk_OPENSSL_STRING_free(osk);
return ret;
+3 -2
View File
@@ -2,10 +2,11 @@
qw(openssl.c
asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c dhparam.c
dsa.c dsaparam.c ec.c ecparam.c enc.c engine.c errstr.c gendsa.c
genpkey.c genrsa.c mac.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c
genpkey.c genrsa.c kdf.c mac.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c
pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c
rsautl.c s_client.c s_server.c s_time.c sess_id.c smime.c speed.c
spkac.c srp.c ts.c verify.c version.c x509.c rehash.c storeutl.c);
spkac.c srp.c ts.c verify.c version.c x509.c rehash.c storeutl.c
info.c);
our @apps_lib_src =
( qw(apps.c apps_ui.c opt.c fmt.c s_cb.c s_socket.c app_rand.c
bf_prefix.c),
+97
View File
@@ -0,0 +1,97 @@
/*
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <openssl/crypto.h>
#include "apps.h"
#include "progs.h"
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_CONFIGDIR, OPT_ENGINESDIR, OPT_MODULESDIR, OPT_DSOEXT, OPT_DIRNAMESEP,
OPT_LISTSEP
} OPTION_CHOICE;
const OPTIONS info_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"configdir", OPT_CONFIGDIR, '-', "Default configuration file directory"},
{"c", OPT_CONFIGDIR, '-', "Default configuration file directory"},
{"enginesdir", OPT_ENGINESDIR, '-', "Default engine module directory"},
{"e", OPT_ENGINESDIR, '-', "Default engine module directory"},
{"modulesdir", OPT_ENGINESDIR, '-',
"Default module directory (other than engine modules)"},
{"m", OPT_ENGINESDIR, '-',
"Default module directory (other than engine modules)"},
{"dsoext", OPT_DSOEXT, '-', "Configured extension for modules"},
{"dirnamesep", OPT_DIRNAMESEP, '-', "Directory-filename separator"},
{"listsep", OPT_LISTSEP, '-', "List separator character"},
{NULL}
};
int info_main(int argc, char **argv)
{
int ret = 1, dirty = 0, type = 0;
char *prog;
OPTION_CHOICE o;
prog = opt_init(argc, argv, info_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
case OPT_EOF:
case OPT_ERR:
opthelp:
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
goto end;
case OPT_HELP:
opt_help(info_options);
ret = 0;
goto end;
case OPT_CONFIGDIR:
type = OPENSSL_INFO_CONFIG_DIR;
dirty++;
break;
case OPT_ENGINESDIR:
type = OPENSSL_INFO_ENGINES_DIR;
dirty++;
break;
case OPT_MODULESDIR:
type = OPENSSL_INFO_MODULES_DIR;
dirty++;
break;
case OPT_DSOEXT:
type = OPENSSL_INFO_DSO_EXTENSION;
dirty++;
break;
case OPT_DIRNAMESEP:
type = OPENSSL_INFO_DIR_FILENAME_SEPARATOR;
dirty++;
break;
case OPT_LISTSEP:
type = OPENSSL_INFO_LIST_SEPARATOR;
dirty++;
break;
}
}
if (opt_num_rest() != 0) {
BIO_printf(bio_err, "%s: Extra parameters given.\n", prog);
goto opthelp;
}
if (dirty > 1) {
BIO_printf(bio_err, "%s: Only one item allowed\n", prog);
goto opthelp;
}
if (dirty == 0) {
BIO_printf(bio_err, "%s: No items chosen\n", prog);
goto opthelp;
}
BIO_printf(bio_out, "%s\n", OPENSSL_info(type));
ret = 0;
end:
return ret;
}
+158
View File
@@ -0,0 +1,158 @@
/*
* Copyright 2019 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 "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/kdf.h>
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_KDFOPT, OPT_BIN, OPT_KEYLEN, OPT_OUT
} OPTION_CHOICE;
const OPTIONS kdf_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [options] kdf_name\n"},
{OPT_HELP_STR, 1, '-', "kdf_name\t KDF algorithm.\n"},
{"help", OPT_HELP, '-', "Display this summary"},
{"kdfopt", OPT_KDFOPT, 's', "KDF algorithm control parameters in n:v form. "
"See 'Supported Controls' in the EVP_KDF_ docs"},
{"keylen", OPT_KEYLEN, 's', "The size of the output derived key"},
{"out", OPT_OUT, '>', "Output to filename rather than stdout"},
{"binary", OPT_BIN, '-', "Output in binary format (Default is hexadecimal "
"output)"},
{NULL}
};
static int kdf_ctrl_string(EVP_KDF_CTX *ctx, const char *value)
{
int rv;
char *stmp, *vtmp = NULL;
stmp = OPENSSL_strdup(value);
if (stmp == NULL)
return -1;
vtmp = strchr(stmp, ':');
if (vtmp != NULL) {
*vtmp = 0;
vtmp++;
}
rv = EVP_KDF_ctrl_str(ctx, stmp, vtmp);
OPENSSL_free(stmp);
return rv;
}
int kdf_main(int argc, char **argv)
{
int ret = 1, i, id, out_bin = 0;
OPTION_CHOICE o;
STACK_OF(OPENSSL_STRING) *opts = NULL;
char *prog, *hexout = NULL;
const char *outfile = NULL;
unsigned char *dkm_bytes = NULL;
size_t dkm_len = 0;
BIO *out = NULL;
EVP_KDF_CTX *ctx = NULL;
prog = opt_init(argc, argv, kdf_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
default:
opthelp:
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
goto err;
case OPT_HELP:
opt_help(kdf_options);
ret = 0;
goto err;
case OPT_BIN:
out_bin = 1;
break;
case OPT_KEYLEN:
dkm_len = (size_t)atoi(opt_arg());
break;
case OPT_OUT:
outfile = opt_arg();
break;
case OPT_KDFOPT:
if (opts == NULL)
opts = sk_OPENSSL_STRING_new_null();
if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg()))
goto opthelp;
break;
}
}
argc = opt_num_rest();
argv = opt_rest();
if (argc != 1) {
BIO_printf(bio_err, "Invalid number of extra arguments\n");
goto opthelp;
}
id = OBJ_sn2nid(argv[0]);
if (id == NID_undef) {
BIO_printf(bio_err, "Invalid KDF name %s\n", argv[0]);
goto opthelp;
}
ctx = EVP_KDF_CTX_new_id(id);
if (ctx == NULL)
goto err;
if (opts != NULL) {
for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
char *opt = sk_OPENSSL_STRING_value(opts, i);
if (kdf_ctrl_string(ctx, opt) <= 0) {
BIO_printf(bio_err, "KDF parameter error '%s'\n", opt);
ERR_print_errors(bio_err);
goto err;
}
}
}
out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
if (out == NULL)
goto err;
if (dkm_len <= 0) {
BIO_printf(bio_err, "Invalid derived key length.\n");
goto err;
}
dkm_bytes = app_malloc(dkm_len, "out buffer");
if (dkm_bytes == NULL)
goto err;
if (!EVP_KDF_derive(ctx, dkm_bytes, dkm_len)) {
BIO_printf(bio_err, "EVP_KDF_derive failed\n");
goto err;
}
if (out_bin) {
BIO_write(out, dkm_bytes, dkm_len);
} else {
hexout = OPENSSL_buf2hexstr(dkm_bytes, dkm_len);
BIO_printf(out, "%s\n\n", hexout);
}
ret = 0;
err:
if (ret != 0)
ERR_print_errors(bio_err);
OPENSSL_clear_free(dkm_bytes, dkm_len);
sk_OPENSSL_STRING_free(opts);
EVP_KDF_CTX_free(ctx);
BIO_free(out);
OPENSSL_free(hexout);
return ret;
}
+3
View File
@@ -51,6 +51,9 @@ print <<"EOF";
* https://www.openssl.org/source/license.html
*/
#include <openssl/lhash.h>
#include "opt.h"
typedef enum FUNC_TYPE {
FT_none, FT_general, FT_md, FT_cipher, FT_pkey,
FT_md_alg, FT_cipher_alg
+10 -3
View File
@@ -33,7 +33,7 @@
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_B, OPT_D, OPT_E, OPT_F, OPT_O, OPT_P, OPT_V, OPT_A, OPT_R
OPT_B, OPT_D, OPT_E, OPT_M, OPT_F, OPT_O, OPT_P, OPT_V, OPT_A, OPT_R
} OPTION_CHOICE;
const OPTIONS version_options[] = {
@@ -42,6 +42,7 @@ const OPTIONS version_options[] = {
{"b", OPT_B, '-', "Show build date"},
{"d", OPT_D, '-', "Show configuration directory"},
{"e", OPT_E, '-', "Show engines directory"},
{"m", OPT_M, '-', "Show modules directory"},
{"f", OPT_F, '-', "Show compiler flags used"},
{"o", OPT_O, '-', "Show some internal datatype options"},
{"p", OPT_P, '-', "Show target build platform"},
@@ -64,7 +65,7 @@ int version_main(int argc, char **argv)
{
int ret = 1, dirty = 0, seed = 0;
int cflags = 0, version = 0, date = 0, options = 0, platform = 0, dir = 0;
int engdir = 0;
int engdir = 0, moddir = 0;
char *prog;
OPTION_CHOICE o;
@@ -89,6 +90,9 @@ opthelp:
case OPT_E:
dirty = engdir = 1;
break;
case OPT_M:
dirty = moddir = 1;
break;
case OPT_F:
dirty = cflags = 1;
break;
@@ -105,7 +109,8 @@ opthelp:
dirty = version = 1;
break;
case OPT_A:
seed = options = cflags = version = date = platform = dir = engdir
seed = options = cflags = version = date = platform
= dir = engdir = moddir
= 1;
break;
}
@@ -155,6 +160,8 @@ opthelp:
printf("%s\n", OpenSSL_version(OPENSSL_DIR));
if (engdir)
printf("%s\n", OpenSSL_version(OPENSSL_ENGINES_DIR));
if (moddir)
printf("%s\n", OpenSSL_version(OPENSSL_MODULES_DIR));
if (seed) {
printf("Seeding source:");
#ifdef OPENSSL_RAND_SEED_RTDSC
+1 -1
View File
@@ -3,7 +3,7 @@
SUBDIRS=crypto ssl apps test util tools fuzz engines providers
LIBS=libcrypto libssl
INCLUDE[libcrypto]=. crypto/include include
INCLUDE[libcrypto]=. crypto/include include providers/common/include
INCLUDE[libssl]=. include
DEPEND[libssl]=libcrypto
+389 -5
View File
@@ -27,18 +27,34 @@
# CBC encrypt case. On Cortex-A57 parallelizable mode performance
# seems to be limited by sheer amount of NEON instructions...
#
# April 2019
#
# Key to performance of parallelize-able modes is round instruction
# interleaving. But which factor to use? There is optimal one for
# each combination of instruction latency and issue rate, beyond
# which increasing interleave factor doesn't pay off. While on cons
# side we have code size increase and resource waste on platforms for
# which interleave factor is too high. In other words you want it to
# be just right. So far interleave factor of 3x was serving well all
# platforms. But for ThunderX2 optimal interleave factor was measured
# to be 5x...
#
# Performance in cycles per byte processed with 128-bit key:
#
# CBC enc CBC dec CTR
# Apple A7 2.39 1.20 1.20
# Cortex-A53 1.32 1.29 1.46
# Cortex-A57(*) 1.95 0.85 0.93
# Denver 1.96 0.86 0.80
# Mongoose 1.33 1.20 1.20
# Kryo 1.26 0.94 1.00
# Cortex-A53 1.32 1.17/1.29(**) 1.36/1.46
# Cortex-A57(*) 1.95 0.82/0.85 0.89/0.93
# Cortex-A72 1.33 0.85/0.88 0.92/0.96
# Denver 1.96 0.65/0.86 0.76/0.80
# Mongoose 1.33 1.23/1.20 1.30/1.20
# Kryo 1.26 0.87/0.94 1.00/1.00
# ThunderX2 5.95 1.25 1.30
#
# (*) original 3.64/1.34/1.32 results were for r0p0 revision
# and are still same even for updated module;
# (**) numbers after slash are for 32-bit code, which is 3x-
# interleaved;
$flavour = shift;
$output = shift;
@@ -523,6 +539,13 @@ $code.=<<___;
___
{
my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9));
my ($dat3,$in3,$tmp3); # used only in 64-bit mode
my ($dat4,$in4,$tmp4);
if ($flavour =~ /64/) {
($dat2,$dat3,$dat4,$in2,$in3,$in4,$tmp3,$tmp4)=map("q$_",(16..23));
}
$code.=<<___;
.align 5
.Lcbc_dec:
@@ -539,7 +562,196 @@ $code.=<<___;
vorr $in0,$dat,$dat
vorr $in1,$dat1,$dat1
vorr $in2,$dat2,$dat2
___
$code.=<<___ if ($flavour =~ /64/);
cmp $len,#32
b.lo .Loop3x_cbc_dec
vld1.8 {$dat3},[$inp],#16
vld1.8 {$dat4},[$inp],#16
sub $len,$len,#32 // bias
mov $cnt,$rounds
vorr $in3,$dat3,$dat3
vorr $in4,$dat4,$dat4
.Loop5x_cbc_dec:
aesd $dat0,q8
aesimc $dat0,$dat0
aesd $dat1,q8
aesimc $dat1,$dat1
aesd $dat2,q8
aesimc $dat2,$dat2
aesd $dat3,q8
aesimc $dat3,$dat3
aesd $dat4,q8
aesimc $dat4,$dat4
vld1.32 {q8},[$key_],#16
subs $cnt,$cnt,#2
aesd $dat0,q9
aesimc $dat0,$dat0
aesd $dat1,q9
aesimc $dat1,$dat1
aesd $dat2,q9
aesimc $dat2,$dat2
aesd $dat3,q9
aesimc $dat3,$dat3
aesd $dat4,q9
aesimc $dat4,$dat4
vld1.32 {q9},[$key_],#16
b.gt .Loop5x_cbc_dec
aesd $dat0,q8
aesimc $dat0,$dat0
aesd $dat1,q8
aesimc $dat1,$dat1
aesd $dat2,q8
aesimc $dat2,$dat2
aesd $dat3,q8
aesimc $dat3,$dat3
aesd $dat4,q8
aesimc $dat4,$dat4
cmp $len,#0x40 // because .Lcbc_tail4x
sub $len,$len,#0x50
aesd $dat0,q9
aesimc $dat0,$dat0
aesd $dat1,q9
aesimc $dat1,$dat1
aesd $dat2,q9
aesimc $dat2,$dat2
aesd $dat3,q9
aesimc $dat3,$dat3
aesd $dat4,q9
aesimc $dat4,$dat4
csel x6,xzr,$len,gt // borrow x6, $cnt, "gt" is not typo
mov $key_,$key
aesd $dat0,q10
aesimc $dat0,$dat0
aesd $dat1,q10
aesimc $dat1,$dat1
aesd $dat2,q10
aesimc $dat2,$dat2
aesd $dat3,q10
aesimc $dat3,$dat3
aesd $dat4,q10
aesimc $dat4,$dat4
add $inp,$inp,x6 // $inp is adjusted in such way that
// at exit from the loop $dat1-$dat4
// are loaded with last "words"
add x6,$len,#0x60 // because .Lcbc_tail4x
aesd $dat0,q11
aesimc $dat0,$dat0
aesd $dat1,q11
aesimc $dat1,$dat1
aesd $dat2,q11
aesimc $dat2,$dat2
aesd $dat3,q11
aesimc $dat3,$dat3
aesd $dat4,q11
aesimc $dat4,$dat4
aesd $dat0,q12
aesimc $dat0,$dat0
aesd $dat1,q12
aesimc $dat1,$dat1
aesd $dat2,q12
aesimc $dat2,$dat2
aesd $dat3,q12
aesimc $dat3,$dat3
aesd $dat4,q12
aesimc $dat4,$dat4
aesd $dat0,q13
aesimc $dat0,$dat0
aesd $dat1,q13
aesimc $dat1,$dat1
aesd $dat2,q13
aesimc $dat2,$dat2
aesd $dat3,q13
aesimc $dat3,$dat3
aesd $dat4,q13
aesimc $dat4,$dat4
aesd $dat0,q14
aesimc $dat0,$dat0
aesd $dat1,q14
aesimc $dat1,$dat1
aesd $dat2,q14
aesimc $dat2,$dat2
aesd $dat3,q14
aesimc $dat3,$dat3
aesd $dat4,q14
aesimc $dat4,$dat4
veor $tmp0,$ivec,$rndlast
aesd $dat0,q15
veor $tmp1,$in0,$rndlast
vld1.8 {$in0},[$inp],#16
aesd $dat1,q15
veor $tmp2,$in1,$rndlast
vld1.8 {$in1},[$inp],#16
aesd $dat2,q15
veor $tmp3,$in2,$rndlast
vld1.8 {$in2},[$inp],#16
aesd $dat3,q15
veor $tmp4,$in3,$rndlast
vld1.8 {$in3},[$inp],#16
aesd $dat4,q15
vorr $ivec,$in4,$in4
vld1.8 {$in4},[$inp],#16
cbz x6,.Lcbc_tail4x
vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0]
veor $tmp0,$tmp0,$dat0
vorr $dat0,$in0,$in0
veor $tmp1,$tmp1,$dat1
vorr $dat1,$in1,$in1
veor $tmp2,$tmp2,$dat2
vorr $dat2,$in2,$in2
veor $tmp3,$tmp3,$dat3
vorr $dat3,$in3,$in3
veor $tmp4,$tmp4,$dat4
vst1.8 {$tmp0},[$out],#16
vorr $dat4,$in4,$in4
vst1.8 {$tmp1},[$out],#16
mov $cnt,$rounds
vst1.8 {$tmp2},[$out],#16
vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1]
vst1.8 {$tmp3},[$out],#16
vst1.8 {$tmp4},[$out],#16
b.hs .Loop5x_cbc_dec
add $len,$len,#0x50
cbz $len,.Lcbc_done
add $cnt,$rounds,#2
subs $len,$len,#0x30
vorr $dat0,$in2,$in2
vorr $in0,$in2,$in2
vorr $dat1,$in3,$in3
vorr $in1,$in3,$in3
vorr $dat2,$in4,$in4
vorr $in2,$in4,$in4
b.lo .Lcbc_dec_tail
b .Loop3x_cbc_dec
.align 4
.Lcbc_tail4x:
veor $tmp1,$tmp0,$dat1
veor $tmp2,$tmp2,$dat2
veor $tmp3,$tmp3,$dat3
veor $tmp4,$tmp4,$dat4
vst1.8 {$tmp1},[$out],#16
vst1.8 {$tmp2},[$out],#16
vst1.8 {$tmp3},[$out],#16
vst1.8 {$tmp4},[$out],#16
b .Lcbc_done
.align 4
___
$code.=<<___;
.Loop3x_cbc_dec:
aesd $dat0,q8
aesimc $dat0,$dat0
@@ -700,6 +912,9 @@ my $step="x12"; # aliases with $tctr2
my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$ivec,$rndlast)=map("q$_",(0..7));
my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9));
# used only in 64-bit mode...
my ($dat3,$dat4,$in3,$in4)=map("q$_",(16..23));
my ($dat,$tmp)=($dat0,$tmp0);
### q8-q15 preloaded key schedule
@@ -752,6 +967,175 @@ $code.=<<___;
rev $tctr2, $ctr
sub $len,$len,#3 // bias
vmov.32 ${dat2}[3],$tctr2
___
$code.=<<___ if ($flavour =~ /64/);
cmp $len,#2
b.lo .Loop3x_ctr32
add w13,$ctr,#1
add w14,$ctr,#2
vorr $dat3,$dat0,$dat0
rev w13,w13
vorr $dat4,$dat0,$dat0
rev w14,w14
vmov.32 ${dat3}[3],w13
sub $len,$len,#2 // bias
vmov.32 ${dat4}[3],w14
add $ctr,$ctr,#2
b .Loop5x_ctr32
.align 4
.Loop5x_ctr32:
aese $dat0,q8
aesmc $dat0,$dat0
aese $dat1,q8
aesmc $dat1,$dat1
aese $dat2,q8
aesmc $dat2,$dat2
aese $dat3,q8
aesmc $dat3,$dat3
aese $dat4,q8
aesmc $dat4,$dat4
vld1.32 {q8},[$key_],#16
subs $cnt,$cnt,#2
aese $dat0,q9
aesmc $dat0,$dat0
aese $dat1,q9
aesmc $dat1,$dat1
aese $dat2,q9
aesmc $dat2,$dat2
aese $dat3,q9
aesmc $dat3,$dat3
aese $dat4,q9
aesmc $dat4,$dat4
vld1.32 {q9},[$key_],#16
b.gt .Loop5x_ctr32
mov $key_,$key
aese $dat0,q8
aesmc $dat0,$dat0
aese $dat1,q8
aesmc $dat1,$dat1
aese $dat2,q8
aesmc $dat2,$dat2
aese $dat3,q8
aesmc $dat3,$dat3
aese $dat4,q8
aesmc $dat4,$dat4
vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0]
aese $dat0,q9
aesmc $dat0,$dat0
aese $dat1,q9
aesmc $dat1,$dat1
aese $dat2,q9
aesmc $dat2,$dat2
aese $dat3,q9
aesmc $dat3,$dat3
aese $dat4,q9
aesmc $dat4,$dat4
vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1]
aese $dat0,q12
aesmc $dat0,$dat0
add $tctr0,$ctr,#1
add $tctr1,$ctr,#2
aese $dat1,q12
aesmc $dat1,$dat1
add $tctr2,$ctr,#3
add w13,$ctr,#4
aese $dat2,q12
aesmc $dat2,$dat2
add w14,$ctr,#5
rev $tctr0,$tctr0
aese $dat3,q12
aesmc $dat3,$dat3
rev $tctr1,$tctr1
rev $tctr2,$tctr2
aese $dat4,q12
aesmc $dat4,$dat4
rev w13,w13
rev w14,w14
aese $dat0,q13
aesmc $dat0,$dat0
aese $dat1,q13
aesmc $dat1,$dat1
aese $dat2,q13
aesmc $dat2,$dat2
aese $dat3,q13
aesmc $dat3,$dat3
aese $dat4,q13
aesmc $dat4,$dat4
aese $dat0,q14
aesmc $dat0,$dat0
vld1.8 {$in0},[$inp],#16
aese $dat1,q14
aesmc $dat1,$dat1
vld1.8 {$in1},[$inp],#16
aese $dat2,q14
aesmc $dat2,$dat2
vld1.8 {$in2},[$inp],#16
aese $dat3,q14
aesmc $dat3,$dat3
vld1.8 {$in3},[$inp],#16
aese $dat4,q14
aesmc $dat4,$dat4
vld1.8 {$in4},[$inp],#16
aese $dat0,q15
veor $in0,$in0,$rndlast
aese $dat1,q15
veor $in1,$in1,$rndlast
aese $dat2,q15
veor $in2,$in2,$rndlast
aese $dat3,q15
veor $in3,$in3,$rndlast
aese $dat4,q15
veor $in4,$in4,$rndlast
veor $in0,$in0,$dat0
vorr $dat0,$ivec,$ivec
veor $in1,$in1,$dat1
vorr $dat1,$ivec,$ivec
veor $in2,$in2,$dat2
vorr $dat2,$ivec,$ivec
veor $in3,$in3,$dat3
vorr $dat3,$ivec,$ivec
veor $in4,$in4,$dat4
vorr $dat4,$ivec,$ivec
vst1.8 {$in0},[$out],#16
vmov.32 ${dat0}[3],$tctr0
vst1.8 {$in1},[$out],#16
vmov.32 ${dat1}[3],$tctr1
vst1.8 {$in2},[$out],#16
vmov.32 ${dat2}[3],$tctr2
vst1.8 {$in3},[$out],#16
vmov.32 ${dat3}[3],w13
vst1.8 {$in4},[$out],#16
vmov.32 ${dat4}[3],w14
mov $cnt,$rounds
cbz $len,.Lctr32_done
add $ctr,$ctr,#5
subs $len,$len,#5
b.hs .Loop5x_ctr32
add $len,$len,#5
sub $ctr,$ctr,#5
cmp $len,#2
mov $step,#16
cclr $step,lo
b.ls .Lctr32_tail
sub $len,$len,#3 // bias
add $ctr,$ctr,#3
___
$code.=<<___;
b .Loop3x_ctr32
.align 4
+1
View File
@@ -30,6 +30,7 @@
# Denver(***) 16.6(**) 15.1/17.8(**) [8.80/9.93 ]
# Apple A7(***) 22.7(**) 10.9/14.3 [8.45/10.0 ]
# Mongoose(***) 26.3(**) 21.0/25.0(**) [13.3/16.8 ]
# ThunderX2(***) 39.4(**) 33.8/48.6(**)
#
# (*) ECB denotes approximate result for parallelizable modes
# such as CBC decrypt, CTR, etc.;
+24 -7
View File
@@ -57,7 +57,12 @@ static const BIO_METHOD secmem_method = {
NULL, /* mem_callback_ctrl */
};
/* BIO memory stores buffer and read pointer */
/*
* BIO memory stores buffer and read pointer
* however the roles are different for read only BIOs.
* In that case the readp just stores the original state
* to be used for reset.
*/
typedef struct bio_buf_mem_st {
struct buf_mem_st *buf; /* allocated buffer */
struct buf_mem_st *readp; /* read pointer */
@@ -192,11 +197,14 @@ static int mem_read(BIO *b, char *out, int outl)
BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
BUF_MEM *bm = bbm->readp;
if (b->flags & BIO_FLAGS_MEM_RDONLY)
bm = bbm->buf;
BIO_clear_retry_flags(b);
ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl;
if ((out != NULL) && (ret > 0)) {
memcpy(out, bm->data, ret);
bm->length -= ret;
bm->max -= ret;
bm->data += ret;
} else if (bm->length == 0) {
ret = b->num;
@@ -241,29 +249,36 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
BUF_MEM *bm;
if (b->flags & BIO_FLAGS_MEM_RDONLY)
bm = bbm->buf;
else
bm = bbm->readp;
switch (cmd) {
case BIO_CTRL_RESET:
bm = bbm->buf;
if (bm->data != NULL) {
/* For read only case reset to the start again */
if ((b->flags & BIO_FLAGS_MEM_RDONLY) || (b->flags & BIO_FLAGS_NONCLEAR_RST)) {
if (!(b->flags & BIO_FLAGS_MEM_RDONLY)) {
if (b->flags & BIO_FLAGS_NONCLEAR_RST) {
bm->length = bm->max;
} else {
memset(bm->data, 0, bm->max);
bm->length = 0;
}
*bbm->readp = *bbm->buf;
} else {
/* For read only case just reset to the start again */
*bbm->buf = *bbm->readp;
}
}
break;
case BIO_CTRL_EOF:
bm = bbm->readp;
ret = (long)(bm->length == 0);
break;
case BIO_C_SET_BUF_MEM_EOF_RETURN:
b->num = (int)num;
break;
case BIO_CTRL_INFO:
bm = bbm->readp;
ret = (long)bm->length;
if (ptr != NULL) {
pptr = (char **)ptr;
@@ -278,8 +293,9 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
break;
case BIO_C_GET_BUF_MEM_PTR:
if (ptr != NULL) {
if (!(b->flags & BIO_FLAGS_MEM_RDONLY))
mem_buf_sync(b);
bm = bbm->readp;
bm = bbm->buf;
pptr = (char **)ptr;
*pptr = (char *)bm;
}
@@ -294,7 +310,6 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = 0L;
break;
case BIO_CTRL_PENDING:
bm = bbm->readp;
ret = (long)bm->length;
break;
case BIO_CTRL_DUP:
@@ -318,6 +333,8 @@ static int mem_gets(BIO *bp, char *buf, int size)
BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)bp->ptr;
BUF_MEM *bm = bbm->readp;
if (bp->flags & BIO_FLAGS_MEM_RDONLY)
bm = bbm->buf;
BIO_clear_retry_flags(bp);
j = bm->length;
if ((size - 1) < j)
+2 -2
View File
@@ -329,8 +329,6 @@ int bn_miller_rabin_is_prime(const BIGNUM *w, int iterations, BN_CTX *ctx,
if (BN_is_one(z))
goto composite;
}
if (!BN_GENCB_call(cb, 1, i))
goto err;
/* At this point z = b^((w-1)/2) mod w */
/* (Steps 4.8 - 4.9) x = z, z = x^2 mod w */
if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx))
@@ -358,6 +356,8 @@ composite:
goto err;
outer_loop: ;
/* (Step 4.1.5) */
if (!BN_GENCB_call(cb, 1, i))
goto err;
}
/* (Step 5) */
*status = BN_PRIMETEST_PROBABLY_PRIME;
+1 -1
View File
@@ -14,7 +14,7 @@ SOURCE[../libcrypto]=provider_core.c provider_predefined.c provider_conf.c \
# Central utilities
SOURCE[../libcrypto]=\
cryptlib.c mem.c mem_dbg.c cversion.c ex_data.c cpt_err.c \
cryptlib.c mem.c mem_dbg.c cversion.c info.c ex_data.c cpt_err.c \
ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fopen.c ctype.c \
threads_pthread.c threads_win.c threads_none.c getenv.c \
o_init.c o_fips.c mem_sec.c init.c context.c sparse_array.c \
+316 -163
View File
@@ -18,22 +18,31 @@
#
# ChaCha20 for ARMv8.
#
# April 2019
#
# Replace 3xNEON+1xIALU code path with 4+1. 4+1 is actually fastest
# option on most(*), but not all, processors, yet 6+2 is retained.
# This is because penalties are considered tolerable in comparison to
# improvement on processors where 6+2 helps. Most notably +37% on
# ThunderX2. It's server-oriented processor which will have to serve
# as many requests as possible. While others are mostly clients, when
# performance doesn't have to be absolute top-notch, just fast enough,
# as majority of time is spent "entertaining" relatively slow human.
#
# Performance in cycles per byte out of large buffer.
#
# IALU/gcc-4.9 3xNEON+1xIALU 6xNEON+2xIALU
# IALU/gcc-4.9 4xNEON+1xIALU 6xNEON+2xIALU
#
# Apple A7 5.50/+49% 3.33 1.70
# Cortex-A53 8.40/+80% 4.72 4.72(*)
# Cortex-A57 8.06/+43% 4.90 4.43(**)
# Denver 4.50/+82% 2.63 2.67(*)
# X-Gene 9.50/+46% 8.82 8.89(*)
# Mongoose 8.00/+44% 3.64 3.25
# Kryo 8.17/+50% 4.83 4.65
# Apple A7 5.50/+49% 2.72 1.60
# Cortex-A53 8.40/+80% 4.06 4.45(*)
# Cortex-A57 8.06/+43% 4.15 4.40(*)
# Denver 4.50/+82% 2.30 2.70(*)
# X-Gene 9.50/+46% 8.20 8.90(*)
# Mongoose 8.00/+44% 2.74 3.12(*)
# Kryo 8.17/+50% 4.47 4.65(*)
# ThunderX2 7.22/+48% 5.64 4.10
#
# (*) it's expected that doubling interleave factor doesn't help
# all processors, only those with higher NEON latency and
# higher instruction issue rate;
# (**) expected improvement was actually higher;
# (*) slower than 4+1:-(
$flavour=shift;
$output=shift;
@@ -120,18 +129,21 @@ my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
}
$code.=<<___;
#include "arm_arch.h"
#ifndef __KERNEL__
# include "arm_arch.h"
.extern OPENSSL_armcap_P
#endif
.text
.extern OPENSSL_armcap_P
.align 5
.Lsigma:
.quad 0x3320646e61707865,0x6b20657479622d32 // endian-neutral
.Lone:
.long 1,0,0,0
.asciz "ChaCha20 for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
.long 1,2,3,4
.Lrot24:
.long 0x02010003,0x06050407,0x0a09080b,0x0e0d0c0f
.asciz "ChaCha20 for ARMv8, CRYPTOGAMS by \@dot-asm"
.globl ChaCha20_ctr32
.type ChaCha20_ctr32,%function
@@ -141,10 +153,12 @@ ChaCha20_ctr32:
cmp $len,#192
b.lo .Lshort
#ifndef __KERNEL__
adrp x17,OPENSSL_armcap_P
ldr w17,[x17,#:lo12:OPENSSL_armcap_P]
tst w17,#ARMV7_NEON
b.ne .LChaCha20_neon
#endif
.Lshort:
.inst 0xd503233f // paciasp
@@ -163,7 +177,7 @@ ChaCha20_ctr32:
ldp @d[2],@d[3],[$key] // load key
ldp @d[4],@d[5],[$key,#16]
ldp @d[6],@d[7],[$ctr] // load counter
#ifdef __ARMEB__
#ifdef __AARCH64EB__
ror @d[2],@d[2],#32
ror @d[3],@d[3],#32
ror @d[4],@d[4],#32
@@ -232,7 +246,7 @@ $code.=<<___;
add @x[14],@x[14],@x[15],lsl#32
ldp @x[13],@x[15],[$inp,#48]
add $inp,$inp,#64
#ifdef __ARMEB__
#ifdef __AARCH64EB__
rev @x[0],@x[0]
rev @x[2],@x[2]
rev @x[4],@x[4]
@@ -289,7 +303,7 @@ $code.=<<___;
add @x[10],@x[10],@x[11],lsl#32
add @x[12],@x[12],@x[13],lsl#32
add @x[14],@x[14],@x[15],lsl#32
#ifdef __ARMEB__
#ifdef __AARCH64EB__
rev @x[0],@x[0]
rev @x[2],@x[2]
rev @x[4],@x[4]
@@ -330,43 +344,87 @@ $code.=<<___;
___
{{{
my ($A0,$B0,$C0,$D0,$A1,$B1,$C1,$D1,$A2,$B2,$C2,$D2,$T0,$T1,$T2,$T3) =
map("v$_.4s",(0..7,16..23));
my (@K)=map("v$_.4s",(24..30));
my $ONE="v31.4s";
my @K = map("v$_.4s",(0..3));
my ($xt0,$xt1,$xt2,$xt3, $CTR,$ROT24) = map("v$_.4s",(4..9));
my @X = map("v$_.4s",(16,20,24,28, 17,21,25,29, 18,22,26,30, 19,23,27,31));
my ($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3,
$xc0,$xc1,$xc2,$xc3, $xd0,$xd1,$xd2,$xd3) = @X;
sub NEONROUND {
my $odd = pop;
my ($a,$b,$c,$d,$t)=@_;
sub NEON_lane_ROUND {
my ($a0,$b0,$c0,$d0)=@_;
my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
my @x=map("'$_'",@X);
(
"&add ('$a','$a','$b')",
"&eor ('$d','$d','$a')",
"&rev32_16 ('$d','$d')", # vrot ($d,16)
"&add (@x[$a0],@x[$a0],@x[$b0])", # Q1
"&add (@x[$a1],@x[$a1],@x[$b1])", # Q2
"&add (@x[$a2],@x[$a2],@x[$b2])", # Q3
"&add (@x[$a3],@x[$a3],@x[$b3])", # Q4
"&eor (@x[$d0],@x[$d0],@x[$a0])",
"&eor (@x[$d1],@x[$d1],@x[$a1])",
"&eor (@x[$d2],@x[$d2],@x[$a2])",
"&eor (@x[$d3],@x[$d3],@x[$a3])",
"&rev32_16 (@x[$d0],@x[$d0])",
"&rev32_16 (@x[$d1],@x[$d1])",
"&rev32_16 (@x[$d2],@x[$d2])",
"&rev32_16 (@x[$d3],@x[$d3])",
"&add ('$c','$c','$d')",
"&eor ('$t','$b','$c')",
"&ushr ('$b','$t',20)",
"&sli ('$b','$t',12)",
"&add (@x[$c0],@x[$c0],@x[$d0])",
"&add (@x[$c1],@x[$c1],@x[$d1])",
"&add (@x[$c2],@x[$c2],@x[$d2])",
"&add (@x[$c3],@x[$c3],@x[$d3])",
"&eor ('$xt0',@x[$b0],@x[$c0])",
"&eor ('$xt1',@x[$b1],@x[$c1])",
"&eor ('$xt2',@x[$b2],@x[$c2])",
"&eor ('$xt3',@x[$b3],@x[$c3])",
"&ushr (@x[$b0],'$xt0',20)",
"&ushr (@x[$b1],'$xt1',20)",
"&ushr (@x[$b2],'$xt2',20)",
"&ushr (@x[$b3],'$xt3',20)",
"&sli (@x[$b0],'$xt0',12)",
"&sli (@x[$b1],'$xt1',12)",
"&sli (@x[$b2],'$xt2',12)",
"&sli (@x[$b3],'$xt3',12)",
"&add ('$a','$a','$b')",
"&eor ('$t','$d','$a')",
"&ushr ('$d','$t',24)",
"&sli ('$d','$t',8)",
"&add (@x[$a0],@x[$a0],@x[$b0])",
"&add (@x[$a1],@x[$a1],@x[$b1])",
"&add (@x[$a2],@x[$a2],@x[$b2])",
"&add (@x[$a3],@x[$a3],@x[$b3])",
"&eor ('$xt0',@x[$d0],@x[$a0])",
"&eor ('$xt1',@x[$d1],@x[$a1])",
"&eor ('$xt2',@x[$d2],@x[$a2])",
"&eor ('$xt3',@x[$d3],@x[$a3])",
"&tbl (@x[$d0],'{$xt0}','$ROT24')",
"&tbl (@x[$d1],'{$xt1}','$ROT24')",
"&tbl (@x[$d2],'{$xt2}','$ROT24')",
"&tbl (@x[$d3],'{$xt3}','$ROT24')",
"&add ('$c','$c','$d')",
"&eor ('$t','$b','$c')",
"&ushr ('$b','$t',25)",
"&sli ('$b','$t',7)",
"&ext ('$c','$c','$c',8)",
"&ext ('$d','$d','$d',$odd?4:12)",
"&ext ('$b','$b','$b',$odd?12:4)"
"&add (@x[$c0],@x[$c0],@x[$d0])",
"&add (@x[$c1],@x[$c1],@x[$d1])",
"&add (@x[$c2],@x[$c2],@x[$d2])",
"&add (@x[$c3],@x[$c3],@x[$d3])",
"&eor ('$xt0',@x[$b0],@x[$c0])",
"&eor ('$xt1',@x[$b1],@x[$c1])",
"&eor ('$xt2',@x[$b2],@x[$c2])",
"&eor ('$xt3',@x[$b3],@x[$c3])",
"&ushr (@x[$b0],'$xt0',25)",
"&ushr (@x[$b1],'$xt1',25)",
"&ushr (@x[$b2],'$xt2',25)",
"&ushr (@x[$b3],'$xt3',25)",
"&sli (@x[$b0],'$xt0',7)",
"&sli (@x[$b1],'$xt1',7)",
"&sli (@x[$b2],'$xt2',7)",
"&sli (@x[$b3],'$xt3',7)"
);
}
$code.=<<___;
#ifdef __KERNEL__
.globl ChaCha20_neon
#endif
.type ChaCha20_neon,%function
.align 5
ChaCha20_neon:
@@ -393,8 +451,9 @@ ChaCha20_neon:
ld1 {@K[1],@K[2]},[$key]
ldp @d[6],@d[7],[$ctr] // load counter
ld1 {@K[3]},[$ctr]
ld1 {$ONE},[@x[0]]
#ifdef __ARMEB__
stp d8,d9,[sp] // meet ABI requirements
ld1 {$CTR,$ROT24},[@x[0]]
#ifdef __AARCH64EB__
rev64 @K[0],@K[0]
ror @d[2],@d[2],#32
ror @d[3],@d[3],#32
@@ -403,115 +462,129 @@ ChaCha20_neon:
ror @d[6],@d[6],#32
ror @d[7],@d[7],#32
#endif
add @K[3],@K[3],$ONE // += 1
add @K[4],@K[3],$ONE
add @K[5],@K[4],$ONE
shl $ONE,$ONE,#2 // 1 -> 4
.Loop_outer_neon:
mov.32 @x[0],@d[0] // unpack key block
dup $xa0,@{K[0]}[0] // unpack key block
mov.32 @x[0],@d[0]
dup $xa1,@{K[0]}[1]
lsr @x[1],@d[0],#32
mov $A0,@K[0]
dup $xa2,@{K[0]}[2]
mov.32 @x[2],@d[1]
dup $xa3,@{K[0]}[3]
lsr @x[3],@d[1],#32
mov $A1,@K[0]
dup $xb0,@{K[1]}[0]
mov.32 @x[4],@d[2]
dup $xb1,@{K[1]}[1]
lsr @x[5],@d[2],#32
mov $A2,@K[0]
dup $xb2,@{K[1]}[2]
mov.32 @x[6],@d[3]
mov $B0,@K[1]
dup $xb3,@{K[1]}[3]
lsr @x[7],@d[3],#32
mov $B1,@K[1]
dup $xd0,@{K[3]}[0]
mov.32 @x[8],@d[4]
mov $B2,@K[1]
dup $xd1,@{K[3]}[1]
lsr @x[9],@d[4],#32
mov $D0,@K[3]
dup $xd2,@{K[3]}[2]
mov.32 @x[10],@d[5]
mov $D1,@K[4]
dup $xd3,@{K[3]}[3]
lsr @x[11],@d[5],#32
mov $D2,@K[5]
add $xd0,$xd0,$CTR
mov.32 @x[12],@d[6]
mov $C0,@K[2]
dup $xc0,@{K[2]}[0]
lsr @x[13],@d[6],#32
mov $C1,@K[2]
dup $xc1,@{K[2]}[1]
mov.32 @x[14],@d[7]
mov $C2,@K[2]
dup $xc2,@{K[2]}[2]
lsr @x[15],@d[7],#32
dup $xc3,@{K[2]}[3]
mov $ctr,#10
subs $len,$len,#256
subs $len,$len,#320
.Loop_neon:
sub $ctr,$ctr,#1
___
my @thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,0);
my @thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,0);
my @thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,0);
my @thread3=&ROUND(0,4,8,12);
my @plus_one=&ROUND(0,4,8,12);
foreach (&NEON_lane_ROUND(0,4,8,12)) { eval; eval(shift(@plus_one)); }
foreach (@thread0) {
eval; eval(shift(@thread3));
eval(shift(@thread1)); eval(shift(@thread3));
eval(shift(@thread2)); eval(shift(@thread3));
}
@thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,1);
@thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,1);
@thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,1);
@thread3=&ROUND(0,5,10,15);
foreach (@thread0) {
eval; eval(shift(@thread3));
eval(shift(@thread1)); eval(shift(@thread3));
eval(shift(@thread2)); eval(shift(@thread3));
}
@plus_one=&ROUND(0,5,10,15);
foreach (&NEON_lane_ROUND(0,5,10,15)) { eval; eval(shift(@plus_one)); }
$code.=<<___;
cbnz $ctr,.Loop_neon
add $xd0,$xd0,$CTR
zip1 $xt0,$xa0,$xa1 // transpose data
zip1 $xt1,$xa2,$xa3
zip2 $xt2,$xa0,$xa1
zip2 $xt3,$xa2,$xa3
zip1.64 $xa0,$xt0,$xt1
zip2.64 $xa1,$xt0,$xt1
zip1.64 $xa2,$xt2,$xt3
zip2.64 $xa3,$xt2,$xt3
zip1 $xt0,$xb0,$xb1
zip1 $xt1,$xb2,$xb3
zip2 $xt2,$xb0,$xb1
zip2 $xt3,$xb2,$xb3
zip1.64 $xb0,$xt0,$xt1
zip2.64 $xb1,$xt0,$xt1
zip1.64 $xb2,$xt2,$xt3
zip2.64 $xb3,$xt2,$xt3
zip1 $xt0,$xc0,$xc1
add.32 @x[0],@x[0],@d[0] // accumulate key block
add $A0,$A0,@K[0]
zip1 $xt1,$xc2,$xc3
add @x[1],@x[1],@d[0],lsr#32
add $A1,$A1,@K[0]
zip2 $xt2,$xc0,$xc1
add.32 @x[2],@x[2],@d[1]
add $A2,$A2,@K[0]
zip2 $xt3,$xc2,$xc3
add @x[3],@x[3],@d[1],lsr#32
add $C0,$C0,@K[2]
zip1.64 $xc0,$xt0,$xt1
add.32 @x[4],@x[4],@d[2]
add $C1,$C1,@K[2]
zip2.64 $xc1,$xt0,$xt1
add @x[5],@x[5],@d[2],lsr#32
add $C2,$C2,@K[2]
zip1.64 $xc2,$xt2,$xt3
add.32 @x[6],@x[6],@d[3]
add $D0,$D0,@K[3]
zip2.64 $xc3,$xt2,$xt3
add @x[7],@x[7],@d[3],lsr#32
zip1 $xt0,$xd0,$xd1
add.32 @x[8],@x[8],@d[4]
add $D1,$D1,@K[4]
zip1 $xt1,$xd2,$xd3
add @x[9],@x[9],@d[4],lsr#32
zip2 $xt2,$xd0,$xd1
add.32 @x[10],@x[10],@d[5]
add $D2,$D2,@K[5]
zip2 $xt3,$xd2,$xd3
add @x[11],@x[11],@d[5],lsr#32
zip1.64 $xd0,$xt0,$xt1
add.32 @x[12],@x[12],@d[6]
add $B0,$B0,@K[1]
zip2.64 $xd1,$xt0,$xt1
add @x[13],@x[13],@d[6],lsr#32
zip1.64 $xd2,$xt2,$xt3
add.32 @x[14],@x[14],@d[7]
add $B1,$B1,@K[1]
zip2.64 $xd3,$xt2,$xt3
add @x[15],@x[15],@d[7],lsr#32
add $B2,$B2,@K[1]
b.lo .Ltail_neon
add @x[0],@x[0],@x[1],lsl#32 // pack
add @x[2],@x[2],@x[3],lsl#32
ldp @x[1],@x[3],[$inp,#0] // load input
add $xa0,$xa0,@K[0] // accumulate key block
add @x[4],@x[4],@x[5],lsl#32
add @x[6],@x[6],@x[7],lsl#32
ldp @x[5],@x[7],[$inp,#16]
add $xb0,$xb0,@K[1]
add @x[8],@x[8],@x[9],lsl#32
add @x[10],@x[10],@x[11],lsl#32
ldp @x[9],@x[11],[$inp,#32]
add $xc0,$xc0,@K[2]
add @x[12],@x[12],@x[13],lsl#32
add @x[14],@x[14],@x[15],lsl#32
ldp @x[13],@x[15],[$inp,#48]
add $xd0,$xd0,@K[3]
add $inp,$inp,#64
#ifdef __ARMEB__
#ifdef __AARCH64EB__
rev @x[0],@x[0]
rev @x[2],@x[2]
rev @x[4],@x[4]
@@ -521,48 +594,68 @@ $code.=<<___;
rev @x[12],@x[12]
rev @x[14],@x[14]
#endif
ld1.8 {$T0-$T3},[$inp],#64
ld1.8 {$xt0-$xt3},[$inp],#64
eor @x[0],@x[0],@x[1]
add $xa1,$xa1,@K[0]
eor @x[2],@x[2],@x[3]
add $xb1,$xb1,@K[1]
eor @x[4],@x[4],@x[5]
add $xc1,$xc1,@K[2]
eor @x[6],@x[6],@x[7]
add $xd1,$xd1,@K[3]
eor @x[8],@x[8],@x[9]
eor $A0,$A0,$T0
eor $xa0,$xa0,$xt0
movi $xt0,#5
eor @x[10],@x[10],@x[11]
eor $B0,$B0,$T1
eor $xb0,$xb0,$xt1
eor @x[12],@x[12],@x[13]
eor $C0,$C0,$T2
eor $xc0,$xc0,$xt2
eor @x[14],@x[14],@x[15]
eor $D0,$D0,$T3
ld1.8 {$T0-$T3},[$inp],#64
eor $xd0,$xd0,$xt3
add $CTR,$CTR,$xt0 // += 5
ld1.8 {$xt0-$xt3},[$inp],#64
stp @x[0],@x[2],[$out,#0] // store output
add @d[6],@d[6],#4 // increment counter
add @d[6],@d[6],#5 // increment counter
stp @x[4],@x[6],[$out,#16]
add @K[3],@K[3],$ONE // += 4
stp @x[8],@x[10],[$out,#32]
add @K[4],@K[4],$ONE
stp @x[12],@x[14],[$out,#48]
add @K[5],@K[5],$ONE
add $out,$out,#64
st1.8 {$A0-$D0},[$out],#64
ld1.8 {$A0-$D0},[$inp],#64
st1.8 {$xa0-$xd0},[$out],#64
add $xa2,$xa2,@K[0]
add $xb2,$xb2,@K[1]
add $xc2,$xc2,@K[2]
add $xd2,$xd2,@K[3]
ld1.8 {$xa0-$xd0},[$inp],#64
eor $A1,$A1,$T0
eor $B1,$B1,$T1
eor $C1,$C1,$T2
eor $D1,$D1,$T3
st1.8 {$A1-$D1},[$out],#64
eor $xa1,$xa1,$xt0
eor $xb1,$xb1,$xt1
eor $xc1,$xc1,$xt2
eor $xd1,$xd1,$xt3
st1.8 {$xa1-$xd1},[$out],#64
add $xa3,$xa3,@K[0]
add $xb3,$xb3,@K[1]
add $xc3,$xc3,@K[2]
add $xd3,$xd3,@K[3]
ld1.8 {$xa1-$xd1},[$inp],#64
eor $A2,$A2,$A0
eor $B2,$B2,$B0
eor $C2,$C2,$C0
eor $D2,$D2,$D0
st1.8 {$A2-$D2},[$out],#64
eor $xa2,$xa2,$xa0
eor $xb2,$xb2,$xb0
eor $xc2,$xc2,$xc0
eor $xd2,$xd2,$xd0
st1.8 {$xa2-$xd2},[$out],#64
eor $xa3,$xa3,$xa1
eor $xb3,$xb3,$xb1
eor $xc3,$xc3,$xc1
eor $xd3,$xd3,$xd1
st1.8 {$xa3-$xd3},[$out],#64
b.hi .Loop_outer_neon
ldp d8,d9,[sp] // meet ABI requirements
ldp x19,x20,[x29,#16]
add sp,sp,#64
ldp x21,x22,[x29,#32]
@@ -573,8 +666,10 @@ $code.=<<___;
.inst 0xd50323bf // autiasp
ret
.align 4
.Ltail_neon:
add $len,$len,#256
add $len,$len,#320
ldp d8,d9,[sp] // meet ABI requirements
cmp $len,#64
b.lo .Less_than_64
@@ -591,7 +686,7 @@ $code.=<<___;
add @x[14],@x[14],@x[15],lsl#32
ldp @x[13],@x[15],[$inp,#48]
add $inp,$inp,#64
#ifdef __ARMEB__
#ifdef __AARCH64EB__
rev @x[0],@x[0]
rev @x[2],@x[2]
rev @x[4],@x[4]
@@ -611,48 +706,68 @@ $code.=<<___;
eor @x[14],@x[14],@x[15]
stp @x[0],@x[2],[$out,#0] // store output
add @d[6],@d[6],#4 // increment counter
add $xa0,$xa0,@K[0] // accumulate key block
stp @x[4],@x[6],[$out,#16]
add $xb0,$xb0,@K[1]
stp @x[8],@x[10],[$out,#32]
add $xc0,$xc0,@K[2]
stp @x[12],@x[14],[$out,#48]
add $xd0,$xd0,@K[3]
add $out,$out,#64
b.eq .Ldone_neon
sub $len,$len,#64
cmp $len,#64
b.lo .Less_than_128
b.lo .Last_neon
ld1.8 {$T0-$T3},[$inp],#64
eor $A0,$A0,$T0
eor $B0,$B0,$T1
eor $C0,$C0,$T2
eor $D0,$D0,$T3
st1.8 {$A0-$D0},[$out],#64
ld1.8 {$xt0-$xt3},[$inp],#64
eor $xa0,$xa0,$xt0
eor $xb0,$xb0,$xt1
eor $xc0,$xc0,$xt2
eor $xd0,$xd0,$xt3
st1.8 {$xa0-$xd0},[$out],#64
b.eq .Ldone_neon
add $xa0,$xa1,@K[0]
add $xb0,$xb1,@K[1]
sub $len,$len,#64
add $xc0,$xc1,@K[2]
cmp $len,#64
b.lo .Less_than_192
add $xd0,$xd1,@K[3]
b.lo .Last_neon
ld1.8 {$T0-$T3},[$inp],#64
eor $A1,$A1,$T0
eor $B1,$B1,$T1
eor $C1,$C1,$T2
eor $D1,$D1,$T3
st1.8 {$A1-$D1},[$out],#64
ld1.8 {$xt0-$xt3},[$inp],#64
eor $xa1,$xa0,$xt0
eor $xb1,$xb0,$xt1
eor $xc1,$xc0,$xt2
eor $xd1,$xd0,$xt3
st1.8 {$xa1-$xd1},[$out],#64
b.eq .Ldone_neon
add $xa0,$xa2,@K[0]
add $xb0,$xb2,@K[1]
sub $len,$len,#64
add $xc0,$xc2,@K[2]
cmp $len,#64
add $xd0,$xd2,@K[3]
b.lo .Last_neon
ld1.8 {$xt0-$xt3},[$inp],#64
eor $xa2,$xa0,$xt0
eor $xb2,$xb0,$xt1
eor $xc2,$xc0,$xt2
eor $xd2,$xd0,$xt3
st1.8 {$xa2-$xd2},[$out],#64
b.eq .Ldone_neon
add $xa0,$xa3,@K[0]
add $xb0,$xb3,@K[1]
add $xc0,$xc3,@K[2]
add $xd0,$xd3,@K[3]
sub $len,$len,#64
st1.8 {$A2-$D2},[sp]
b .Last_neon
.Less_than_128:
st1.8 {$A0-$D0},[sp]
b .Last_neon
.Less_than_192:
st1.8 {$A1-$D1},[sp]
b .Last_neon
.align 4
.Last_neon:
st1.8 {$xa0-$xd0},[sp]
sub $out,$out,#1
add $inp,$inp,$len
add $out,$out,$len
@@ -685,9 +800,41 @@ $code.=<<___;
.size ChaCha20_neon,.-ChaCha20_neon
___
{
my @K = map("v$_.4s",(0..6));
my ($T0,$T1,$T2,$T3,$T4,$T5)=@K;
my ($A0,$B0,$C0,$D0,$A1,$B1,$C1,$D1,$A2,$B2,$C2,$D2,
$A3,$B3,$C3,$D3,$A4,$B4,$C4,$D4,$A5,$B5,$C5,$D5) = map("v$_.4s",(0..23));
$A3,$B3,$C3,$D3,$A4,$B4,$C4,$D4,$A5,$B5,$C5,$D5) = map("v$_.4s",(8..31));
my $rot24 = @K[6];
my $ONE = "v7.4s";
sub NEONROUND {
my $odd = pop;
my ($a,$b,$c,$d,$t)=@_;
(
"&add ('$a','$a','$b')",
"&eor ('$d','$d','$a')",
"&rev32_16 ('$d','$d')", # vrot ($d,16)
"&add ('$c','$c','$d')",
"&eor ('$t','$b','$c')",
"&ushr ('$b','$t',20)",
"&sli ('$b','$t',12)",
"&add ('$a','$a','$b')",
"&eor ('$d','$d','$a')",
"&tbl ('$d','{$d}','$rot24')",
"&add ('$c','$c','$d')",
"&eor ('$t','$b','$c')",
"&ushr ('$b','$t',25)",
"&sli ('$b','$t',7)",
"&ext ('$c','$c','$c',8)",
"&ext ('$d','$d','$d',$odd?4:12)",
"&ext ('$b','$b','$b',$odd?12:4)"
);
}
$code.=<<___;
.type ChaCha20_512_neon,%function
@@ -707,6 +854,7 @@ ChaCha20_512_neon:
.L512_or_more_neon:
sub sp,sp,#128+64
eor $ONE,$ONE,$ONE
ldp @d[0],@d[1],[@x[0]] // load sigma
ld1 {@K[0]},[@x[0]],#16
ldp @d[2],@d[3],[$key] // load key
@@ -714,8 +862,9 @@ ChaCha20_512_neon:
ld1 {@K[1],@K[2]},[$key]
ldp @d[6],@d[7],[$ctr] // load counter
ld1 {@K[3]},[$ctr]
ld1 {$ONE},[@x[0]]
#ifdef __ARMEB__
ld1 {$ONE}[0],[@x[0]]
add $key,@x[0],#16 // .Lrot24
#ifdef __AARCH64EB__
rev64 @K[0],@K[0]
ror @d[2],@d[2],#32
ror @d[3],@d[3],#32
@@ -782,9 +931,10 @@ ChaCha20_512_neon:
mov $C4,@K[2]
stp @K[3],@K[4],[sp,#48] // off-load key block, variable part
mov $C5,@K[2]
str @K[5],[sp,#80]
stp @K[5],@K[6],[sp,#80]
mov $ctr,#5
ld1 {$rot24},[$key]
subs $len,$len,#512
.Loop_upper_neon:
sub $ctr,$ctr,#1
@@ -857,7 +1007,7 @@ $code.=<<___;
add @x[14],@x[14],@x[15],lsl#32
ldp @x[13],@x[15],[$inp,#48]
add $inp,$inp,#64
#ifdef __ARMEB__
#ifdef __AARCH64EB__
rev @x[0],@x[0]
rev @x[2],@x[2]
rev @x[4],@x[4]
@@ -946,6 +1096,7 @@ $code.=<<___;
add.32 @x[2],@x[2],@d[1]
ldp @K[4],@K[5],[sp,#64]
add @x[3],@x[3],@d[1],lsr#32
ldr @K[6],[sp,#96]
add $A0,$A0,@K[0]
add.32 @x[4],@x[4],@d[2]
add $A1,$A1,@K[0]
@@ -998,7 +1149,7 @@ $code.=<<___;
add $inp,$inp,#64
add $B5,$B5,@K[1]
#ifdef __ARMEB__
#ifdef __AARCH64EB__
rev @x[0],@x[0]
rev @x[2],@x[2]
rev @x[4],@x[4]
@@ -1076,24 +1227,24 @@ $code.=<<___;
b.hs .Loop_outer_512_neon
adds $len,$len,#512
ushr $A0,$ONE,#2 // 4 -> 1
ushr $ONE,$ONE,#1 // 4 -> 2
ldp d8,d9,[sp,#128+0] // meet ABI requirements
ldp d10,d11,[sp,#128+16]
ldp d12,d13,[sp,#128+32]
ldp d14,d15,[sp,#128+48]
stp @K[0],$ONE,[sp,#0] // wipe off-load area
stp @K[0],$ONE,[sp,#32]
stp @K[0],$ONE,[sp,#64]
stp @K[0],@K[0],[sp,#0] // wipe off-load area
stp @K[0],@K[0],[sp,#32]
stp @K[0],@K[0],[sp,#64]
b.eq .Ldone_512_neon
sub $key,$key,#16 // .Lone
cmp $len,#192
sub @K[3],@K[3],$A0 // -= 1
sub @K[4],@K[4],$A0
sub @K[5],@K[5],$A0
add sp,sp,#128
sub @K[3],@K[3],$ONE // -= 2
ld1 {$CTR,$ROT24},[$key]
b.hs .Loop_outer_neon
eor @K[1],@K[1],@K[1]
@@ -1123,9 +1274,11 @@ foreach (split("\n",$code)) {
s/\`([^\`]*)\`/eval $1/geo;
(s/\b([a-z]+)\.32\b/$1/ and (s/x([0-9]+)/w$1/g or 1)) or
(m/\b(eor|ext|mov)\b/ and (s/\.4s/\.16b/g or 1)) or
(m/\b(eor|ext|mov|tbl)\b/ and (s/\.4s/\.16b/g or 1)) or
(s/\b((?:ld|st)1)\.8\b/$1/ and (s/\.4s/\.16b/g or 1)) or
(m/\b(ld|st)[rp]\b/ and (s/v([0-9]+)\.4s/q$1/g or 1)) or
(m/\b(dup|ld1)\b/ and (s/\.4(s}?\[[0-3]\])/.$1/g or 1)) or
(s/\b(zip[12])\.64\b/$1/ and (s/\.4s/\.2d/g or 1)) or
(s/\brev32\.16\b/rev32/ and (s/\.4s/\.8h/g or 1));
#s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo;
+1 -1
View File
@@ -40,7 +40,7 @@
use strict;
use FindBin qw($Bin);
use lib "$Bin/../..";
use perlasm::s390x qw(:DEFAULT :VX AUTOLOAD LABEL INCLUDE);
use perlasm::s390x qw(:DEFAULT :VX :LD AUTOLOAD LABEL INCLUDE);
my $flavour = shift;
+6
View File
@@ -69,6 +69,12 @@ const char *OpenSSL_version(int t)
return "ENGINESDIR: \"" ENGINESDIR "\"";
#else
return "ENGINESDIR: N/A";
#endif
case OPENSSL_MODULES_DIR:
#ifdef MODULESDIR
return "MODULESDIR: \"" MODULESDIR "\"";
#else
return "MODULESDIR: N/A";
#endif
}
return "not available";
+1 -1
View File
@@ -1488,7 +1488,7 @@ $code.=<<___;
////////////////////////////////////////////////////////////////////////
// void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4],
// int rep);
// uint64_t rep);
.globl ecp_nistz256_ord_sqr_mont
.type ecp_nistz256_ord_sqr_mont,%function
.align 4
+1 -1
View File
@@ -1919,7 +1919,7 @@ $code.=<<___;
################################################################################
# void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4],
# int rep);
# uint64_t rep);
.globl ecp_nistz256_ord_sqr_mont
.align 5
ecp_nistz256_ord_sqr_mont:
+1 -1
View File
@@ -826,7 +826,7 @@ $code.=<<___;
# void ecp_nistz256_ord_sqr_mont(
# uint64_t res[4],
# uint64_t a[4],
# int rep);
# uint64_t rep);
.globl ecp_nistz256_ord_sqr_mont
.type ecp_nistz256_ord_sqr_mont,\@function,3
+2 -2
View File
@@ -441,7 +441,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
* scalar multiplication implementation based on a Montgomery ladder,
* with various timing attack defenses.
*/
if ((scalar != NULL) && (num == 0)) {
if ((scalar != group->order) && (scalar != NULL) && (num == 0)) {
/*-
* In this case we want to compute scalar * GeneratorPoint: this
* codepath is reached most prominently by (ephemeral) key
@@ -452,7 +452,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
*/
return ec_scalar_mul_ladder(group, r, scalar, NULL, ctx);
}
if ((scalar == NULL) && (num == 1)) {
if ((scalar == NULL) && (num == 1) && (scalars[0] != group->order)) {
/*-
* In this case we want to compute scalar * VariablePoint: this
* codepath is reached most prominently by the second half of ECDH,
+1 -1
View File
@@ -1467,7 +1467,7 @@ void ecp_nistz256_ord_mul_mont(BN_ULONG res[P256_LIMBS],
const BN_ULONG b[P256_LIMBS]);
void ecp_nistz256_ord_sqr_mont(BN_ULONG res[P256_LIMBS],
const BN_ULONG a[P256_LIMBS],
int rep);
BN_ULONG rep);
static int ecp_nistz256_inv_mod_ord(const EC_GROUP *group, BIGNUM *r,
const BIGNUM *x, BN_CTX *ctx)
+1
View File
@@ -66,6 +66,7 @@ static ERR_STRING_DATA ERR_str_libraries[] = {
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, 0), "STORE routines"},
{ERR_PACK(ERR_LIB_SM2, 0, 0), "SM2 routines"},
{ERR_PACK(ERR_LIB_ESS, 0, 0), "ESS routines"},
{ERR_PACK(ERR_LIB_PROV, 0, 0), "Provider routines"},
{0, NULL},
};
+3 -1
View File
@@ -41,6 +41,7 @@
#include <openssl/storeerr.h>
#include <openssl/esserr.h>
#include "internal/propertyerr.h"
#include "internal/providercommonerr.h"
int err_load_crypto_strings_int(void)
{
@@ -102,7 +103,8 @@ int err_load_crypto_strings_int(void)
#endif
ERR_load_KDF_strings() == 0 ||
ERR_load_OSSL_STORE_strings() == 0 ||
ERR_load_PROP_strings() == 0)
ERR_load_PROP_strings() == 0 ||
ERR_load_PROV_strings() == 0)
return 0;
return 1;
+1
View File
@@ -37,6 +37,7 @@ L SM2 crypto/include/internal/sm2.h crypto/sm2/sm2_err.c
L OSSL_STORE include/openssl/store.h crypto/store/store_err.c
L ESS include/openssl/ess.h crypto/ess/ess_err.c
L PROP include/internal/property.h crypto/property/property_err.c
L PROV providers/common/include/internal/providercommon.h providers/common/provider_err.c
# additional header files to be scanned for function names
L NONE include/openssl/x509_vfy.h NONE
+27
View File
@@ -785,6 +785,9 @@ EVP_F_EVP_CIPHER_ASN1_TO_PARAM:204:EVP_CIPHER_asn1_to_param
EVP_F_EVP_CIPHER_CTX_COPY:163:EVP_CIPHER_CTX_copy
EVP_F_EVP_CIPHER_CTX_CTRL:124:EVP_CIPHER_CTX_ctrl
EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH:122:EVP_CIPHER_CTX_set_key_length
EVP_F_EVP_CIPHER_CTX_SET_PADDING:237:EVP_CIPHER_CTX_set_padding
EVP_F_EVP_CIPHER_FROM_DISPATCH:238:evp_cipher_from_dispatch
EVP_F_EVP_CIPHER_MODE:239:EVP_CIPHER_mode
EVP_F_EVP_CIPHER_PARAM_TO_ASN1:205:EVP_CIPHER_param_to_asn1
EVP_F_EVP_DECRYPTFINAL_EX:101:EVP_DecryptFinal_ex
EVP_F_EVP_DECRYPTUPDATE:166:EVP_DecryptUpdate
@@ -1102,6 +1105,21 @@ PROP_F_PARSE_NUMBER:104:parse_number
PROP_F_PARSE_OCT:105:parse_oct
PROP_F_PARSE_STRING:106:parse_string
PROP_F_PARSE_UNQUOTED:107:parse_unquoted
PROV_F_AESNI_INIT_KEY:101:aesni_init_key
PROV_F_AES_BLOCK_FINAL:102:aes_block_final
PROV_F_AES_BLOCK_UPDATE:103:aes_block_update
PROV_F_AES_CIPHER:104:aes_cipher
PROV_F_AES_CTX_GET_PARAMS:105:aes_ctx_get_params
PROV_F_AES_CTX_SET_PARAMS:106:aes_ctx_set_params
PROV_F_AES_DINIT:107:aes_dinit
PROV_F_AES_DUPCTX:108:aes_dupctx
PROV_F_AES_EINIT:109:aes_einit
PROV_F_AES_INIT_KEY:110:aes_init_key
PROV_F_AES_STREAM_UPDATE:111:aes_stream_update
PROV_F_AES_T4_INIT_KEY:112:aes_t4_init_key
PROV_F_PROV_AES_KEY_GENERIC_INIT:113:PROV_AES_KEY_generic_init
PROV_F_TRAILINGDATA:114:trailingdata
PROV_F_UNPADBLOCK:100:unpadblock
RAND_F_DRBG_BYTES:101:drbg_bytes
RAND_F_DRBG_CTR_INIT:125:drbg_ctr_init
RAND_F_DRBG_GET_ENTROPY:105:drbg_get_entropy
@@ -2381,6 +2399,7 @@ EVP_R_INVALID_FIPS_MODE:168:invalid fips mode
EVP_R_INVALID_KEY:163:invalid key
EVP_R_INVALID_KEY_LENGTH:130:invalid key length
EVP_R_INVALID_OPERATION:148:invalid operation
EVP_R_INVALID_PROVIDER_FUNCTIONS:193:invalid provider functions
EVP_R_INVALID_SALT_LENGTH:186:invalid salt length
EVP_R_KEYGEN_FAILURE:120:keygen failure
EVP_R_KEY_SETUP_FAILED:180:key setup failed
@@ -2604,6 +2623,14 @@ PROP_R_NO_VALUE:107:no value
PROP_R_PARSE_FAILED:108:parse failed
PROP_R_STRING_TOO_LONG:109:string too long
PROP_R_TRAILING_CHARACTERS:110:trailing characters
PROV_R_AES_KEY_SETUP_FAILED:101:aes key setup failed
PROV_R_BAD_DECRYPT:100:bad decrypt
PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed
PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter
PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter
PROV_R_INVALID_KEYLEN:105:invalid keylen
PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small
PROV_R_WRONG_FINAL_BLOCK_LENGTH:107:wrong final block length
RAND_R_ADDITIONAL_INPUT_TOO_LONG:102:additional input too long
RAND_R_ALREADY_INSTANTIATED:103:already instantiated
RAND_R_ARGUMENT_OUT_OF_RANGE:105:argument out of range
+29 -1
View File
@@ -11,6 +11,7 @@
#include <openssl/evp.h>
#include "internal/evp_int.h"
#include "internal/provider.h"
#include "evp_locl.h"
EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len)
@@ -21,6 +22,12 @@ EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len)
cipher->nid = cipher_type;
cipher->block_size = block_size;
cipher->key_len = key_len;
cipher->lock = CRYPTO_THREAD_lock_new();
if (cipher->lock == NULL) {
OPENSSL_free(cipher);
return NULL;
}
cipher->refcnt = 1;
}
return cipher;
}
@@ -30,14 +37,35 @@ EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher)
EVP_CIPHER *to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size,
cipher->key_len);
if (to != NULL)
if (to != NULL) {
CRYPTO_RWLOCK *lock = to->lock;
memcpy(to, cipher, sizeof(*to));
to->lock = lock;
}
return to;
}
void EVP_CIPHER_meth_free(EVP_CIPHER *cipher)
{
if (cipher != NULL) {
int i;
CRYPTO_DOWN_REF(&cipher->refcnt, &i, cipher->lock);
if (i > 0)
return;
ossl_provider_free(cipher->prov);
CRYPTO_THREAD_lock_free(cipher->lock);
OPENSSL_free(cipher);
}
}
int EVP_CIPHER_upref(EVP_CIPHER *cipher)
{
int ref = 0;
CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock);
return 1;
}
int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len)
+5 -4
View File
@@ -295,6 +295,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
{
int ret;
size_t size = 0;
size_t mdsize = EVP_MD_size(ctx->digest);
if (ctx->digest == NULL || ctx->digest->prov == NULL)
goto legacy;
@@ -304,7 +305,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
return 0;
}
ret = ctx->digest->dfinal(ctx->provctx, md, &size);
ret = ctx->digest->dfinal(ctx->provctx, md, &size, mdsize);
if (isize != NULL) {
if (size <= UINT_MAX) {
@@ -321,10 +322,10 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
/* TODO(3.0): Remove legacy code below */
legacy:
OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
OPENSSL_assert(mdsize <= EVP_MAX_MD_SIZE);
ret = ctx->digest->final(ctx, md);
if (isize != NULL)
*isize = ctx->digest->md_size;
*isize = mdsize;
if (ctx->digest->cleanup) {
ctx->digest->cleanup(ctx);
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
@@ -516,7 +517,7 @@ static void *evp_md_from_dispatch(int mdtype, const OSSL_DISPATCH *fns,
md->dinit = OSSL_get_OP_digest_init(fns);
fncnt++;
break;
case OSSL_FUNC_DIGEST_UPDDATE:
case OSSL_FUNC_DIGEST_UPDATE:
if (md->dupdate != NULL)
break;
md->dupdate = OSSL_get_OP_digest_update(fns);
+510 -27
View File
@@ -15,25 +15,46 @@
#include <openssl/rand.h>
#include <openssl/rand_drbg.h>
#include <openssl/engine.h>
#include <openssl/params.h>
#include <openssl/core_names.h>
#include "internal/evp_int.h"
#include "internal/provider.h"
#include "evp_locl.h"
int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c)
int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx)
{
if (c == NULL)
if (ctx == NULL)
return 1;
if (c->cipher != NULL) {
if (c->cipher->cleanup && !c->cipher->cleanup(c))
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
goto legacy;
if (ctx->provctx != NULL) {
if (ctx->cipher->freectx != NULL)
ctx->cipher->freectx(ctx->provctx);
ctx->provctx = NULL;
}
if (ctx->fetched_cipher != NULL)
EVP_CIPHER_meth_free(ctx->fetched_cipher);
memset(ctx, 0, sizeof(*ctx));
return 1;
/* TODO(3.0): Remove legacy code below */
legacy:
if (ctx->cipher != NULL) {
if (ctx->cipher->cleanup && !ctx->cipher->cleanup(ctx))
return 0;
/* Cleanse cipher context data */
if (c->cipher_data && c->cipher->ctx_size)
OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
if (ctx->cipher_data && ctx->cipher->ctx_size)
OPENSSL_cleanse(ctx->cipher_data, ctx->cipher->ctx_size);
}
OPENSSL_free(c->cipher_data);
OPENSSL_free(ctx->cipher_data);
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(c->engine);
ENGINE_finish(ctx->engine);
#endif
memset(c, 0, sizeof(*c));
memset(ctx, 0, sizeof(*ctx));
return 1;
}
@@ -60,13 +81,30 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
ENGINE *impl, const unsigned char *key,
const unsigned char *iv, int enc)
{
if (enc == -1)
EVP_CIPHER *provciph = NULL;
ENGINE *tmpimpl = NULL;
const EVP_CIPHER *tmpcipher;
/*
* enc == 1 means we are encrypting.
* enc == 0 means we are decrypting.
* enc == -1 means, use the previously initialised value for encrypt/decrypt
*/
if (enc == -1) {
enc = ctx->encrypt;
else {
} else {
if (enc)
enc = 1;
ctx->encrypt = enc;
}
if (cipher == NULL && ctx->cipher == NULL) {
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
return 0;
}
/* TODO(3.0): Legacy work around code below. Remove this */
#ifndef OPENSSL_NO_ENGINE
/*
* Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
@@ -77,11 +115,161 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
if (ctx->engine && ctx->cipher
&& (cipher == NULL || cipher->nid == ctx->cipher->nid))
goto skip_to_init;
if (cipher != NULL && impl == NULL) {
/* Ask if an ENGINE is reserved for this job */
tmpimpl = ENGINE_get_cipher_engine(cipher->nid);
}
#endif
if (cipher) {
/*
* Ensure a context left lying around from last time is cleared (the
* previous check attempted to avoid this if the same ENGINE and
* If there are engines involved then we should use legacy handling for now.
*/
if (ctx->engine != NULL
|| impl != NULL
|| tmpimpl != NULL) {
if (ctx->cipher == ctx->fetched_cipher)
ctx->cipher = NULL;
EVP_CIPHER_meth_free(ctx->fetched_cipher);
ctx->fetched_cipher = NULL;
goto legacy;
}
tmpcipher = (cipher == NULL) ? ctx->cipher : cipher;
if (tmpcipher->prov == NULL) {
switch(tmpcipher->nid) {
case NID_aes_256_ecb:
case NID_aes_192_ecb:
case NID_aes_128_ecb:
case NID_aes_256_cbc:
case NID_aes_192_cbc:
case NID_aes_128_cbc:
case NID_aes_256_ofb128:
case NID_aes_192_ofb128:
case NID_aes_128_ofb128:
case NID_aes_256_cfb128:
case NID_aes_192_cfb128:
case NID_aes_128_cfb128:
case NID_aes_256_cfb1:
case NID_aes_192_cfb1:
case NID_aes_128_cfb1:
case NID_aes_256_cfb8:
case NID_aes_192_cfb8:
case NID_aes_128_cfb8:
case NID_aes_256_ctr:
case NID_aes_192_ctr:
case NID_aes_128_ctr:
break;
default:
goto legacy;
}
}
/*
* Ensure a context left lying around from last time is cleared
* (legacy code)
*/
if (cipher != NULL && ctx->cipher != NULL) {
OPENSSL_clear_free(ctx->cipher_data, ctx->cipher->ctx_size);
ctx->cipher_data = NULL;
}
/* TODO(3.0): Start of non-legacy code below */
/* Ensure a context left lying around from last time is cleared */
if (cipher != NULL && ctx->cipher != NULL) {
unsigned long flags = ctx->flags;
EVP_CIPHER_CTX_reset(ctx);
/* Restore encrypt and flags */
ctx->encrypt = enc;
ctx->flags = flags;
}
if (cipher != NULL)
ctx->cipher = cipher;
else
cipher = ctx->cipher;
if (cipher->prov == NULL) {
provciph = EVP_CIPHER_fetch(NULL, OBJ_nid2sn(cipher->nid), "");
if (provciph == NULL) {
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
return 0;
}
cipher = provciph;
EVP_CIPHER_meth_free(ctx->fetched_cipher);
ctx->fetched_cipher = provciph;
}
ctx->cipher = cipher;
if (ctx->provctx == NULL) {
ctx->provctx = ctx->cipher->newctx();
if (ctx->provctx == NULL) {
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
return 0;
}
}
if ((ctx->flags & EVP_CIPH_NO_PADDING) != 0) {
/*
* If this ctx was already set up for no padding then we need to tell
* the new cipher about it.
*/
if (!EVP_CIPHER_CTX_set_padding(ctx, 0))
return 0;
}
switch (EVP_CIPHER_mode(ctx->cipher)) {
case EVP_CIPH_CFB_MODE:
case EVP_CIPH_OFB_MODE:
case EVP_CIPH_CBC_MODE:
/* For these modes we remember the original IV for later use */
if (!ossl_assert(EVP_CIPHER_CTX_iv_length(ctx) <= (int)sizeof(ctx->oiv))) {
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
return 0;
}
if (iv != NULL)
memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
}
if (enc) {
if (ctx->cipher->einit == NULL) {
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
return 0;
}
return ctx->cipher->einit(ctx->provctx,
key,
key == NULL ? 0
: EVP_CIPHER_CTX_key_length(ctx),
iv,
iv == NULL ? 0
: EVP_CIPHER_CTX_iv_length(ctx));
}
if (ctx->cipher->dinit == NULL) {
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
return 0;
}
return ctx->cipher->dinit(ctx->provctx,
key,
key == NULL ? 0
: EVP_CIPHER_CTX_key_length(ctx),
iv,
iv == NULL ? 0
: EVP_CIPHER_CTX_iv_length(ctx));
/* TODO(3.0): Remove legacy code below */
legacy:
if (cipher != NULL) {
/*
* Ensure a context left lying around from last time is cleared (we
* previously attempted to avoid this if the same ENGINE and
* EVP_CIPHER could be used).
*/
if (ctx->cipher) {
@@ -92,18 +280,19 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
ctx->flags = flags;
}
#ifndef OPENSSL_NO_ENGINE
if (impl) {
if (impl != NULL) {
if (!ENGINE_init(impl)) {
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
return 0;
}
} else
/* Ask if an ENGINE is reserved for this job */
impl = ENGINE_get_cipher_engine(cipher->nid);
if (impl) {
} else {
impl = tmpimpl;
}
if (impl != NULL) {
/* There's an ENGINE for this job ... (apparently) */
const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
if (!c) {
if (c == NULL) {
/*
* One positive side-effect of US's export control history,
* is that we should at least be able to avoid using US
@@ -119,8 +308,9 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
* from an ENGINE and we need to release it when done.
*/
ctx->engine = impl;
} else
} else {
ctx->engine = NULL;
}
#endif
ctx->cipher = cipher;
@@ -144,9 +334,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
return 0;
}
}
} else if (!ctx->cipher) {
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
return 0;
}
#ifndef OPENSSL_NO_ENGINE
skip_to_init:
@@ -377,12 +564,39 @@ static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
const unsigned char *in, int inl)
{
int ret;
size_t soutl;
int blocksize;
/* Prevent accidental use of decryption context when encrypting */
if (!ctx->encrypt) {
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_INVALID_OPERATION);
return 0;
}
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
goto legacy;
blocksize = EVP_CIPHER_CTX_block_size(ctx);
if (ctx->cipher->cupdate == NULL || blocksize < 1) {
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_UPDATE_ERROR);
return 0;
}
ret = ctx->cipher->cupdate(ctx->provctx, out, &soutl,
inl + (blocksize == 1 ? 0 : blocksize), in,
(size_t)inl);
if (soutl > INT_MAX) {
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_UPDATE_ERROR);
return 0;
}
*outl = soutl;
return ret;
/* TODO(3.0): Remove legacy code below */
legacy:
return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl);
}
@@ -397,6 +611,8 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int n, ret;
unsigned int i, b, bl;
size_t soutl;
int blocksize;
/* Prevent accidental use of decryption context when encrypting */
if (!ctx->encrypt) {
@@ -404,6 +620,30 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
return 0;
}
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
goto legacy;
blocksize = EVP_CIPHER_CTX_block_size(ctx);
if (blocksize < 1 || ctx->cipher->cfinal == NULL) {
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_FINAL_ERROR);
return 0;
}
ret = ctx->cipher->cfinal(ctx->provctx, out, &soutl,
blocksize == 1 ? 0 : blocksize);
if (soutl > INT_MAX) {
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_FINAL_ERROR);
return 0;
}
*outl = soutl;
return ret;
/* TODO(3.0): Remove legacy code below */
legacy:
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
ret = ctx->cipher->do_cipher(ctx, out, NULL, 0);
if (ret < 0)
@@ -444,8 +684,10 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
const unsigned char *in, int inl)
{
int fix_len, cmpl = inl;
int fix_len, cmpl = inl, ret;
unsigned int b;
size_t soutl;
int blocksize;
/* Prevent accidental use of encryption context when decrypting */
if (ctx->encrypt) {
@@ -453,6 +695,32 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
return 0;
}
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
goto legacy;
blocksize = EVP_CIPHER_CTX_block_size(ctx);
if (ctx->cipher->cupdate == NULL || blocksize < 1) {
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_UPDATE_ERROR);
return 0;
}
ret = ctx->cipher->cupdate(ctx->provctx, out, &soutl,
inl + (blocksize == 1 ? 0 : blocksize), in,
(size_t)inl);
if (ret) {
if (soutl > INT_MAX) {
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_UPDATE_ERROR);
return 0;
}
*outl = soutl;
}
return ret;
/* TODO(3.0): Remove legacy code below */
legacy:
b = ctx->cipher->block_size;
if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
@@ -527,6 +795,9 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
int i, n;
unsigned int b;
size_t soutl;
int ret;
int blocksize;
/* Prevent accidental use of encryption context when decrypting */
if (ctx->encrypt) {
@@ -534,6 +805,32 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
return 0;
}
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
goto legacy;
blocksize = EVP_CIPHER_CTX_block_size(ctx);
if (blocksize < 1 || ctx->cipher->cfinal == NULL) {
EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_FINAL_ERROR);
return 0;
}
ret = ctx->cipher->cfinal(ctx->provctx, out, &soutl,
blocksize == 1 ? 0 : blocksize);
if (ret) {
if (soutl > INT_MAX) {
EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_FINAL_ERROR);
return 0;
}
*outl = soutl;
}
return ret;
/* TODO(3.0): Remove legacy code below */
legacy:
*outl = 0;
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
@@ -590,7 +887,7 @@ int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
{
if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
if (c->key_len == keylen)
if (EVP_CIPHER_CTX_key_length(c) == keylen)
return 1;
if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) {
c->key_len = keylen;
@@ -606,6 +903,24 @@ int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
ctx->flags &= ~EVP_CIPH_NO_PADDING;
else
ctx->flags |= EVP_CIPH_NO_PADDING;
if (ctx->cipher != NULL && ctx->cipher->prov != NULL) {
OSSL_PARAM params[] = {
OSSL_PARAM_int(OSSL_CIPHER_PARAM_PADDING, NULL),
OSSL_PARAM_END
};
params[0].data = &pad;
if (ctx->cipher->ctx_set_params == NULL) {
EVPerr(EVP_F_EVP_CIPHER_CTX_SET_PADDING, EVP_R_CTRL_NOT_IMPLEMENTED);
return 0;
}
if (!ctx->cipher->ctx_set_params(ctx->provctx, params))
return 0;
}
return 1;
}
@@ -636,7 +951,7 @@ int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
{
if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
if (RAND_priv_bytes(key, ctx->key_len) <= 0)
if (RAND_priv_bytes(key, EVP_CIPHER_CTX_key_length(ctx)) <= 0)
return 0;
return 1;
}
@@ -647,6 +962,36 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INPUT_NOT_INITIALIZED);
return 0;
}
if (in->cipher->prov == NULL)
goto legacy;
if (in->cipher->dupctx == NULL) {
EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_NOT_ABLE_TO_COPY_CTX);
return 0;
}
EVP_CIPHER_CTX_reset(out);
*out = *in;
out->provctx = NULL;
if (in->fetched_cipher != NULL && !EVP_CIPHER_upref(in->fetched_cipher)) {
out->fetched_cipher = NULL;
return 0;
}
out->provctx = in->cipher->dupctx(in->provctx);
if (out->provctx == NULL) {
EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_NOT_ABLE_TO_COPY_CTX);
return 0;
}
return 1;
/* TODO(3.0): Remove legacy code below */
legacy:
#ifndef OPENSSL_NO_ENGINE
/* Make sure it's safe to copy a cipher context using an ENGINE */
if (in->engine && !ENGINE_init(in->engine)) {
@@ -676,3 +1021,141 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
}
return 1;
}
static void *evp_cipher_from_dispatch(int nid, const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov)
{
EVP_CIPHER *cipher = NULL;
int fnciphcnt = 0, fnctxcnt = 0;
if ((cipher = EVP_CIPHER_meth_new(nid, 0, 0)) == NULL)
return NULL;
for (; fns->function_id != 0; fns++) {
switch (fns->function_id) {
case OSSL_FUNC_CIPHER_NEWCTX:
if (cipher->newctx != NULL)
break;
cipher->newctx = OSSL_get_OP_cipher_newctx(fns);
fnctxcnt++;
break;
case OSSL_FUNC_CIPHER_ENCRYPT_INIT:
if (cipher->einit != NULL)
break;
cipher->einit = OSSL_get_OP_cipher_encrypt_init(fns);
fnciphcnt++;
break;
case OSSL_FUNC_CIPHER_DECRYPT_INIT:
if (cipher->dinit != NULL)
break;
cipher->dinit = OSSL_get_OP_cipher_decrypt_init(fns);
fnciphcnt++;
break;
case OSSL_FUNC_CIPHER_UPDATE:
if (cipher->cupdate != NULL)
break;
cipher->cupdate = OSSL_get_OP_cipher_update(fns);
fnciphcnt++;
break;
case OSSL_FUNC_CIPHER_FINAL:
if (cipher->cfinal != NULL)
break;
cipher->cfinal = OSSL_get_OP_cipher_final(fns);
fnciphcnt++;
break;
case OSSL_FUNC_CIPHER_CIPHER:
if (cipher->ccipher != NULL)
break;
cipher->ccipher = OSSL_get_OP_cipher_cipher(fns);
break;
case OSSL_FUNC_CIPHER_FREECTX:
if (cipher->freectx != NULL)
break;
cipher->freectx = OSSL_get_OP_cipher_freectx(fns);
fnctxcnt++;
break;
case OSSL_FUNC_CIPHER_DUPCTX:
if (cipher->dupctx != NULL)
break;
cipher->dupctx = OSSL_get_OP_cipher_dupctx(fns);
break;
case OSSL_FUNC_CIPHER_KEY_LENGTH:
if (cipher->key_length != NULL)
break;
cipher->key_length = OSSL_get_OP_cipher_key_length(fns);
break;
case OSSL_FUNC_CIPHER_IV_LENGTH:
if (cipher->iv_length != NULL)
break;
cipher->iv_length = OSSL_get_OP_cipher_iv_length(fns);
break;
case OSSL_FUNC_CIPHER_BLOCK_SIZE:
if (cipher->blocksize != NULL)
break;
cipher->blocksize = OSSL_get_OP_cipher_block_size(fns);
break;
case OSSL_FUNC_CIPHER_GET_PARAMS:
if (cipher->get_params != NULL)
break;
cipher->get_params = OSSL_get_OP_cipher_get_params(fns);
break;
case OSSL_FUNC_CIPHER_CTX_GET_PARAMS:
if (cipher->ctx_get_params != NULL)
break;
cipher->ctx_get_params = OSSL_get_OP_cipher_ctx_get_params(fns);
break;
case OSSL_FUNC_CIPHER_CTX_SET_PARAMS:
if (cipher->ctx_set_params != NULL)
break;
cipher->ctx_set_params = OSSL_get_OP_cipher_ctx_set_params(fns);
break;
}
}
if ((fnciphcnt != 0 && fnciphcnt != 3 && fnciphcnt != 4)
|| (fnciphcnt == 0 && cipher->ccipher == NULL)
|| fnctxcnt != 2
|| cipher->blocksize == NULL
|| cipher->iv_length == NULL
|| cipher->key_length == NULL) {
/*
* In order to be a consistent set of functions we must have at least
* a complete set of "encrypt" functions, or a complete set of "decrypt"
* functions, or a single "cipher" function. In all cases we need a
* complete set of context management functions, as well as the
* blocksize, iv_length and key_length functions.
*/
EVP_CIPHER_meth_free(cipher);
EVPerr(EVP_F_EVP_CIPHER_FROM_DISPATCH, EVP_R_INVALID_PROVIDER_FUNCTIONS);
return NULL;
}
cipher->prov = prov;
if (prov != NULL)
ossl_provider_upref(prov);
return cipher;
}
static int evp_cipher_upref(void *cipher)
{
return EVP_CIPHER_upref(cipher);
}
static void evp_cipher_free(void *cipher)
{
EVP_CIPHER_meth_free(cipher);
}
static int evp_cipher_nid(void *vcipher)
{
EVP_CIPHER *cipher = vcipher;
return cipher->nid;
}
EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
const char *properties)
{
return evp_generic_fetch(ctx, OSSL_OP_CIPHER, algorithm, properties,
evp_cipher_from_dispatch, evp_cipher_upref,
evp_cipher_free, evp_cipher_nid);
}
+7
View File
@@ -53,6 +53,11 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
"EVP_CIPHER_CTX_ctrl"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, 0),
"EVP_CIPHER_CTX_set_key_length"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_SET_PADDING, 0),
"EVP_CIPHER_CTX_set_padding"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_FROM_DISPATCH, 0),
"evp_cipher_from_dispatch"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_MODE, 0), "EVP_CIPHER_mode"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_PARAM_TO_ASN1, 0),
"EVP_CIPHER_param_to_asn1"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, 0),
@@ -246,6 +251,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY), "invalid key"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY_LENGTH), "invalid key length"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "invalid operation"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_PROVIDER_FUNCTIONS),
"invalid provider functions"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SALT_LENGTH),
"invalid salt length"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYGEN_FAILURE), "keygen failure"},
+8 -2
View File
@@ -173,11 +173,15 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
void (*free_method)(void *),
int (*nid_method)(void *))
{
OSSL_METHOD_STORE *store = get_default_method_store(libctx);
int nid = OBJ_sn2nid(algorithm);
void *method = NULL;
if (store == NULL)
return NULL;
if (nid == NID_undef
|| !ossl_method_store_cache_get(NULL, nid, properties, &method)) {
|| !ossl_method_store_cache_get(store, nid, properties, &method)) {
OSSL_METHOD_CONSTRUCT_METHOD mcm = {
alloc_tmp_method_store,
dealloc_tmp_method_store,
@@ -198,7 +202,9 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
method = ossl_method_construct(libctx, operation_id, algorithm,
properties, 0 /* !force_cache */,
&mcm, &mcmdata);
ossl_method_store_cache_set(NULL, nid, properties, method);
ossl_method_store_cache_set(store, nid, properties, method);
} else {
upref_method(method);
}
return method;
+113 -20
View File
@@ -11,6 +11,8 @@
#include "internal/cryptlib.h"
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/params.h>
#include <openssl/core_names.h>
#include "internal/evp_int.h"
#include "internal/provider.h"
#include "evp_locl.h"
@@ -18,13 +20,28 @@
int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
{
int ret;
const EVP_CIPHER *cipher = c->cipher;
if (c->cipher->set_asn1_parameters != NULL)
ret = c->cipher->set_asn1_parameters(c, type);
else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
switch (EVP_CIPHER_CTX_mode(c)) {
if (cipher->prov != NULL) {
/*
* The cipher has come from a provider and won't have the default flags.
* Find the implicit form so we can check the flags.
* TODO(3.0): This won't work for 3rd party ciphers we know nothing about
* We'll need to think of something else for those.
*/
cipher = EVP_get_cipherbynid(cipher->nid);
if (cipher == NULL) {
EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, ASN1_R_UNSUPPORTED_CIPHER);
return -1;
}
}
if (cipher->set_asn1_parameters != NULL)
ret = cipher->set_asn1_parameters(c, type);
else if (cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
switch (EVP_CIPHER_mode(cipher)) {
case EVP_CIPH_WRAP_MODE:
if (EVP_CIPHER_CTX_nid(c) == NID_id_smime_alg_CMS3DESwrap)
if (EVP_CIPHER_nid(cipher) == NID_id_smime_alg_CMS3DESwrap)
ASN1_TYPE_set(type, V_ASN1_NULL, NULL);
ret = 1;
break;
@@ -53,11 +70,22 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
{
int ret;
const EVP_CIPHER *cipher = c->cipher;
if (c->cipher->get_asn1_parameters != NULL)
ret = c->cipher->get_asn1_parameters(c, type);
else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
switch (EVP_CIPHER_CTX_mode(c)) {
if (cipher->prov != NULL) {
/*
* The cipher has come from a provider and won't have the default flags.
* Find the implicit form so we can check the flags.
*/
cipher = EVP_get_cipherbynid(cipher->nid);
if (cipher == NULL)
return -1;
}
if (cipher->get_asn1_parameters != NULL)
ret = cipher->get_asn1_parameters(c, type);
else if (cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
switch (EVP_CIPHER_mode(cipher)) {
case EVP_CIPH_WRAP_MODE:
ret = 1;
@@ -85,19 +113,23 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
return ret;
}
int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *ctx, ASN1_TYPE *type)
{
int i = 0;
unsigned int l;
if (type != NULL) {
l = EVP_CIPHER_CTX_iv_length(c);
OPENSSL_assert(l <= sizeof(c->iv));
i = ASN1_TYPE_get_octetstring(type, c->oiv, l);
unsigned char iv[EVP_MAX_IV_LENGTH];
l = EVP_CIPHER_CTX_iv_length(ctx);
if (!ossl_assert(l <= sizeof(iv)))
return -1;
i = ASN1_TYPE_get_octetstring(type, iv, l);
if (i != (int)l)
return -1;
else if (i > 0)
memcpy(c->iv, c->oiv, l);
if (!EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1))
return -1;
}
return i;
}
@@ -175,14 +207,20 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx)
}
}
int EVP_CIPHER_block_size(const EVP_CIPHER *e)
int EVP_CIPHER_block_size(const EVP_CIPHER *cipher)
{
return e->block_size;
if (cipher->prov != NULL) {
if (cipher->blocksize != NULL)
return cipher->blocksize();
/* We default to a block size of 1 */
return 1;
}
return cipher->block_size;
}
int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
{
return ctx->cipher->block_size;
return EVP_CIPHER_block_size(ctx->cipher);
}
int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *e)
@@ -193,6 +231,12 @@ int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *e)
int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, unsigned int inl)
{
if (ctx->cipher->prov != NULL) {
if (ctx->cipher->ccipher != NULL)
return ctx->cipher->ccipher(ctx->provctx, out, in, (size_t)inl);
return 0;
}
return ctx->cipher->do_cipher(ctx, out, in, inl);
}
@@ -238,12 +282,18 @@ void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data)
int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
{
if (cipher->prov != NULL) {
if (cipher->iv_length != NULL)
return (int)cipher->iv_length();
return 0;
}
return cipher->iv_len;
}
int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
{
return ctx->cipher->iv_len;
return EVP_CIPHER_iv_length(ctx->cipher);
}
const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx)
@@ -278,11 +328,23 @@ void EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num)
int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
{
if (cipher->prov != NULL) {
if (cipher->key_length != NULL)
return (int)cipher->key_length();
return -1;
}
return cipher->key_len;
}
int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
{
/*
* TODO(3.0): This may need to change if/when we introduce variable length
* key ciphers into the providers.
*/
if (ctx->cipher != NULL && ctx->cipher->prov != NULL)
return EVP_CIPHER_key_length(ctx->cipher);
return ctx->key_len;
}
@@ -296,6 +358,33 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
return ctx->cipher->nid;
}
int EVP_CIPHER_mode(const EVP_CIPHER *cipher)
{
if (cipher->prov != NULL) {
int mode;
/* Cipher comes from a provider - so ask the provider for the mode */
OSSL_PARAM params[] = {
OSSL_PARAM_int(OSSL_CIPHER_PARAM_MODE, NULL),
OSSL_PARAM_END
};
params[0].data = &mode;
if (cipher->get_params == NULL) {
EVPerr(EVP_F_EVP_CIPHER_MODE, EVP_R_CTRL_NOT_IMPLEMENTED);
return 0;
}
if (!cipher->get_params(params))
return 0;
return mode;
}
return EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE;
}
int EVP_MD_block_size(const EVP_MD *md)
{
if (md == NULL) {
@@ -353,12 +442,16 @@ EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type)
}
return md;
}
EVP_MD *EVP_MD_meth_dup(const EVP_MD *md)
{
EVP_MD *to = EVP_MD_meth_new(md->type, md->pkey_type);
if (to != NULL)
if (to != NULL) {
CRYPTO_RWLOCK *lock = to->lock;
memcpy(to, md, sizeof(*to));
to->lock = lock;
}
return to;
}
+4
View File
@@ -44,6 +44,10 @@ struct evp_cipher_ctx_st {
int final_used;
int block_mask;
unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */
/* Provider ctx */
void *provctx;
EVP_CIPHER *fetched_cipher;
} /* EVP_CIPHER_CTX */ ;
struct evp_mac_ctx_st {
+24
View File
@@ -210,10 +210,14 @@ struct evp_md_st {
struct evp_cipher_st {
int nid;
int block_size;
/* Default value for variable length ciphers */
int key_len;
int iv_len;
/* Legacy structure members */
/* TODO(3.0): Remove these */
/* Various flags */
unsigned long flags;
/* init key */
@@ -234,6 +238,26 @@ struct evp_cipher_st {
int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr);
/* Application data */
void *app_data;
/* New structure members */
/* TODO(3.0): Remove above comment when legacy has gone */
OSSL_PROVIDER *prov;
CRYPTO_REF_COUNT refcnt;
CRYPTO_RWLOCK *lock;
OSSL_OP_cipher_newctx_fn *newctx;
OSSL_OP_cipher_encrypt_init_fn *einit;
OSSL_OP_cipher_decrypt_init_fn *dinit;
OSSL_OP_cipher_update_fn *cupdate;
OSSL_OP_cipher_final_fn *cfinal;
OSSL_OP_cipher_cipher_fn *ccipher;
OSSL_OP_cipher_freectx_fn *freectx;
OSSL_OP_cipher_dupctx_fn *dupctx;
OSSL_OP_cipher_key_length_fn *key_length;
OSSL_OP_cipher_iv_length_fn *iv_length;
OSSL_OP_cipher_block_size_fn *blocksize;
OSSL_OP_cipher_get_params_fn *get_params;
OSSL_OP_cipher_ctx_get_params_fn *ctx_get_params;
OSSL_OP_cipher_ctx_set_params_fn *ctx_set_params;
} /* EVP_CIPHER */ ;
/* Macros to code block cipher wrappers */
+44
View File
@@ -0,0 +1,44 @@
/*
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <stddef.h>
#include <openssl/crypto.h>
#include "internal/dso_conf.h"
#include "e_os.h"
const char *OPENSSL_info(int t)
{
switch (t) {
case OPENSSL_INFO_CONFIG_DIR:
return OPENSSLDIR;
case OPENSSL_INFO_ENGINES_DIR:
return ENGINESDIR;
case OPENSSL_INFO_MODULES_DIR:
return MODULESDIR;
case OPENSSL_INFO_DSO_EXTENSION:
return DSO_EXTENSION;
case OPENSSL_INFO_DIR_FILENAME_SEPARATOR:
#if defined(_WIN32)
return "\\";
#elif defined(__VMS)
return "";
#else /* Assume POSIX */
return "/";
#endif
case OPENSSL_INFO_LIST_SEPARATOR:
{
static const char list_sep[] = { LIST_SEPARATOR_CHAR, '\0' };
return list_sep;
}
default:
break;
}
/* Not an error */
return NULL;
}
+1
View File
@@ -98,6 +98,7 @@ void OPENSSL_LH_flush(OPENSSL_LHASH *lh)
OPENSSL_free(n);
n = nn;
}
lh->b[i] = NULL;
}
}
+1
View File
@@ -42,6 +42,7 @@
# Denver 0.51 0.65 6.02
# Mongoose 0.65 1.10 8.06
# Kryo 0.76 1.16 8.00
# ThunderX2 1.05
#
# (*) presented for reference/comparison purposes;
+1 -1
View File
@@ -425,7 +425,7 @@ size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
M *= 2;
M += 2;
if (len < M)
if (len != M)
return 0;
memcpy(tag, ctx->cmac.c, M);
return M;
+88 -6
View File
@@ -6,23 +6,37 @@
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
# Copyright IBM Corp. 2018
# Copyright IBM Corp. 2018-2019
# Author: Patrick Steuer <patrick.steuer@de.ibm.com>
package perlasm::s390x;
use strict;
use warnings;
use bigint;
use Carp qw(confess);
use Exporter qw(import);
our @EXPORT=qw(PERLASM_BEGIN PERLASM_END);
our @EXPORT_OK=qw(AUTOLOAD LABEL INCLUDE stfle);
our %EXPORT_TAGS=(
# long-displacement facility
LD => [qw(clgfi)],
# general-instruction-extension facility
GE => [qw(risbg)],
# extended-immediate facility
EI => [qw(lt)],
# miscellaneous-instruction-extensions facility 1
MI1 => [qw(risbgn)],
# message-security assist
MSA => [qw(kmac km kmc kimd klmd)],
# message-security-assist extension 4
MSA4 => [qw(kmf kmo pcc kmctr)],
# message-security-assist extension 5
MSA5 => [qw(ppno prno)],
# message-security-assist extension 8
MSA8 => [qw(kma)],
# vector facility
VX => [qw(vgef vgeg vgbm vzero vone vgm vgmb vgmh vgmf vgmg
vl vlr vlrep vlrepb vlreph vlrepf vlrepg vleb vleh vlef vleg vleib
vleih vleif vleig vlgv vlgvb vlgvh vlgvf vlgvg vllez vllezb vllezh
@@ -71,6 +85,7 @@ our %EXPORT_TAGS=(
wfmadb vfms vfmsdb wfmsdb vfpso vfpsodb wfpsodb vflcdb wflcdb
vflndb wflndb vflpdb wflpdb vfsq vfsqdb wfsqdb vfs vfsdb wfsdb
vftci vftcidb wftcidb)],
# vector-enhancements facility 1
VXE => [qw(vbperm vllezlf vmsl vmslg vnx vnn voc vpopctb vpopcth
vpopctf vpopctg vfasb wfasb wfaxb wfcsb wfcxb wfksb wfkxb vfcesb
vfcesbs wfcesb wfcesbs wfcexb wfcexbs vfchsb vfchsbs wfchsb wfchsbs
@@ -83,10 +98,11 @@ our %EXPORT_TAGS=(
wfnmsxb vfpsosb wfpsosb vflcsb wflcsb vflnsb wflnsb vflpsb wflpsb
vfpsoxb wfpsoxb vflcxb wflcxb vflnxb wflnxb vflpxb wflpxb vfsqsb
wfsqsb wfsqxb vfssb wfssb wfsxb vftcisb wftcisb wftcixb)],
# vector-packed-decimal facility
VXD => [qw(vlrlr vlrl vstrlr vstrl vap vcp vcvb vcvbg vcvd vcvdg vdp
vlip vmp vmsp vpkz vpsop vrp vsdp vsrp vsp vtp vupkz)],
);
Exporter::export_ok_tags(qw(MSA MSA4 MSA5 MSA8 VX VXE VXD));
Exporter::export_ok_tags(qw(LD GE EI MI1 MSA MSA4 MSA5 MSA8 VX VXE VXD));
our $AUTOLOAD;
@@ -143,6 +159,28 @@ sub stfle {
S(0xb2b0,@_);
}
# MISC
sub clgfi {
confess(err("ARGNUM")) if ($#_!=1);
RILa(0xc2e,@_);
}
sub lt {
confess(err("ARGNUM")) if ($#_!=1);
RXYa(0xe312,@_);
}
sub risbg {
confess(err("ARGNUM")) if ($#_<3||$#_>4);
RIEf(0xec55,@_);
}
sub risbgn {
confess(err("ARGNUM")) if ($#_<3||$#_>4);
RIEf(0xec59,@_);
}
# MSA
sub kmac {
@@ -250,7 +288,7 @@ sub vgmg {
}
sub vl {
confess(err("ARGNUM")) if ($#_!=1);
confess(err("ARGNUM")) if ($#_<1||$#_>2);
VRX(0xe706,@_);
}
@@ -345,7 +383,7 @@ sub vllezg {
}
sub vlm {
confess(err("ARGNUM")) if ($#_!=2);
confess(err("ARGNUM")) if ($#_<2||$#_>3);
VRSa(0xe736,@_);
}
@@ -548,7 +586,7 @@ sub vsegf {
}
sub vst {
confess(err("ARGNUM")) if ($#_!=1);
confess(err("ARGNUM")) if ($#_<1||$#_>2);
VRX(0xe70e,@_);
}
@@ -570,7 +608,7 @@ sub vsteg {
}
sub vstm {
confess(err("ARGNUM")) if ($#_!=2);
confess(err("ARGNUM")) if ($#_<2||$#_>3);
VRSa(0xe73e,@_);
}
@@ -2486,6 +2524,36 @@ sub vupkz {
# Instruction Formats
#
sub RIEf {
confess(err("ARGNUM")) if ($#_<4||5<$#_);
my $ops=join(',',@_[1..$#_]);
my $memn=(caller(1))[3];
$memn=~s/^.*:://;
my ($opcode,$r1,$r2,$i3,$i4,$i5)=(shift,get_R(shift),get_R(shift),
get_I(shift,8),get_I(shift,8),
get_I(shift,8));
$out.="\t.word\t";
$out.=sprintf("%#06x",(($opcode>>8)<<8|$r1<<4|$r2)).",";
$out.=sprintf("%#06x",($i3<<8)|$i4).",";
$out.=sprintf("%#06x",($i5<<8)|($opcode&0xff));
$out.="\t# $memn\t$ops\n"
}
sub RILa {
confess(err("ARGNUM")) if ($#_!=2);
my $ops=join(',',@_[1..$#_]);
my $memn=(caller(1))[3];
$memn=~s/^.*:://;
my ($opcode,$r1,$i2)=(shift,get_R(shift),get_I(shift,32));
$out.="\t.word\t";
$out.=sprintf("%#06x",(($opcode>>4)<<8|$r1<<4|($opcode&0xf))).",";
$out.=sprintf("%#06x",($i2>>16)).",";
$out.=sprintf("%#06x",($i2&0xffff));
$out.="\t# $memn\t$ops\n"
}
sub RRE {
confess(err("ARGNUM")) if ($#_<0||2<$#_);
my $ops=join(',',@_[1..$#_]);
@@ -2510,6 +2578,20 @@ sub RRFb {
$out.="\t# $memn\t$ops\n"
}
sub RXYa {
confess(err("ARGNUM")) if ($#_!=2);
my $ops=join(',',@_[1..$#_]);
my $memn=(caller(1))[3];
$memn=~s/^.*:://;
my ($opcode,$r1,$d2,$x2,$b2)=(shift,get_R(shift),get_DXB(shift));
$out.="\t.word\t";
$out.=sprintf("%#06x",(($opcode>>8)<<8|$r1<<4|$x2)).",";
$out.=sprintf("%#06x",($b2<<12|($d2&0xfff))).",";
$out.=sprintf("%#06x",(($d2>>12)<<8|$opcode&0xff));
$out.="\t# $memn\t$ops\n"
}
sub S {
confess(err("ARGNUM")) if ($#_<0||1<$#_);
my $ops=join(',',@_[1..$#_]);
+1
View File
@@ -29,6 +29,7 @@
# X-Gene 2.13/+68% 2.27
# Mongoose 1.77/+75% 1.12
# Kryo 2.70/+55% 1.13
# ThunderX2 1.17/+95% 1.36
#
# (*) estimate based on resources availability is less than 1.0,
# i.e. measured result is worse than expected, presumably binary
+1 -1
View File
@@ -45,7 +45,7 @@
use strict;
use FindBin qw($Bin);
use lib "$Bin/../..";
use perlasm::s390x qw(:DEFAULT :VX AUTOLOAD LABEL INCLUDE);
use perlasm::s390x qw(:DEFAULT :LD :GE :EI :MI1 :VX AUTOLOAD LABEL INCLUDE);
my $flavour = shift;
+1 -1
View File
@@ -450,7 +450,7 @@ int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, int nid,
return 0;
}
elem.query = prop_query;
elem.query = prop_query != NULL ? prop_query : "";
r = lh_QUERY_retrieve(alg->cache, &elem);
if (r == NULL) {
ossl_property_unlock(store);
+1 -1
View File
@@ -30,7 +30,7 @@ int rand_crngt_get_entropy_cb(unsigned char *buf)
while ((n = rand_pool_acquire_entropy(crngt_pool)) != 0)
if (n >= CRNGT_BUFSIZ) {
p = rand_pool_detach(crngt_pool);
memcpy(crngt_prev, p, CRNGT_BUFSIZ);
memcpy(buf, p, CRNGT_BUFSIZ);
rand_pool_reattach(crngt_pool, p);
return 1;
}
+27
View File
@@ -38,6 +38,13 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
param, plen, NULL, NULL);
}
/*
* Perform ihe padding as per NIST 800-56B 7.2.2.3
* from (K) is the key material.
* param (A) is the additional input.
* Step numbers are included here but not in the constant time inverse below
* to avoid complicating an already difficult enough function.
*/
int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
const unsigned char *from, int flen,
const unsigned char *param, int plen,
@@ -57,6 +64,7 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
mdlen = EVP_MD_size(md);
/* step 2b: check KLen > nLen - 2 HLen - 2 */
if (flen > emlen - 2 * mdlen - 1) {
RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,
RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
@@ -69,15 +77,20 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
return 0;
}
/* step 3i: EM = 00000000 || maskedMGF || maskedDB */
to[0] = 0;
seed = to + 1;
db = to + mdlen + 1;
/* step 3a: hash the additional input */
if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL))
goto err;
/* step 3b: zero bytes array of length nLen - KLen - 2 HLen -2 */
memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1);
/* step 3c: DB = HA || PS || 00000001 || K */
db[emlen - flen - mdlen - 1] = 0x01;
memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen);
/* step 3d: generate random byte string */
if (RAND_bytes(seed, mdlen) <= 0)
goto err;
@@ -88,13 +101,17 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
goto err;
}
/* step 3e: dbMask = MGF(mgfSeed, nLen - HLen - 1) */
if (PKCS1_MGF1(dbmask, dbmask_len, seed, mdlen, mgf1md) < 0)
goto err;
/* step 3f: maskedDB = DB XOR dbMask */
for (i = 0; i < dbmask_len; i++)
db[i] ^= dbmask[i];
/* step 3g: mgfSeed = MGF(maskedDB, HLen) */
if (PKCS1_MGF1(seedmask, mdlen, db, dbmask_len, mgf1md) < 0)
goto err;
/* stepo 3h: maskedMGFSeed = mgfSeed XOR mgfSeedMask */
for (i = 0; i < mdlen; i++)
seed[i] ^= seedmask[i];
rv = 1;
@@ -270,6 +287,13 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
return constant_time_select_int(good, mlen, -1);
}
/*
* Mask Generation Function corresponding to section 7.2.2.2 of NIST SP 800-56B.
* The variables are named differently to NIST:
* mask (T) and len (maskLen)are the returned mask.
* seed (mgfSeed).
* The range checking steps inm the process are performed outside.
*/
int PKCS1_MGF1(unsigned char *mask, long len,
const unsigned char *seed, long seedlen, const EVP_MD *dgst)
{
@@ -285,11 +309,14 @@ int PKCS1_MGF1(unsigned char *mask, long len,
mdlen = EVP_MD_size(dgst);
if (mdlen < 0)
goto err;
/* step 4 */
for (i = 0; outlen < len; i++) {
/* step 4a: D = I2BS(counter, 4) */
cnt[0] = (unsigned char)((i >> 24) & 255);
cnt[1] = (unsigned char)((i >> 16) & 255);
cnt[2] = (unsigned char)((i >> 8)) & 255;
cnt[3] = (unsigned char)(i & 255);
/* step 4b: T =T || hash(mgfSeed || D) */
if (!EVP_DigestInit_ex(c, dgst, NULL)
|| !EVP_DigestUpdate(c, seed, seedlen)
|| !EVP_DigestUpdate(c, cnt, 4))
+1
View File
@@ -51,6 +51,7 @@
# Kryo 12
# Denver 7.8
# Apple A7 7.2
# ThunderX2 9.7
#
# (*) Corresponds to SHA3-256. No improvement coefficients are listed
# because they vary too much from compiler to compiler. Newer
+1
View File
@@ -27,6 +27,7 @@
# X-Gene 8.80 (+200%)
# Mongoose 2.05 6.50 (+160%)
# Kryo 1.88 8.00 (+90%)
# ThunderX2 2.64 6.36 (+150%)
#
# (*) Software results are presented mostly for reference purposes.
# (**) Keep in mind that Denver relies on binary translation, which
+1
View File
@@ -28,6 +28,7 @@
# X-Gene 20.0 (+100%) 12.8 (+300%(***))
# Mongoose 2.36 13.0 (+50%) 8.36 (+33%)
# Kryo 1.92 17.4 (+30%) 11.2 (+8%)
# ThunderX2 2.54 13.2 (+40%) 8.40 (+18%)
#
# (*) Software SHA256 results are of lesser relevance, presented
# mostly for informational purposes.
+81
View File
@@ -0,0 +1,81 @@
=pod
=head1 NAME
openssl-info,
info - print OpenSSL built-in information
=head1 SYNOPSIS
B<openssl info>
[B<-help>]
[B<-configdir> | B<-c>]
[B<-enginesdir> | B<-e>]
[B<-modulesdir> | B<-m>]
[B<-dsoext>]
[B<-dirfilesep>]
[B<-listsep]>
=head1 DESCRIPTION
This command is used to print out information about OpenSSL.
The information is written exactly as it is with no extra text, which
makes useful for scripts.
As a consequence, only one item may be chosen for each run of this
command.
=head1 OPTIONS
=over 4
=item B<-help>
Print out a usage message.
=item B<-configdir>, B<-c>
Outputs the default directory for OpenSSL configuration files.
=item B<-enginesdir>, B<-e>
Outputs the default directory for OpenSSL engine modules.
=item B<-modulesdir>, B<-m>
Outputs the default directory for OpenSSL dynamically loadable modules
other than engine modules.
=item B<-dsoext>
Outputs the DSO extension OpenSSL uses.
=item B<-dirnamesep>
Outputs the separator character between a directory specification and
a file name.
Note that on some operating systems, this is not the same as the
separator between directory elements.
=item B<-listsep>
Outputs the OpenSSL list separator character.
This is typically used to construct C<$PATH> (C<%PATH%> on Windows)
style lists.
=back
=head1 HISTORY
The B<openssl info> command was added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut
+167
View File
@@ -0,0 +1,167 @@
=pod
=head1 NAME
openssl-kdf,
kdf - perform Key Derivation Function operations
=head1 SYNOPSIS
B<openssl kdf>
[B<-help>]
[B<-kdfopt> I<nm:v>]
[B<-keylen> I<num>]
[B<-out> I<filename>]
[B<-binary>]
I<kdf_name>
=head1 DESCRIPTION
The key derivation functions generate a derived key from either a secret or
password.
=head1 OPTIONS
=over 4
=item B<-help>
Print a usage message.
=item B<-keylen> I<num>
The output size of the derived key. This field is required.
=item B<-out> I<filename>
Filename to output to, or standard output by default.
=item B<-binary>
Output the derived key in binary form. Uses hexadecimal text format if not specified.
=item B<-kdfopt> I<nm:v>
Passes options to the KDF algorithm.
A comprehensive list of controls can be found in the EVP_KDF_CTX implementation
documentation.
Common control strings used by EVP_KDF_ctrl_str() are:
=over 4
=item B<key:>I<string>
Specifies the secret key as an alphanumeric string (use if the key contains
printable characters only).
The string length must conform to any restrictions of the KDF algorithm.
A key must be specified for most KDF algorithms.
=item B<hexkey:>I<string>
Specifies the secret key in hexadecimal form (two hex digits per byte).
The key length must conform to any restrictions of the KDF algorithm.
A key must be specified for most KDF algorithms.
=item B<pass:>I<string>
Specifies the password as an alphanumeric string (use if the password contains
printable characters only).
The password must be specified for PBKDF2 and scrypt.
=item B<hexpass:>I<string>
Specifies the password in hexadecimal form (two hex digits per byte).
The password must be specified for PBKDF2 and scrypt.
=item B<digest:>I<string>
Specifies the name of a digest as an alphanumeric string.
To see the list of supported digests, use the command I<list -digest-commands>.
=back
=item I<kdf_name>
Specifies the name of a supported KDF algorithm which will be used.
The supported algorithms names are TLS1-PRF, HKDF, SSKDF, PBKDF2, SSHKDF and id-scrypt.
=back
=head1 EXAMPLES
Use TLS1-PRF to create a hex-encoded derived key from a secret key and seed:
openssl kdf -keylen 16 -kdfopt digest:SHA256 -kdfopt key:secret \
-kdfopt seed:seed TLS1-PRF
Use HKDF to create a hex-encoded derived key from a secret key, salt and info:
openssl kdf -keylen 10 -kdfopt digest:SHA256 -kdfopt key:secret \
-kdfopt salt:salt -kdfopt info:label HKDF
Use SSKDF with KMAC to create a hex-encoded derived key from a secret key, salt and info:
openssl kdf -keylen 64 -kdfopt mac:KMAC128 -kdfopt maclen:20 \
-kdfopt hexkey:b74a149a161545 -kdfopt hexinfo:348a37a2 \
-kdfopt hexsalt:3638271ccd68a2 SSKDF
Use SSKDF with HMAC to create a hex-encoded derived key from a secret key, salt and info:
openssl kdf -keylen 16 -kdfopt mac:HMAC -kdfopt digest:SHA256 \
-kdfopt hexkey:b74a149a -kdfopt hexinfo:348a37a2 \
-kdfopt hexsalt:3638271c SSKDF
Use SSKDF with Hash to create a hex-encoded derived key from a secret key, salt and info:
openssl kdf -keylen 14 -kdfopt digest:SHA256 \
-kdfopt hexkey:6dbdc23f045488 \
-kdfopt hexinfo:a1b2c3d4 SSKDF
Use SSHKDF to create a hex-encoded derived key from a secret key, hash and session_id:
openssl kdf -keylen 16 -kdfopt digest:SHA256 \
-kdfopt hexkey:0102030405 \
-kdfopt hexxcghash:06090A \
-kdfopt hexsession_id:01020304 \
-kdfopt type:A SSHKDF
Use PBKDF2 to create a hex-encoded derived key from a password and salt:
openssl kdf -keylen 32 -kdfopt digest:SHA256 -kdfopt pass:password \
-kdfopt salt:salt -kdfopt iter:2 PBKDF2
Use scrypt to create a hex-encoded derived key from a password and salt:
openssl kdf -keylen 64 -kdfopt pass:password -kdfopt salt:NaCl \
-kdfopt N:1024 -kdfopt r:8 -kdfopt p:16 \
-kdfopt maxmem_bytes:10485760 id-scrypt
=head1 NOTES
The KDF mechanisms that are available will depend on the options
used when building OpenSSL.
=head1 SEE ALSO
L<EVP_KDF_CTX(3)>,
L<EVP_KDF_SCRYPT(7)>
L<EVP_KDF_TLS1_PRF(7)>
L<EVP_KDF_PBKDF2(7)>
L<EVP_KDF_HKDF(7)>
L<EVP_KDF_SS(7)>
L<EVP_KDF_SSHKDF(7)>
=head1 HISTORY
Added in OpenSSL 3.0
=head1 COPYRIGHT
Copyright 2019 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
+10 -2
View File
@@ -167,6 +167,14 @@ Generation of Private Key or Parameters.
Generation of RSA Private Key. Superseded by L<genpkey(1)>.
=item B<info>
Display diverse information built into the OpenSSL libraries.
=item B<kdf>
Key Derivation Functions.
=item B<mac>
Message Authentication Code Calculation.
@@ -612,7 +620,7 @@ L<crl(1)>, L<crl2pkcs7(1)>, L<dgst(1)>,
L<dhparam(1)>, L<dsa(1)>, L<dsaparam(1)>,
L<ec(1)>, L<ecparam(1)>,
L<enc(1)>, L<engine(1)>, L<errstr(1)>, L<gendsa(1)>, L<genpkey(1)>,
L<genrsa(1)>, L<mac(1)>, L<nseq(1)>, L<ocsp(1)>,
L<genrsa(1)>, L<kdf(1)>, L<mac(1)>, L<nseq(1)>, L<ocsp(1)>,
L<passwd(1)>,
L<pkcs12(1)>, L<pkcs7(1)>, L<pkcs8(1)>,
L<pkey(1)>, L<pkeyparam(1)>, L<pkeyutl(1)>, L<prime(1)>,
@@ -632,7 +640,7 @@ manual pages.
=head1 COPYRIGHT
Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
+16
View File
@@ -88,6 +88,22 @@ a buffering BIO to the chain will speed up the process.
Calling BIO_set_mem_buf() on a BIO created with BIO_new_secmem() will
give undefined results, including perhaps a program crash.
Switching the memory BIO from read write to read only is not supported and
can give undefined results including a program crash. There are two notable
exceptions to the rule. The first one is to assign a static memory buffer
immediately after BIO creation and set the BIO as read only.
The other supported sequence is to start with read write BIO then temporarily
switch it to read only and call BIO_reset() on the read only BIO immediately
before switching it back to read write. Before the BIO is freed it must be
switched back to the read write mode.
Calling BIO_get_mem_ptr() on read only BIO will return a BUF_MEM that
contains only the remaining data to be read. If the close status of the
BIO is set to BIO_NOCLOSE, before freeing the BUF_MEM the data pointer
in it must be set to NULL as the data pointer does not point to an
allocated memory.
=head1 BUGS
There should be an option to set the maximum size of a memory BIO.
+1 -1
View File
@@ -200,7 +200,7 @@ ANSI X9.62, US Federal Information Processing Standard FIPS 186-2
=head1 SEE ALSO
L<DSA_new(3)>,
L<EC_KEY_new(3)>,
L<EVP_DigestSignInit(3)>,
L<EVP_DigestVerifyInit(3)>
+3 -2
View File
@@ -151,9 +151,9 @@ The value string is expected to be the name of a MAC.
This control expects one argument: C<EVP_MD *md>
For MAC implementations that use a message digest as an underlying computation
algorithm, this control set what the digest algorithm should be.
algorithm, this control sets what the digest algorithm should be.
EVP_KDF_ctrl_str() type string: "md"
EVP_KDF_ctrl_str() type string: "digest"
The value string is expected to be the name of a digest.
@@ -232,6 +232,7 @@ L<EVP_KDF_TLS1_PRF(7)>
L<EVP_KDF_PBKDF2(7)>
L<EVP_KDF_HKDF(7)>
L<EVP_KDF_SS(7)>
L<EVP_KDF_SSHKDF(7)>
=head1 HISTORY
+9 -1
View File
@@ -21,7 +21,15 @@ The ChaCha20 stream cipher for EVP.
=item EVP_chacha20()
The ChaCha20 stream cipher. The key length is 256 bits, the IV is 96 bits long.
The ChaCha20 stream cipher. The key length is 256 bits, the IV is 128 bits long.
The first 32 bits consists of a counter in little-endian order followed by a 96
bit nonce. For example a nonce of:
000000000000000000000002
With an initial counter of 42 (2a in hex) would be expressed as:
2a000000000000000000000000000002
=item EVP_chacha20_poly1305()
+45 -2
View File
@@ -8,8 +8,8 @@ OPENSSL_VERSION_PRE_RELEASE_STR, OPENSSL_VERSION_BUILD_METADATA_STR,
OPENSSL_VERSION_TEXT,
OPENSSL_version_major, OPENSSL_version_minor, OPENSSL_version_patch,
OPENSSL_version_pre_release, OPENSSL_version_build_metadata, OpenSSL_version,
OPENSSL_VERSION_NUMBER, OpenSSL_version_num
- get OpenSSL version number
OPENSSL_VERSION_NUMBER, OpenSSL_version_num, OPENSSL_info
- get OpenSSL version number and other information
=head1 SYNOPSIS
@@ -37,6 +37,8 @@ OPENSSL_VERSION_NUMBER, OpenSSL_version_num
const char *OpenSSL_version(int t);
const char *OPENSSL_info(int t);
Deprecated:
/* from openssl/opensslv.h */
@@ -127,6 +129,47 @@ if available or "ENGINESDIR: N/A" otherwise.
For an unknown B<t>, the text "not available" is returned.
OPENSSL_info() also returns different strings depending on B<t>:
=over 4
=item OPENSSL_INFO_CONFIG_DIR
The configured C<OPENSSLDIR>, which is the default location for
OpenSSL configuration files.
=item OPENSSL_INFO_ENGINES_DIR
The configured C<ENGINESDIR>, which is the default location for
OpenSSL engines.
=item OPENSSL_INFO_MODULES_DIR
The configured C<MODULESDIR>, which is the default location for
dynamically loadable OpenSSL modules other than engines.
=item OPENSSL_INFO_DSO_EXTENSION
The configured dynamically loadable module extension.
=item OPENSSL_INFO_DIR_FILENAME_SEPARATOR
The separator between a directory specification and a file name.
Note that on some operating systems, this is not the same as the
separator between directory elements.
=item OPENSSL_INFO_LIST_SEPARATOR
The OpenSSL list separator.
This is typically used in strings that are lists of items, such as the
value of the environment variable C<$PATH> on Unix (where the
separator is ":") or C<%PATH%> on Windows (where the separator is
";").
=back
For an unknown B<t>, NULL is returned.
=head1 BACKWARD COMPATIBILITY
For compatibility, some older macros and functions are retained or
+2
View File
@@ -65,6 +65,8 @@ both required, and on success the caller must release the storage allocated for
B<*out> using OPENSSL_free(). The contents of B<*out> is an array of integers
holding the numerical value of the TLS extension types in the order they appear
in the ClientHello. B<*outlen> contains the number of elements in the array.
In situations when the ClientHello has no extensions, the function will return
success with B<*out> set to NULL and B<*outlen> set to 0.
=head1 NOTES
+4
View File
@@ -90,6 +90,10 @@ static ossl_inline int ktls_read_record(int fd, void *data, size_t length)
# define TCP_ULP 31
# endif
# ifndef TLS_RX
# define TLS_RX 2
# endif
/*
* When successful, this socket option doesn't change the behaviour of the
* TCP socket, except changing the TCP setsockopt handler to enable the
+9 -2
View File
@@ -155,10 +155,17 @@ extern "C" {
# define BIO_CTRL_GET_KTLS_SEND 73
# define BIO_CTRL_GET_KTLS_RECV 76
# ifndef OPENSSL_NO_KTLS
# define BIO_get_ktls_send(b) \
BIO_ctrl(b, BIO_CTRL_GET_KTLS_SEND, 0, NULL)
(BIO_method_type(b) == BIO_TYPE_SOCKET \
&& BIO_ctrl(b, BIO_CTRL_GET_KTLS_SEND, 0, NULL))
# define BIO_get_ktls_recv(b) \
BIO_ctrl(b, BIO_CTRL_GET_KTLS_RECV, 0, NULL)
(BIO_method_type(b) == BIO_TYPE_SOCKET \
&& BIO_ctrl(b, BIO_CTRL_GET_KTLS_RECV, 0, NULL))
# else
# define BIO_get_ktls_send(b) (0)
# define BIO_get_ktls_recv(b) (0)
# endif
/* modifiers */
# define BIO_FP_READ 0x02
+6
View File
@@ -34,6 +34,12 @@ extern "C" {
*/
#define OSSL_PROV_PARAM_BUILDINFO "buildinfo"
/* Well known cipher parameters */
#define OSSL_CIPHER_PARAM_PADDING "padding"
#define OSSL_CIPHER_PARAM_MODE "mode"
# ifdef __cplusplus
}
# endif
+56 -3
View File
@@ -78,7 +78,7 @@ OSSL_CORE_MAKE_FUNC(const OSSL_ALGORITHM *,provider_query_operation,
# define OSSL_FUNC_DIGEST_NEWCTX 1
# define OSSL_FUNC_DIGEST_INIT 2
# define OSSL_FUNC_DIGEST_UPDDATE 3
# define OSSL_FUNC_DIGEST_UPDATE 3
# define OSSL_FUNC_DIGEST_FINAL 4
# define OSSL_FUNC_DIGEST_DIGEST 5
# define OSSL_FUNC_DIGEST_FREECTX 6
@@ -86,21 +86,74 @@ OSSL_CORE_MAKE_FUNC(const OSSL_ALGORITHM *,provider_query_operation,
# define OSSL_FUNC_DIGEST_SIZE 8
# define OSSL_FUNC_DIGEST_BLOCK_SIZE 9
OSSL_CORE_MAKE_FUNC(void *, OP_digest_newctx, (void))
OSSL_CORE_MAKE_FUNC(int, OP_digest_init, (void *vctx))
OSSL_CORE_MAKE_FUNC(int, OP_digest_update,
(void *, const unsigned char *in, size_t inl))
OSSL_CORE_MAKE_FUNC(int, OP_digest_final,
(void *, unsigned char *out, size_t *outl))
(void *, unsigned char *out, size_t *outl, size_t outsz))
OSSL_CORE_MAKE_FUNC(int, OP_digest_digest,
(const unsigned char *in, size_t inl, unsigned char *out,
size_t *out_l))
size_t *out_l, size_t outsz))
OSSL_CORE_MAKE_FUNC(void, OP_digest_cleanctx, (void *vctx))
OSSL_CORE_MAKE_FUNC(void, OP_digest_freectx, (void *vctx))
OSSL_CORE_MAKE_FUNC(void *, OP_digest_dupctx, (void *vctx))
OSSL_CORE_MAKE_FUNC(size_t, OP_digest_size, (void))
OSSL_CORE_MAKE_FUNC(size_t, OP_digest_block_size, (void))
/* Symmetric Ciphers */
# define OSSL_OP_CIPHER 2
# define OSSL_FUNC_CIPHER_NEWCTX 1
# define OSSL_FUNC_CIPHER_ENCRYPT_INIT 2
# define OSSL_FUNC_CIPHER_DECRYPT_INIT 3
# define OSSL_FUNC_CIPHER_UPDATE 4
# define OSSL_FUNC_CIPHER_FINAL 5
# define OSSL_FUNC_CIPHER_CIPHER 6
# define OSSL_FUNC_CIPHER_FREECTX 7
# define OSSL_FUNC_CIPHER_DUPCTX 8
# define OSSL_FUNC_CIPHER_KEY_LENGTH 9
# define OSSL_FUNC_CIPHER_IV_LENGTH 10
# define OSSL_FUNC_CIPHER_BLOCK_SIZE 11
# define OSSL_FUNC_CIPHER_GET_PARAMS 12
# define OSSL_FUNC_CIPHER_CTX_GET_PARAMS 13
# define OSSL_FUNC_CIPHER_CTX_SET_PARAMS 14
OSSL_CORE_MAKE_FUNC(void *, OP_cipher_newctx, (void))
OSSL_CORE_MAKE_FUNC(int, OP_cipher_encrypt_init, (void *vctx,
const unsigned char *key,
size_t keylen,
const unsigned char *iv,
size_t ivlen))
OSSL_CORE_MAKE_FUNC(int, OP_cipher_decrypt_init, (void *vctx,
const unsigned char *key,
size_t keylen,
const unsigned char *iv,
size_t ivlen))
OSSL_CORE_MAKE_FUNC(int, OP_cipher_update,
(void *, unsigned char *out, size_t *outl, size_t outsize,
const unsigned char *in, size_t inl))
OSSL_CORE_MAKE_FUNC(int, OP_cipher_final,
(void *, unsigned char *out, size_t *outl, size_t outsize))
OSSL_CORE_MAKE_FUNC(int, OP_cipher_cipher,
(void *, unsigned char *out, const unsigned char *in,
size_t inl))
OSSL_CORE_MAKE_FUNC(void, OP_cipher_freectx, (void *vctx))
OSSL_CORE_MAKE_FUNC(void *, OP_cipher_dupctx, (void *vctx))
OSSL_CORE_MAKE_FUNC(size_t, OP_cipher_key_length, (void))
OSSL_CORE_MAKE_FUNC(size_t, OP_cipher_iv_length, (void))
OSSL_CORE_MAKE_FUNC(size_t, OP_cipher_block_size, (void))
OSSL_CORE_MAKE_FUNC(int, OP_cipher_get_params, (const OSSL_PARAM params[]))
OSSL_CORE_MAKE_FUNC(int, OP_cipher_ctx_get_params, (void *vctx,
const OSSL_PARAM params[]))
OSSL_CORE_MAKE_FUNC(int, OP_cipher_ctx_set_params, (void *vctx,
const OSSL_PARAM params[]))
# ifdef __cplusplus
}
# endif
+13
View File
@@ -163,6 +163,19 @@ const char *OpenSSL_version(int type);
# define OPENSSL_ENGINES_DIR 5
# define OPENSSL_VERSION_STRING 6
# define OPENSSL_FULL_VERSION_STRING 7
# define OPENSSL_MODULES_DIR 8
const char *OPENSSL_info(int type);
/*
* The series starts at 1001 to avoid confusion with the OpenSSL_version
* types.
*/
# define OPENSSL_INFO_CONFIG_DIR 1001
# define OPENSSL_INFO_ENGINES_DIR 1002
# define OPENSSL_INFO_MODULES_DIR 1003
# define OPENSSL_INFO_DSO_EXTENSION 1004
# define OPENSSL_INFO_DIR_FILENAME_SEPARATOR 1005
# define OPENSSL_INFO_LIST_SEPARATOR 1006
int OPENSSL_issetugid(void);
+2
View File
@@ -98,6 +98,7 @@ typedef struct err_state_st {
# define ERR_LIB_ESS 54
# define ERR_LIB_PROP 55
# define ERR_LIB_CRMF 56
# define ERR_LIB_PROV 57
# define ERR_LIB_USER 128
@@ -140,6 +141,7 @@ typedef struct err_state_st {
# define SM2err(f,r) ERR_PUT_error(ERR_LIB_SM2,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
# define ESSerr(f,r) ERR_PUT_error(ERR_LIB_ESS,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
# define PROPerr(f,r) ERR_PUT_error(ERR_LIB_PROP,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
# define PROVerr(f,r) ERR_PUT_error(ERR_LIB_PROV,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
# define ERR_PACK(l,f,r) ( \
(((unsigned int)(l) & 0x0FF) << 24L) | \
+4 -1
View File
@@ -190,6 +190,7 @@ int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len);
EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher);
void EVP_CIPHER_meth_free(EVP_CIPHER *cipher);
int EVP_CIPHER_upref(EVP_CIPHER *cipher);
int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len);
int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags);
@@ -473,7 +474,9 @@ int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *cipher);
int EVP_CIPHER_key_length(const EVP_CIPHER *cipher);
int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher);
unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher);
# define EVP_CIPHER_mode(e) (EVP_CIPHER_flags(e) & EVP_CIPH_MODE)
int EVP_CIPHER_mode(const EVP_CIPHER *cipher);
EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
const char *properties);
const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx);
int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx);
+4
View File
@@ -55,6 +55,9 @@ int ERR_load_EVP_strings(void);
# define EVP_F_EVP_CIPHER_CTX_COPY 163
# define EVP_F_EVP_CIPHER_CTX_CTRL 124
# define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122
# define EVP_F_EVP_CIPHER_CTX_SET_PADDING 237
# define EVP_F_EVP_CIPHER_FROM_DISPATCH 238
# define EVP_F_EVP_CIPHER_MODE 239
# define EVP_F_EVP_CIPHER_PARAM_TO_ASN1 205
# define EVP_F_EVP_DECRYPTFINAL_EX 101
# define EVP_F_EVP_DECRYPTUPDATE 166
@@ -190,6 +193,7 @@ int ERR_load_EVP_strings(void);
# define EVP_R_INVALID_KEY 163
# define EVP_R_INVALID_KEY_LENGTH 130
# define EVP_R_INVALID_OPERATION 148
# define EVP_R_INVALID_PROVIDER_FUNCTIONS 193
# define EVP_R_INVALID_SALT_LENGTH 186
# define EVP_R_KEYGEN_FAILURE 120
# define EVP_R_KEY_SETUP_FAILED 180
+1 -1
View File
@@ -7,7 +7,7 @@ IF[{- !$disabled{fips} -}]
SOURCE[fips]=fips.ld
GENERATE[fips.ld]=../util/providers.num
ENDIF
INCLUDE[fips]=.. ../include ../crypto/include
INCLUDE[fips]=.. ../include ../crypto/include common/include
DEFINE[fips]=FIPS_MODE
ENDIF
+4 -1
View File
@@ -1 +1,4 @@
SUBDIRS=digests
SUBDIRS=digests ciphers
SOURCE[../../libcrypto]=\
provider_err.c
+470
View File
@@ -0,0 +1,470 @@
/*
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/core_numbers.h>
#include <openssl/core_names.h>
#include <openssl/evp.h>
#include <openssl/params.h>
#include "internal/cryptlib.h"
#include "internal/provider_algs.h"
#include "ciphers_locl.h"
#include "internal/providercommonerr.h"
static OSSL_OP_cipher_encrypt_init_fn aes_einit;
static OSSL_OP_cipher_decrypt_init_fn aes_dinit;
static OSSL_OP_cipher_update_fn aes_block_update;
static OSSL_OP_cipher_final_fn aes_block_final;
static OSSL_OP_cipher_update_fn aes_stream_update;
static OSSL_OP_cipher_final_fn aes_stream_final;
static OSSL_OP_cipher_cipher_fn aes_cipher;
static OSSL_OP_cipher_freectx_fn aes_freectx;
static OSSL_OP_cipher_dupctx_fn aes_dupctx;
static OSSL_OP_cipher_key_length_fn key_length_256;
static OSSL_OP_cipher_key_length_fn key_length_192;
static OSSL_OP_cipher_key_length_fn key_length_128;
static OSSL_OP_cipher_iv_length_fn iv_length_16;
static OSSL_OP_cipher_iv_length_fn iv_length_0;
static OSSL_OP_cipher_block_size_fn block_size_16;
static OSSL_OP_cipher_block_size_fn block_size_1;
static OSSL_OP_cipher_ctx_get_params_fn aes_ctx_get_params;
static OSSL_OP_cipher_ctx_set_params_fn aes_ctx_set_params;
static int PROV_AES_KEY_generic_init(PROV_AES_KEY *ctx,
const unsigned char *iv,
size_t ivlen,
int enc)
{
if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) {
if (ivlen != AES_BLOCK_SIZE) {
PROVerr(PROV_F_PROV_AES_KEY_GENERIC_INIT, ERR_R_INTERNAL_ERROR);
return 0;
}
memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
}
ctx->enc = enc;
return 1;
}
static int aes_einit(void *vctx, const unsigned char *key, size_t keylen,
const unsigned char *iv, size_t ivlen)
{
PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
if (!PROV_AES_KEY_generic_init(ctx, iv, ivlen, 1)) {
/* PROVerr already called */
return 0;
}
if (key != NULL) {
if (keylen != ctx->keylen) {
PROVerr(PROV_F_AES_EINIT, PROV_R_INVALID_KEYLEN);
return 0;
}
return ctx->ciph->init(ctx, key, ctx->keylen);
}
return 1;
}
static int aes_dinit(void *vctx, const unsigned char *key, size_t keylen,
const unsigned char *iv, size_t ivlen)
{
PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
if (!PROV_AES_KEY_generic_init(ctx, iv, ivlen, 0)) {
/* PROVerr already called */
return 0;
}
if (key != NULL) {
if (keylen != ctx->keylen) {
PROVerr(PROV_F_AES_DINIT, PROV_R_INVALID_KEYLEN);
return 0;
}
return ctx->ciph->init(ctx, key, ctx->keylen);
}
return 1;
}
static int aes_block_update(void *vctx, unsigned char *out, size_t *outl,
size_t outsize, const unsigned char *in, size_t inl)
{
PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE, &in,
&inl);
size_t outlint = 0;
/*
* If we're decrypting and we end an update on a block boundary we hold
* the last block back in case this is the last update call and the last
* block is padded.
*/
if (ctx->bufsz == AES_BLOCK_SIZE
&& (ctx->enc || inl > 0 || !ctx->pad)) {
if (outsize < AES_BLOCK_SIZE) {
PROVerr(PROV_F_AES_BLOCK_UPDATE, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE)) {
PROVerr(PROV_F_AES_BLOCK_UPDATE, PROV_R_CIPHER_OPERATION_FAILED);
return 0;
}
ctx->bufsz = 0;
outlint = AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
if (nextblocks > 0) {
if (!ctx->enc && ctx->pad && nextblocks == inl) {
if (!ossl_assert(inl >= AES_BLOCK_SIZE)) {
PROVerr(PROV_F_AES_BLOCK_UPDATE, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
nextblocks -= AES_BLOCK_SIZE;
}
outlint += nextblocks;
if (outsize < outlint) {
PROVerr(PROV_F_AES_BLOCK_UPDATE, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
if (!ctx->ciph->cipher(ctx, out, in, nextblocks)) {
PROVerr(PROV_F_AES_BLOCK_UPDATE, PROV_R_CIPHER_OPERATION_FAILED);
return 0;
}
in += nextblocks;
inl -= nextblocks;
}
if (!trailingdata(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE, &in, &inl)) {
/* PROVerr already called */
return 0;
}
*outl = outlint;
return inl == 0;
}
static int aes_block_final(void *vctx, unsigned char *out, size_t *outl,
size_t outsize)
{
PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
if (ctx->enc) {
if (ctx->pad) {
padblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE);
} else if (ctx->bufsz == 0) {
*outl = 0;
return 1;
} else if (ctx->bufsz != AES_BLOCK_SIZE) {
PROVerr(PROV_F_AES_BLOCK_FINAL, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
return 0;
}
if (outsize < AES_BLOCK_SIZE) {
PROVerr(PROV_F_AES_BLOCK_FINAL, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE)) {
PROVerr(PROV_F_AES_BLOCK_FINAL, PROV_R_CIPHER_OPERATION_FAILED);
return 0;
}
ctx->bufsz = 0;
*outl = AES_BLOCK_SIZE;
return 1;
}
/* Decrypting */
if (ctx->bufsz != AES_BLOCK_SIZE) {
if (ctx->bufsz == 0 && !ctx->pad) {
*outl = 0;
return 1;
}
PROVerr(PROV_F_AES_BLOCK_FINAL, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
return 0;
}
if (!ctx->ciph->cipher(ctx, ctx->buf, ctx->buf, AES_BLOCK_SIZE)) {
PROVerr(PROV_F_AES_BLOCK_FINAL, PROV_R_CIPHER_OPERATION_FAILED);
return 0;
}
if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE)) {
/* PROVerr already called */
return 0;
}
if (outsize < ctx->bufsz) {
PROVerr(PROV_F_AES_BLOCK_FINAL, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
memcpy(out, ctx->buf, ctx->bufsz);
*outl = ctx->bufsz;
ctx->bufsz = 0;
return 1;
}
static int aes_stream_update(void *vctx, unsigned char *out, size_t *outl,
size_t outsize, const unsigned char *in,
size_t inl)
{
PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
if (outsize < inl) {
PROVerr(PROV_F_AES_STREAM_UPDATE, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
if (!ctx->ciph->cipher(ctx, out, in, inl)) {
PROVerr(PROV_F_AES_STREAM_UPDATE, PROV_R_CIPHER_OPERATION_FAILED);
return 0;
}
*outl = inl;
return 1;
}
static int aes_stream_final(void *vctx, unsigned char *out, size_t *outl,
size_t outsize)
{
*outl = 0;
return 1;
}
static int aes_cipher(void *vctx, unsigned char *out, const unsigned char *in,
size_t inl)
{
PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
if (!ctx->ciph->cipher(ctx, out, in, inl)) {
PROVerr(PROV_F_AES_CIPHER, PROV_R_CIPHER_OPERATION_FAILED);
return 0;
}
return 1;
}
#define IMPLEMENT_new_params(lcmode, UCMODE) \
static OSSL_OP_cipher_get_params_fn aes_##lcmode##_get_params; \
static int aes_##lcmode##_get_params(const OSSL_PARAM params[]) \
{ \
const OSSL_PARAM *p; \
\
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); \
if (p != NULL && !OSSL_PARAM_set_int(p, EVP_CIPH_##UCMODE##_MODE)) \
return 0; \
\
return 1; \
}
#define IMPLEMENT_new_ctx(lcmode, UCMODE, len) \
static OSSL_OP_cipher_newctx_fn aes_##len##_##lcmode##_newctx; \
static void *aes_##len##_##lcmode##_newctx(void) \
{ \
PROV_AES_KEY *ctx = OPENSSL_zalloc(sizeof(*ctx)); \
\
ctx->pad = 1; \
ctx->keylen = (len / 8); \
ctx->ciph = PROV_AES_CIPHER_##lcmode(ctx->keylen); \
ctx->mode = EVP_CIPH_##UCMODE##_MODE; \
return ctx; \
}
/* ECB */
IMPLEMENT_new_params(ecb, ECB)
IMPLEMENT_new_ctx(ecb, ECB, 256)
IMPLEMENT_new_ctx(ecb, ECB, 192)
IMPLEMENT_new_ctx(ecb, ECB, 128)
/* CBC */
IMPLEMENT_new_params(cbc, CBC)
IMPLEMENT_new_ctx(cbc, CBC, 256)
IMPLEMENT_new_ctx(cbc, CBC, 192)
IMPLEMENT_new_ctx(cbc, CBC, 128)
/* OFB */
IMPLEMENT_new_params(ofb, OFB)
IMPLEMENT_new_ctx(ofb, OFB, 256)
IMPLEMENT_new_ctx(ofb, OFB, 192)
IMPLEMENT_new_ctx(ofb, OFB, 128)
/* CFB */
IMPLEMENT_new_params(cfb, CFB)
IMPLEMENT_new_params(cfb1, CFB)
IMPLEMENT_new_params(cfb8, CFB)
IMPLEMENT_new_ctx(cfb, CFB, 256)
IMPLEMENT_new_ctx(cfb, CFB, 192)
IMPLEMENT_new_ctx(cfb, CFB, 128)
IMPLEMENT_new_ctx(cfb1, CFB, 256)
IMPLEMENT_new_ctx(cfb1, CFB, 192)
IMPLEMENT_new_ctx(cfb1, CFB, 128)
IMPLEMENT_new_ctx(cfb8, CFB, 256)
IMPLEMENT_new_ctx(cfb8, CFB, 192)
IMPLEMENT_new_ctx(cfb8, CFB, 128)
/* CTR */
IMPLEMENT_new_params(ctr, CTR)
IMPLEMENT_new_ctx(ctr, CTR, 256)
IMPLEMENT_new_ctx(ctr, CTR, 192)
IMPLEMENT_new_ctx(ctr, CTR, 128)
static void aes_freectx(void *vctx)
{
PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
OPENSSL_clear_free(ctx, sizeof(*ctx));
}
static void *aes_dupctx(void *ctx)
{
PROV_AES_KEY *in = (PROV_AES_KEY *)ctx;
PROV_AES_KEY *ret = OPENSSL_malloc(sizeof(*ret));
if (ret == NULL) {
PROVerr(PROV_F_AES_DUPCTX, ERR_R_MALLOC_FAILURE);
return NULL;
}
*ret = *in;
return ret;
}
static size_t key_length_256(void)
{
return 256 / 8;
}
static size_t key_length_192(void)
{
return 192 / 8;
}
static size_t key_length_128(void)
{
return 128 / 8;
}
static size_t iv_length_16(void)
{
return 16;
}
static size_t iv_length_0(void)
{
return 0;
}
static size_t block_size_16(void)
{
return 16;
}
static size_t block_size_1(void)
{
return 1;
}
static int aes_ctx_get_params(void *vctx, const OSSL_PARAM params[])
{
PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
const OSSL_PARAM *p;
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING);
if (p != NULL && !OSSL_PARAM_set_int(p, ctx->pad)) {
PROVerr(PROV_F_AES_CTX_GET_PARAMS, PROV_R_FAILED_TO_SET_PARAMETER);
return 0;
}
return 1;
}
static int aes_ctx_set_params(void *vctx, const OSSL_PARAM params[])
{
PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
const OSSL_PARAM *p;
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING);
if (p != NULL) {
int pad;
if (!OSSL_PARAM_get_int(p, &pad)) {
PROVerr(PROV_F_AES_CTX_SET_PARAMS, PROV_R_FAILED_TO_GET_PARAMETER);
return 0;
}
ctx->pad = pad ? 1 : 0;
}
return 1;
}
#define IMPLEMENT_block_funcs(mode, keylen, ivlen) \
const OSSL_DISPATCH aes##keylen##mode##_functions[] = { \
{ OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##keylen##_##mode##_newctx }, \
{ OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, \
{ OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, \
{ OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_block_update }, \
{ OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_block_final }, \
{ OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_cipher }, \
{ OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, \
{ OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, \
{ OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_##keylen }, \
{ OSSL_FUNC_CIPHER_IV_LENGTH, (void (*)(void))iv_length_##ivlen }, \
{ OSSL_FUNC_CIPHER_BLOCK_SIZE, (void (*)(void))block_size_16 }, \
{ OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##mode##_get_params }, \
{ OSSL_FUNC_CIPHER_CTX_GET_PARAMS, (void (*)(void))aes_ctx_get_params }, \
{ OSSL_FUNC_CIPHER_CTX_SET_PARAMS, (void (*)(void))aes_ctx_set_params }, \
{ 0, NULL } \
};
#define IMPLEMENT_stream_funcs(mode, keylen, ivlen) \
const OSSL_DISPATCH aes##keylen##mode##_functions[] = { \
{ OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##keylen##_##mode##_newctx }, \
{ OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_einit }, \
{ OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_dinit }, \
{ OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_stream_update }, \
{ OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_stream_final }, \
{ OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_cipher }, \
{ OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_freectx }, \
{ OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_dupctx }, \
{ OSSL_FUNC_CIPHER_KEY_LENGTH, (void (*)(void))key_length_##keylen }, \
{ OSSL_FUNC_CIPHER_IV_LENGTH, (void (*)(void))iv_length_##ivlen }, \
{ OSSL_FUNC_CIPHER_BLOCK_SIZE, (void (*)(void))block_size_1 }, \
{ OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))aes_##mode##_get_params }, \
{ OSSL_FUNC_CIPHER_CTX_GET_PARAMS, (void (*)(void))aes_ctx_get_params }, \
{ OSSL_FUNC_CIPHER_CTX_SET_PARAMS, (void (*)(void))aes_ctx_set_params }, \
{ 0, NULL } \
};
/* ECB */
IMPLEMENT_block_funcs(ecb, 256, 0)
IMPLEMENT_block_funcs(ecb, 192, 0)
IMPLEMENT_block_funcs(ecb, 128, 0)
/* CBC */
IMPLEMENT_block_funcs(cbc, 256, 16)
IMPLEMENT_block_funcs(cbc, 192, 16)
IMPLEMENT_block_funcs(cbc, 128, 16)
/* OFB */
IMPLEMENT_stream_funcs(ofb, 256, 16)
IMPLEMENT_stream_funcs(ofb, 192, 16)
IMPLEMENT_stream_funcs(ofb, 128, 16)
/* CFB */
IMPLEMENT_stream_funcs(cfb, 256, 16)
IMPLEMENT_stream_funcs(cfb, 192, 16)
IMPLEMENT_stream_funcs(cfb, 128, 16)
IMPLEMENT_stream_funcs(cfb1, 256, 16)
IMPLEMENT_stream_funcs(cfb1, 192, 16)
IMPLEMENT_stream_funcs(cfb1, 128, 16)
IMPLEMENT_stream_funcs(cfb8, 256, 16)
IMPLEMENT_stream_funcs(cfb8, 192, 16)
IMPLEMENT_stream_funcs(cfb8, 128, 16)
/* CTR */
IMPLEMENT_stream_funcs(ctr, 256, 16)
IMPLEMENT_stream_funcs(ctr, 192, 16)
IMPLEMENT_stream_funcs(ctr, 128, 16)
+866
View File
@@ -0,0 +1,866 @@
/*
* Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <openssl/opensslconf.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <string.h>
#include <assert.h>
#include <openssl/aes.h>
#include "internal/evp_int.h"
#include <openssl/rand.h>
#include <openssl/cmac.h>
#include "ciphers_locl.h"
#include "internal/providercommonerr.h"
#define MAXBITCHUNK ((size_t)1 << (sizeof(size_t) * 8 - 4))
#ifdef VPAES_ASM
int vpaes_set_encrypt_key(const unsigned char *userKey, int bits,
AES_KEY *key);
int vpaes_set_decrypt_key(const unsigned char *userKey, int bits,
AES_KEY *key);
void vpaes_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void vpaes_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void vpaes_cbc_encrypt(const unsigned char *in,
unsigned char *out,
size_t length,
const AES_KEY *key, unsigned char *ivec, int enc);
#endif
#ifdef BSAES_ASM
void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char ivec[16], int enc);
void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
size_t len, const AES_KEY *key,
const unsigned char ivec[16]);
#endif
#ifdef AES_CTR_ASM
void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
size_t blocks, const AES_KEY *key,
const unsigned char ivec[AES_BLOCK_SIZE]);
#endif
#if defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
# include "ppc_arch.h"
# ifdef VPAES_ASM
# define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC)
# endif
# define HWAES_CAPABLE (OPENSSL_ppccap_P & PPC_CRYPTO207)
# define HWAES_set_encrypt_key aes_p8_set_encrypt_key
# define HWAES_set_decrypt_key aes_p8_set_decrypt_key
# define HWAES_encrypt aes_p8_encrypt
# define HWAES_decrypt aes_p8_decrypt
# define HWAES_cbc_encrypt aes_p8_cbc_encrypt
# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks
# define HWAES_xts_encrypt aes_p8_xts_encrypt
# define HWAES_xts_decrypt aes_p8_xts_decrypt
#endif
#if defined(AES_ASM) && !defined(I386_ONLY) && ( \
((defined(__i386) || defined(__i386__) || \
defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
defined(__x86_64) || defined(__x86_64__) || \
defined(_M_AMD64) || defined(_M_X64) )
extern unsigned int OPENSSL_ia32cap_P[];
# ifdef VPAES_ASM
# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
# endif
# ifdef BSAES_ASM
# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
# endif
/*
* AES-NI section
*/
# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32)))
int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
AES_KEY *key);
int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
AES_KEY *key);
void aesni_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void aesni_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void aesni_ecb_encrypt(const unsigned char *in,
unsigned char *out,
size_t length, const AES_KEY *key, int enc);
void aesni_cbc_encrypt(const unsigned char *in,
unsigned char *out,
size_t length,
const AES_KEY *key, unsigned char *ivec, int enc);
void aesni_ctr32_encrypt_blocks(const unsigned char *in,
unsigned char *out,
size_t blocks,
const void *key, const unsigned char *ivec);
static int aesni_init_key(PROV_AES_KEY *dat, const unsigned char *key,
size_t keylen)
{
int ret;
if ((dat->mode == EVP_CIPH_ECB_MODE || dat->mode == EVP_CIPH_CBC_MODE)
&& !dat->enc) {
ret = aesni_set_decrypt_key(key, keylen * 8, &dat->ks.ks);
dat->block = (block128_f) aesni_decrypt;
dat->stream.cbc = dat->mode == EVP_CIPH_CBC_MODE ?
(cbc128_f) aesni_cbc_encrypt : NULL;
} else {
ret = aesni_set_encrypt_key(key, keylen * 8, &dat->ks.ks);
dat->block = (block128_f) aesni_encrypt;
if (dat->mode == EVP_CIPH_CBC_MODE)
dat->stream.cbc = (cbc128_f) aesni_cbc_encrypt;
else if (dat->mode == EVP_CIPH_CTR_MODE)
dat->stream.ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
else
dat->stream.cbc = NULL;
}
if (ret < 0) {
PROVerr(PROV_F_AESNI_INIT_KEY, PROV_R_AES_KEY_SETUP_FAILED);
return 0;
}
return 1;
}
static int aesni_cbc_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len)
{
aesni_cbc_encrypt(in, out, len, &ctx->ks.ks, ctx->iv, ctx->enc);
return 1;
}
static int aesni_ecb_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len)
{
if (len < AES_BLOCK_SIZE)
return 1;
aesni_ecb_encrypt(in, out, len, &ctx->ks.ks, ctx->enc);
return 1;
}
# define aesni_ofb_cipher aes_ofb_cipher
static int aesni_ofb_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len);
# define aesni_cfb_cipher aes_cfb_cipher
static int aesni_cfb_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len);
# define aesni_cfb8_cipher aes_cfb8_cipher
static int aesni_cfb8_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len);
# define aesni_cfb1_cipher aes_cfb1_cipher
static int aesni_cfb1_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len);
# define aesni_ctr_cipher aes_ctr_cipher
static int aesni_ctr_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len);
# define BLOCK_CIPHER_generic_prov(mode) \
static const PROV_AES_CIPHER aesni_##mode = { \
aesni_init_key, \
aesni_##mode##_cipher}; \
static const PROV_AES_CIPHER aes_##mode = { \
aes_init_key, \
aes_##mode##_cipher}; \
const PROV_AES_CIPHER *PROV_AES_CIPHER_##mode(size_t keylen) \
{ return AESNI_CAPABLE?&aesni_##mode:&aes_##mode; }
#elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
# include "sparc_arch.h"
extern unsigned int OPENSSL_sparcv9cap_P[];
/*
* Fujitsu SPARC64 X support
*/
# define HWAES_CAPABLE (OPENSSL_sparcv9cap_P[0] & SPARCV9_FJAESX)
# define HWAES_set_encrypt_key aes_fx_set_encrypt_key
# define HWAES_set_decrypt_key aes_fx_set_decrypt_key
# define HWAES_encrypt aes_fx_encrypt
# define HWAES_decrypt aes_fx_decrypt
# define HWAES_cbc_encrypt aes_fx_cbc_encrypt
# define HWAES_ctr32_encrypt_blocks aes_fx_ctr32_encrypt_blocks
# define SPARC_AES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_AES)
void aes_t4_set_encrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
void aes_t4_set_decrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
void aes_t4_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void aes_t4_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
/*
* Key-length specific subroutines were chosen for following reason.
* Each SPARC T4 core can execute up to 8 threads which share core's
* resources. Loading as much key material to registers allows to
* minimize references to shared memory interface, as well as amount
* of instructions in inner loops [much needed on T4]. But then having
* non-key-length specific routines would require conditional branches
* either in inner loops or on subroutines' entries. Former is hardly
* acceptable, while latter means code size increase to size occupied
* by multiple key-length specific subroutines, so why fight?
*/
void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const AES_KEY *key,
unsigned char *ivec);
void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
size_t len, const AES_KEY *key,
unsigned char *ivec);
void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const AES_KEY *key,
unsigned char *ivec);
void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
size_t len, const AES_KEY *key,
unsigned char *ivec);
void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const AES_KEY *key,
unsigned char *ivec);
void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
size_t len, const AES_KEY *key,
unsigned char *ivec);
void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
size_t blocks, const AES_KEY *key,
unsigned char *ivec);
void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
size_t blocks, const AES_KEY *key,
unsigned char *ivec);
void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
size_t blocks, const AES_KEY *key,
unsigned char *ivec);
static int aes_t4_init_key(PROV_AES_KEY *dat, const unsigned char *key,
size_t keylen)
{
int ret, bits;
bits = keylen * 8;
if ((dat->mode == EVP_CIPH_ECB_MODE || dat->mode == EVP_CIPH_CBC_MODE)
&& !dat->enc) {
ret = 0;
aes_t4_set_decrypt_key(key, bits, &dat->ks.ks);
dat->block = (block128_f) aes_t4_decrypt;
switch (bits) {
case 128:
dat->stream.cbc = dat->mode == EVP_CIPH_CBC_MODE ?
(cbc128_f) aes128_t4_cbc_decrypt : NULL;
break;
case 192:
dat->stream.cbc = dat->mode == EVP_CIPH_CBC_MODE ?
(cbc128_f) aes192_t4_cbc_decrypt : NULL;
break;
case 256:
dat->stream.cbc = dat->mode == EVP_CIPH_CBC_MODE ?
(cbc128_f) aes256_t4_cbc_decrypt : NULL;
break;
default:
ret = -1;
}
} else {
ret = 0;
aes_t4_set_encrypt_key(key, bits, &dat->ks.ks);
dat->block = (block128_f)aes_t4_encrypt;
switch (bits) {
case 128:
if (dat->mode == EVP_CIPH_CBC_MODE)
dat->stream.cbc = (cbc128_f)aes128_t4_cbc_encrypt;
else if (dat->mode == EVP_CIPH_CTR_MODE)
dat->stream.ctr = (ctr128_f)aes128_t4_ctr32_encrypt;
else
dat->stream.cbc = NULL;
break;
case 192:
if (dat->mode == EVP_CIPH_CBC_MODE)
dat->stream.cbc = (cbc128_f)aes192_t4_cbc_encrypt;
else if (dat->mode == EVP_CIPH_CTR_MODE)
dat->stream.ctr = (ctr128_f)aes192_t4_ctr32_encrypt;
else
dat->stream.cbc = NULL;
break;
case 256:
if (dat->mode == EVP_CIPH_CBC_MODE)
dat->stream.cbc = (cbc128_f)aes256_t4_cbc_encrypt;
else if (dat->mode == EVP_CIPH_CTR_MODE)
dat->stream.ctr = (ctr128_f)aes256_t4_ctr32_encrypt;
else
dat->stream.cbc = NULL;
break;
default:
ret = -1;
}
}
if (ret < 0) {
PROVerr(PROV_F_AES_T4_INIT_KEY, PROV_R_AES_KEY_SETUP_FAILED);
return 0;
}
return 1;
}
# define aes_t4_cbc_cipher aes_cbc_cipher
static int aes_t4_cbc_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len);
# define aes_t4_ecb_cipher aes_ecb_cipher
static int aes_t4_ecb_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len);
# define aes_t4_ofb_cipher aes_ofb_cipher
static int aes_t4_ofb_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len);
# define aes_t4_cfb_cipher aes_cfb_cipher
static int aes_t4_cfb_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len);
# define aes_t4_cfb8_cipher aes_cfb8_cipher
static int aes_t4_cfb8_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len);
# define aes_t4_cfb1_cipher aes_cfb1_cipher
static int aes_t4_cfb1_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len);
# define aes_t4_ctr_cipher aes_ctr_cipher
static int aes_t4_ctr_cipher(PROV_AES_KEY *ctx, unsigned char *out,
const unsigned char *in, size_t len);
# define BLOCK_CIPHER_generic_prov(mode) \
static const PROV_AES_CIPHER aes_t4_##mode = { \
aes_t4_init_key, \
aes_t4_##mode##_cipher}; \
static const PROV_AES_CIPHER aes_##mode = { \
aes_init_key, \
aes_##mode##_cipher}; \
const PROV_AES_CIPHER *PROV_AES_CIPHER_##mode(size_t keylen) \
{ return SPARC_AES_CAPABLE?&aes_t4_##mode:&aes_##mode; }
#elif defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
/*
* IBM S390X support
*/
# include "s390x_arch.h"
/* Convert key size to function code: [16,24,32] -> [18,19,20]. */
# define S390X_AES_FC(keylen) (S390X_AES_128 + ((((keylen) << 3) - 128) >> 6))
/* Most modes of operation need km for partial block processing. */
# define S390X_aes_128_CAPABLE (OPENSSL_s390xcap_P.km[0] & \
S390X_CAPBIT(S390X_AES_128))
# define S390X_aes_192_CAPABLE (OPENSSL_s390xcap_P.km[0] & \
S390X_CAPBIT(S390X_AES_192))
# define S390X_aes_256_CAPABLE (OPENSSL_s390xcap_P.km[0] & \
S390X_CAPBIT(S390X_AES_256))
# define s390x_aes_init_key aes_init_key
static int s390x_aes_init_key(PROV_AES_KEY *dat, const unsigned char *key,
size_t keylen);
# define S390X_aes_128_cbc_CAPABLE 1 /* checked by callee */
# define S390X_aes_192_cbc_CAPABLE 1
# define S390X_aes_256_cbc_CAPABLE 1
# define S390X_AES_CBC_CTX PROV_AES_KEY
# define s390x_aes_cbc_init_key aes_init_key
# define s390x_aes_cbc_cipher aes_cbc_cipher
static int s390x_aes_cbc_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len);
# define S390X_aes_128_ecb_CAPABLE S390X_aes_128_CAPABLE
# define S390X_aes_192_ecb_CAPABLE S390X_aes_192_CAPABLE
# define S390X_aes_256_ecb_CAPABLE S390X_aes_256_CAPABLE
static int s390x_aes_ecb_init_key(PROV_AES_KEY *dat, const unsigned char *key,
size_t keylen)
{
dat->plat.s390x.fc = S390X_AES_FC(keylen);
if (!dat->enc)
dat->plat.s390x.fc |= S390X_DECRYPT;
memcpy(dat->plat.s390x.param.km.k, key, keylen);
return 1;
}
static int s390x_aes_ecb_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len)
{
s390x_km(in, len, out, dat->plat.s390x.fc,
&dat->plat.s390x.param.km);
return 1;
}
# define S390X_aes_128_ofb_CAPABLE (S390X_aes_128_CAPABLE && \
(OPENSSL_s390xcap_P.kmo[0] & \
S390X_CAPBIT(S390X_AES_128)))
# define S390X_aes_192_ofb_CAPABLE (S390X_aes_192_CAPABLE && \
(OPENSSL_s390xcap_P.kmo[0] & \
S390X_CAPBIT(S390X_AES_192)))
# define S390X_aes_256_ofb_CAPABLE (S390X_aes_256_CAPABLE && \
(OPENSSL_s390xcap_P.kmo[0] & \
S390X_CAPBIT(S390X_AES_256)))
static int s390x_aes_ofb_init_key(PROV_AES_KEY *dat, const unsigned char *key,
size_t keylen)
{
memcpy(dat->plat.s390x.param.kmo_kmf.cv, dat->iv, AES_BLOCK_SIZE);
memcpy(dat->plat.s390x.param.kmo_kmf.k, key, keylen);
dat->plat.s390x.fc = S390X_AES_FC(keylen);
dat->plat.s390x.res = 0;
return 1;
}
static int s390x_aes_ofb_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len)
{
int n = dat->plat.s390x.res;
int rem;
while (n && len) {
*out = *in ^ dat->plat.s390x.param.kmo_kmf.cv[n];
n = (n + 1) & 0xf;
--len;
++in;
++out;
}
rem = len & 0xf;
len &= ~(size_t)0xf;
if (len) {
s390x_kmo(in, len, out, dat->plat.s390x.fc,
&dat->plat.s390x.param.kmo_kmf);
out += len;
in += len;
}
if (rem) {
s390x_km(dat->plat.s390x.param.kmo_kmf.cv, 16,
dat->plat.s390x.param.kmo_kmf.cv, dat->plat.s390x.fc,
dat->plat.s390x.param.kmo_kmf.k);
while (rem--) {
out[n] = in[n] ^ dat->plat.s390x.param.kmo_kmf.cv[n];
++n;
}
}
dat->plat.s390x.res = n;
return 1;
}
# define S390X_aes_128_cfb_CAPABLE (S390X_aes_128_CAPABLE && \
(OPENSSL_s390xcap_P.kmf[0] & \
S390X_CAPBIT(S390X_AES_128)))
# define S390X_aes_192_cfb_CAPABLE (S390X_aes_192_CAPABLE && \
(OPENSSL_s390xcap_P.kmf[0] & \
S390X_CAPBIT(S390X_AES_192)))
# define S390X_aes_256_cfb_CAPABLE (S390X_aes_256_CAPABLE && \
(OPENSSL_s390xcap_P.kmf[0] & \
S390X_CAPBIT(S390X_AES_256)))
static int s390x_aes_cfb_init_key(PROV_AES_KEY *dat, const unsigned char *key,
size_t keylen)
{
dat->plat.s390x.fc = S390X_AES_FC(keylen);
dat->plat.s390x.fc |= 16 << 24; /* 16 bytes cipher feedback */
if (!dat->enc)
dat->plat.s390x.fc |= S390X_DECRYPT;
dat->plat.s390x.res = 0;
memcpy(dat->plat.s390x.param.kmo_kmf.cv, dat->iv, AES_BLOCK_SIZE);
memcpy(dat->plat.s390x.param.kmo_kmf.k, key, keylen);
return 1;
}
static int s390x_aes_cfb_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len)
{
int n = dat->plat.s390x.res;
int rem;
unsigned char tmp;
while (n && len) {
tmp = *in;
*out = dat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp;
dat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? *out : tmp;
n = (n + 1) & 0xf;
--len;
++in;
++out;
}
rem = len & 0xf;
len &= ~(size_t)0xf;
if (len) {
s390x_kmf(in, len, out, dat->plat.s390x.fc,
&dat->plat.s390x.param.kmo_kmf);
out += len;
in += len;
}
if (rem) {
s390x_km(dat->plat.s390x.param.kmo_kmf.cv, 16,
dat->plat.s390x.param.kmo_kmf.cv,
S390X_AES_FC(dat->keylen), dat->plat.s390x.param.kmo_kmf.k);
while (rem--) {
tmp = in[n];
out[n] = dat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp;
dat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? out[n] : tmp;
++n;
}
}
dat->plat.s390x.res = n;
return 1;
}
# define S390X_aes_128_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \
S390X_CAPBIT(S390X_AES_128))
# define S390X_aes_192_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \
S390X_CAPBIT(S390X_AES_192))
# define S390X_aes_256_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \
S390X_CAPBIT(S390X_AES_256))
static int s390x_aes_cfb8_init_key(PROV_AES_KEY *dat, const unsigned char *key,
size_t keylen)
{
dat->plat.s390x.fc = S390X_AES_FC(keylen);
dat->plat.s390x.fc |= 1 << 24; /* 1 byte cipher feedback */
if (!dat->enc)
dat->plat.s390x.fc |= S390X_DECRYPT;
memcpy(dat->plat.s390x.param.kmo_kmf.cv, dat->iv, AES_BLOCK_SIZE);
memcpy(dat->plat.s390x.param.kmo_kmf.k, key, keylen);
return 1;
}
static int s390x_aes_cfb8_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len)
{
s390x_kmf(in, len, out, dat->plat.s390x.fc,
&dat->plat.s390x.param.kmo_kmf);
return 1;
}
# define S390X_aes_128_cfb1_CAPABLE 0
# define S390X_aes_192_cfb1_CAPABLE 0
# define S390X_aes_256_cfb1_CAPABLE 0
# define s390x_aes_cfb1_init_key aes_init_key
# define s390x_aes_cfb1_cipher aes_cfb1_cipher
static int s390x_aes_cfb1_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len);
# define S390X_aes_128_ctr_CAPABLE 1 /* checked by callee */
# define S390X_aes_192_ctr_CAPABLE 1
# define S390X_aes_256_ctr_CAPABLE 1
# define S390X_AES_CTR_CTX PROV_AES_KEY
# define s390x_aes_ctr_init_key aes_init_key
# define s390x_aes_ctr_cipher aes_ctr_cipher
static int s390x_aes_ctr_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len);
# define BLOCK_CIPHER_generic_prov(mode) \
static const PROV_AES_CIPHER s390x_aes_##mode = { \
s390x_aes_##mode##_init_key, \
s390x_aes_##mode##_cipher \
}; \
static const PROV_AES_CIPHER aes_##mode = { \
aes_init_key, \
aes_##mode##_cipher \
}; \
const PROV_AES_CIPHER *PROV_AES_CIPHER_##mode(size_t keylen) \
{ \
if ((keylen == 128 && S390X_aes_128_##mode##_CAPABLE) \
|| (keylen == 192 && S390X_aes_192_##mode##_CAPABLE) \
|| (keylen == 256 && S390X_aes_256_##mode##_CAPABLE)) \
return &s390x_aes_##mode; \
\
return &aes_##mode; \
}
#else
# define BLOCK_CIPHER_generic_prov(mode) \
static const PROV_AES_CIPHER aes_##mode = { \
aes_init_key, \
aes_##mode##_cipher}; \
const PROV_AES_CIPHER *PROV_AES_CIPHER_##mode(size_t keylen) \
{ return &aes_##mode; }
#endif
#if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__))
# include "arm_arch.h"
# if __ARM_MAX_ARCH__>=7
# if defined(BSAES_ASM)
# define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
# endif
# if defined(VPAES_ASM)
# define VPAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
# endif
# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES)
# define HWAES_set_encrypt_key aes_v8_set_encrypt_key
# define HWAES_set_decrypt_key aes_v8_set_decrypt_key
# define HWAES_encrypt aes_v8_encrypt
# define HWAES_decrypt aes_v8_decrypt
# define HWAES_cbc_encrypt aes_v8_cbc_encrypt
# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks
# endif
#endif
#if defined(HWAES_CAPABLE)
int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
void HWAES_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void HWAES_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
size_t len, const AES_KEY *key,
const unsigned char ivec[16]);
#endif
static int aes_init_key(PROV_AES_KEY *dat, const unsigned char *key,
size_t keylen)
{
int ret;
if ((dat->mode == EVP_CIPH_ECB_MODE || dat->mode == EVP_CIPH_CBC_MODE)
&& !dat->enc) {
#ifdef HWAES_CAPABLE
if (HWAES_CAPABLE) {
ret = HWAES_set_decrypt_key(key, keylen * 8, &dat->ks.ks);
dat->block = (block128_f)HWAES_decrypt;
dat->stream.cbc = NULL;
# ifdef HWAES_cbc_encrypt
if (dat->mode == EVP_CIPH_CBC_MODE)
dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt;
# endif
} else
#endif
#ifdef BSAES_CAPABLE
if (BSAES_CAPABLE && dat->mode == EVP_CIPH_CBC_MODE) {
ret = AES_set_decrypt_key(key, keylen * 8, &dat->ks.ks);
dat->block = (block128_f)AES_decrypt;
dat->stream.cbc = (cbc128_f)bsaes_cbc_encrypt;
} else
#endif
#ifdef VPAES_CAPABLE
if (VPAES_CAPABLE) {
ret = vpaes_set_decrypt_key(key, keylen * 8, &dat->ks.ks);
dat->block = (block128_f)vpaes_decrypt;
dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE)
?(cbc128_f)vpaes_cbc_encrypt : NULL;
} else
#endif
{
ret = AES_set_decrypt_key(key, keylen * 8, &dat->ks.ks);
dat->block = (block128_f)AES_decrypt;
dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE)
? (cbc128_f)AES_cbc_encrypt : NULL;
}
} else
#ifdef HWAES_CAPABLE
if (HWAES_CAPABLE) {
ret = HWAES_set_encrypt_key(key, keylen * 8, &dat->ks.ks);
dat->block = (block128_f)HWAES_encrypt;
dat->stream.cbc = NULL;
# ifdef HWAES_cbc_encrypt
if (dat->mode == EVP_CIPH_CBC_MODE)
dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt;
else
# endif
# ifdef HWAES_ctr32_encrypt_blocks
if (dat->mode == EVP_CIPH_CTR_MODE)
dat->stream.ctr = (ctr128_f)HWAES_ctr32_encrypt_blocks;
else
# endif
(void)0; /* terminate potentially open 'else' */
} else
#endif
#ifdef BSAES_CAPABLE
if (BSAES_CAPABLE && dat->mode == EVP_CIPH_CTR_MODE) {
ret = AES_set_encrypt_key(key, keylen * 8, &dat->ks.ks);
dat->block = (block128_f)AES_encrypt;
dat->stream.ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
} else
#endif
#ifdef VPAES_CAPABLE
if (VPAES_CAPABLE) {
ret = vpaes_set_encrypt_key(key, keylen * 8, &dat->ks.ks);
dat->block = (block128_f)vpaes_encrypt;
dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE)
? (cbc128_f)vpaes_cbc_encrypt : NULL;
} else
#endif
{
ret = AES_set_encrypt_key(key, keylen * 8, &dat->ks.ks);
dat->block = (block128_f)AES_encrypt;
dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE)
? (cbc128_f)AES_cbc_encrypt : NULL;
#ifdef AES_CTR_ASM
if (dat->mode == EVP_CIPH_CTR_MODE)
dat->stream.ctr = (ctr128_f)AES_ctr32_encrypt;
#endif
}
if (ret < 0) {
PROVerr(PROV_F_AES_INIT_KEY, PROV_R_AES_KEY_SETUP_FAILED);
return 0;
}
return 1;
}
static int aes_cbc_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len)
{
if (dat->stream.cbc)
(*dat->stream.cbc) (in, out, len, &dat->ks, dat->iv, dat->enc);
else if (dat->enc)
CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, dat->iv, dat->block);
else
CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, dat->iv, dat->block);
return 1;
}
static int aes_ecb_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len)
{
size_t i;
if (len < AES_BLOCK_SIZE)
return 1;
for (i = 0, len -= AES_BLOCK_SIZE; i <= len; i += AES_BLOCK_SIZE)
(*dat->block) (in + i, out + i, &dat->ks);
return 1;
}
static int aes_ofb_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len)
{
int num = dat->num;
CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, dat->iv, &num, dat->block);
dat->num = num;
return 1;
}
static int aes_cfb_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len)
{
int num = dat->num;
CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, dat->iv, &num, dat->enc,
dat->block);
dat->num = num;
return 1;
}
static int aes_cfb8_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len)
{
int num = dat->num;
CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, dat->iv, &num, dat->enc,
dat->block);
dat->num = num;
return 1;
}
static int aes_cfb1_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len)
{
int num = dat->num;
if ((dat->flags & EVP_CIPH_FLAG_LENGTH_BITS) != 0) {
CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, dat->iv, &num,
dat->enc, dat->block);
dat->num = num;
return 1;
}
while (len >= MAXBITCHUNK) {
CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks,
dat->iv, &num, dat->enc, dat->block);
len -= MAXBITCHUNK;
out += MAXBITCHUNK;
in += MAXBITCHUNK;
}
if (len)
CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks, dat->iv, &num,
dat->enc, dat->block);
dat->num = num;
return 1;
}
static int aes_ctr_cipher(PROV_AES_KEY *dat, unsigned char *out,
const unsigned char *in, size_t len)
{
unsigned int num = dat->num;
if (dat->stream.ctr)
CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, dat->iv, dat->buf,
&num, dat->stream.ctr);
else
CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, dat->iv, dat->buf,
&num, dat->block);
dat->num = num;
return 1;
}
BLOCK_CIPHER_generic_prov(cbc)
BLOCK_CIPHER_generic_prov(ecb)
BLOCK_CIPHER_generic_prov(ofb)
BLOCK_CIPHER_generic_prov(cfb)
BLOCK_CIPHER_generic_prov(cfb1)
BLOCK_CIPHER_generic_prov(cfb8)
BLOCK_CIPHER_generic_prov(ctr)
+118
View File
@@ -0,0 +1,118 @@
/*
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <string.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include "ciphers_locl.h"
#include <assert.h>
#include "internal/providercommonerr.h"
/*
* Fills a single block of buffered data from the input, and returns the amount
* of data remaining in the input that is a multiple of the blocksize. The buffer
* is only filled if it already has some data in it, isn't full already or we
* don't have at least one block in the input.
*
* buf: a buffer of blocksize bytes
* buflen: contains the amount of data already in buf on entry. Updated with the
* amount of data in buf at the end. On entry *buflen must always be
* less than the blocksize
* blocksize: size of a block. Must be greater than 0 and a power of 2
* in: pointer to a pointer containing the input data
* inlen: amount of input data available
*
* On return buf is filled with as much data as possible up to a full block,
* *buflen is updated containing the amount of data in buf. *in is updated to
* the new location where input data should be read from, *inlen is updated with
* the remaining amount of data in *in. Returns the largest value <= *inlen
* which is a multiple of the blocksize.
*/
size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
const unsigned char **in, size_t *inlen)
{
size_t blockmask = ~(blocksize - 1);
assert(*buflen <= blocksize);
assert(blocksize > 0 && (blocksize & (blocksize - 1)) == 0);
if (*buflen != blocksize && (*buflen != 0 || *inlen < blocksize)) {
size_t bufremain = blocksize - *buflen;
if (*inlen < bufremain)
bufremain = *inlen;
memcpy(buf + *buflen, *in, bufremain);
*in += bufremain;
*inlen -= bufremain;
*buflen += bufremain;
}
return *inlen & blockmask;
}
/*
* Fills the buffer with trailing data from an encryption/decryption that didn't
* fit into a full block.
*/
int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
const unsigned char **in, size_t *inlen)
{
if (*inlen == 0)
return 1;
if (*buflen + *inlen > blocksize) {
PROVerr(PROV_F_TRAILINGDATA, ERR_R_INTERNAL_ERROR);
return 0;
}
memcpy(buf + *buflen, *in, *inlen);
*buflen += *inlen;
*inlen = 0;
return 1;
}
/* Pad the final block for encryption */
void padblock(unsigned char *buf, size_t *buflen, size_t blocksize)
{
size_t i;
unsigned char pad = (unsigned char)(blocksize - *buflen);
for (i = *buflen; i < blocksize; i++)
buf[i] = pad;
}
int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize)
{
size_t pad, i;
size_t len = *buflen;
if(len != blocksize) {
PROVerr(PROV_F_UNPADBLOCK, ERR_R_INTERNAL_ERROR);
return 0;
}
/*
* The following assumes that the ciphertext has been authenticated.
* Otherwise it provides a padding oracle.
*/
pad = buf[blocksize - 1];
if (pad == 0 || pad > blocksize) {
PROVerr(PROV_F_UNPADBLOCK, PROV_R_BAD_DECRYPT);
return 0;
}
for (i = 0; i < pad; i++) {
if (buf[--len] != pad) {
PROVerr(PROV_F_UNPADBLOCK, PROV_R_BAD_DECRYPT);
return 0;
}
}
*buflen = len;
return 1;
}
+4
View File
@@ -0,0 +1,4 @@
LIBS=../../../libcrypto
SOURCE[../../../libcrypto]=\
block.c aes.c aes_basic.c
INCLUDE[../../../libcrypto]=. ../../../crypto
+107
View File
@@ -0,0 +1,107 @@
/*
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <openssl/aes.h>
#include <openssl/modes.h>
typedef struct prov_aes_cipher_st PROV_AES_CIPHER;
typedef struct prov_aes_key_st {
union {
double align;
AES_KEY ks;
} ks;
block128_f block;
union {
cbc128_f cbc;
ctr128_f ctr;
} stream;
/* Platform specific data */
union {
int dummy;
#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
struct {
union {
double align;
/*-
* KM-AES parameter block - begin
* (see z/Architecture Principles of Operation >= SA22-7832-06)
*/
struct {
unsigned char k[32];
} km;
/* KM-AES parameter block - end */
/*-
* KMO-AES/KMF-AES parameter block - begin
* (see z/Architecture Principles of Operation >= SA22-7832-08)
*/
struct {
unsigned char cv[16];
unsigned char k[32];
} kmo_kmf;
/* KMO-AES/KMF-AES parameter block - end */
} param;
unsigned int fc;
int res;
} s390x;
#endif /* defined(OPENSSL_CPUID_OBJ) && defined(__s390__) */
} plat;
/* The cipher functions we are going to use */
const PROV_AES_CIPHER *ciph;
/* The mode that we are using */
int mode;
/* Set to 1 if we are encrypting or 0 otherwise */
int enc;
unsigned char iv[AES_BLOCK_SIZE];
/*
* num contains the number of bytes of |iv| which are valid for modes that
* manage partial blocks themselves.
*/
size_t num;
/* Buffer of partial blocks processed via update calls */
unsigned char buf[AES_BLOCK_SIZE];
/* Number of bytes in buf */
size_t bufsz;
uint64_t flags;
size_t keylen;
/* Whether padding should be used or not */
unsigned int pad : 1;
} PROV_AES_KEY;
struct prov_aes_cipher_st {
int (*init)(PROV_AES_KEY *dat, const uint8_t *key, size_t keylen);
int (*cipher)(PROV_AES_KEY *dat, uint8_t *out, const uint8_t *in,
size_t inl);
};
const PROV_AES_CIPHER *PROV_AES_CIPHER_ecb(size_t keylen);
const PROV_AES_CIPHER *PROV_AES_CIPHER_cbc(size_t keylen);
const PROV_AES_CIPHER *PROV_AES_CIPHER_ofb(size_t keylen);
const PROV_AES_CIPHER *PROV_AES_CIPHER_cfb(size_t keylen);
const PROV_AES_CIPHER *PROV_AES_CIPHER_cfb1(size_t keylen);
const PROV_AES_CIPHER *PROV_AES_CIPHER_cfb8(size_t keylen);
const PROV_AES_CIPHER *PROV_AES_CIPHER_ctr(size_t keylen);
size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
const unsigned char **in, size_t *inlen);
int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
const unsigned char **in, size_t *inlen);
void padblock(unsigned char *buf, size_t *buflen, size_t blocksize);
int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize);
+23 -5
View File
@@ -10,11 +10,30 @@
#include <openssl/sha.h>
#include <openssl/crypto.h>
#include <openssl/core_numbers.h>
#include "internal/provider_algs.h"
static int sha256_final(void *ctx, unsigned char *md, size_t *size)
/*
* Forward declaration of everything implemented here. This is not strictly
* necessary for the compiler, but provides an assurance that the signatures
* of the functions in the dispatch table are correct.
*/
static OSSL_OP_digest_newctx_fn sha256_newctx;
#if 0 /* Not defined here */
static OSSL_OP_digest_init_fn sha256_init;
static OSSL_OP_digest_update_fn sha256_update;
#endif
static OSSL_OP_digest_final_fn sha256_final;
static OSSL_OP_digest_freectx_fn sha256_freectx;
static OSSL_OP_digest_dupctx_fn sha256_dupctx;
static OSSL_OP_digest_size_fn sha256_size;
static OSSL_OP_digest_block_size_fn sha256_size;
static int sha256_final(void *ctx,
unsigned char *md, size_t *mdl, size_t mdsz)
{
if (SHA256_Final(md, ctx)) {
*size = SHA256_DIGEST_LENGTH;
if (mdsz >= SHA256_DIGEST_LENGTH
&& SHA256_Final(md, ctx)) {
*mdl = SHA256_DIGEST_LENGTH;
return 1;
}
@@ -55,11 +74,10 @@ static size_t sha256_block_size(void)
return SHA256_CBLOCK;
}
extern const OSSL_DISPATCH sha256_functions[];
const OSSL_DISPATCH sha256_functions[] = {
{ OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))sha256_newctx },
{ OSSL_FUNC_DIGEST_INIT, (void (*)(void))SHA256_Init },
{ OSSL_FUNC_DIGEST_UPDDATE, (void (*)(void))SHA256_Update },
{ OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))SHA256_Update },
{ OSSL_FUNC_DIGEST_FINAL, (void (*)(void))sha256_final },
{ OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))sha256_freectx },
{ OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))sha256_dupctx },
@@ -0,0 +1,34 @@
/*
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
/* Digests */
extern const OSSL_DISPATCH sha256_functions[];
/* Ciphers */
extern const OSSL_DISPATCH aes256ecb_functions[];
extern const OSSL_DISPATCH aes192ecb_functions[];
extern const OSSL_DISPATCH aes128ecb_functions[];
extern const OSSL_DISPATCH aes256cbc_functions[];
extern const OSSL_DISPATCH aes192cbc_functions[];
extern const OSSL_DISPATCH aes128cbc_functions[];
extern const OSSL_DISPATCH aes256ofb_functions[];
extern const OSSL_DISPATCH aes192ofb_functions[];
extern const OSSL_DISPATCH aes128ofb_functions[];
extern const OSSL_DISPATCH aes256cfb_functions[];
extern const OSSL_DISPATCH aes192cfb_functions[];
extern const OSSL_DISPATCH aes128cfb_functions[];
extern const OSSL_DISPATCH aes256cfb1_functions[];
extern const OSSL_DISPATCH aes192cfb1_functions[];
extern const OSSL_DISPATCH aes128cfb1_functions[];
extern const OSSL_DISPATCH aes256cfb8_functions[];
extern const OSSL_DISPATCH aes192cfb8_functions[];
extern const OSSL_DISPATCH aes128cfb8_functions[];
extern const OSSL_DISPATCH aes256ctr_functions[];
extern const OSSL_DISPATCH aes192ctr_functions[];
extern const OSSL_DISPATCH aes128ctr_functions[];
@@ -0,0 +1,54 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#ifndef HEADER_PROVERR_H
# define HEADER_PROVERR_H
# ifndef HEADER_SYMHACKS_H
# include <openssl/symhacks.h>
# endif
# ifdef __cplusplus
extern "C"
# endif
int ERR_load_PROV_strings(void);
/*
* PROV function codes.
*/
# define PROV_F_AESNI_INIT_KEY 101
# define PROV_F_AES_BLOCK_FINAL 102
# define PROV_F_AES_BLOCK_UPDATE 103
# define PROV_F_AES_CIPHER 104
# define PROV_F_AES_CTX_GET_PARAMS 105
# define PROV_F_AES_CTX_SET_PARAMS 106
# define PROV_F_AES_DINIT 107
# define PROV_F_AES_DUPCTX 108
# define PROV_F_AES_EINIT 109
# define PROV_F_AES_INIT_KEY 110
# define PROV_F_AES_STREAM_UPDATE 111
# define PROV_F_AES_T4_INIT_KEY 112
# define PROV_F_PROV_AES_KEY_GENERIC_INIT 113
# define PROV_F_TRAILINGDATA 114
# define PROV_F_UNPADBLOCK 100
/*
* PROV reason codes.
*/
# define PROV_R_AES_KEY_SETUP_FAILED 101
# define PROV_R_BAD_DECRYPT 100
# define PROV_R_CIPHER_OPERATION_FAILED 102
# define PROV_R_FAILED_TO_GET_PARAMETER 103
# define PROV_R_FAILED_TO_SET_PARAMETER 104
# define PROV_R_INVALID_KEYLEN 105
# define PROV_R_OUTPUT_BUFFER_TOO_SMALL 106
# define PROV_R_WRONG_FINAL_BLOCK_LENGTH 107
#endif
+67
View File
@@ -0,0 +1,67 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <openssl/err.h>
#include "internal/providercommonerr.h"
#ifndef OPENSSL_NO_ERR
static const ERR_STRING_DATA PROV_str_functs[] = {
{ERR_PACK(ERR_LIB_PROV, PROV_F_AESNI_INIT_KEY, 0), "aesni_init_key"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_AES_BLOCK_FINAL, 0), "aes_block_final"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_AES_BLOCK_UPDATE, 0), "aes_block_update"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_AES_CIPHER, 0), "aes_cipher"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_AES_CTX_GET_PARAMS, 0),
"aes_ctx_get_params"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_AES_CTX_SET_PARAMS, 0),
"aes_ctx_set_params"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_AES_DINIT, 0), "aes_dinit"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_AES_DUPCTX, 0), "aes_dupctx"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_AES_EINIT, 0), "aes_einit"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_AES_INIT_KEY, 0), "aes_init_key"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_AES_STREAM_UPDATE, 0), "aes_stream_update"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_AES_T4_INIT_KEY, 0), "aes_t4_init_key"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_PROV_AES_KEY_GENERIC_INIT, 0),
"PROV_AES_KEY_generic_init"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_TRAILINGDATA, 0), "trailingdata"},
{ERR_PACK(ERR_LIB_PROV, PROV_F_UNPADBLOCK, 0), "unpadblock"},
{0, NULL}
};
static const ERR_STRING_DATA PROV_str_reasons[] = {
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_AES_KEY_SETUP_FAILED),
"aes key setup failed"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_DECRYPT), "bad decrypt"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_CIPHER_OPERATION_FAILED),
"cipher operation failed"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_GET_PARAMETER),
"failed to get parameter"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SET_PARAMETER),
"failed to set parameter"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEYLEN), "invalid keylen"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_OUTPUT_BUFFER_TOO_SMALL),
"output buffer too small"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_WRONG_FINAL_BLOCK_LENGTH),
"wrong final block length"},
{0, NULL}
};
#endif
int ERR_load_PROV_strings(void)
{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(PROV_str_functs[0].error) == NULL) {
ERR_load_strings_const(PROV_str_functs);
ERR_load_strings_const(PROV_str_reasons);
}
#endif
return 1;
}
+28 -2
View File
@@ -13,6 +13,7 @@
#include <openssl/core_numbers.h>
#include <openssl/core_names.h>
#include <openssl/params.h>
#include "internal/provider_algs.h"
/* Functions provided by the core */
static OSSL_core_get_param_types_fn *c_get_param_types = NULL;
@@ -49,13 +50,36 @@ static int deflt_get_params(const OSSL_PROVIDER *prov,
return 1;
}
extern const OSSL_DISPATCH sha256_functions[];
static const OSSL_ALGORITHM deflt_digests[] = {
{ "SHA256", "default=yes", sha256_functions },
{ NULL, NULL, NULL }
};
static const OSSL_ALGORITHM deflt_ciphers[] = {
{ "AES-256-ECB", "default=yes", aes256ecb_functions },
{ "AES-192-ECB", "default=yes", aes192ecb_functions },
{ "AES-128-ECB", "default=yes", aes128ecb_functions },
{ "AES-256-CBC", "default=yes", aes256cbc_functions },
{ "AES-192-CBC", "default=yes", aes192cbc_functions },
{ "AES-128-CBC", "default=yes", aes128cbc_functions },
{ "AES-256-OFB", "default=yes", aes256ofb_functions },
{ "AES-192-OFB", "default=yes", aes192ofb_functions },
{ "AES-128-OFB", "default=yes", aes128ofb_functions },
{ "AES-256-CFB", "default=yes", aes256cfb_functions },
{ "AES-192-CFB", "default=yes", aes192cfb_functions },
{ "AES-128-CFB", "default=yes", aes128cfb_functions },
{ "AES-256-CFB1", "default=yes", aes256cfb1_functions },
{ "AES-192-CFB1", "default=yes", aes192cfb1_functions },
{ "AES-128-CFB1", "default=yes", aes128cfb1_functions },
{ "AES-256-CFB8", "default=yes", aes256cfb8_functions },
{ "AES-192-CFB8", "default=yes", aes192cfb8_functions },
{ "AES-128-CFB8", "default=yes", aes128cfb8_functions },
{ "AES-256-CTR", "default=yes", aes256ctr_functions },
{ "AES-192-CTR", "default=yes", aes192ctr_functions },
{ "AES-128-CTR", "default=yes", aes128ctr_functions },
{ NULL, NULL, NULL }
};
static const OSSL_ALGORITHM *deflt_query(OSSL_PROVIDER *prov,
int operation_id,
int *no_cache)
@@ -64,6 +88,8 @@ static const OSSL_ALGORITHM *deflt_query(OSSL_PROVIDER *prov,
switch (operation_id) {
case OSSL_OP_DIGEST:
return deflt_digests;
case OSSL_OP_CIPHER:
return deflt_ciphers;
}
return NULL;
}
+1 -1
View File
@@ -54,7 +54,7 @@ extern const OSSL_DISPATCH md2_functions[];
const OSSL_DISPATCH md2_functions[] = {
{ OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))md2_newctx },
{ OSSL_FUNC_DIGEST_INIT, (void (*)(void))MD2_Init },
{ OSSL_FUNC_DIGEST_UPDDATE, (void (*)(void))MD2_Update },
{ OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))MD2_Update },
{ OSSL_FUNC_DIGEST_FINAL, (void (*)(void))md2_final },
{ OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))md2_freectx },
{ OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))md2_dupctx },
+2 -2
View File
@@ -211,9 +211,9 @@ int ssl3_get_record(SSL *s)
SSL3_BUFFER_get_len(rbuf), 0,
num_recs == 0 ? 1 : 0, &n);
if (rret <= 0) {
#ifndef OPENSSL_NO_KTLS
if (!BIO_get_ktls_recv(s->rbio))
return rret; /* error or non-blocking */
#ifndef OPENSSL_NO_KTLS
switch (errno) {
case EBADMSG:
SSLfatal(s, SSL_AD_BAD_RECORD_MAC,
@@ -233,8 +233,8 @@ int ssl3_get_record(SSL *s)
default:
break;
}
return rret;
#endif
return rret;
}
RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
+5
View File
@@ -5201,6 +5201,11 @@ int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen)
if (ext->present)
num++;
}
if (num == 0) {
*out = NULL;
*outlen = 0;
return 1;
}
if ((present = OPENSSL_malloc(sizeof(*present) * num)) == NULL) {
SSLerr(SSL_F_SSL_CLIENT_HELLO_GET1_EXTENSIONS_PRESENT,
ERR_R_MALLOC_FAILURE);
+153 -7
View File
@@ -18,28 +18,170 @@ static int test_bio_memleak(void)
int ok = 0;
BIO *bio;
BUF_MEM bufmem;
const char *str = "BIO test\n";
static const char str[] = "BIO test\n";
char buf[100];
bio = BIO_new(BIO_s_mem());
if (bio == NULL)
if (!TEST_ptr(bio))
goto finish;
bufmem.length = strlen(str) + 1;
bufmem.length = sizeof(str);
bufmem.data = (char *) str;
bufmem.max = bufmem.length;
BIO_set_mem_buf(bio, &bufmem, BIO_NOCLOSE);
BIO_set_flags(bio, BIO_FLAGS_MEM_RDONLY);
if (BIO_read(bio, buf, sizeof(buf)) <= 0)
if (!TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(str)))
goto finish;
ok = strcmp(buf, str) == 0;
if (!TEST_mem_eq(buf, sizeof(str), str, sizeof(str)))
goto finish;
ok = 1;
finish:
BIO_free(bio);
return ok;
}
static int test_bio_get_mem(void)
{
int ok = 0;
BIO *bio = NULL;
BUF_MEM *bufmem = NULL;
bio = BIO_new(BIO_s_mem());
if (!TEST_ptr(bio))
goto finish;
if (!TEST_int_eq(BIO_puts(bio, "Hello World\n"), 12))
goto finish;
BIO_get_mem_ptr(bio, &bufmem);
if (!TEST_ptr(bufmem))
goto finish;
if (!TEST_int_gt(BIO_set_close(bio, BIO_NOCLOSE), 0))
goto finish;
BIO_free(bio);
bio = NULL;
if (!TEST_mem_eq(bufmem->data, bufmem->length, "Hello World\n", 12))
goto finish;
ok = 1;
finish:
BIO_free(bio);
BUF_MEM_free(bufmem);
return ok;
}
static int test_bio_new_mem_buf(void)
{
int ok = 0;
BIO *bio;
BUF_MEM *bufmem;
char data[16];
bio = BIO_new_mem_buf("Hello World\n", 12);
if (!TEST_ptr(bio))
goto finish;
if (!TEST_int_eq(BIO_read(bio, data, 5), 5))
goto finish;
if (!TEST_mem_eq(data, 5, "Hello", 5))
goto finish;
if (!TEST_int_gt(BIO_get_mem_ptr(bio, &bufmem), 0))
goto finish;
if (!TEST_int_lt(BIO_write(bio, "test", 4), 0))
goto finish;
if (!TEST_int_eq(BIO_read(bio, data, 16), 7))
goto finish;
if (!TEST_mem_eq(data, 7, " World\n", 7))
goto finish;
if (!TEST_int_gt(BIO_reset(bio), 0))
goto finish;
if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
goto finish;
if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
goto finish;
ok = 1;
finish:
BIO_free(bio);
return ok;
}
static int test_bio_rdonly_mem_buf(void)
{
int ok = 0;
BIO *bio, *bio2 = NULL;
BUF_MEM *bufmem;
char data[16];
bio = BIO_new_mem_buf("Hello World\n", 12);
if (!TEST_ptr(bio))
goto finish;
if (!TEST_int_eq(BIO_read(bio, data, 5), 5))
goto finish;
if (!TEST_mem_eq(data, 5, "Hello", 5))
goto finish;
if (!TEST_int_gt(BIO_get_mem_ptr(bio, &bufmem), 0))
goto finish;
(void)BIO_set_close(bio, BIO_NOCLOSE);
bio2 = BIO_new(BIO_s_mem());
if (!TEST_ptr(bio2))
goto finish;
BIO_set_mem_buf(bio2, bufmem, BIO_CLOSE);
BIO_set_flags(bio2, BIO_FLAGS_MEM_RDONLY);
if (!TEST_int_eq(BIO_read(bio2, data, 16), 7))
goto finish;
if (!TEST_mem_eq(data, 7, " World\n", 7))
goto finish;
if (!TEST_int_gt(BIO_reset(bio2), 0))
goto finish;
if (!TEST_int_eq(BIO_read(bio2, data, 16), 7))
goto finish;
if (!TEST_mem_eq(data, 7, " World\n", 7))
goto finish;
ok = 1;
finish:
BIO_free(bio);
BIO_free(bio2);
return ok;
}
static int test_bio_rdwr_rdonly(void)
{
int ok = 0;
BIO *bio = NULL;
char data[16];
bio = BIO_new(BIO_s_mem());
if (!TEST_ptr(bio))
goto finish;
if (!TEST_int_eq(BIO_puts(bio, "Hello World\n"), 12))
goto finish;
BIO_set_flags(bio, BIO_FLAGS_MEM_RDONLY);
if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
goto finish;
if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
goto finish;
if (!TEST_int_gt(BIO_reset(bio), 0))
goto finish;
BIO_clear_flags(bio, BIO_FLAGS_MEM_RDONLY);
if (!TEST_int_eq(BIO_puts(bio, "Hi!\n"), 4))
goto finish;
if (!TEST_int_eq(BIO_read(bio, data, 16), 16))
goto finish;
if (!TEST_mem_eq(data, 16, "Hello World\nHi!\n", 16))
goto finish;
ok = 1;
finish:
BIO_free(bio);
return ok;
}
int global_init(void)
{
CRYPTO_set_mem_debug(1);
@@ -50,5 +192,9 @@ int global_init(void)
int setup_tests(void)
{
ADD_TEST(test_bio_memleak);
ADD_TEST(test_bio_get_mem);
ADD_TEST(test_bio_new_mem_buf);
ADD_TEST(test_bio_rdonly_mem_buf);
ADD_TEST(test_bio_rdwr_rdonly);
return 1;
}
+68
View File
@@ -1954,6 +1954,73 @@ static int test_rand(void)
return st;
}
/*
* Run some statistical tests to provide a degree confidence that the
* BN_rand_range() function works as expected. The critical value
* is computed using the R statistical suite:
*
* qchisq(alpha, df=iterations - 1)
*
* where alpha is the significance level (0.95 is used here) and iterations
* is the number of samples being drawn.
*/
static const struct {
unsigned int range;
unsigned int iterations;
double critical;
} rand_range_cases[] = {
{ 2, 100, 123.2252 /* = qchisq(.95, df=99) */ },
{ 12, 1000, 1073.643 /* = qchisq(.95, df=999) */ },
{ 1023, 100000, 100735.7 /* = qchisq(.95, df=99999) */ },
};
static int test_rand_range(int n)
{
const unsigned int range = rand_range_cases[n].range;
const unsigned int iterations = rand_range_cases[n].iterations;
const double critical = rand_range_cases[n].critical;
const double expected = iterations / (double)range;
double sum = 0;
BIGNUM *rng = NULL, *val = NULL;
size_t *counts;
unsigned int i, v;
int res = 0;
if (!TEST_ptr(counts = OPENSSL_zalloc(sizeof(*counts) * range))
|| !TEST_ptr(rng = BN_new())
|| !TEST_ptr(val = BN_new())
|| !TEST_true(BN_set_word(rng, range)))
goto err;
for (i = 0; i < iterations; i++) {
if (!TEST_true(BN_rand_range(val, rng))
|| !TEST_uint_lt(v = (unsigned int)BN_get_word(val), range))
goto err;
counts[v]++;
}
TEST_note("range %u iterations %u critical %.4f", range, iterations,
critical);
if (range < 20) {
TEST_note("frequencies (expected %.2f)", expected);
for (i = 0; i < range; i++)
TEST_note(" %2u %6zu", i, counts[i]);
}
for (i = 0; i < range; i++) {
const double delta = counts[i] - expected;
sum += delta * delta;
}
sum /= expected;
TEST_note("test statistic %.4f", sum);
if (TEST_double_lt(sum, critical))
res = 1;
err:
BN_free(rng);
BN_free(val);
OPENSSL_free(counts);
return res;
}
static int test_negzero(void)
{
BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL;
@@ -2432,6 +2499,7 @@ int setup_tests(void)
#endif
ADD_ALL_TESTS(test_is_prime, (int)OSSL_NELEM(primes));
ADD_ALL_TESTS(test_not_prime, (int)OSSL_NELEM(not_primes));
ADD_ALL_TESTS(test_rand_range, OSSL_NELEM(rand_range_cases));
} else {
ADD_ALL_TESTS(run_file_tests, n);
}
+4 -1
View File
@@ -1884,11 +1884,14 @@ static int check_ec_key_field_public_range_test(int id)
* be the same point on the curve). The add is different for char2 fields.
*/
type = EC_METHOD_get_field_type(meth);
#ifndef OPENSSL_NO_EC2M
if (type == NID_X9_62_characteristic_two_field) {
/* test for binary curves */
if (!TEST_true(BN_GF2m_add(x, x, field)))
goto err;
} else if (type == NID_X9_62_prime_field) {
} else
#endif
if (type == NID_X9_62_prime_field) {
/* test for prime curves */
if (!TEST_true(BN_add(x, x, field)))
goto err;
+55
View File
@@ -253,6 +253,60 @@ static int test_kdf_ss_kmac(void)
return ret;
}
static int test_kdf_sshkdf(void)
{
int ret;
EVP_KDF_CTX *kctx;
unsigned char out[8];
/* Test data from NIST CAVS 14.1 test vectors */
const unsigned char key[] = {
0x00, 0x00, 0x00, 0x81, 0x00, 0x87, 0x5c, 0x55, 0x1c, 0xef, 0x52, 0x6a,
0x4a, 0x8b, 0xe1, 0xa7, 0xdf, 0x27, 0xe9, 0xed, 0x35, 0x4b, 0xac, 0x9a,
0xfb, 0x71, 0xf5, 0x3d, 0xba, 0xe9, 0x05, 0x67, 0x9d, 0x14, 0xf9, 0xfa,
0xf2, 0x46, 0x9c, 0x53, 0x45, 0x7c, 0xf8, 0x0a, 0x36, 0x6b, 0xe2, 0x78,
0x96, 0x5b, 0xa6, 0x25, 0x52, 0x76, 0xca, 0x2d, 0x9f, 0x4a, 0x97, 0xd2,
0x71, 0xf7, 0x1e, 0x50, 0xd8, 0xa9, 0xec, 0x46, 0x25, 0x3a, 0x6a, 0x90,
0x6a, 0xc2, 0xc5, 0xe4, 0xf4, 0x8b, 0x27, 0xa6, 0x3c, 0xe0, 0x8d, 0x80,
0x39, 0x0a, 0x49, 0x2a, 0xa4, 0x3b, 0xad, 0x9d, 0x88, 0x2c, 0xca, 0xc2,
0x3d, 0xac, 0x88, 0xbc, 0xad, 0xa4, 0xb4, 0xd4, 0x26, 0xa3, 0x62, 0x08,
0x3d, 0xab, 0x65, 0x69, 0xc5, 0x4c, 0x22, 0x4d, 0xd2, 0xd8, 0x76, 0x43,
0xaa, 0x22, 0x76, 0x93, 0xe1, 0x41, 0xad, 0x16, 0x30, 0xce, 0x13, 0x14,
0x4e
};
const unsigned char xcghash[] = {
0x0e, 0x68, 0x3f, 0xc8, 0xa9, 0xed, 0x7c, 0x2f, 0xf0, 0x2d, 0xef, 0x23,
0xb2, 0x74, 0x5e, 0xbc, 0x99, 0xb2, 0x67, 0xda, 0xa8, 0x6a, 0x4a, 0xa7,
0x69, 0x72, 0x39, 0x08, 0x82, 0x53, 0xf6, 0x42
};
const unsigned char sessid[] = {
0x0e, 0x68, 0x3f, 0xc8, 0xa9, 0xed, 0x7c, 0x2f, 0xf0, 0x2d, 0xef, 0x23,
0xb2, 0x74, 0x5e, 0xbc, 0x99, 0xb2, 0x67, 0xda, 0xa8, 0x6a, 0x4a, 0xa7,
0x69, 0x72, 0x39, 0x08, 0x82, 0x53, 0xf6, 0x42
};
const unsigned char expected[sizeof(out)] = {
0x41, 0xff, 0x2e, 0xad, 0x16, 0x83, 0xf1, 0xe6
};
ret = TEST_ptr(kctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF))
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()),
0)
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, key,
sizeof(key)), 0)
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSHKDF_XCGHASH,
xcghash, sizeof(xcghash)), 0)
&& TEST_int_gt(EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID,
sessid, sizeof(sessid)), 0)
&& TEST_int_gt(
EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE,
(int)EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV),
0)
&& TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0)
&& TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
EVP_KDF_CTX_free(kctx);
return ret;
}
int setup_tests(void)
{
ADD_TEST(test_kdf_tls1_prf);
@@ -264,5 +318,6 @@ int setup_tests(void)
ADD_TEST(test_kdf_ss_hash);
ADD_TEST(test_kdf_ss_hmac);
ADD_TEST(test_kdf_ss_kmac);
ADD_TEST(test_kdf_sshkdf);
return 1;
}
+78
View File
@@ -0,0 +1,78 @@
#! /usr/bin/env perl
# Copyright 2019 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
use strict;
use warnings;
use OpenSSL::Test;
use OpenSSL::Test::Utils;
setup("test_kdf");
my @kdf_tests = (
{ cmd => [qw{openssl kdf -keylen 16 -kdfopt digest:SHA256 -kdfopt secret:secret -kdfopt seed:seed TLS1-PRF}],
expected => '8E:4D:93:25:30:D7:65:A0:AA:E9:74:C3:04:73:5E:CC',
desc => 'TLS1-PRF SHA256' },
{ cmd => [qw{openssl kdf -keylen 16 -kdfopt digest:MD5-SHA1 -kdfopt secret:secret -kdfopt seed:seed TLS1-PRF}],
expected => '65:6F:31:CB:04:03:D6:51:E2:E8:71:F8:20:04:AB:BA',
desc => 'TLS1-PRF MD5-SHA1' },
{ cmd => [qw{openssl kdf -keylen 10 -kdfopt digest:SHA256 -kdfopt key:secret -kdfopt salt:salt -kdfopt info:label HKDF}],
expected => '2a:c4:36:9f:52:59:96:f8:de:13',
desc => 'HKDF SHA256' },
{ cmd => [qw{openssl kdf -keylen 32 -kdfopt digest:SHA256 -kdfopt pass:password -kdfopt salt:salt -kdfopt iter:2 PBKDF2}],
expected => 'ae:4d:0c:95:af:6b:46:d3:2d:0a:df:f9:28:f0:6d:d0:2a:30:3f:8e:f3:c2:51:df:d6:e2:d8:5a:95:47:4c:43',
desc => 'PBKDF2 SHA256'},
{ cmd => [qw{openssl kdf -keylen 64 -kdfopt mac:KMAC128 -kdfopt maclen:20 -kdfopt hexkey:b74a149a161546f8c20b06ac4ed4 -kdfopt hexinfo:348a37a27ef1282f5f020dcc -kdfopt hexsalt:3638271ccd68a25dc24ecddd39ef3f89 SSKDF}],
expected => 'e9:c1:84:53:a0:62:b5:3b:db:fc:bb:5a:34:bd:b8:e5:e7:07:ee:bb:5d:d1:34:42:43:d8:cf:c2:c2:e6:33:2f:91:bd:a5:86:f3:7d:e4:8a:65:d4:c5:14:fd:ef:aa:1e:67:54:f3:73:d2:38:e1:95:ae:15:7e:1d:e8:14:98:03',
desc => 'SSKDF KMAC128'},
{ cmd => [qw{openssl kdf -keylen 16 -kdfopt mac:HMAC -kdfopt digest:SHA256 -kdfopt hexkey:b74a149a161546f8c20b06ac4ed4 -kdfopt hexinfo:348a37a27ef1282f5f020dcc -kdfopt hexsalt:3638271ccd68a25dc24ecddd39ef3f89 SSKDF}],
expected => '44:f6:76:e8:5c:1b:1a:8b:bc:3d:31:92:18:63:1c:a3',
desc => 'SSKDF HMAC SHA256'},
{ cmd => [qw{openssl kdf -keylen 14 -kdfopt digest:SHA224 -kdfopt hexkey:6dbdc23f045488e4062757b06b9ebae183fc5a5946d80db93fec6f62ec07e3727f0126aed12ce4b262f47d48d54287f81d474c7c3b1850e9 -kdfopt hexinfo:a1b2c3d4e54341565369643c832e9849dcdba71e9a3139e606e095de3c264a66e98a165854cd07989b1ee0ec3f8dbe SSKDF}],
expected => 'a4:62:de:16:a8:9d:e8:46:6e:f5:46:0b:47:b8',
desc => 'SSKDF HASH SHA224'},
{ cmd => [qw{openssl kdf -keylen 16 -kdfopt md:SHA256 -kdfopt hexkey:0102030405 -kdfopt hexxcghash:06090A -kdfopt hexsession_id:01020304 -kdfopt type:A SSHKDF}],
expected => '5C:49:94:47:3B:B1:53:3A:58:EB:19:42:04:D3:78:16',
desc => 'SSHKDF SHA256'},
);
my @scrypt_tests = (
{ cmd => [qw{openssl kdf -keylen 64 -kdfopt pass:password -kdfopt salt:NaCl -kdfopt N:1024 -kdfopt r:8 -kdfopt p:16 -kdfopt maxmem_bytes:10485760 id-scrypt}],
expected => 'fd:ba:be:1c:9d:34:72:00:78:56:e7:19:0d:01:e9:fe:7c:6a:d7:cb:c8:23:78:30:e7:73:76:63:4b:37:31:62:2e:af:30:d9:2e:22:a3:88:6f:f1:09:27:9d:98:30:da:c7:27:af:b9:4a:83:ee:6d:83:60:cb:df:a2:cc:06:40',
desc => 'SCRYPT' },
);
push @kdf_tests, @scrypt_tests unless disabled("scrypt");
plan tests => scalar @kdf_tests;
foreach (@kdf_tests) {
ok(compareline($_->{cmd}, $_->{expected}), $_->{desc});
}
# Check that the stdout output matches the expected value.
sub compareline {
my ($cmdarray, $expect) = @_;
if (defined($expect)) {
$expect = uc $expect;
}
my @lines = run(app($cmdarray), capture => 1);
if (defined($expect)) {
if ($lines[0] =~ m|^\Q${expect}\E\R$|) {
return 1;
} else {
print "Got: $lines[0]";
print "Exp: $expect\n";
return 0;
}
}
return 0;
}
+28 -1
View File
@@ -2388,14 +2388,41 @@ Operation = ENCRYPT
Plaintext = B41E6BE2EBA84A148E2EED84593C5EC7
Ciphertext = 9B9B7BFCD1813CB95D0B3618F40F5122
Title = Chacha20
Title = Chacha20 test vectors from RFC7539
# A.1 Test Vector 1
Cipher = chacha20
Key = 0000000000000000000000000000000000000000000000000000000000000000
IV = 00000000000000000000000000000000
Plaintext = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Ciphertext = 76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586
# A.1 Test Vector 2
Cipher = chacha20
Key = 0000000000000000000000000000000000000000000000000000000000000000
IV = 01000000000000000000000000000000
Plaintext = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Ciphertext = 9f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed29b721769ce64e43d57133b074d839d531ed1f28510afb45ace10a1f4b794d6f
# A.2 Test Vector 1 is the same as A.1 Test Vector 1
# A.2 Test Vector 2
Cipher = chacha20
Key = 0000000000000000000000000000000000000000000000000000000000000001
#Counter (first 4 bytes) expressed in little-endian order
IV = 01000000000000000000000000000002
Plaintext = 416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f
Ciphertext = a3fbf07df3fa2fde4f376ca23e82737041605d9f4f4f57bd8cff2c1d4b7955ec2a97948bd3722915c8f3d337f7d370050e9e96d647b7c39f56e031ca5eb6250d4042e02785ececfa4b4bb5e8ead0440e20b6e8db09d881a7c6132f420e52795042bdfa7773d8a9051447b3291ce1411c680465552aa6c405b7764d5e87bea85ad00f8449ed8f72d0d662ab052691ca66424bc86d2df80ea41f43abf937d3259dc4b2d0dfb48a6c9139ddd7f76966e928e635553ba76c5c879d7b35d49eb2e62b0871cdac638939e25e8a1e0ef9d5280fa8ca328b351c3c765989cbcf3daa8b6ccc3aaf9f3979c92b3720fc88dc95ed84a1be059c6499b9fda236e7e818b04b0bc39c1e876b193bfe5569753f88128cc08aaa9b63d1a16f80ef2554d7189c411f5869ca52c5b83fa36ff216b9c1d30062bebcfd2dc5bce0911934fda79a86f6e698ced759c3ff9b6477338f3da4f9cd8514ea9982ccafb341b2384dd902f3d1ab7ac61dd29c6f21ba5b862f3730e37cfdc4fd806c22f221
# A.2 Test Vector 3
Cipher = chacha20
Key = 1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0
#Counter (first 4 bytes) expressed in little-endian order
IV = 2a000000000000000000000000000002
Plaintext = 2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e
Ciphertext = 62e6347f95ed87a45ffae7426f27a1df5fb69110044c0d73118effa95b01e5cf166d3df2d721caf9b21e5fb14c616871fd84c54f9d65b283196c7fe4f60553ebf39c6402c42234e32a356b3e764312a61a5532055716ead6962568f87d3f3f7704c6a8d1bcd1bf4d50d6154b6da731b187b58dfd728afa36757a797ac188d1
Title = Chacha20
Cipher = chacha20
Key = 0000000000000000000000000000000000000000000000000000000000000001
IV = 00000000000000000000000000000000
+2 -1
View File
@@ -72,7 +72,8 @@ if ( $internal ) {
die "Extra parameters given.\n" if @ARGV;
$config = "crypto/err/openssl.ec" unless defined $config;
@source = ( glob('crypto/*.c'), glob('crypto/*/*.c'),
glob('ssl/*.c'), glob('ssl/*/*.c') );
glob('ssl/*.c'), glob('ssl/*/*.c'), glob('providers/*.c'),
glob('providers/*/*.c'), glob('providers/*/*/*.c') );
} else {
die "Configuration file not given.\nSee '$0 -help' for information\n"
unless defined $config;
+5 -1
View File
@@ -4796,4 +4796,8 @@ EVP_MD_fetch 4743 3_0_0 EXIST::FUNCTION:
EVP_set_default_properties 4744 3_0_0 EXIST::FUNCTION:
OSSL_PARAM_construct_end 4745 3_0_0 EXIST::FUNCTION:
EC_GROUP_check_named_curve 4746 3_0_0 EXIST::FUNCTION:EC
EVP_chacha20_poly1305_draft 4747 3_0_0 EXIST::FUNCTION:CHACHA,POLY1305
EVP_CIPHER_upref 4747 3_0_0 EXIST::FUNCTION:
EVP_CIPHER_fetch 4748 3_0_0 EXIST::FUNCTION:
EVP_CIPHER_mode 4749 3_0_0 EXIST::FUNCTION:
OPENSSL_info 4750 3_0_0 EXIST::FUNCTION:
EVP_chacha20_poly1305_draft 4751 3_0_0 EXIST::FUNCTION:CHACHA,POLY1305
+2 -1
View File
@@ -114,7 +114,8 @@ if ( $internal ) {
die "Cannot mix -internal and -static\n" if $static;
die "Extra parameters given.\n" if @ARGV;
@source = ( glob('crypto/*.c'), glob('crypto/*/*.c'),
glob('ssl/*.c'), glob('ssl/*/*.c') );
glob('ssl/*.c'), glob('ssl/*/*.c'), glob('providers/*.c'),
glob('providers/*/*.c'), glob('providers/*/*/*.c') );
} else {
die "-module isn't useful without -internal\n" if scalar keys %modules > 0;
@source = @ARGV;