Latest update
This commit is contained in:
@@ -9,6 +9,26 @@
|
|||||||
|
|
||||||
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
|
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
|
||||||
|
|
||||||
|
*) Added property based algorithm implementation selection framework to
|
||||||
|
the core.
|
||||||
|
[Paul Dale]
|
||||||
|
|
||||||
|
*) Added SCA hardening for modular field inversion in EC_GROUP through
|
||||||
|
a new dedicated field_inv() pointer in EC_METHOD.
|
||||||
|
This also addresses a leakage affecting conversions from projective
|
||||||
|
to affine coordinates.
|
||||||
|
[Billy Bob Brumley, Nicola Tuveri]
|
||||||
|
|
||||||
|
*) Added EVP_KDF, an EVP layer KDF API, to simplify adding KDF and PRF
|
||||||
|
implementations. This includes an EVP_PKEY to EVP_KDF bridge for
|
||||||
|
those algorithms that were already supported through the EVP_PKEY API
|
||||||
|
(scrypt, TLS1 PRF and HKDF). The low-level KDF functions for PBKDF2
|
||||||
|
and scrypt are now wrappers that call EVP_KDF.
|
||||||
|
[David Makepeace]
|
||||||
|
|
||||||
|
*) Build devcrypto engine as a dynamic engine.
|
||||||
|
[Eneas U de Queiroz]
|
||||||
|
|
||||||
*) Add keyed BLAKE2 to EVP_MAC.
|
*) Add keyed BLAKE2 to EVP_MAC.
|
||||||
[Antoine Salon]
|
[Antoine Salon]
|
||||||
|
|
||||||
@@ -109,6 +129,19 @@
|
|||||||
applications with zero-copy system calls such as sendfile and splice.
|
applications with zero-copy system calls such as sendfile and splice.
|
||||||
[Boris Pismenny]
|
[Boris Pismenny]
|
||||||
|
|
||||||
|
Changes between 1.1.1a and 1.1.1b [xx XXX xxxx]
|
||||||
|
|
||||||
|
*) Change the info callback signals for the start and end of a post-handshake
|
||||||
|
message exchange in TLSv1.3. In 1.1.1/1.1.1a we used SSL_CB_HANDSHAKE_START
|
||||||
|
and SSL_CB_HANDSHAKE_DONE. Experience has shown that many applications get
|
||||||
|
confused by this and assume that a TLSv1.2 renegotiation has started. This
|
||||||
|
can break KeyUpdate handling. Instead we no longer signal the start and end
|
||||||
|
of a post handshake message exchange (although the messages themselves are
|
||||||
|
still signalled). This could break some applications that were expecting
|
||||||
|
the old signals. However without this KeyUpdate is not usable for many
|
||||||
|
applications.
|
||||||
|
[Matt Caswell]
|
||||||
|
|
||||||
Changes between 1.1.1 and 1.1.1a [20 Nov 2018]
|
Changes between 1.1.1 and 1.1.1a [20 Nov 2018]
|
||||||
|
|
||||||
*) Timing vulnerability in DSA signature generation
|
*) Timing vulnerability in DSA signature generation
|
||||||
|
|||||||
@@ -1098,7 +1098,7 @@ my %targets = (
|
|||||||
dso_scheme => "dlfcn",
|
dso_scheme => "dlfcn",
|
||||||
shared_target => "aix",
|
shared_target => "aix",
|
||||||
module_ldflags => "-Wl,-G,-bsymbolic,-bexpall",
|
module_ldflags => "-Wl,-G,-bsymbolic,-bexpall",
|
||||||
shared_ldflag => "-Wl,-G,-bsymbolic",
|
shared_ldflag => "-Wl,-G,-bsymbolic,-bnoentry",
|
||||||
shared_defflag => "-Wl,-bE:",
|
shared_defflag => "-Wl,-bE:",
|
||||||
perl_platform => 'AIX',
|
perl_platform => 'AIX',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -622,7 +622,7 @@ install_runtime_libs: build_libs
|
|||||||
: {- output_off() unless windowsdll(); "" -}; \
|
: {- output_off() unless windowsdll(); "" -}; \
|
||||||
$(ECHO) "install $$s -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
|
$(ECHO) "install $$s -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
|
||||||
cp $$s $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \
|
cp $$s $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \
|
||||||
chmod 644 $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \
|
chmod 755 $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \
|
||||||
mv -f $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new \
|
mv -f $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new \
|
||||||
$(DESTDIR)$(INSTALLTOP)/bin/$$fn; \
|
$(DESTDIR)$(INSTALLTOP)/bin/$$fn; \
|
||||||
: {- output_on() unless windowsdll(); "" -}{- output_off() if windowsdll(); "" -}; \
|
: {- output_on() unless windowsdll(); "" -}{- output_off() if windowsdll(); "" -}; \
|
||||||
@@ -721,7 +721,7 @@ generate: generate_apps generate_crypto_bn generate_crypto_objects \
|
|||||||
generate_crypto_conf generate_crypto_asn1 generate_fuzz_oids
|
generate_crypto_conf generate_crypto_asn1 generate_fuzz_oids
|
||||||
|
|
||||||
.PHONY: doc-nits
|
.PHONY: doc-nits
|
||||||
doc-nits:
|
doc-nits: build_generated
|
||||||
(cd $(SRCDIR); $(PERL) util/find-doc-nits -n -p ) >doc-nits
|
(cd $(SRCDIR); $(PERL) util/find-doc-nits -n -p ) >doc-nits
|
||||||
@if [ -s doc-nits ] ; then cat doc-nits ; exit 1; \
|
@if [ -s doc-nits ] ; then cat doc-nits ; exit 1; \
|
||||||
else echo 'doc-nits: no errors.'; rm doc-nits ; fi
|
else echo 'doc-nits: no errors.'; rm doc-nits ; fi
|
||||||
|
|||||||
@@ -145,6 +145,8 @@ my $gcc_devteam_warn = "-DDEBUG_UNUSED"
|
|||||||
# -Wlanguage-extension-token -- no, we use asm()
|
# -Wlanguage-extension-token -- no, we use asm()
|
||||||
# -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
|
# -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
|
||||||
# -Wextended-offsetof -- no, needed in CMS ASN1 code
|
# -Wextended-offsetof -- no, needed in CMS ASN1 code
|
||||||
|
# -Wunused-function -- no, it forces header use of safestack et al
|
||||||
|
# DEFINE macros
|
||||||
my $clang_devteam_warn = ""
|
my $clang_devteam_warn = ""
|
||||||
. " -Wswitch-default"
|
. " -Wswitch-default"
|
||||||
. " -Wno-parentheses-equality"
|
. " -Wno-parentheses-equality"
|
||||||
@@ -154,6 +156,7 @@ my $clang_devteam_warn = ""
|
|||||||
. " -Wincompatible-pointer-types-discards-qualifiers"
|
. " -Wincompatible-pointer-types-discards-qualifiers"
|
||||||
. " -Wmissing-variable-declarations"
|
. " -Wmissing-variable-declarations"
|
||||||
. " -Wno-unknown-warning-option"
|
. " -Wno-unknown-warning-option"
|
||||||
|
. " -Wno-unused-function"
|
||||||
;
|
;
|
||||||
|
|
||||||
# This adds backtrace information to the memory leak info. Is only used
|
# This adds backtrace information to the memory leak info. Is only used
|
||||||
@@ -749,7 +752,11 @@ while (@argvcopy)
|
|||||||
}
|
}
|
||||||
elsif (/^--strict-warnings$/)
|
elsif (/^--strict-warnings$/)
|
||||||
{
|
{
|
||||||
$strict_warnings = 1;
|
# Pretend that our strict flags is a C flag, and replace it
|
||||||
|
# with the proper flags later on
|
||||||
|
push @{$useradd{CFLAGS}}, '--ossl-strict-warnings';
|
||||||
|
push @{$useradd{CXXFLAGS}}, '--ossl-strict-warnings';
|
||||||
|
$strict_warnings=1;
|
||||||
}
|
}
|
||||||
elsif (/^--debug$/)
|
elsif (/^--debug$/)
|
||||||
{
|
{
|
||||||
@@ -1500,6 +1507,7 @@ $config{openssl_api_defines} = [
|
|||||||
"OPENSSL_MIN_API=".($apitable->{$config{api} // ""} // -1)
|
"OPENSSL_MIN_API=".($apitable->{$config{api} // ""} // -1)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
my @strict_warnings_collection=();
|
||||||
if ($strict_warnings)
|
if ($strict_warnings)
|
||||||
{
|
{
|
||||||
my $wopt;
|
my $wopt;
|
||||||
@@ -1507,25 +1515,16 @@ if ($strict_warnings)
|
|||||||
|
|
||||||
die "ERROR --strict-warnings requires gcc[>=4] or gcc-alike"
|
die "ERROR --strict-warnings requires gcc[>=4] or gcc-alike"
|
||||||
unless $gccver >= 4;
|
unless $gccver >= 4;
|
||||||
foreach $wopt (split /\s+/, $gcc_devteam_warn)
|
push @strict_warnings_collection, (split /\s+/, $gcc_devteam_warn);
|
||||||
{
|
push @strict_warnings_collection, (split /\s+/, $clang_devteam_warn)
|
||||||
push @{$config{cflags}}, $wopt
|
if (defined($predefined{__clang__}));
|
||||||
unless grep { $_ eq $wopt } @{$config{cflags}};
|
|
||||||
push @{$config{cxxflags}}, $wopt
|
|
||||||
if ($config{CXX}
|
|
||||||
&& !grep { $_ eq $wopt } @{$config{cxxflags}});
|
|
||||||
}
|
}
|
||||||
if (defined($predefined{__clang__}))
|
foreach (qw(CFLAGS CXXFLAGS))
|
||||||
{
|
{
|
||||||
foreach $wopt (split /\s+/, $clang_devteam_warn)
|
$useradd{$_} = [ map { $_ eq '--ossl-strict-warnings'
|
||||||
{
|
? @strict_warnings_collection
|
||||||
push @{$config{cflags}}, $wopt
|
: ( $_ ) }
|
||||||
unless grep { $_ eq $wopt } @{$config{cflags}};
|
@{$useradd{$_}} ];
|
||||||
push @{$config{cxxflags}}, $wopt
|
|
||||||
if ($config{CXX}
|
|
||||||
&& !grep { $_ eq $wopt } @{$config{cxxflags}});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unless ($disabled{"crypto-mdebug-backtrace"})
|
unless ($disabled{"crypto-mdebug-backtrace"})
|
||||||
|
|||||||
+2
-2
@@ -15,12 +15,12 @@
|
|||||||
IF[{- !$disabled{apps} -}]
|
IF[{- !$disabled{apps} -}]
|
||||||
LIBS{noinst}=libapps.a
|
LIBS{noinst}=libapps.a
|
||||||
SOURCE[libapps.a]={- join(" ", @apps_lib_src) -}
|
SOURCE[libapps.a]={- join(" ", @apps_lib_src) -}
|
||||||
INCLUDE[libapps.a]=.. ../include
|
INCLUDE[libapps.a]=.. ../include include
|
||||||
|
|
||||||
PROGRAMS=openssl
|
PROGRAMS=openssl
|
||||||
SOURCE[openssl]={- join(" ", @apps_init_src) -}
|
SOURCE[openssl]={- join(" ", @apps_init_src) -}
|
||||||
SOURCE[openssl]={- join(" ", @apps_openssl_src) -}
|
SOURCE[openssl]={- join(" ", @apps_openssl_src) -}
|
||||||
INCLUDE[openssl]=.. ../include
|
INCLUDE[openssl]=.. ../include include
|
||||||
DEPEND[openssl]=libapps.a ../libssl
|
DEPEND[openssl]=libapps.a ../libssl
|
||||||
|
|
||||||
IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-)/ -}]
|
IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-)/ -}]
|
||||||
|
|||||||
+2
-2
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#define COOKIE_SECRET_LENGTH 16
|
#define COOKIE_SECRET_LENGTH 16
|
||||||
|
|
||||||
VERIFY_CB_ARGS verify_args = { 0, 0, X509_V_OK, 0 };
|
VERIFY_CB_ARGS verify_args = { -1, 0, X509_V_OK, 0 };
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_SOCK
|
#ifndef OPENSSL_NO_SOCK
|
||||||
static unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
|
static unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
|
||||||
@@ -63,7 +63,7 @@ int verify_callback(int ok, X509_STORE_CTX *ctx)
|
|||||||
if (!ok) {
|
if (!ok) {
|
||||||
BIO_printf(bio_err, "verify error:num=%d:%s\n", err,
|
BIO_printf(bio_err, "verify error:num=%d:%s\n", err,
|
||||||
X509_verify_cert_error_string(err));
|
X509_verify_cert_error_string(err));
|
||||||
if (verify_args.depth >= depth) {
|
if (verify_args.depth < 0 || verify_args.depth >= depth) {
|
||||||
if (!verify_args.return_error)
|
if (!verify_args.return_error)
|
||||||
ok = 1;
|
ok = 1;
|
||||||
verify_args.error = err;
|
verify_args.error = err;
|
||||||
|
|||||||
+72
-3
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
* Copyright 2005 Nokia. All rights reserved.
|
* Copyright 2005 Nokia. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||||
@@ -75,6 +75,7 @@ static int ocsp_resp_cb(SSL *s, void *arg);
|
|||||||
#endif
|
#endif
|
||||||
static int ldap_ExtendedResponse_parse(const char *buf, long rem);
|
static int ldap_ExtendedResponse_parse(const char *buf, long rem);
|
||||||
static char *base64encode (const void *buf, size_t len);
|
static char *base64encode (const void *buf, size_t len);
|
||||||
|
static int is_dNS_name(const char *host);
|
||||||
|
|
||||||
static int saved_errno;
|
static int saved_errno;
|
||||||
|
|
||||||
@@ -1138,6 +1139,7 @@ int s_client_main(int argc, char **argv)
|
|||||||
goto opthelp;
|
goto opthelp;
|
||||||
break;
|
break;
|
||||||
case OPT_VERIFY_RET_ERROR:
|
case OPT_VERIFY_RET_ERROR:
|
||||||
|
verify = SSL_VERIFY_PEER;
|
||||||
verify_args.return_error = 1;
|
verify_args.return_error = 1;
|
||||||
break;
|
break;
|
||||||
case OPT_VERIFY_QUIET:
|
case OPT_VERIFY_QUIET:
|
||||||
@@ -2012,9 +2014,11 @@ int s_client_main(int argc, char **argv)
|
|||||||
SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
|
SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
|
||||||
|
|
||||||
if (!noservername && (servername != NULL || dane_tlsa_domain == NULL)) {
|
if (!noservername && (servername != NULL || dane_tlsa_domain == NULL)) {
|
||||||
if (servername == NULL)
|
if (servername == NULL) {
|
||||||
|
if(host == NULL || is_dNS_name(host))
|
||||||
servername = (host == NULL) ? "localhost" : host;
|
servername = (host == NULL) ? "localhost" : host;
|
||||||
if (!SSL_set_tlsext_host_name(con, servername)) {
|
}
|
||||||
|
if (servername != NULL && !SSL_set_tlsext_host_name(con, servername)) {
|
||||||
BIO_printf(bio_err, "Unable to set TLS servername extension.\n");
|
BIO_printf(bio_err, "Unable to set TLS servername extension.\n");
|
||||||
ERR_print_errors(bio_err);
|
ERR_print_errors(bio_err);
|
||||||
goto end;
|
goto end;
|
||||||
@@ -3553,4 +3557,69 @@ static char *base64encode (const void *buf, size_t len)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Host dNS Name verifier: used for checking that the hostname is in dNS format
|
||||||
|
* before setting it as SNI
|
||||||
|
*/
|
||||||
|
static int is_dNS_name(const char *host)
|
||||||
|
{
|
||||||
|
const size_t MAX_LABEL_LENGTH = 63;
|
||||||
|
size_t i;
|
||||||
|
int isdnsname = 0;
|
||||||
|
size_t length = strlen(host);
|
||||||
|
size_t label_length = 0;
|
||||||
|
int all_numeric = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deviation from strict DNS name syntax, also check names with '_'
|
||||||
|
* Check DNS name syntax, any '-' or '.' must be internal,
|
||||||
|
* and on either side of each '.' we can't have a '-' or '.'.
|
||||||
|
*
|
||||||
|
* If the name has just one label, we don't consider it a DNS name.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < length && label_length < MAX_LABEL_LENGTH; ++i) {
|
||||||
|
char c = host[i];
|
||||||
|
|
||||||
|
if ((c >= 'a' && c <= 'z')
|
||||||
|
|| (c >= 'A' && c <= 'Z')
|
||||||
|
|| c == '_') {
|
||||||
|
label_length += 1;
|
||||||
|
all_numeric = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
|
label_length += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dot and hyphen cannot be first or last. */
|
||||||
|
if (i > 0 && i < length - 1) {
|
||||||
|
if (c == '-') {
|
||||||
|
label_length += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Next to a dot the preceding and following characters must not be
|
||||||
|
* another dot or a hyphen. Otherwise, record that the name is
|
||||||
|
* plausible, since it has two or more labels.
|
||||||
|
*/
|
||||||
|
if (c == '.'
|
||||||
|
&& host[i + 1] != '.'
|
||||||
|
&& host[i - 1] != '-'
|
||||||
|
&& host[i + 1] != '-') {
|
||||||
|
label_length = 0;
|
||||||
|
isdnsname = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isdnsname = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dNS name must not be all numeric and labels must be shorter than 64 characters. */
|
||||||
|
isdnsname &= !all_numeric && !(label_length == MAX_LABEL_LENGTH);
|
||||||
|
|
||||||
|
return isdnsname;
|
||||||
|
}
|
||||||
#endif /* OPENSSL_NO_SOCK */
|
#endif /* OPENSSL_NO_SOCK */
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
The sparse_array.c file contains an implementation of a sparse array that
|
||||||
|
attempts to be both space and time efficient.
|
||||||
|
|
||||||
|
The sparse array is represented using a tree structure. Each node in the
|
||||||
|
tree contains a block of pointers to either the user supplied leaf values or
|
||||||
|
to another node.
|
||||||
|
|
||||||
|
There are a number of parameters used to define the block size:
|
||||||
|
|
||||||
|
OPENSSL_SA_BLOCK_BITS Specifies the number of bits covered by each block
|
||||||
|
SA_BLOCK_MAX Specifies the number of pointers in each block
|
||||||
|
SA_BLOCK_MASK Specifies a bit mask to perform modulo block size
|
||||||
|
SA_BLOCK_MAX_LEVELS Indicates the maximum possible height of the tree
|
||||||
|
|
||||||
|
These constants are inter-related:
|
||||||
|
SA_BLOCK_MAX = 2 ^ OPENSSL_SA_BLOCK_BITS
|
||||||
|
SA_BLOCK_MASK = SA_BLOCK_MAX - 1
|
||||||
|
SA_BLOCK_MAX_LEVELS = number of bits in size_t divided by
|
||||||
|
OPENSSL_SA_BLOCK_BITS rounded up to the next multiple
|
||||||
|
of OPENSSL_SA_BLOCK_BITS
|
||||||
|
|
||||||
|
OPENSSL_SA_BLOCK_BITS can be defined at compile time and this overrides the
|
||||||
|
built in setting.
|
||||||
|
|
||||||
|
As a space and performance optimisation, the height of the tree is usually
|
||||||
|
less than the maximum possible height. Only sufficient height is allocated to
|
||||||
|
accommodate the largest index added to the data structure.
|
||||||
|
|
||||||
|
The largest index used to add a value to the array determines the tree height:
|
||||||
|
|
||||||
|
+----------------------+---------------------+
|
||||||
|
| Largest Added Index | Height of Tree |
|
||||||
|
+----------------------+---------------------+
|
||||||
|
| SA_BLOCK_MAX - 1 | 1 |
|
||||||
|
| SA_BLOCK_MAX ^ 2 - 1 | 2 |
|
||||||
|
| SA_BLOCK_MAX ^ 3 - 1 | 3 |
|
||||||
|
| ... | ... |
|
||||||
|
| size_t max | SA_BLOCK_MAX_LEVELS |
|
||||||
|
+----------------------+---------------------+
|
||||||
|
|
||||||
|
The tree height is dynamically increased as needed based on additions.
|
||||||
|
|
||||||
|
An empty tree is represented by a NULL root pointer. Inserting a value at
|
||||||
|
index 0 results in the allocation of a top level node full of null pointers
|
||||||
|
except for the single pointer to the user's data (N = SA_BLOCK_MAX for
|
||||||
|
breviety):
|
||||||
|
|
||||||
|
+----+
|
||||||
|
|Root|
|
||||||
|
|Node|
|
||||||
|
+-+--+
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+-+-+---+---+---+---+
|
||||||
|
| 0 | 1 | 2 |...|N-1|
|
||||||
|
| |nil|nil|...|nil|
|
||||||
|
+-+-+---+---+---+---+
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+-+--+
|
||||||
|
|User|
|
||||||
|
|Data|
|
||||||
|
+----+
|
||||||
|
Index 0
|
||||||
|
|
||||||
|
|
||||||
|
Inserting at element 2N+1 creates a new root node and pushes down the old root
|
||||||
|
node. It then creates a second second level node to hold the pointer to the
|
||||||
|
user's new data:
|
||||||
|
|
||||||
|
+----+
|
||||||
|
|Root|
|
||||||
|
|Node|
|
||||||
|
+-+--+
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+-+-+---+---+---+---+
|
||||||
|
| 0 | 1 | 2 |...|N-1|
|
||||||
|
| |nil| |...|nil|
|
||||||
|
+-+-+---+-+-+---+---+
|
||||||
|
| |
|
||||||
|
| +------------------+
|
||||||
|
| |
|
||||||
|
v v
|
||||||
|
+-+-+---+---+---+---+ +-+-+---+---+---+---+
|
||||||
|
| 0 | 1 | 2 |...|N-1| | 0 | 1 | 2 |...|N-1|
|
||||||
|
|nil| |nil|...|nil| |nil| |nil|...|nil|
|
||||||
|
+-+-+---+---+---+---+ +---+-+-+---+---+---+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
v v
|
||||||
|
+-+--+ +-+--+
|
||||||
|
|User| |User|
|
||||||
|
|Data| |Data|
|
||||||
|
+----+ +----+
|
||||||
|
Index 0 Index 2N+1
|
||||||
|
|
||||||
|
|
||||||
|
The nodes themselves are allocated in a sparse manner. Only nodes which exist
|
||||||
|
along a path from the root of the tree to an added leaf will be allocated.
|
||||||
|
The complexity is hidden and nodes are allocated on an as needed basis.
|
||||||
|
Because the data is expected to be sparse this doesn't result in a large waste
|
||||||
|
of space.
|
||||||
|
|
||||||
|
Values can be removed from the sparse array by setting their index position to
|
||||||
|
NULL. The data structure does not attempt to reclaim nodes or reduce the
|
||||||
|
height of the tree on removal. For example, now setting index 0 to NULL would
|
||||||
|
result in:
|
||||||
|
|
||||||
|
+----+
|
||||||
|
|Root|
|
||||||
|
|Node|
|
||||||
|
+-+--+
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+-+-+---+---+---+---+
|
||||||
|
| 0 | 1 | 2 |...|N-1|
|
||||||
|
| |nil| |...|nil|
|
||||||
|
+-+-+---+-+-+---+---+
|
||||||
|
| |
|
||||||
|
| +------------------+
|
||||||
|
| |
|
||||||
|
v v
|
||||||
|
+-+-+---+---+---+---+ +-+-+---+---+---+---+
|
||||||
|
| 0 | 1 | 2 |...|N-1| | 0 | 1 | 2 |...|N-1|
|
||||||
|
|nil|nil|nil|...|nil| |nil| |nil|...|nil|
|
||||||
|
+---+---+---+---+---+ +---+-+-+---+---+---+
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+-+--+
|
||||||
|
|User|
|
||||||
|
|Data|
|
||||||
|
+----+
|
||||||
|
Index 2N+1
|
||||||
|
|
||||||
|
|
||||||
|
Accesses to elements in the sparse array take O(log n) time where n is the
|
||||||
|
largest element. The base of the logarithm is SA_BLOCK_MAX, so for moderately
|
||||||
|
small indices (e.g. NIDs), single level (constant time) access is achievable.
|
||||||
|
Space usage is O(minimum(m, n log(n)) where m is the number of elements in the
|
||||||
|
array.
|
||||||
|
|
||||||
|
Note: sparse arrays only include pointers to types. Thus, SPARSE_ARRAY_OF(char)
|
||||||
|
can be used to store a string.
|
||||||
@@ -76,7 +76,6 @@ $code=<<___;
|
|||||||
# define __ARM_ARCH__ __LINUX_ARM_ARCH__
|
# define __ARM_ARCH__ __LINUX_ARM_ARCH__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.text
|
|
||||||
#if defined(__thumb2__) && !defined(__APPLE__)
|
#if defined(__thumb2__) && !defined(__APPLE__)
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.thumb
|
.thumb
|
||||||
@@ -85,6 +84,8 @@ $code=<<___;
|
|||||||
#undef __thumb2__
|
#undef __thumb2__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
.type AES_Te,%object
|
.type AES_Te,%object
|
||||||
.align 5
|
.align 5
|
||||||
AES_Te:
|
AES_Te:
|
||||||
|
|||||||
+85
-49
@@ -1,5 +1,5 @@
|
|||||||
#! /usr/bin/env perl
|
#! /usr/bin/env perl
|
||||||
# Copyright 2010-2018 The OpenSSL Project Authors. All Rights Reserved.
|
# Copyright 2010-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License 2.0 (the "License"). You may not use
|
# 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
|
# this file except in compliance with the License. You can obtain a copy
|
||||||
@@ -34,6 +34,11 @@
|
|||||||
# instead, code path is chosen upon pre-process time, pass -mips32r2
|
# instead, code path is chosen upon pre-process time, pass -mips32r2
|
||||||
# or/and -msmartmips.
|
# or/and -msmartmips.
|
||||||
|
|
||||||
|
# February 2019
|
||||||
|
#
|
||||||
|
# Normalize MIPS32R2 AES table address calculation by always using EXT
|
||||||
|
# instruction. This reduces the standard codebase by another 10%.
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# There is a number of MIPS ABI in use, O32 and N32/64 are most
|
# There is a number of MIPS ABI in use, O32 and N32/64 are most
|
||||||
# widely used. Then there is a new contender: NUBI. It appears that if
|
# widely used. Then there is a new contender: NUBI. It appears that if
|
||||||
@@ -223,6 +228,33 @@ _mips_AES_encrypt:
|
|||||||
ext $i0,$s1,16,8
|
ext $i0,$s1,16,8
|
||||||
|
|
||||||
_xtr $i0,$s1,16-2
|
_xtr $i0,$s1,16-2
|
||||||
|
#else
|
||||||
|
#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
|
||||||
|
move $i0,$Tbl
|
||||||
|
move $i1,$Tbl
|
||||||
|
move $i2,$Tbl
|
||||||
|
move $i3,$Tbl
|
||||||
|
ext $t0,$s1,16,8
|
||||||
|
.Loop_enc:
|
||||||
|
ext $t1,$s2,16,8
|
||||||
|
ext $t2,$s3,16,8
|
||||||
|
ext $t3,$s0,16,8
|
||||||
|
$PTR_INS $i0,$t0,2,8
|
||||||
|
$PTR_INS $i1,$t1,2,8
|
||||||
|
$PTR_INS $i2,$t2,2,8
|
||||||
|
$PTR_INS $i3,$t3,2,8
|
||||||
|
lw $t0,0($i0) # Te1[s1>>16]
|
||||||
|
ext $t4,$s2,8,8
|
||||||
|
lw $t1,0($i1) # Te1[s2>>16]
|
||||||
|
ext $t5,$s3,8,8
|
||||||
|
lw $t2,0($i2) # Te1[s3>>16]
|
||||||
|
ext $t6,$s0,8,8
|
||||||
|
lw $t3,0($i3) # Te1[s0>>16]
|
||||||
|
ext $t7,$s1,8,8
|
||||||
|
$PTR_INS $i0,$t4,2,8
|
||||||
|
$PTR_INS $i1,$t5,2,8
|
||||||
|
$PTR_INS $i2,$t6,2,8
|
||||||
|
$PTR_INS $i3,$t7,2,8
|
||||||
#else
|
#else
|
||||||
_xtr $i0,$s1,16-2
|
_xtr $i0,$s1,16-2
|
||||||
.Loop_enc:
|
.Loop_enc:
|
||||||
@@ -237,16 +269,6 @@ _mips_AES_encrypt:
|
|||||||
$PTR_ADD $i1,$Tbl
|
$PTR_ADD $i1,$Tbl
|
||||||
$PTR_ADD $i2,$Tbl
|
$PTR_ADD $i2,$Tbl
|
||||||
$PTR_ADD $i3,$Tbl
|
$PTR_ADD $i3,$Tbl
|
||||||
#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
|
|
||||||
lw $t0,0($i0) # Te1[s1>>16]
|
|
||||||
_xtr $i0,$s2,8-2
|
|
||||||
lw $t1,0($i1) # Te1[s2>>16]
|
|
||||||
_xtr $i1,$s3,8-2
|
|
||||||
lw $t2,0($i2) # Te1[s3>>16]
|
|
||||||
_xtr $i2,$s0,8-2
|
|
||||||
lw $t3,0($i3) # Te1[s0>>16]
|
|
||||||
_xtr $i3,$s1,8-2
|
|
||||||
#else
|
|
||||||
lwl $t0,3($i0) # Te1[s1>>16]
|
lwl $t0,3($i0) # Te1[s1>>16]
|
||||||
lwl $t1,3($i1) # Te1[s2>>16]
|
lwl $t1,3($i1) # Te1[s2>>16]
|
||||||
lwl $t2,3($i2) # Te1[s3>>16]
|
lwl $t2,3($i2) # Te1[s3>>16]
|
||||||
@@ -259,7 +281,6 @@ _mips_AES_encrypt:
|
|||||||
_xtr $i2,$s0,8-2
|
_xtr $i2,$s0,8-2
|
||||||
lwr $t3,2($i3) # Te1[s0>>16]
|
lwr $t3,2($i3) # Te1[s0>>16]
|
||||||
_xtr $i3,$s1,8-2
|
_xtr $i3,$s1,8-2
|
||||||
#endif
|
|
||||||
and $i0,0x3fc
|
and $i0,0x3fc
|
||||||
and $i1,0x3fc
|
and $i1,0x3fc
|
||||||
and $i2,0x3fc
|
and $i2,0x3fc
|
||||||
@@ -268,6 +289,7 @@ _mips_AES_encrypt:
|
|||||||
$PTR_ADD $i1,$Tbl
|
$PTR_ADD $i1,$Tbl
|
||||||
$PTR_ADD $i2,$Tbl
|
$PTR_ADD $i2,$Tbl
|
||||||
$PTR_ADD $i3,$Tbl
|
$PTR_ADD $i3,$Tbl
|
||||||
|
#endif
|
||||||
#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
|
#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
|
||||||
rotr $t0,$t0,8
|
rotr $t0,$t0,8
|
||||||
rotr $t1,$t1,8
|
rotr $t1,$t1,8
|
||||||
@@ -275,22 +297,18 @@ _mips_AES_encrypt:
|
|||||||
rotr $t3,$t3,8
|
rotr $t3,$t3,8
|
||||||
# if defined(_MIPSEL)
|
# if defined(_MIPSEL)
|
||||||
lw $t4,0($i0) # Te2[s2>>8]
|
lw $t4,0($i0) # Te2[s2>>8]
|
||||||
_xtr $i0,$s3,0-2
|
ext $t8,$s3,0,8
|
||||||
lw $t5,0($i1) # Te2[s3>>8]
|
lw $t5,0($i1) # Te2[s3>>8]
|
||||||
_xtr $i1,$s0,0-2
|
ext $t9,$s0,0,8
|
||||||
lw $t6,0($i2) # Te2[s0>>8]
|
lw $t6,0($i2) # Te2[s0>>8]
|
||||||
_xtr $i2,$s1,0-2
|
ext $t10,$s1,0,8
|
||||||
lw $t7,0($i3) # Te2[s1>>8]
|
lw $t7,0($i3) # Te2[s1>>8]
|
||||||
_xtr $i3,$s2,0-2
|
ext $t11,$s2,0,8
|
||||||
|
$PTR_INS $i0,$t8,2,8
|
||||||
|
$PTR_INS $i1,$t9,2,8
|
||||||
|
$PTR_INS $i2,$t10,2,8
|
||||||
|
$PTR_INS $i3,$t11,2,8
|
||||||
|
|
||||||
and $i0,0x3fc
|
|
||||||
and $i1,0x3fc
|
|
||||||
and $i2,0x3fc
|
|
||||||
and $i3,0x3fc
|
|
||||||
$PTR_ADD $i0,$Tbl
|
|
||||||
$PTR_ADD $i1,$Tbl
|
|
||||||
$PTR_ADD $i2,$Tbl
|
|
||||||
$PTR_ADD $i3,$Tbl
|
|
||||||
lw $t8,0($i0) # Te3[s3]
|
lw $t8,0($i0) # Te3[s3]
|
||||||
$PTR_INS $i0,$s0,2,8
|
$PTR_INS $i0,$s0,2,8
|
||||||
lw $t9,0($i1) # Te3[s0]
|
lw $t9,0($i1) # Te3[s0]
|
||||||
@@ -411,6 +429,9 @@ _mips_AES_encrypt:
|
|||||||
xor $s3,$t3
|
xor $s3,$t3
|
||||||
.set noreorder
|
.set noreorder
|
||||||
bnez $cnt,.Loop_enc
|
bnez $cnt,.Loop_enc
|
||||||
|
#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
|
||||||
|
ext $t0,$s1,16,8
|
||||||
|
#endif
|
||||||
_xtr $i0,$s1,16-2
|
_xtr $i0,$s1,16-2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -811,6 +832,33 @@ _mips_AES_decrypt:
|
|||||||
ext $i0,$s3,16,8
|
ext $i0,$s3,16,8
|
||||||
|
|
||||||
_xtr $i0,$s3,16-2
|
_xtr $i0,$s3,16-2
|
||||||
|
#else
|
||||||
|
#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
|
||||||
|
move $i0,$Tbl
|
||||||
|
move $i1,$Tbl
|
||||||
|
move $i2,$Tbl
|
||||||
|
move $i3,$Tbl
|
||||||
|
ext $t0,$s3,16,8
|
||||||
|
.Loop_dec:
|
||||||
|
ext $t1,$s0,16,8
|
||||||
|
ext $t2,$s1,16,8
|
||||||
|
ext $t3,$s2,16,8
|
||||||
|
$PTR_INS $i0,$t0,2,8
|
||||||
|
$PTR_INS $i1,$t1,2,8
|
||||||
|
$PTR_INS $i2,$t2,2,8
|
||||||
|
$PTR_INS $i3,$t3,2,8
|
||||||
|
lw $t0,0($i0) # Td1[s3>>16]
|
||||||
|
ext $t4,$s2,8,8
|
||||||
|
lw $t1,0($i1) # Td1[s0>>16]
|
||||||
|
ext $t5,$s3,8,8
|
||||||
|
lw $t2,0($i2) # Td1[s1>>16]
|
||||||
|
ext $t6,$s0,8,8
|
||||||
|
lw $t3,0($i3) # Td1[s2>>16]
|
||||||
|
ext $t7,$s1,8,8
|
||||||
|
$PTR_INS $i0,$t4,2,8
|
||||||
|
$PTR_INS $i1,$t5,2,8
|
||||||
|
$PTR_INS $i2,$t6,2,8
|
||||||
|
$PTR_INS $i3,$t7,2,8
|
||||||
#else
|
#else
|
||||||
_xtr $i0,$s3,16-2
|
_xtr $i0,$s3,16-2
|
||||||
.Loop_dec:
|
.Loop_dec:
|
||||||
@@ -825,16 +873,6 @@ _mips_AES_decrypt:
|
|||||||
$PTR_ADD $i1,$Tbl
|
$PTR_ADD $i1,$Tbl
|
||||||
$PTR_ADD $i2,$Tbl
|
$PTR_ADD $i2,$Tbl
|
||||||
$PTR_ADD $i3,$Tbl
|
$PTR_ADD $i3,$Tbl
|
||||||
#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
|
|
||||||
lw $t0,0($i0) # Td1[s3>>16]
|
|
||||||
_xtr $i0,$s2,8-2
|
|
||||||
lw $t1,0($i1) # Td1[s0>>16]
|
|
||||||
_xtr $i1,$s3,8-2
|
|
||||||
lw $t2,0($i2) # Td1[s1>>16]
|
|
||||||
_xtr $i2,$s0,8-2
|
|
||||||
lw $t3,0($i3) # Td1[s2>>16]
|
|
||||||
_xtr $i3,$s1,8-2
|
|
||||||
#else
|
|
||||||
lwl $t0,3($i0) # Td1[s3>>16]
|
lwl $t0,3($i0) # Td1[s3>>16]
|
||||||
lwl $t1,3($i1) # Td1[s0>>16]
|
lwl $t1,3($i1) # Td1[s0>>16]
|
||||||
lwl $t2,3($i2) # Td1[s1>>16]
|
lwl $t2,3($i2) # Td1[s1>>16]
|
||||||
@@ -847,8 +885,6 @@ _mips_AES_decrypt:
|
|||||||
_xtr $i2,$s0,8-2
|
_xtr $i2,$s0,8-2
|
||||||
lwr $t3,2($i3) # Td1[s2>>16]
|
lwr $t3,2($i3) # Td1[s2>>16]
|
||||||
_xtr $i3,$s1,8-2
|
_xtr $i3,$s1,8-2
|
||||||
#endif
|
|
||||||
|
|
||||||
and $i0,0x3fc
|
and $i0,0x3fc
|
||||||
and $i1,0x3fc
|
and $i1,0x3fc
|
||||||
and $i2,0x3fc
|
and $i2,0x3fc
|
||||||
@@ -857,6 +893,7 @@ _mips_AES_decrypt:
|
|||||||
$PTR_ADD $i1,$Tbl
|
$PTR_ADD $i1,$Tbl
|
||||||
$PTR_ADD $i2,$Tbl
|
$PTR_ADD $i2,$Tbl
|
||||||
$PTR_ADD $i3,$Tbl
|
$PTR_ADD $i3,$Tbl
|
||||||
|
#endif
|
||||||
#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
|
#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
|
||||||
rotr $t0,$t0,8
|
rotr $t0,$t0,8
|
||||||
rotr $t1,$t1,8
|
rotr $t1,$t1,8
|
||||||
@@ -864,22 +901,17 @@ _mips_AES_decrypt:
|
|||||||
rotr $t3,$t3,8
|
rotr $t3,$t3,8
|
||||||
# if defined(_MIPSEL)
|
# if defined(_MIPSEL)
|
||||||
lw $t4,0($i0) # Td2[s2>>8]
|
lw $t4,0($i0) # Td2[s2>>8]
|
||||||
_xtr $i0,$s1,0-2
|
ext $t8,$s1,0,8
|
||||||
lw $t5,0($i1) # Td2[s3>>8]
|
lw $t5,0($i1) # Td2[s3>>8]
|
||||||
_xtr $i1,$s2,0-2
|
ext $t9,$s2,0,8
|
||||||
lw $t6,0($i2) # Td2[s0>>8]
|
lw $t6,0($i2) # Td2[s0>>8]
|
||||||
_xtr $i2,$s3,0-2
|
ext $t10,$s3,0,8
|
||||||
lw $t7,0($i3) # Td2[s1>>8]
|
lw $t7,0($i3) # Td2[s1>>8]
|
||||||
_xtr $i3,$s0,0-2
|
ext $t11,$s0,0,8
|
||||||
|
$PTR_INS $i0,$t8,2,8
|
||||||
and $i0,0x3fc
|
$PTR_INS $i1,$t9,2,8
|
||||||
and $i1,0x3fc
|
$PTR_INS $i2,$t10,2,8
|
||||||
and $i2,0x3fc
|
$PTR_INS $i3,$t11,2,8
|
||||||
and $i3,0x3fc
|
|
||||||
$PTR_ADD $i0,$Tbl
|
|
||||||
$PTR_ADD $i1,$Tbl
|
|
||||||
$PTR_ADD $i2,$Tbl
|
|
||||||
$PTR_ADD $i3,$Tbl
|
|
||||||
lw $t8,0($i0) # Td3[s1]
|
lw $t8,0($i0) # Td3[s1]
|
||||||
$PTR_INS $i0,$s0,2,8
|
$PTR_INS $i0,$s0,2,8
|
||||||
lw $t9,0($i1) # Td3[s2]
|
lw $t9,0($i1) # Td3[s2]
|
||||||
@@ -1001,6 +1033,10 @@ _mips_AES_decrypt:
|
|||||||
xor $s3,$t3
|
xor $s3,$t3
|
||||||
.set noreorder
|
.set noreorder
|
||||||
bnez $cnt,.Loop_dec
|
bnez $cnt,.Loop_dec
|
||||||
|
#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
|
||||||
|
ext $t0,$s3,16,8
|
||||||
|
#endif
|
||||||
|
|
||||||
_xtr $i0,$s3,16-2
|
_xtr $i0,$s3,16-2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -554,6 +554,7 @@ $code.=<<___;
|
|||||||
.type _x86_64_AES_encrypt_compact,\@abi-omnipotent
|
.type _x86_64_AES_encrypt_compact,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_x86_64_AES_encrypt_compact:
|
_x86_64_AES_encrypt_compact:
|
||||||
|
.cfi_startproc
|
||||||
lea 128($sbox),$inp # size optimization
|
lea 128($sbox),$inp # size optimization
|
||||||
mov 0-128($inp),$acc1 # prefetch Te4
|
mov 0-128($inp),$acc1 # prefetch Te4
|
||||||
mov 32-128($inp),$acc2
|
mov 32-128($inp),$acc2
|
||||||
@@ -587,6 +588,7 @@ $code.=<<___;
|
|||||||
xor 8($key),$s2
|
xor 8($key),$s2
|
||||||
xor 12($key),$s3
|
xor 12($key),$s3
|
||||||
.byte 0xf3,0xc3 # rep ret
|
.byte 0xf3,0xc3 # rep ret
|
||||||
|
.cfi_endproc
|
||||||
.size _x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact
|
.size _x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -1161,6 +1163,7 @@ $code.=<<___;
|
|||||||
.type _x86_64_AES_decrypt_compact,\@abi-omnipotent
|
.type _x86_64_AES_decrypt_compact,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_x86_64_AES_decrypt_compact:
|
_x86_64_AES_decrypt_compact:
|
||||||
|
.cfi_startproc
|
||||||
lea 128($sbox),$inp # size optimization
|
lea 128($sbox),$inp # size optimization
|
||||||
mov 0-128($inp),$acc1 # prefetch Td4
|
mov 0-128($inp),$acc1 # prefetch Td4
|
||||||
mov 32-128($inp),$acc2
|
mov 32-128($inp),$acc2
|
||||||
@@ -1203,6 +1206,7 @@ $code.=<<___;
|
|||||||
xor 8($key),$s2
|
xor 8($key),$s2
|
||||||
xor 12($key),$s3
|
xor 12($key),$s3
|
||||||
.byte 0xf3,0xc3 # rep ret
|
.byte 0xf3,0xc3 # rep ret
|
||||||
|
.cfi_endproc
|
||||||
.size _x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact
|
.size _x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -1365,6 +1369,7 @@ AES_set_encrypt_key:
|
|||||||
.type _x86_64_AES_set_encrypt_key,\@abi-omnipotent
|
.type _x86_64_AES_set_encrypt_key,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_x86_64_AES_set_encrypt_key:
|
_x86_64_AES_set_encrypt_key:
|
||||||
|
.cfi_startproc
|
||||||
mov %esi,%ecx # %ecx=bits
|
mov %esi,%ecx # %ecx=bits
|
||||||
mov %rdi,%rsi # %rsi=userKey
|
mov %rdi,%rsi # %rsi=userKey
|
||||||
mov %rdx,%rdi # %rdi=key
|
mov %rdx,%rdi # %rdi=key
|
||||||
@@ -1546,6 +1551,7 @@ $code.=<<___;
|
|||||||
mov \$-1,%rax
|
mov \$-1,%rax
|
||||||
.Lexit:
|
.Lexit:
|
||||||
.byte 0xf3,0xc3 # rep ret
|
.byte 0xf3,0xc3 # rep ret
|
||||||
|
.cfi_endproc
|
||||||
.size _x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key
|
.size _x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -1728,7 +1734,9 @@ AES_cbc_encrypt:
|
|||||||
cmp \$0,%rdx # check length
|
cmp \$0,%rdx # check length
|
||||||
je .Lcbc_epilogue
|
je .Lcbc_epilogue
|
||||||
pushfq
|
pushfq
|
||||||
.cfi_push 49 # %rflags
|
# This could be .cfi_push 49, but libunwind fails on registers it does not
|
||||||
|
# recognize. See https://bugzilla.redhat.com/show_bug.cgi?id=217087.
|
||||||
|
.cfi_adjust_cfa_offset 8
|
||||||
push %rbx
|
push %rbx
|
||||||
.cfi_push %rbx
|
.cfi_push %rbx
|
||||||
push %rbp
|
push %rbp
|
||||||
@@ -1751,6 +1759,7 @@ AES_cbc_encrypt:
|
|||||||
cmp \$0,%r9
|
cmp \$0,%r9
|
||||||
cmoveq %r10,$sbox
|
cmoveq %r10,$sbox
|
||||||
|
|
||||||
|
.cfi_remember_state
|
||||||
mov OPENSSL_ia32cap_P(%rip),%r10d
|
mov OPENSSL_ia32cap_P(%rip),%r10d
|
||||||
cmp \$$speed_limit,%rdx
|
cmp \$$speed_limit,%rdx
|
||||||
jb .Lcbc_slow_prologue
|
jb .Lcbc_slow_prologue
|
||||||
@@ -1986,6 +1995,7 @@ AES_cbc_encrypt:
|
|||||||
#--------------------------- SLOW ROUTINE ---------------------------#
|
#--------------------------- SLOW ROUTINE ---------------------------#
|
||||||
.align 16
|
.align 16
|
||||||
.Lcbc_slow_prologue:
|
.Lcbc_slow_prologue:
|
||||||
|
.cfi_restore_state
|
||||||
# allocate aligned stack frame...
|
# allocate aligned stack frame...
|
||||||
lea -88(%rsp),%rbp
|
lea -88(%rsp),%rbp
|
||||||
and \$-64,%rbp
|
and \$-64,%rbp
|
||||||
@@ -1997,8 +2007,10 @@ AES_cbc_encrypt:
|
|||||||
sub %r10,%rbp
|
sub %r10,%rbp
|
||||||
|
|
||||||
xchg %rsp,%rbp
|
xchg %rsp,%rbp
|
||||||
|
.cfi_def_cfa_register %rbp
|
||||||
#add \$8,%rsp # reserve for return address!
|
#add \$8,%rsp # reserve for return address!
|
||||||
mov %rbp,$_rsp # save %rsp
|
mov %rbp,$_rsp # save %rsp
|
||||||
|
.cfi_cfa_expression $_rsp,deref,+64
|
||||||
.Lcbc_slow_body:
|
.Lcbc_slow_body:
|
||||||
#mov %rdi,$_inp # save copy of inp
|
#mov %rdi,$_inp # save copy of inp
|
||||||
#mov %rsi,$_out # save copy of out
|
#mov %rsi,$_out # save copy of out
|
||||||
@@ -2187,7 +2199,9 @@ AES_cbc_encrypt:
|
|||||||
.cfi_def_cfa %rsp,16
|
.cfi_def_cfa %rsp,16
|
||||||
.Lcbc_popfq:
|
.Lcbc_popfq:
|
||||||
popfq
|
popfq
|
||||||
.cfi_pop 49 # %rflags
|
# This could be .cfi_pop 49, but libunwind fails on registers it does not
|
||||||
|
# recognize. See https://bugzilla.redhat.com/show_bug.cgi?id=217087.
|
||||||
|
.cfi_adjust_cfa_offset -8
|
||||||
.Lcbc_epilogue:
|
.Lcbc_epilogue:
|
||||||
ret
|
ret
|
||||||
.cfi_endproc
|
.cfi_endproc
|
||||||
|
|||||||
@@ -274,6 +274,7 @@ $code.=<<___;
|
|||||||
.type ${PREFIX}_encrypt,\@abi-omnipotent
|
.type ${PREFIX}_encrypt,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
${PREFIX}_encrypt:
|
${PREFIX}_encrypt:
|
||||||
|
.cfi_startproc
|
||||||
movups ($inp),$inout0 # load input
|
movups ($inp),$inout0 # load input
|
||||||
mov 240($key),$rounds # key->rounds
|
mov 240($key),$rounds # key->rounds
|
||||||
___
|
___
|
||||||
@@ -284,12 +285,14 @@ $code.=<<___;
|
|||||||
movups $inout0,($out) # output
|
movups $inout0,($out) # output
|
||||||
pxor $inout0,$inout0
|
pxor $inout0,$inout0
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size ${PREFIX}_encrypt,.-${PREFIX}_encrypt
|
.size ${PREFIX}_encrypt,.-${PREFIX}_encrypt
|
||||||
|
|
||||||
.globl ${PREFIX}_decrypt
|
.globl ${PREFIX}_decrypt
|
||||||
.type ${PREFIX}_decrypt,\@abi-omnipotent
|
.type ${PREFIX}_decrypt,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
${PREFIX}_decrypt:
|
${PREFIX}_decrypt:
|
||||||
|
.cfi_startproc
|
||||||
movups ($inp),$inout0 # load input
|
movups ($inp),$inout0 # load input
|
||||||
mov 240($key),$rounds # key->rounds
|
mov 240($key),$rounds # key->rounds
|
||||||
___
|
___
|
||||||
@@ -300,6 +303,7 @@ $code.=<<___;
|
|||||||
movups $inout0,($out) # output
|
movups $inout0,($out) # output
|
||||||
pxor $inout0,$inout0
|
pxor $inout0,$inout0
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size ${PREFIX}_decrypt, .-${PREFIX}_decrypt
|
.size ${PREFIX}_decrypt, .-${PREFIX}_decrypt
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -325,6 +329,7 @@ $code.=<<___;
|
|||||||
.type _aesni_${dir}rypt2,\@abi-omnipotent
|
.type _aesni_${dir}rypt2,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_aesni_${dir}rypt2:
|
_aesni_${dir}rypt2:
|
||||||
|
.cfi_startproc
|
||||||
$movkey ($key),$rndkey0
|
$movkey ($key),$rndkey0
|
||||||
shl \$4,$rounds
|
shl \$4,$rounds
|
||||||
$movkey 16($key),$rndkey1
|
$movkey 16($key),$rndkey1
|
||||||
@@ -350,6 +355,7 @@ _aesni_${dir}rypt2:
|
|||||||
aes${dir}last $rndkey0,$inout0
|
aes${dir}last $rndkey0,$inout0
|
||||||
aes${dir}last $rndkey0,$inout1
|
aes${dir}last $rndkey0,$inout1
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _aesni_${dir}rypt2,.-_aesni_${dir}rypt2
|
.size _aesni_${dir}rypt2,.-_aesni_${dir}rypt2
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -361,6 +367,7 @@ $code.=<<___;
|
|||||||
.type _aesni_${dir}rypt3,\@abi-omnipotent
|
.type _aesni_${dir}rypt3,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_aesni_${dir}rypt3:
|
_aesni_${dir}rypt3:
|
||||||
|
.cfi_startproc
|
||||||
$movkey ($key),$rndkey0
|
$movkey ($key),$rndkey0
|
||||||
shl \$4,$rounds
|
shl \$4,$rounds
|
||||||
$movkey 16($key),$rndkey1
|
$movkey 16($key),$rndkey1
|
||||||
@@ -391,6 +398,7 @@ _aesni_${dir}rypt3:
|
|||||||
aes${dir}last $rndkey0,$inout1
|
aes${dir}last $rndkey0,$inout1
|
||||||
aes${dir}last $rndkey0,$inout2
|
aes${dir}last $rndkey0,$inout2
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _aesni_${dir}rypt3,.-_aesni_${dir}rypt3
|
.size _aesni_${dir}rypt3,.-_aesni_${dir}rypt3
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -406,6 +414,7 @@ $code.=<<___;
|
|||||||
.type _aesni_${dir}rypt4,\@abi-omnipotent
|
.type _aesni_${dir}rypt4,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_aesni_${dir}rypt4:
|
_aesni_${dir}rypt4:
|
||||||
|
.cfi_startproc
|
||||||
$movkey ($key),$rndkey0
|
$movkey ($key),$rndkey0
|
||||||
shl \$4,$rounds
|
shl \$4,$rounds
|
||||||
$movkey 16($key),$rndkey1
|
$movkey 16($key),$rndkey1
|
||||||
@@ -442,6 +451,7 @@ _aesni_${dir}rypt4:
|
|||||||
aes${dir}last $rndkey0,$inout2
|
aes${dir}last $rndkey0,$inout2
|
||||||
aes${dir}last $rndkey0,$inout3
|
aes${dir}last $rndkey0,$inout3
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _aesni_${dir}rypt4,.-_aesni_${dir}rypt4
|
.size _aesni_${dir}rypt4,.-_aesni_${dir}rypt4
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -453,6 +463,7 @@ $code.=<<___;
|
|||||||
.type _aesni_${dir}rypt6,\@abi-omnipotent
|
.type _aesni_${dir}rypt6,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_aesni_${dir}rypt6:
|
_aesni_${dir}rypt6:
|
||||||
|
.cfi_startproc
|
||||||
$movkey ($key),$rndkey0
|
$movkey ($key),$rndkey0
|
||||||
shl \$4,$rounds
|
shl \$4,$rounds
|
||||||
$movkey 16($key),$rndkey1
|
$movkey 16($key),$rndkey1
|
||||||
@@ -503,6 +514,7 @@ _aesni_${dir}rypt6:
|
|||||||
aes${dir}last $rndkey0,$inout4
|
aes${dir}last $rndkey0,$inout4
|
||||||
aes${dir}last $rndkey0,$inout5
|
aes${dir}last $rndkey0,$inout5
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _aesni_${dir}rypt6,.-_aesni_${dir}rypt6
|
.size _aesni_${dir}rypt6,.-_aesni_${dir}rypt6
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -514,6 +526,7 @@ $code.=<<___;
|
|||||||
.type _aesni_${dir}rypt8,\@abi-omnipotent
|
.type _aesni_${dir}rypt8,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_aesni_${dir}rypt8:
|
_aesni_${dir}rypt8:
|
||||||
|
.cfi_startproc
|
||||||
$movkey ($key),$rndkey0
|
$movkey ($key),$rndkey0
|
||||||
shl \$4,$rounds
|
shl \$4,$rounds
|
||||||
$movkey 16($key),$rndkey1
|
$movkey 16($key),$rndkey1
|
||||||
@@ -574,6 +587,7 @@ _aesni_${dir}rypt8:
|
|||||||
aes${dir}last $rndkey0,$inout6
|
aes${dir}last $rndkey0,$inout6
|
||||||
aes${dir}last $rndkey0,$inout7
|
aes${dir}last $rndkey0,$inout7
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _aesni_${dir}rypt8,.-_aesni_${dir}rypt8
|
.size _aesni_${dir}rypt8,.-_aesni_${dir}rypt8
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -598,6 +612,7 @@ $code.=<<___;
|
|||||||
.type aesni_ecb_encrypt,\@function,5
|
.type aesni_ecb_encrypt,\@function,5
|
||||||
.align 16
|
.align 16
|
||||||
aesni_ecb_encrypt:
|
aesni_ecb_encrypt:
|
||||||
|
.cfi_startproc
|
||||||
___
|
___
|
||||||
$code.=<<___ if ($win64);
|
$code.=<<___ if ($win64);
|
||||||
lea -0x58(%rsp),%rsp
|
lea -0x58(%rsp),%rsp
|
||||||
@@ -943,6 +958,7 @@ $code.=<<___ if ($win64);
|
|||||||
___
|
___
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size aesni_ecb_encrypt,.-aesni_ecb_encrypt
|
.size aesni_ecb_encrypt,.-aesni_ecb_encrypt
|
||||||
___
|
___
|
||||||
|
|
||||||
|
|||||||
@@ -53,18 +53,27 @@ open OUT,"| \"$^X\" $xlate $flavour $output";
|
|||||||
|
|
||||||
$prefix="aes_v8";
|
$prefix="aes_v8";
|
||||||
|
|
||||||
|
$_byte = ($flavour =~ /win/ ? "DCB" : ".byte");
|
||||||
|
|
||||||
$code=<<___;
|
$code=<<___;
|
||||||
#include "arm_arch.h"
|
#include "arm_arch.h"
|
||||||
|
|
||||||
#if __ARM_MAX_ARCH__>=7
|
#if __ARM_MAX_ARCH__>=7
|
||||||
.text
|
|
||||||
___
|
___
|
||||||
$code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/);
|
$code.=".arch armv8-a+crypto\n.text\n" if ($flavour =~ /64/);
|
||||||
$code.=<<___ if ($flavour !~ /64/);
|
$code.=<<___ if ($flavour !~ /64/);
|
||||||
.arch armv7-a // don't confuse not-so-latest binutils with argv8 :-)
|
.arch armv7-a // don't confuse not-so-latest binutils with argv8 :-)
|
||||||
.fpu neon
|
.fpu neon
|
||||||
|
#ifdef __thumb2__
|
||||||
|
.syntax unified
|
||||||
|
.thumb
|
||||||
|
# define INST(a,b,c,d) $_byte c,d|0xc,a,b
|
||||||
|
#else
|
||||||
.code 32
|
.code 32
|
||||||
#undef __thumb2__
|
# define INST(a,b,c,d) $_byte a,b,c,d
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
___
|
___
|
||||||
|
|
||||||
# Assembler mnemonics are an eclectic mix of 32- and 64-bit syntax,
|
# Assembler mnemonics are an eclectic mix of 32- and 64-bit syntax,
|
||||||
@@ -262,6 +271,7 @@ $code.=<<___;
|
|||||||
${prefix}_set_decrypt_key:
|
${prefix}_set_decrypt_key:
|
||||||
___
|
___
|
||||||
$code.=<<___ if ($flavour =~ /64/);
|
$code.=<<___ if ($flavour =~ /64/);
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
___
|
___
|
||||||
@@ -305,6 +315,7 @@ $code.=<<___ if ($flavour !~ /64/);
|
|||||||
___
|
___
|
||||||
$code.=<<___ if ($flavour =~ /64/);
|
$code.=<<___ if ($flavour =~ /64/);
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
___
|
___
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
@@ -953,7 +964,7 @@ if ($flavour =~ /64/) { ######## 64-bit code
|
|||||||
# since ARMv7 instructions are always encoded little-endian.
|
# since ARMv7 instructions are always encoded little-endian.
|
||||||
# correct solution is to use .inst directive, but older
|
# correct solution is to use .inst directive, but older
|
||||||
# assemblers don't implement it:-(
|
# assemblers don't implement it:-(
|
||||||
sprintf ".byte\t0x%02x,0x%02x,0x%02x,0x%02x\t@ %s %s",
|
sprintf "INST(0x%02x,0x%02x,0x%02x,0x%02x)\t@ %s %s",
|
||||||
$word&0xff,($word>>8)&0xff,
|
$word&0xff,($word>>8)&0xff,
|
||||||
($word>>16)&0xff,($word>>24)&0xff,
|
($word>>16)&0xff,($word>>24)&0xff,
|
||||||
$mnemonic,$arg;
|
$mnemonic,$arg;
|
||||||
@@ -994,14 +1005,17 @@ if ($flavour =~ /64/) { ######## 64-bit code
|
|||||||
s/\],#[0-9]+/]!/o;
|
s/\],#[0-9]+/]!/o;
|
||||||
|
|
||||||
s/[v]?(aes\w+)\s+([qv].*)/unaes($1,$2)/geo or
|
s/[v]?(aes\w+)\s+([qv].*)/unaes($1,$2)/geo or
|
||||||
s/cclr\s+([^,]+),\s*([a-z]+)/mov$2 $1,#0/o or
|
s/cclr\s+([^,]+),\s*([a-z]+)/mov.$2 $1,#0/o or
|
||||||
s/vtbl\.8\s+(.*)/unvtbl($1)/geo or
|
s/vtbl\.8\s+(.*)/unvtbl($1)/geo or
|
||||||
s/vdup\.32\s+(.*)/unvdup32($1)/geo or
|
s/vdup\.32\s+(.*)/unvdup32($1)/geo or
|
||||||
s/vmov\.32\s+(.*)/unvmov32($1)/geo or
|
s/vmov\.32\s+(.*)/unvmov32($1)/geo or
|
||||||
s/^(\s+)b\./$1b/o or
|
s/^(\s+)b\./$1b/o or
|
||||||
s/^(\s+)mov\./$1mov/o or
|
|
||||||
s/^(\s+)ret/$1bx\tlr/o;
|
s/^(\s+)ret/$1bx\tlr/o;
|
||||||
|
|
||||||
|
if (s/^(\s+)mov\.([a-z]+)/$1mov$2/) {
|
||||||
|
print " it $2\n";
|
||||||
|
}
|
||||||
|
|
||||||
print $_,"\n";
|
print $_,"\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -728,7 +728,6 @@ $code.=<<___;
|
|||||||
.arch armv7-a
|
.arch armv7-a
|
||||||
.fpu neon
|
.fpu neon
|
||||||
|
|
||||||
.text
|
|
||||||
.syntax unified @ ARMv7-capable assembler is expected to handle this
|
.syntax unified @ ARMv7-capable assembler is expected to handle this
|
||||||
#if defined(__thumb2__) && !defined(__APPLE__)
|
#if defined(__thumb2__) && !defined(__APPLE__)
|
||||||
.thumb
|
.thumb
|
||||||
@@ -737,6 +736,8 @@ $code.=<<___;
|
|||||||
# undef __thumb2__
|
# undef __thumb2__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
.type _bsaes_decrypt8,%function
|
.type _bsaes_decrypt8,%function
|
||||||
.align 4
|
.align 4
|
||||||
_bsaes_decrypt8:
|
_bsaes_decrypt8:
|
||||||
@@ -1125,9 +1126,9 @@ bsaes_cbc_encrypt:
|
|||||||
#ifndef __thumb__
|
#ifndef __thumb__
|
||||||
blo AES_cbc_encrypt
|
blo AES_cbc_encrypt
|
||||||
#else
|
#else
|
||||||
bhs 1f
|
bhs .Lcbc_do_bsaes
|
||||||
b AES_cbc_encrypt
|
b AES_cbc_encrypt
|
||||||
1:
|
.Lcbc_do_bsaes:
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -816,6 +816,7 @@ $code.=<<___;
|
|||||||
.type _bsaes_encrypt8,\@abi-omnipotent
|
.type _bsaes_encrypt8,\@abi-omnipotent
|
||||||
.align 64
|
.align 64
|
||||||
_bsaes_encrypt8:
|
_bsaes_encrypt8:
|
||||||
|
.cfi_startproc
|
||||||
lea .LBS0(%rip), $const # constants table
|
lea .LBS0(%rip), $const # constants table
|
||||||
|
|
||||||
movdqa ($key), @XMM[9] # round 0 key
|
movdqa ($key), @XMM[9] # round 0 key
|
||||||
@@ -875,11 +876,13 @@ $code.=<<___;
|
|||||||
pxor @XMM[8], @XMM[0]
|
pxor @XMM[8], @XMM[0]
|
||||||
pxor @XMM[8], @XMM[1]
|
pxor @XMM[8], @XMM[1]
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _bsaes_encrypt8,.-_bsaes_encrypt8
|
.size _bsaes_encrypt8,.-_bsaes_encrypt8
|
||||||
|
|
||||||
.type _bsaes_decrypt8,\@abi-omnipotent
|
.type _bsaes_decrypt8,\@abi-omnipotent
|
||||||
.align 64
|
.align 64
|
||||||
_bsaes_decrypt8:
|
_bsaes_decrypt8:
|
||||||
|
.cfi_startproc
|
||||||
lea .LBS0(%rip), $const # constants table
|
lea .LBS0(%rip), $const # constants table
|
||||||
|
|
||||||
movdqa ($key), @XMM[9] # round 0 key
|
movdqa ($key), @XMM[9] # round 0 key
|
||||||
@@ -937,6 +940,7 @@ $code.=<<___;
|
|||||||
pxor @XMM[8], @XMM[0]
|
pxor @XMM[8], @XMM[0]
|
||||||
pxor @XMM[8], @XMM[1]
|
pxor @XMM[8], @XMM[1]
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _bsaes_decrypt8,.-_bsaes_decrypt8
|
.size _bsaes_decrypt8,.-_bsaes_decrypt8
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -971,6 +975,7 @@ $code.=<<___;
|
|||||||
.type _bsaes_key_convert,\@abi-omnipotent
|
.type _bsaes_key_convert,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_bsaes_key_convert:
|
_bsaes_key_convert:
|
||||||
|
.cfi_startproc
|
||||||
lea .Lmasks(%rip), $const
|
lea .Lmasks(%rip), $const
|
||||||
movdqu ($inp), %xmm7 # load round 0 key
|
movdqu ($inp), %xmm7 # load round 0 key
|
||||||
lea 0x10($inp), $inp
|
lea 0x10($inp), $inp
|
||||||
@@ -1049,6 +1054,7 @@ _bsaes_key_convert:
|
|||||||
movdqa 0x50($const), %xmm7 # .L63
|
movdqa 0x50($const), %xmm7 # .L63
|
||||||
#movdqa %xmm6, ($out) # don't save last round key
|
#movdqa %xmm6, ($out) # don't save last round key
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _bsaes_key_convert,.-_bsaes_key_convert
|
.size _bsaes_key_convert,.-_bsaes_key_convert
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
|
|||||||
+156
-138
@@ -150,12 +150,12 @@ my ($sb1u,$sb1t,$sb2u,$sb2t) = map("v$_.16b",(24..27));
|
|||||||
my ($sb9u,$sb9t,$sbdu,$sbdt,$sbbu,$sbbt,$sbeu,$sbet)=map("v$_.16b",(24..31));
|
my ($sb9u,$sb9t,$sbdu,$sbdt,$sbbu,$sbbt,$sbeu,$sbet)=map("v$_.16b",(24..31));
|
||||||
|
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
##
|
//
|
||||||
## _aes_preheat
|
// _aes_preheat
|
||||||
##
|
//
|
||||||
## Fills register %r10 -> .aes_consts (so you can -fPIC)
|
// Fills register %r10 -> .aes_consts (so you can -fPIC)
|
||||||
## and %xmm9-%xmm15 as specified below.
|
// and %xmm9-%xmm15 as specified below.
|
||||||
##
|
//
|
||||||
.type _vpaes_encrypt_preheat,%function
|
.type _vpaes_encrypt_preheat,%function
|
||||||
.align 4
|
.align 4
|
||||||
_vpaes_encrypt_preheat:
|
_vpaes_encrypt_preheat:
|
||||||
@@ -167,21 +167,21 @@ _vpaes_encrypt_preheat:
|
|||||||
ret
|
ret
|
||||||
.size _vpaes_encrypt_preheat,.-_vpaes_encrypt_preheat
|
.size _vpaes_encrypt_preheat,.-_vpaes_encrypt_preheat
|
||||||
|
|
||||||
##
|
//
|
||||||
## _aes_encrypt_core
|
// _aes_encrypt_core
|
||||||
##
|
//
|
||||||
## AES-encrypt %xmm0.
|
// AES-encrypt %xmm0.
|
||||||
##
|
//
|
||||||
## Inputs:
|
// Inputs:
|
||||||
## %xmm0 = input
|
// %xmm0 = input
|
||||||
## %xmm9-%xmm15 as in _vpaes_preheat
|
// %xmm9-%xmm15 as in _vpaes_preheat
|
||||||
## (%rdx) = scheduled keys
|
// (%rdx) = scheduled keys
|
||||||
##
|
//
|
||||||
## Output in %xmm0
|
// Output in %xmm0
|
||||||
## Clobbers %xmm1-%xmm5, %r9, %r10, %r11, %rax
|
// Clobbers %xmm1-%xmm5, %r9, %r10, %r11, %rax
|
||||||
## Preserves %xmm6 - %xmm8 so you get some local vectors
|
// Preserves %xmm6 - %xmm8 so you get some local vectors
|
||||||
##
|
//
|
||||||
##
|
//
|
||||||
.type _vpaes_encrypt_core,%function
|
.type _vpaes_encrypt_core,%function
|
||||||
.align 4
|
.align 4
|
||||||
_vpaes_encrypt_core:
|
_vpaes_encrypt_core:
|
||||||
@@ -255,6 +255,7 @@ _vpaes_encrypt_core:
|
|||||||
.type vpaes_encrypt,%function
|
.type vpaes_encrypt,%function
|
||||||
.align 4
|
.align 4
|
||||||
vpaes_encrypt:
|
vpaes_encrypt:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -264,6 +265,7 @@ vpaes_encrypt:
|
|||||||
st1 {v0.16b}, [$out]
|
st1 {v0.16b}, [$out]
|
||||||
|
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size vpaes_encrypt,.-vpaes_encrypt
|
.size vpaes_encrypt,.-vpaes_encrypt
|
||||||
|
|
||||||
@@ -385,11 +387,11 @@ _vpaes_decrypt_preheat:
|
|||||||
ret
|
ret
|
||||||
.size _vpaes_decrypt_preheat,.-_vpaes_decrypt_preheat
|
.size _vpaes_decrypt_preheat,.-_vpaes_decrypt_preheat
|
||||||
|
|
||||||
##
|
//
|
||||||
## Decryption core
|
// Decryption core
|
||||||
##
|
//
|
||||||
## Same API as encryption core.
|
// Same API as encryption core.
|
||||||
##
|
//
|
||||||
.type _vpaes_decrypt_core,%function
|
.type _vpaes_decrypt_core,%function
|
||||||
.align 4
|
.align 4
|
||||||
_vpaes_decrypt_core:
|
_vpaes_decrypt_core:
|
||||||
@@ -486,6 +488,7 @@ _vpaes_decrypt_core:
|
|||||||
.type vpaes_decrypt,%function
|
.type vpaes_decrypt,%function
|
||||||
.align 4
|
.align 4
|
||||||
vpaes_decrypt:
|
vpaes_decrypt:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -495,6 +498,7 @@ vpaes_decrypt:
|
|||||||
st1 {v0.16b}, [$out]
|
st1 {v0.16b}, [$out]
|
||||||
|
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size vpaes_decrypt,.-vpaes_decrypt
|
.size vpaes_decrypt,.-vpaes_decrypt
|
||||||
|
|
||||||
@@ -639,11 +643,11 @@ my ($inp,$bits,$out,$dir)=("x0","w1","x2","w3");
|
|||||||
my ($invlo,$invhi,$iptlo,$ipthi,$rcon) = map("v$_.16b",(18..21,8));
|
my ($invlo,$invhi,$iptlo,$ipthi,$rcon) = map("v$_.16b",(18..21,8));
|
||||||
|
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
########################################################
|
////////////////////////////////////////////////////////
|
||||||
## ##
|
// //
|
||||||
## AES key schedule ##
|
// AES key schedule //
|
||||||
## ##
|
// //
|
||||||
########################################################
|
////////////////////////////////////////////////////////
|
||||||
.type _vpaes_key_preheat,%function
|
.type _vpaes_key_preheat,%function
|
||||||
.align 4
|
.align 4
|
||||||
_vpaes_key_preheat:
|
_vpaes_key_preheat:
|
||||||
@@ -665,6 +669,7 @@ _vpaes_key_preheat:
|
|||||||
.type _vpaes_schedule_core,%function
|
.type _vpaes_schedule_core,%function
|
||||||
.align 4
|
.align 4
|
||||||
_vpaes_schedule_core:
|
_vpaes_schedule_core:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29, x30, [sp,#-16]!
|
stp x29, x30, [sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -698,14 +703,14 @@ _vpaes_schedule_core:
|
|||||||
b.eq .Lschedule_192
|
b.eq .Lschedule_192
|
||||||
// 128: fall though
|
// 128: fall though
|
||||||
|
|
||||||
##
|
//
|
||||||
## .schedule_128
|
// .schedule_128
|
||||||
##
|
//
|
||||||
## 128-bit specific part of key schedule.
|
// 128-bit specific part of key schedule.
|
||||||
##
|
//
|
||||||
## This schedule is really simple, because all its parts
|
// This schedule is really simple, because all its parts
|
||||||
## are accomplished by the subroutines.
|
// are accomplished by the subroutines.
|
||||||
##
|
//
|
||||||
.Lschedule_128:
|
.Lschedule_128:
|
||||||
mov $inp, #10 // mov \$10, %esi
|
mov $inp, #10 // mov \$10, %esi
|
||||||
|
|
||||||
@@ -716,21 +721,21 @@ _vpaes_schedule_core:
|
|||||||
bl _vpaes_schedule_mangle // write output
|
bl _vpaes_schedule_mangle // write output
|
||||||
b .Loop_schedule_128
|
b .Loop_schedule_128
|
||||||
|
|
||||||
##
|
//
|
||||||
## .aes_schedule_192
|
// .aes_schedule_192
|
||||||
##
|
//
|
||||||
## 192-bit specific part of key schedule.
|
// 192-bit specific part of key schedule.
|
||||||
##
|
//
|
||||||
## The main body of this schedule is the same as the 128-bit
|
// The main body of this schedule is the same as the 128-bit
|
||||||
## schedule, but with more smearing. The long, high side is
|
// schedule, but with more smearing. The long, high side is
|
||||||
## stored in %xmm7 as before, and the short, low side is in
|
// stored in %xmm7 as before, and the short, low side is in
|
||||||
## the high bits of %xmm6.
|
// the high bits of %xmm6.
|
||||||
##
|
//
|
||||||
## This schedule is somewhat nastier, however, because each
|
// This schedule is somewhat nastier, however, because each
|
||||||
## round produces 192 bits of key material, or 1.5 round keys.
|
// round produces 192 bits of key material, or 1.5 round keys.
|
||||||
## Therefore, on each cycle we do 2 rounds and produce 3 round
|
// Therefore, on each cycle we do 2 rounds and produce 3 round
|
||||||
## keys.
|
// keys.
|
||||||
##
|
//
|
||||||
.align 4
|
.align 4
|
||||||
.Lschedule_192:
|
.Lschedule_192:
|
||||||
sub $inp, $inp, #8
|
sub $inp, $inp, #8
|
||||||
@@ -754,16 +759,16 @@ _vpaes_schedule_core:
|
|||||||
bl _vpaes_schedule_192_smear
|
bl _vpaes_schedule_192_smear
|
||||||
b .Loop_schedule_192
|
b .Loop_schedule_192
|
||||||
|
|
||||||
##
|
//
|
||||||
## .aes_schedule_256
|
// .aes_schedule_256
|
||||||
##
|
//
|
||||||
## 256-bit specific part of key schedule.
|
// 256-bit specific part of key schedule.
|
||||||
##
|
//
|
||||||
## The structure here is very similar to the 128-bit
|
// The structure here is very similar to the 128-bit
|
||||||
## schedule, but with an additional "low side" in
|
// schedule, but with an additional "low side" in
|
||||||
## %xmm6. The low side's rounds are the same as the
|
// %xmm6. The low side's rounds are the same as the
|
||||||
## high side's, except no rcon and no rotation.
|
// high side's, except no rcon and no rotation.
|
||||||
##
|
//
|
||||||
.align 4
|
.align 4
|
||||||
.Lschedule_256:
|
.Lschedule_256:
|
||||||
ld1 {v0.16b}, [$inp] // vmovdqu 16(%rdi),%xmm0 # load key part 2 (unaligned)
|
ld1 {v0.16b}, [$inp] // vmovdqu 16(%rdi),%xmm0 # load key part 2 (unaligned)
|
||||||
@@ -790,16 +795,16 @@ _vpaes_schedule_core:
|
|||||||
|
|
||||||
b .Loop_schedule_256
|
b .Loop_schedule_256
|
||||||
|
|
||||||
##
|
//
|
||||||
## .aes_schedule_mangle_last
|
// .aes_schedule_mangle_last
|
||||||
##
|
//
|
||||||
## Mangler for last round of key schedule
|
// Mangler for last round of key schedule
|
||||||
## Mangles %xmm0
|
// Mangles %xmm0
|
||||||
## when encrypting, outputs out(%xmm0) ^ 63
|
// when encrypting, outputs out(%xmm0) ^ 63
|
||||||
## when decrypting, outputs unskew(%xmm0)
|
// when decrypting, outputs unskew(%xmm0)
|
||||||
##
|
//
|
||||||
## Always called right before return... jumps to cleanup and exits
|
// Always called right before return... jumps to cleanup and exits
|
||||||
##
|
//
|
||||||
.align 4
|
.align 4
|
||||||
.Lschedule_mangle_last:
|
.Lschedule_mangle_last:
|
||||||
// schedule last round key from xmm0
|
// schedule last round key from xmm0
|
||||||
@@ -829,23 +834,24 @@ _vpaes_schedule_core:
|
|||||||
eor v6.16b, v6.16b, v6.16b // vpxor %xmm6, %xmm6, %xmm6
|
eor v6.16b, v6.16b, v6.16b // vpxor %xmm6, %xmm6, %xmm6
|
||||||
eor v7.16b, v7.16b, v7.16b // vpxor %xmm7, %xmm7, %xmm7
|
eor v7.16b, v7.16b, v7.16b // vpxor %xmm7, %xmm7, %xmm7
|
||||||
ldp x29, x30, [sp],#16
|
ldp x29, x30, [sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size _vpaes_schedule_core,.-_vpaes_schedule_core
|
.size _vpaes_schedule_core,.-_vpaes_schedule_core
|
||||||
|
|
||||||
##
|
//
|
||||||
## .aes_schedule_192_smear
|
// .aes_schedule_192_smear
|
||||||
##
|
//
|
||||||
## Smear the short, low side in the 192-bit key schedule.
|
// Smear the short, low side in the 192-bit key schedule.
|
||||||
##
|
//
|
||||||
## Inputs:
|
// Inputs:
|
||||||
## %xmm7: high side, b a x y
|
// %xmm7: high side, b a x y
|
||||||
## %xmm6: low side, d c 0 0
|
// %xmm6: low side, d c 0 0
|
||||||
## %xmm13: 0
|
// %xmm13: 0
|
||||||
##
|
//
|
||||||
## Outputs:
|
// Outputs:
|
||||||
## %xmm6: b+c+d b+c 0 0
|
// %xmm6: b+c+d b+c 0 0
|
||||||
## %xmm0: b+c+d b+c b a
|
// %xmm0: b+c+d b+c b a
|
||||||
##
|
//
|
||||||
.type _vpaes_schedule_192_smear,%function
|
.type _vpaes_schedule_192_smear,%function
|
||||||
.align 4
|
.align 4
|
||||||
_vpaes_schedule_192_smear:
|
_vpaes_schedule_192_smear:
|
||||||
@@ -861,24 +867,24 @@ _vpaes_schedule_192_smear:
|
|||||||
ret
|
ret
|
||||||
.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
|
.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
|
||||||
|
|
||||||
##
|
//
|
||||||
## .aes_schedule_round
|
// .aes_schedule_round
|
||||||
##
|
//
|
||||||
## Runs one main round of the key schedule on %xmm0, %xmm7
|
// Runs one main round of the key schedule on %xmm0, %xmm7
|
||||||
##
|
//
|
||||||
## Specifically, runs subbytes on the high dword of %xmm0
|
// Specifically, runs subbytes on the high dword of %xmm0
|
||||||
## then rotates it by one byte and xors into the low dword of
|
// then rotates it by one byte and xors into the low dword of
|
||||||
## %xmm7.
|
// %xmm7.
|
||||||
##
|
//
|
||||||
## Adds rcon from low byte of %xmm8, then rotates %xmm8 for
|
// Adds rcon from low byte of %xmm8, then rotates %xmm8 for
|
||||||
## next rcon.
|
// next rcon.
|
||||||
##
|
//
|
||||||
## Smears the dwords of %xmm7 by xoring the low into the
|
// Smears the dwords of %xmm7 by xoring the low into the
|
||||||
## second low, result into third, result into highest.
|
// second low, result into third, result into highest.
|
||||||
##
|
//
|
||||||
## Returns results in %xmm7 = %xmm0.
|
// Returns results in %xmm7 = %xmm0.
|
||||||
## Clobbers %xmm1-%xmm4, %r11.
|
// Clobbers %xmm1-%xmm4, %r11.
|
||||||
##
|
//
|
||||||
.type _vpaes_schedule_round,%function
|
.type _vpaes_schedule_round,%function
|
||||||
.align 4
|
.align 4
|
||||||
_vpaes_schedule_round:
|
_vpaes_schedule_round:
|
||||||
@@ -926,15 +932,15 @@ _vpaes_schedule_low_round:
|
|||||||
ret
|
ret
|
||||||
.size _vpaes_schedule_round,.-_vpaes_schedule_round
|
.size _vpaes_schedule_round,.-_vpaes_schedule_round
|
||||||
|
|
||||||
##
|
//
|
||||||
## .aes_schedule_transform
|
// .aes_schedule_transform
|
||||||
##
|
//
|
||||||
## Linear-transform %xmm0 according to tables at (%r11)
|
// Linear-transform %xmm0 according to tables at (%r11)
|
||||||
##
|
//
|
||||||
## Requires that %xmm9 = 0x0F0F... as in preheat
|
// Requires that %xmm9 = 0x0F0F... as in preheat
|
||||||
## Output in %xmm0
|
// Output in %xmm0
|
||||||
## Clobbers %xmm1, %xmm2
|
// Clobbers %xmm1, %xmm2
|
||||||
##
|
//
|
||||||
.type _vpaes_schedule_transform,%function
|
.type _vpaes_schedule_transform,%function
|
||||||
.align 4
|
.align 4
|
||||||
_vpaes_schedule_transform:
|
_vpaes_schedule_transform:
|
||||||
@@ -948,29 +954,29 @@ _vpaes_schedule_transform:
|
|||||||
ret
|
ret
|
||||||
.size _vpaes_schedule_transform,.-_vpaes_schedule_transform
|
.size _vpaes_schedule_transform,.-_vpaes_schedule_transform
|
||||||
|
|
||||||
##
|
//
|
||||||
## .aes_schedule_mangle
|
// .aes_schedule_mangle
|
||||||
##
|
//
|
||||||
## Mangle xmm0 from (basis-transformed) standard version
|
// Mangle xmm0 from (basis-transformed) standard version
|
||||||
## to our version.
|
// to our version.
|
||||||
##
|
//
|
||||||
## On encrypt,
|
// On encrypt,
|
||||||
## xor with 0x63
|
// xor with 0x63
|
||||||
## multiply by circulant 0,1,1,1
|
// multiply by circulant 0,1,1,1
|
||||||
## apply shiftrows transform
|
// apply shiftrows transform
|
||||||
##
|
//
|
||||||
## On decrypt,
|
// On decrypt,
|
||||||
## xor with 0x63
|
// xor with 0x63
|
||||||
## multiply by "inverse mixcolumns" circulant E,B,D,9
|
// multiply by "inverse mixcolumns" circulant E,B,D,9
|
||||||
## deskew
|
// deskew
|
||||||
## apply shiftrows transform
|
// apply shiftrows transform
|
||||||
##
|
//
|
||||||
##
|
//
|
||||||
## Writes out to (%rdx), and increments or decrements it
|
// Writes out to (%rdx), and increments or decrements it
|
||||||
## Keeps track of round number mod 4 in %r8
|
// Keeps track of round number mod 4 in %r8
|
||||||
## Preserves xmm0
|
// Preserves xmm0
|
||||||
## Clobbers xmm1-xmm5
|
// Clobbers xmm1-xmm5
|
||||||
##
|
//
|
||||||
.type _vpaes_schedule_mangle,%function
|
.type _vpaes_schedule_mangle,%function
|
||||||
.align 4
|
.align 4
|
||||||
_vpaes_schedule_mangle:
|
_vpaes_schedule_mangle:
|
||||||
@@ -1041,6 +1047,7 @@ _vpaes_schedule_mangle:
|
|||||||
.type vpaes_set_encrypt_key,%function
|
.type vpaes_set_encrypt_key,%function
|
||||||
.align 4
|
.align 4
|
||||||
vpaes_set_encrypt_key:
|
vpaes_set_encrypt_key:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp d8,d9,[sp,#-16]! // ABI spec says so
|
stp d8,d9,[sp,#-16]! // ABI spec says so
|
||||||
@@ -1056,6 +1063,7 @@ vpaes_set_encrypt_key:
|
|||||||
|
|
||||||
ldp d8,d9,[sp],#16
|
ldp d8,d9,[sp],#16
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size vpaes_set_encrypt_key,.-vpaes_set_encrypt_key
|
.size vpaes_set_encrypt_key,.-vpaes_set_encrypt_key
|
||||||
|
|
||||||
@@ -1063,6 +1071,7 @@ vpaes_set_encrypt_key:
|
|||||||
.type vpaes_set_decrypt_key,%function
|
.type vpaes_set_decrypt_key,%function
|
||||||
.align 4
|
.align 4
|
||||||
vpaes_set_decrypt_key:
|
vpaes_set_decrypt_key:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp d8,d9,[sp,#-16]! // ABI spec says so
|
stp d8,d9,[sp,#-16]! // ABI spec says so
|
||||||
@@ -1082,6 +1091,7 @@ vpaes_set_decrypt_key:
|
|||||||
|
|
||||||
ldp d8,d9,[sp],#16
|
ldp d8,d9,[sp],#16
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size vpaes_set_decrypt_key,.-vpaes_set_decrypt_key
|
.size vpaes_set_decrypt_key,.-vpaes_set_decrypt_key
|
||||||
___
|
___
|
||||||
@@ -1098,6 +1108,7 @@ vpaes_cbc_encrypt:
|
|||||||
cmp w5, #0 // check direction
|
cmp w5, #0 // check direction
|
||||||
b.eq vpaes_cbc_decrypt
|
b.eq vpaes_cbc_decrypt
|
||||||
|
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -1120,6 +1131,7 @@ vpaes_cbc_encrypt:
|
|||||||
st1 {v0.16b}, [$ivec] // write ivec
|
st1 {v0.16b}, [$ivec] // write ivec
|
||||||
|
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
.Lcbc_abort:
|
.Lcbc_abort:
|
||||||
ret
|
ret
|
||||||
.size vpaes_cbc_encrypt,.-vpaes_cbc_encrypt
|
.size vpaes_cbc_encrypt,.-vpaes_cbc_encrypt
|
||||||
@@ -1127,6 +1139,7 @@ vpaes_cbc_encrypt:
|
|||||||
.type vpaes_cbc_decrypt,%function
|
.type vpaes_cbc_decrypt,%function
|
||||||
.align 4
|
.align 4
|
||||||
vpaes_cbc_decrypt:
|
vpaes_cbc_decrypt:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp d8,d9,[sp,#-16]! // ABI spec says so
|
stp d8,d9,[sp,#-16]! // ABI spec says so
|
||||||
@@ -1168,6 +1181,7 @@ vpaes_cbc_decrypt:
|
|||||||
ldp d10,d11,[sp],#16
|
ldp d10,d11,[sp],#16
|
||||||
ldp d8,d9,[sp],#16
|
ldp d8,d9,[sp],#16
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size vpaes_cbc_decrypt,.-vpaes_cbc_decrypt
|
.size vpaes_cbc_decrypt,.-vpaes_cbc_decrypt
|
||||||
___
|
___
|
||||||
@@ -1177,6 +1191,7 @@ $code.=<<___;
|
|||||||
.type vpaes_ecb_encrypt,%function
|
.type vpaes_ecb_encrypt,%function
|
||||||
.align 4
|
.align 4
|
||||||
vpaes_ecb_encrypt:
|
vpaes_ecb_encrypt:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp d8,d9,[sp,#-16]! // ABI spec says so
|
stp d8,d9,[sp,#-16]! // ABI spec says so
|
||||||
@@ -1210,6 +1225,7 @@ vpaes_ecb_encrypt:
|
|||||||
ldp d10,d11,[sp],#16
|
ldp d10,d11,[sp],#16
|
||||||
ldp d8,d9,[sp],#16
|
ldp d8,d9,[sp],#16
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size vpaes_ecb_encrypt,.-vpaes_ecb_encrypt
|
.size vpaes_ecb_encrypt,.-vpaes_ecb_encrypt
|
||||||
|
|
||||||
@@ -1217,6 +1233,7 @@ vpaes_ecb_encrypt:
|
|||||||
.type vpaes_ecb_decrypt,%function
|
.type vpaes_ecb_decrypt,%function
|
||||||
.align 4
|
.align 4
|
||||||
vpaes_ecb_decrypt:
|
vpaes_ecb_decrypt:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp d8,d9,[sp,#-16]! // ABI spec says so
|
stp d8,d9,[sp,#-16]! // ABI spec says so
|
||||||
@@ -1250,6 +1267,7 @@ vpaes_ecb_decrypt:
|
|||||||
ldp d10,d11,[sp],#16
|
ldp d10,d11,[sp],#16
|
||||||
ldp d8,d9,[sp],#16
|
ldp d8,d9,[sp],#16
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size vpaes_ecb_decrypt,.-vpaes_ecb_decrypt
|
.size vpaes_ecb_decrypt,.-vpaes_ecb_decrypt
|
||||||
___
|
___
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ $code.=<<___;
|
|||||||
.type _vpaes_encrypt_core,\@abi-omnipotent
|
.type _vpaes_encrypt_core,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_vpaes_encrypt_core:
|
_vpaes_encrypt_core:
|
||||||
|
.cfi_startproc
|
||||||
mov %rdx, %r9
|
mov %rdx, %r9
|
||||||
mov \$16, %r11
|
mov \$16, %r11
|
||||||
mov 240(%rdx),%eax
|
mov 240(%rdx),%eax
|
||||||
@@ -171,6 +172,7 @@ _vpaes_encrypt_core:
|
|||||||
pxor %xmm4, %xmm0 # 0 = A
|
pxor %xmm4, %xmm0 # 0 = A
|
||||||
pshufb %xmm1, %xmm0
|
pshufb %xmm1, %xmm0
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _vpaes_encrypt_core,.-_vpaes_encrypt_core
|
.size _vpaes_encrypt_core,.-_vpaes_encrypt_core
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -181,6 +183,7 @@ _vpaes_encrypt_core:
|
|||||||
.type _vpaes_decrypt_core,\@abi-omnipotent
|
.type _vpaes_decrypt_core,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_vpaes_decrypt_core:
|
_vpaes_decrypt_core:
|
||||||
|
.cfi_startproc
|
||||||
mov %rdx, %r9 # load key
|
mov %rdx, %r9 # load key
|
||||||
mov 240(%rdx),%eax
|
mov 240(%rdx),%eax
|
||||||
movdqa %xmm9, %xmm1
|
movdqa %xmm9, %xmm1
|
||||||
@@ -277,6 +280,7 @@ _vpaes_decrypt_core:
|
|||||||
pxor %xmm4, %xmm0 # 0 = A
|
pxor %xmm4, %xmm0 # 0 = A
|
||||||
pshufb %xmm2, %xmm0
|
pshufb %xmm2, %xmm0
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _vpaes_decrypt_core,.-_vpaes_decrypt_core
|
.size _vpaes_decrypt_core,.-_vpaes_decrypt_core
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
@@ -287,6 +291,7 @@ _vpaes_decrypt_core:
|
|||||||
.type _vpaes_schedule_core,\@abi-omnipotent
|
.type _vpaes_schedule_core,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_vpaes_schedule_core:
|
_vpaes_schedule_core:
|
||||||
|
.cfi_startproc
|
||||||
# rdi = key
|
# rdi = key
|
||||||
# rsi = size in bits
|
# rsi = size in bits
|
||||||
# rdx = buffer
|
# rdx = buffer
|
||||||
@@ -453,6 +458,7 @@ _vpaes_schedule_core:
|
|||||||
pxor %xmm6, %xmm6
|
pxor %xmm6, %xmm6
|
||||||
pxor %xmm7, %xmm7
|
pxor %xmm7, %xmm7
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _vpaes_schedule_core,.-_vpaes_schedule_core
|
.size _vpaes_schedule_core,.-_vpaes_schedule_core
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -472,6 +478,7 @@ _vpaes_schedule_core:
|
|||||||
.type _vpaes_schedule_192_smear,\@abi-omnipotent
|
.type _vpaes_schedule_192_smear,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_vpaes_schedule_192_smear:
|
_vpaes_schedule_192_smear:
|
||||||
|
.cfi_startproc
|
||||||
pshufd \$0x80, %xmm6, %xmm1 # d c 0 0 -> c 0 0 0
|
pshufd \$0x80, %xmm6, %xmm1 # d c 0 0 -> c 0 0 0
|
||||||
pshufd \$0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a
|
pshufd \$0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a
|
||||||
pxor %xmm1, %xmm6 # -> c+d c 0 0
|
pxor %xmm1, %xmm6 # -> c+d c 0 0
|
||||||
@@ -480,6 +487,7 @@ _vpaes_schedule_192_smear:
|
|||||||
movdqa %xmm6, %xmm0
|
movdqa %xmm6, %xmm0
|
||||||
movhlps %xmm1, %xmm6 # clobber low side with zeros
|
movhlps %xmm1, %xmm6 # clobber low side with zeros
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
|
.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -503,6 +511,7 @@ _vpaes_schedule_192_smear:
|
|||||||
.type _vpaes_schedule_round,\@abi-omnipotent
|
.type _vpaes_schedule_round,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_vpaes_schedule_round:
|
_vpaes_schedule_round:
|
||||||
|
.cfi_startproc
|
||||||
# extract rcon from xmm8
|
# extract rcon from xmm8
|
||||||
pxor %xmm1, %xmm1
|
pxor %xmm1, %xmm1
|
||||||
palignr \$15, %xmm8, %xmm1
|
palignr \$15, %xmm8, %xmm1
|
||||||
@@ -556,6 +565,7 @@ _vpaes_schedule_low_round:
|
|||||||
pxor %xmm7, %xmm0
|
pxor %xmm7, %xmm0
|
||||||
movdqa %xmm0, %xmm7
|
movdqa %xmm0, %xmm7
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _vpaes_schedule_round,.-_vpaes_schedule_round
|
.size _vpaes_schedule_round,.-_vpaes_schedule_round
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -570,6 +580,7 @@ _vpaes_schedule_low_round:
|
|||||||
.type _vpaes_schedule_transform,\@abi-omnipotent
|
.type _vpaes_schedule_transform,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_vpaes_schedule_transform:
|
_vpaes_schedule_transform:
|
||||||
|
.cfi_startproc
|
||||||
movdqa %xmm9, %xmm1
|
movdqa %xmm9, %xmm1
|
||||||
pandn %xmm0, %xmm1
|
pandn %xmm0, %xmm1
|
||||||
psrld \$4, %xmm1
|
psrld \$4, %xmm1
|
||||||
@@ -580,6 +591,7 @@ _vpaes_schedule_transform:
|
|||||||
pshufb %xmm1, %xmm0
|
pshufb %xmm1, %xmm0
|
||||||
pxor %xmm2, %xmm0
|
pxor %xmm2, %xmm0
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _vpaes_schedule_transform,.-_vpaes_schedule_transform
|
.size _vpaes_schedule_transform,.-_vpaes_schedule_transform
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -608,6 +620,7 @@ _vpaes_schedule_transform:
|
|||||||
.type _vpaes_schedule_mangle,\@abi-omnipotent
|
.type _vpaes_schedule_mangle,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_vpaes_schedule_mangle:
|
_vpaes_schedule_mangle:
|
||||||
|
.cfi_startproc
|
||||||
movdqa %xmm0, %xmm4 # save xmm0 for later
|
movdqa %xmm0, %xmm4 # save xmm0 for later
|
||||||
movdqa .Lk_mc_forward(%rip),%xmm5
|
movdqa .Lk_mc_forward(%rip),%xmm5
|
||||||
test %rcx, %rcx
|
test %rcx, %rcx
|
||||||
@@ -672,6 +685,7 @@ _vpaes_schedule_mangle:
|
|||||||
and \$0x30, %r8
|
and \$0x30, %r8
|
||||||
movdqu %xmm3, (%rdx)
|
movdqu %xmm3, (%rdx)
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle
|
.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -681,6 +695,7 @@ _vpaes_schedule_mangle:
|
|||||||
.type ${PREFIX}_set_encrypt_key,\@function,3
|
.type ${PREFIX}_set_encrypt_key,\@function,3
|
||||||
.align 16
|
.align 16
|
||||||
${PREFIX}_set_encrypt_key:
|
${PREFIX}_set_encrypt_key:
|
||||||
|
.cfi_startproc
|
||||||
___
|
___
|
||||||
$code.=<<___ if ($win64);
|
$code.=<<___ if ($win64);
|
||||||
lea -0xb8(%rsp),%rsp
|
lea -0xb8(%rsp),%rsp
|
||||||
@@ -723,12 +738,14 @@ ___
|
|||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
xor %eax,%eax
|
xor %eax,%eax
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size ${PREFIX}_set_encrypt_key,.-${PREFIX}_set_encrypt_key
|
.size ${PREFIX}_set_encrypt_key,.-${PREFIX}_set_encrypt_key
|
||||||
|
|
||||||
.globl ${PREFIX}_set_decrypt_key
|
.globl ${PREFIX}_set_decrypt_key
|
||||||
.type ${PREFIX}_set_decrypt_key,\@function,3
|
.type ${PREFIX}_set_decrypt_key,\@function,3
|
||||||
.align 16
|
.align 16
|
||||||
${PREFIX}_set_decrypt_key:
|
${PREFIX}_set_decrypt_key:
|
||||||
|
.cfi_startproc
|
||||||
___
|
___
|
||||||
$code.=<<___ if ($win64);
|
$code.=<<___ if ($win64);
|
||||||
lea -0xb8(%rsp),%rsp
|
lea -0xb8(%rsp),%rsp
|
||||||
@@ -776,12 +793,14 @@ ___
|
|||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
xor %eax,%eax
|
xor %eax,%eax
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size ${PREFIX}_set_decrypt_key,.-${PREFIX}_set_decrypt_key
|
.size ${PREFIX}_set_decrypt_key,.-${PREFIX}_set_decrypt_key
|
||||||
|
|
||||||
.globl ${PREFIX}_encrypt
|
.globl ${PREFIX}_encrypt
|
||||||
.type ${PREFIX}_encrypt,\@function,3
|
.type ${PREFIX}_encrypt,\@function,3
|
||||||
.align 16
|
.align 16
|
||||||
${PREFIX}_encrypt:
|
${PREFIX}_encrypt:
|
||||||
|
.cfi_startproc
|
||||||
___
|
___
|
||||||
$code.=<<___ if ($win64);
|
$code.=<<___ if ($win64);
|
||||||
lea -0xb8(%rsp),%rsp
|
lea -0xb8(%rsp),%rsp
|
||||||
@@ -819,12 +838,14 @@ $code.=<<___ if ($win64);
|
|||||||
___
|
___
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size ${PREFIX}_encrypt,.-${PREFIX}_encrypt
|
.size ${PREFIX}_encrypt,.-${PREFIX}_encrypt
|
||||||
|
|
||||||
.globl ${PREFIX}_decrypt
|
.globl ${PREFIX}_decrypt
|
||||||
.type ${PREFIX}_decrypt,\@function,3
|
.type ${PREFIX}_decrypt,\@function,3
|
||||||
.align 16
|
.align 16
|
||||||
${PREFIX}_decrypt:
|
${PREFIX}_decrypt:
|
||||||
|
.cfi_startproc
|
||||||
___
|
___
|
||||||
$code.=<<___ if ($win64);
|
$code.=<<___ if ($win64);
|
||||||
lea -0xb8(%rsp),%rsp
|
lea -0xb8(%rsp),%rsp
|
||||||
@@ -862,6 +883,7 @@ $code.=<<___ if ($win64);
|
|||||||
___
|
___
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size ${PREFIX}_decrypt,.-${PREFIX}_decrypt
|
.size ${PREFIX}_decrypt,.-${PREFIX}_decrypt
|
||||||
___
|
___
|
||||||
{
|
{
|
||||||
@@ -874,6 +896,7 @@ $code.=<<___;
|
|||||||
.type ${PREFIX}_cbc_encrypt,\@function,6
|
.type ${PREFIX}_cbc_encrypt,\@function,6
|
||||||
.align 16
|
.align 16
|
||||||
${PREFIX}_cbc_encrypt:
|
${PREFIX}_cbc_encrypt:
|
||||||
|
.cfi_startproc
|
||||||
xchg $key,$len
|
xchg $key,$len
|
||||||
___
|
___
|
||||||
($len,$key)=($key,$len);
|
($len,$key)=($key,$len);
|
||||||
@@ -944,6 +967,7 @@ ___
|
|||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
.Lcbc_abort:
|
.Lcbc_abort:
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size ${PREFIX}_cbc_encrypt,.-${PREFIX}_cbc_encrypt
|
.size ${PREFIX}_cbc_encrypt,.-${PREFIX}_cbc_encrypt
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -957,6 +981,7 @@ $code.=<<___;
|
|||||||
.type _vpaes_preheat,\@abi-omnipotent
|
.type _vpaes_preheat,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
_vpaes_preheat:
|
_vpaes_preheat:
|
||||||
|
.cfi_startproc
|
||||||
lea .Lk_s0F(%rip), %r10
|
lea .Lk_s0F(%rip), %r10
|
||||||
movdqa -0x20(%r10), %xmm10 # .Lk_inv
|
movdqa -0x20(%r10), %xmm10 # .Lk_inv
|
||||||
movdqa -0x10(%r10), %xmm11 # .Lk_inv+16
|
movdqa -0x10(%r10), %xmm11 # .Lk_inv+16
|
||||||
@@ -966,6 +991,7 @@ _vpaes_preheat:
|
|||||||
movdqa 0x50(%r10), %xmm15 # .Lk_sb2
|
movdqa 0x50(%r10), %xmm15 # .Lk_sb2
|
||||||
movdqa 0x60(%r10), %xmm14 # .Lk_sb2+16
|
movdqa 0x60(%r10), %xmm14 # .Lk_sb2+16
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size _vpaes_preheat,.-_vpaes_preheat
|
.size _vpaes_preheat,.-_vpaes_preheat
|
||||||
########################################################
|
########################################################
|
||||||
## ##
|
## ##
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ open OUT,"| \"$^X\" $xlate $flavour $output";
|
|||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
#include "arm_arch.h"
|
#include "arm_arch.h"
|
||||||
|
|
||||||
.text
|
|
||||||
#if defined(__thumb2__) && !defined(__APPLE__)
|
#if defined(__thumb2__) && !defined(__APPLE__)
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.thumb
|
.thumb
|
||||||
@@ -30,6 +29,8 @@ $code.=<<___;
|
|||||||
#undef __thumb2__
|
#undef __thumb2__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
.align 5
|
.align 5
|
||||||
.global OPENSSL_atomic_add
|
.global OPENSSL_atomic_add
|
||||||
.type OPENSSL_atomic_add,%function
|
.type OPENSSL_atomic_add,%function
|
||||||
|
|||||||
@@ -253,9 +253,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
|
|||||||
}
|
}
|
||||||
# elif defined(OPENSSL_SYS_WIN32_CYGWIN)
|
# elif defined(OPENSSL_SYS_WIN32_CYGWIN)
|
||||||
int fd = fileno((FILE *)ptr);
|
int fd = fileno((FILE *)ptr);
|
||||||
if (num & BIO_FP_TEXT)
|
if (!(num & BIO_FP_TEXT))
|
||||||
setmode(fd, O_TEXT);
|
|
||||||
else
|
|
||||||
setmode(fd, O_BINARY);
|
setmode(fd, O_BINARY);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
@@ -279,11 +277,14 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32_CYGWIN)
|
# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS)
|
||||||
if (!(num & BIO_FP_TEXT))
|
if (!(num & BIO_FP_TEXT))
|
||||||
OPENSSL_strlcat(p, "b", sizeof(p));
|
OPENSSL_strlcat(p, "b", sizeof(p));
|
||||||
else
|
else
|
||||||
OPENSSL_strlcat(p, "t", sizeof(p));
|
OPENSSL_strlcat(p, "t", sizeof(p));
|
||||||
|
# elif defined(OPENSSL_SYS_WIN32_CYGWIN)
|
||||||
|
if (!(num & BIO_FP_TEXT))
|
||||||
|
OPENSSL_strlcat(p, "b", sizeof(p));
|
||||||
# endif
|
# endif
|
||||||
fp = openssl_fopen(ptr, p);
|
fp = openssl_fopen(ptr, p);
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
|
|||||||
@@ -57,13 +57,14 @@ if ($flavour && $flavour ne "void") {
|
|||||||
$code=<<___;
|
$code=<<___;
|
||||||
#include "arm_arch.h"
|
#include "arm_arch.h"
|
||||||
|
|
||||||
.text
|
|
||||||
#if defined(__thumb2__)
|
#if defined(__thumb2__)
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.thumb
|
.thumb
|
||||||
#else
|
#else
|
||||||
.code 32
|
.code 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
___
|
___
|
||||||
################
|
################
|
||||||
# private interface to mul_1x1_ialu
|
# private interface to mul_1x1_ialu
|
||||||
@@ -176,11 +177,13 @@ bn_GF2m_mul_2x2:
|
|||||||
#if __ARM_MAX_ARCH__>=7
|
#if __ARM_MAX_ARCH__>=7
|
||||||
stmdb sp!,{r10,lr}
|
stmdb sp!,{r10,lr}
|
||||||
ldr r12,.LOPENSSL_armcap
|
ldr r12,.LOPENSSL_armcap
|
||||||
|
# if !defined(_WIN32)
|
||||||
adr r10,.LOPENSSL_armcap
|
adr r10,.LOPENSSL_armcap
|
||||||
ldr r12,[r12,r10]
|
ldr r12,[r12,r10]
|
||||||
#ifdef __APPLE__
|
# endif
|
||||||
|
# if defined(__APPLE__) || defined(_WIN32)
|
||||||
ldr r12,[r12]
|
ldr r12,[r12]
|
||||||
#endif
|
# endif
|
||||||
tst r12,#ARMV7_NEON
|
tst r12,#ARMV7_NEON
|
||||||
itt ne
|
itt ne
|
||||||
ldrne r10,[sp],#8
|
ldrne r10,[sp],#8
|
||||||
@@ -310,7 +313,11 @@ $code.=<<___;
|
|||||||
#if __ARM_MAX_ARCH__>=7
|
#if __ARM_MAX_ARCH__>=7
|
||||||
.align 5
|
.align 5
|
||||||
.LOPENSSL_armcap:
|
.LOPENSSL_armcap:
|
||||||
|
# ifdef _WIN32
|
||||||
|
.word OPENSSL_armcap_P
|
||||||
|
# else
|
||||||
.word OPENSSL_armcap_P-.
|
.word OPENSSL_armcap_P-.
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
.asciz "GF(2^m) Multiplication for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
|
.asciz "GF(2^m) Multiplication for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
|
||||||
.align 5
|
.align 5
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ $_num="$num,#15*4"; $_bpend=$_num;
|
|||||||
$code=<<___;
|
$code=<<___;
|
||||||
#include "arm_arch.h"
|
#include "arm_arch.h"
|
||||||
|
|
||||||
.text
|
|
||||||
#if defined(__thumb2__)
|
#if defined(__thumb2__)
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.thumb
|
.thumb
|
||||||
@@ -105,10 +104,16 @@ $code=<<___;
|
|||||||
.code 32
|
.code 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
#if __ARM_MAX_ARCH__>=7
|
#if __ARM_MAX_ARCH__>=7
|
||||||
.align 5
|
.align 5
|
||||||
.LOPENSSL_armcap:
|
.LOPENSSL_armcap:
|
||||||
|
# ifdef _WIN32
|
||||||
|
.word OPENSSL_armcap_P
|
||||||
|
# else
|
||||||
.word OPENSSL_armcap_P-.Lbn_mul_mont
|
.word OPENSSL_armcap_P-.Lbn_mul_mont
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.global bn_mul_mont
|
.global bn_mul_mont
|
||||||
@@ -122,12 +127,14 @@ bn_mul_mont:
|
|||||||
#if __ARM_MAX_ARCH__>=7
|
#if __ARM_MAX_ARCH__>=7
|
||||||
tst ip,#7
|
tst ip,#7
|
||||||
bne .Lialu
|
bne .Lialu
|
||||||
adr r0,.Lbn_mul_mont
|
ldr r0,.LOPENSSL_armcap
|
||||||
ldr r2,.LOPENSSL_armcap
|
#if !defined(_WIN32)
|
||||||
|
adr r2,.Lbn_mul_mont
|
||||||
ldr r0,[r0,r2]
|
ldr r0,[r0,r2]
|
||||||
#ifdef __APPLE__
|
# endif
|
||||||
|
# if defined(__APPLE__) || defined(_WIN32)
|
||||||
ldr r0,[r0]
|
ldr r0,[r0]
|
||||||
#endif
|
# endif
|
||||||
tst r0,#ARMV7_NEON @ NEON available?
|
tst r0,#ARMV7_NEON @ NEON available?
|
||||||
ldmia sp, {r0,r2}
|
ldmia sp, {r0,r2}
|
||||||
beq .Lialu
|
beq .Lialu
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ bn_mul_mont:
|
|||||||
mul $nlo,$nj,$m1 // np[j]*m1
|
mul $nlo,$nj,$m1 // np[j]*m1
|
||||||
adds $lo1,$lo1,$lo0
|
adds $lo1,$lo1,$lo0
|
||||||
umulh $nhi,$nj,$m1
|
umulh $nhi,$nj,$m1
|
||||||
str $lo1,[$tp,#-16] // tp[j-1]
|
stur $lo1,[$tp,#-16] // tp[j-1]
|
||||||
cbnz $j,.Linner
|
cbnz $j,.Linner
|
||||||
|
|
||||||
.Linner_skip:
|
.Linner_skip:
|
||||||
@@ -253,13 +253,13 @@ bn_mul_mont:
|
|||||||
csel $nj,$tj,$aj,lo // did it borrow?
|
csel $nj,$tj,$aj,lo // did it borrow?
|
||||||
ldr $tj,[$tp],#8
|
ldr $tj,[$tp],#8
|
||||||
ldr $aj,[$rp],#8
|
ldr $aj,[$rp],#8
|
||||||
str xzr,[$tp,#-16] // wipe tp
|
stur xzr,[$tp,#-16] // wipe tp
|
||||||
str $nj,[$rp,#-16]
|
stur $nj,[$rp,#-16]
|
||||||
cbnz $num,.Lcond_copy
|
cbnz $num,.Lcond_copy
|
||||||
|
|
||||||
csel $nj,$tj,$aj,lo
|
csel $nj,$tj,$aj,lo
|
||||||
str xzr,[$tp,#-8] // wipe tp
|
stur xzr,[$tp,#-8] // wipe tp
|
||||||
str $nj,[$rp,#-8]
|
stur $nj,[$rp,#-8]
|
||||||
|
|
||||||
ldp x19,x20,[x29,#16]
|
ldp x19,x20,[x29,#16]
|
||||||
mov sp,x29
|
mov sp,x29
|
||||||
@@ -287,6 +287,7 @@ __bn_sqr8x_mont:
|
|||||||
cmp $ap,$bp
|
cmp $ap,$bp
|
||||||
b.ne __bn_mul4x_mont
|
b.ne __bn_mul4x_mont
|
||||||
.Lsqr8x_mont:
|
.Lsqr8x_mont:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-128]!
|
stp x29,x30,[sp,#-128]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp x19,x20,[sp,#16]
|
stp x19,x20,[sp,#16]
|
||||||
@@ -595,7 +596,7 @@ __bn_sqr8x_mont:
|
|||||||
ldp $a4,$a5,[$tp,#8*4]
|
ldp $a4,$a5,[$tp,#8*4]
|
||||||
ldp $a6,$a7,[$tp,#8*6]
|
ldp $a6,$a7,[$tp,#8*6]
|
||||||
adds $acc0,$acc0,$a0
|
adds $acc0,$acc0,$a0
|
||||||
ldr $n0,[$rp,#-8*8]
|
ldur $n0,[$rp,#-8*8]
|
||||||
adcs $acc1,$acc1,$a1
|
adcs $acc1,$acc1,$a1
|
||||||
ldp $a0,$a1,[$ap,#8*0]
|
ldp $a0,$a1,[$ap,#8*0]
|
||||||
adcs $acc2,$acc2,$a2
|
adcs $acc2,$acc2,$a2
|
||||||
@@ -793,7 +794,7 @@ $code.=<<___;
|
|||||||
//adc $carry,xzr,xzr // moved below
|
//adc $carry,xzr,xzr // moved below
|
||||||
cbz $cnt,.Lsqr8x8_post_condition
|
cbz $cnt,.Lsqr8x8_post_condition
|
||||||
|
|
||||||
ldr $n0,[$tp,#-8*8]
|
ldur $n0,[$tp,#-8*8]
|
||||||
ldp $a0,$a1,[$np,#8*0]
|
ldp $a0,$a1,[$np,#8*0]
|
||||||
ldp $a2,$a3,[$np,#8*2]
|
ldp $a2,$a3,[$np,#8*2]
|
||||||
ldp $a4,$a5,[$np,#8*4]
|
ldp $a4,$a5,[$np,#8*4]
|
||||||
@@ -851,7 +852,7 @@ $code.=<<___;
|
|||||||
ldp $a6,$a7,[$tp,#8*6]
|
ldp $a6,$a7,[$tp,#8*6]
|
||||||
cbz $cnt,.Lsqr8x_tail_break
|
cbz $cnt,.Lsqr8x_tail_break
|
||||||
|
|
||||||
ldr $n0,[$rp,#-8*8]
|
ldur $n0,[$rp,#-8*8]
|
||||||
adds $acc0,$acc0,$a0
|
adds $acc0,$acc0,$a0
|
||||||
adcs $acc1,$acc1,$a1
|
adcs $acc1,$acc1,$a1
|
||||||
ldp $a0,$a1,[$np,#8*0]
|
ldp $a0,$a1,[$np,#8*0]
|
||||||
@@ -1040,6 +1041,7 @@ $code.=<<___;
|
|||||||
ldp x25,x26,[x29,#64]
|
ldp x25,x26,[x29,#64]
|
||||||
ldp x27,x28,[x29,#80]
|
ldp x27,x28,[x29,#80]
|
||||||
ldr x29,[sp],#128
|
ldr x29,[sp],#128
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size __bn_sqr8x_mont,.-__bn_sqr8x_mont
|
.size __bn_sqr8x_mont,.-__bn_sqr8x_mont
|
||||||
___
|
___
|
||||||
@@ -1063,6 +1065,7 @@ $code.=<<___;
|
|||||||
.type __bn_mul4x_mont,%function
|
.type __bn_mul4x_mont,%function
|
||||||
.align 5
|
.align 5
|
||||||
__bn_mul4x_mont:
|
__bn_mul4x_mont:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-128]!
|
stp x29,x30,[sp,#-128]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp x19,x20,[sp,#16]
|
stp x19,x20,[sp,#16]
|
||||||
@@ -1496,6 +1499,7 @@ __bn_mul4x_mont:
|
|||||||
ldp x25,x26,[x29,#64]
|
ldp x25,x26,[x29,#64]
|
||||||
ldp x27,x28,[x29,#80]
|
ldp x27,x28,[x29,#80]
|
||||||
ldr x29,[sp],#128
|
ldr x29,[sp],#128
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size __bn_mul4x_mont,.-__bn_mul4x_mont
|
.size __bn_mul4x_mont,.-__bn_mul4x_mont
|
||||||
___
|
___
|
||||||
|
|||||||
@@ -1492,6 +1492,7 @@ $code.=<<___;
|
|||||||
.type rsaz_1024_red2norm_avx2,\@abi-omnipotent
|
.type rsaz_1024_red2norm_avx2,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
rsaz_1024_red2norm_avx2:
|
rsaz_1024_red2norm_avx2:
|
||||||
|
.cfi_startproc
|
||||||
sub \$-128,$inp # size optimization
|
sub \$-128,$inp # size optimization
|
||||||
xor %rax,%rax
|
xor %rax,%rax
|
||||||
___
|
___
|
||||||
@@ -1525,12 +1526,14 @@ ___
|
|||||||
}
|
}
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size rsaz_1024_red2norm_avx2,.-rsaz_1024_red2norm_avx2
|
.size rsaz_1024_red2norm_avx2,.-rsaz_1024_red2norm_avx2
|
||||||
|
|
||||||
.globl rsaz_1024_norm2red_avx2
|
.globl rsaz_1024_norm2red_avx2
|
||||||
.type rsaz_1024_norm2red_avx2,\@abi-omnipotent
|
.type rsaz_1024_norm2red_avx2,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
rsaz_1024_norm2red_avx2:
|
rsaz_1024_norm2red_avx2:
|
||||||
|
.cfi_startproc
|
||||||
sub \$-128,$out # size optimization
|
sub \$-128,$out # size optimization
|
||||||
mov ($inp),@T[0]
|
mov ($inp),@T[0]
|
||||||
mov \$0x1fffffff,%eax
|
mov \$0x1fffffff,%eax
|
||||||
@@ -1562,6 +1565,7 @@ $code.=<<___;
|
|||||||
mov @T[0],`8*($j+2)-128`($out)
|
mov @T[0],`8*($j+2)-128`($out)
|
||||||
mov @T[0],`8*($j+3)-128`($out)
|
mov @T[0],`8*($j+3)-128`($out)
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size rsaz_1024_norm2red_avx2,.-rsaz_1024_norm2red_avx2
|
.size rsaz_1024_norm2red_avx2,.-rsaz_1024_norm2red_avx2
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -1573,6 +1577,7 @@ $code.=<<___;
|
|||||||
.type rsaz_1024_scatter5_avx2,\@abi-omnipotent
|
.type rsaz_1024_scatter5_avx2,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
rsaz_1024_scatter5_avx2:
|
rsaz_1024_scatter5_avx2:
|
||||||
|
.cfi_startproc
|
||||||
vzeroupper
|
vzeroupper
|
||||||
vmovdqu .Lscatter_permd(%rip),%ymm5
|
vmovdqu .Lscatter_permd(%rip),%ymm5
|
||||||
shl \$4,$power
|
shl \$4,$power
|
||||||
@@ -1592,6 +1597,7 @@ rsaz_1024_scatter5_avx2:
|
|||||||
|
|
||||||
vzeroupper
|
vzeroupper
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size rsaz_1024_scatter5_avx2,.-rsaz_1024_scatter5_avx2
|
.size rsaz_1024_scatter5_avx2,.-rsaz_1024_scatter5_avx2
|
||||||
|
|
||||||
.globl rsaz_1024_gather5_avx2
|
.globl rsaz_1024_gather5_avx2
|
||||||
|
|||||||
@@ -2910,6 +2910,7 @@ bn_powerx5:
|
|||||||
.align 32
|
.align 32
|
||||||
bn_sqrx8x_internal:
|
bn_sqrx8x_internal:
|
||||||
__bn_sqrx8x_internal:
|
__bn_sqrx8x_internal:
|
||||||
|
.cfi_startproc
|
||||||
##################################################################
|
##################################################################
|
||||||
# Squaring part:
|
# Squaring part:
|
||||||
#
|
#
|
||||||
@@ -3542,6 +3543,7 @@ __bn_sqrx8x_reduction:
|
|||||||
cmp 8+8(%rsp),%r8 # end of t[]?
|
cmp 8+8(%rsp),%r8 # end of t[]?
|
||||||
jb .Lsqrx8x_reduction_loop
|
jb .Lsqrx8x_reduction_loop
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size bn_sqrx8x_internal,.-bn_sqrx8x_internal
|
.size bn_sqrx8x_internal,.-bn_sqrx8x_internal
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* 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
|
* 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
|
* this file except in compliance with the License. You can obtain a copy
|
||||||
@@ -227,6 +227,8 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx)
|
|||||||
}
|
}
|
||||||
/* OK, make sure the returned bignum is "zero" */
|
/* OK, make sure the returned bignum is "zero" */
|
||||||
BN_zero(ret);
|
BN_zero(ret);
|
||||||
|
/* clear BN_FLG_CONSTTIME if leaked from previous frames */
|
||||||
|
ret->flags &= (~BN_FLG_CONSTTIME);
|
||||||
ctx->used++;
|
ctx->used++;
|
||||||
CTXDBG_RET(ctx, ret);
|
CTXDBG_RET(ctx, ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
# Note that these directories are filtered in Configure. Look for %skipdir
|
# Note that these directories are filtered in Configure. Look for %skipdir
|
||||||
# there for further explanations.
|
# there for further explanations.
|
||||||
SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 x509v3 conf \
|
SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 x509v3 conf \
|
||||||
txt_db pkcs7 pkcs12 ui kdf store \
|
txt_db pkcs7 pkcs12 ui kdf store property \
|
||||||
md2 md4 md5 sha mdc2 gmac hmac ripemd whrlpool poly1305 blake2 \
|
md2 md4 md5 sha mdc2 gmac hmac ripemd whrlpool poly1305 blake2 \
|
||||||
siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \
|
siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \
|
||||||
seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \
|
seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \
|
||||||
@@ -12,8 +12,8 @@ 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 ex_data.c cpt_err.c \
|
||||||
ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fopen.c ctype.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 \
|
threads_pthread.c threads_win.c threads_none.c getenv.c \
|
||||||
o_init.c o_fips.c mem_sec.c init.c {- $target{cpuid_asm_src} -} \
|
o_init.c o_fips.c mem_sec.c init.c context.c sparse_array.c \
|
||||||
{- $target{uplink_aux_src} -}
|
{- $target{cpuid_asm_src} -} {- $target{uplink_aux_src} -}
|
||||||
|
|
||||||
DEPEND[cversion.o]=buildinf.h
|
DEPEND[cversion.o]=buildinf.h
|
||||||
GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q)" "$(PLATFORM)"
|
GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q)" "$(PLATFORM)"
|
||||||
|
|||||||
@@ -171,7 +171,6 @@ my @ret;
|
|||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
#include "arm_arch.h"
|
#include "arm_arch.h"
|
||||||
|
|
||||||
.text
|
|
||||||
#if defined(__thumb2__) || defined(__clang__)
|
#if defined(__thumb2__) || defined(__clang__)
|
||||||
.syntax unified
|
.syntax unified
|
||||||
#endif
|
#endif
|
||||||
@@ -185,6 +184,8 @@ $code.=<<___;
|
|||||||
#define ldrhsb ldrbhs
|
#define ldrhsb ldrbhs
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
.align 5
|
.align 5
|
||||||
.Lsigma:
|
.Lsigma:
|
||||||
.long 0x61707865,0x3320646e,0x79622d32,0x6b206574 @ endian-neutral
|
.long 0x61707865,0x3320646e,0x79622d32,0x6b206574 @ endian-neutral
|
||||||
@@ -192,7 +193,11 @@ $code.=<<___;
|
|||||||
.long 1,0,0,0
|
.long 1,0,0,0
|
||||||
#if __ARM_MAX_ARCH__>=7
|
#if __ARM_MAX_ARCH__>=7
|
||||||
.LOPENSSL_armcap:
|
.LOPENSSL_armcap:
|
||||||
|
# ifdef _WIN32
|
||||||
|
.word OPENSSL_armcap_P
|
||||||
|
# else
|
||||||
.word OPENSSL_armcap_P-.LChaCha20_ctr32
|
.word OPENSSL_armcap_P-.LChaCha20_ctr32
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
.word -1
|
.word -1
|
||||||
#endif
|
#endif
|
||||||
@@ -219,8 +224,10 @@ ChaCha20_ctr32:
|
|||||||
cmp r2,#192 @ test len
|
cmp r2,#192 @ test len
|
||||||
bls .Lshort
|
bls .Lshort
|
||||||
ldr r4,[r14,#-32]
|
ldr r4,[r14,#-32]
|
||||||
|
# if !defined(_WIN32)
|
||||||
ldr r4,[r14,r4]
|
ldr r4,[r14,r4]
|
||||||
# ifdef __APPLE__
|
# endif
|
||||||
|
# if defined(__APPLE__) || defined(_WIN32)
|
||||||
ldr r4,[r4]
|
ldr r4,[r4]
|
||||||
# endif
|
# endif
|
||||||
tst r4,#ARMV7_NEON
|
tst r4,#ARMV7_NEON
|
||||||
|
|||||||
@@ -131,12 +131,6 @@ $code.=<<___;
|
|||||||
.quad 0x3320646e61707865,0x6b20657479622d32 // endian-neutral
|
.quad 0x3320646e61707865,0x6b20657479622d32 // endian-neutral
|
||||||
.Lone:
|
.Lone:
|
||||||
.long 1,0,0,0
|
.long 1,0,0,0
|
||||||
.LOPENSSL_armcap_P:
|
|
||||||
#ifdef __ILP32__
|
|
||||||
.long OPENSSL_armcap_P-.
|
|
||||||
#else
|
|
||||||
.quad OPENSSL_armcap_P-.
|
|
||||||
#endif
|
|
||||||
.asciz "ChaCha20 for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
|
.asciz "ChaCha20 for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
|
||||||
|
|
||||||
.globl ChaCha20_ctr32
|
.globl ChaCha20_ctr32
|
||||||
@@ -144,19 +138,16 @@ $code.=<<___;
|
|||||||
.align 5
|
.align 5
|
||||||
ChaCha20_ctr32:
|
ChaCha20_ctr32:
|
||||||
cbz $len,.Labort
|
cbz $len,.Labort
|
||||||
adr @x[0],.LOPENSSL_armcap_P
|
|
||||||
cmp $len,#192
|
cmp $len,#192
|
||||||
b.lo .Lshort
|
b.lo .Lshort
|
||||||
#ifdef __ILP32__
|
|
||||||
ldrsw @x[1],[@x[0]]
|
adrp x17,OPENSSL_armcap_P
|
||||||
#else
|
ldr w17,[x17,#:lo12:OPENSSL_armcap_P]
|
||||||
ldr @x[1],[@x[0]]
|
|
||||||
#endif
|
|
||||||
ldr w17,[@x[1],@x[0]]
|
|
||||||
tst w17,#ARMV7_NEON
|
tst w17,#ARMV7_NEON
|
||||||
b.ne ChaCha20_neon
|
b.ne .LChaCha20_neon
|
||||||
|
|
||||||
.Lshort:
|
.Lshort:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-96]!
|
stp x29,x30,[sp,#-96]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -276,6 +267,7 @@ $code.=<<___;
|
|||||||
ldp x25,x26,[x29,#64]
|
ldp x25,x26,[x29,#64]
|
||||||
ldp x27,x28,[x29,#80]
|
ldp x27,x28,[x29,#80]
|
||||||
ldp x29,x30,[sp],#96
|
ldp x29,x30,[sp],#96
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
.Labort:
|
.Labort:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@@ -332,6 +324,7 @@ $code.=<<___;
|
|||||||
ldp x25,x26,[x29,#64]
|
ldp x25,x26,[x29,#64]
|
||||||
ldp x27,x28,[x29,#80]
|
ldp x27,x28,[x29,#80]
|
||||||
ldp x29,x30,[sp],#96
|
ldp x29,x30,[sp],#96
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ChaCha20_ctr32,.-ChaCha20_ctr32
|
.size ChaCha20_ctr32,.-ChaCha20_ctr32
|
||||||
___
|
___
|
||||||
@@ -377,6 +370,8 @@ $code.=<<___;
|
|||||||
.type ChaCha20_neon,%function
|
.type ChaCha20_neon,%function
|
||||||
.align 5
|
.align 5
|
||||||
ChaCha20_neon:
|
ChaCha20_neon:
|
||||||
|
.LChaCha20_neon:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-96]!
|
stp x29,x30,[sp,#-96]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -575,6 +570,7 @@ $code.=<<___;
|
|||||||
ldp x25,x26,[x29,#64]
|
ldp x25,x26,[x29,#64]
|
||||||
ldp x27,x28,[x29,#80]
|
ldp x27,x28,[x29,#80]
|
||||||
ldp x29,x30,[sp],#96
|
ldp x29,x30,[sp],#96
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.Ltail_neon:
|
.Ltail_neon:
|
||||||
@@ -684,6 +680,7 @@ $code.=<<___;
|
|||||||
ldp x25,x26,[x29,#64]
|
ldp x25,x26,[x29,#64]
|
||||||
ldp x27,x28,[x29,#80]
|
ldp x27,x28,[x29,#80]
|
||||||
ldp x29,x30,[sp],#96
|
ldp x29,x30,[sp],#96
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ChaCha20_neon,.-ChaCha20_neon
|
.size ChaCha20_neon,.-ChaCha20_neon
|
||||||
___
|
___
|
||||||
@@ -696,6 +693,7 @@ $code.=<<___;
|
|||||||
.type ChaCha20_512_neon,%function
|
.type ChaCha20_512_neon,%function
|
||||||
.align 5
|
.align 5
|
||||||
ChaCha20_512_neon:
|
ChaCha20_512_neon:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-96]!
|
stp x29,x30,[sp,#-96]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -1114,6 +1112,7 @@ $code.=<<___;
|
|||||||
ldp x25,x26,[x29,#64]
|
ldp x25,x26,[x29,#64]
|
||||||
ldp x27,x28,[x29,#80]
|
ldp x27,x28,[x29,#80]
|
||||||
ldp x29,x30,[sp],#96
|
ldp x29,x30,[sp],#96
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ChaCha20_512_neon,.-ChaCha20_512_neon
|
.size ChaCha20_512_neon,.-ChaCha20_512_neon
|
||||||
___
|
___
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ LABEL ("ChaCha20_ctr32");
|
|||||||
larl ("%r1","OPENSSL_s390xcap_P");
|
larl ("%r1","OPENSSL_s390xcap_P");
|
||||||
|
|
||||||
lghi ("%r0",64);
|
lghi ("%r0",64);
|
||||||
&{$z? \&cgr:\&cr} ($len,"%r0");
|
&{$z? \&clgr:\&clr} ($len,"%r0");
|
||||||
jle ("_s390x_chacha_novx");
|
jle ("_s390x_chacha_novx");
|
||||||
|
|
||||||
lg ("%r0","S390X_STFLE+16(%r1)");
|
lg ("%r0","S390X_STFLE+16(%r1)");
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialise a ktri based on passed certificate and key */
|
/* Initialise a kari based on passed certificate and key */
|
||||||
|
|
||||||
int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
|
int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
|
||||||
EVP_PKEY *pk, unsigned int flags)
|
EVP_PKEY *pk, unsigned int flags)
|
||||||
@@ -299,6 +299,9 @@ int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
|
|||||||
kari->version = 3;
|
kari->version = 3;
|
||||||
|
|
||||||
rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
|
rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
|
||||||
|
if (rek == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) {
|
if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) {
|
||||||
M_ASN1_free_of(rek, CMS_RecipientEncryptedKey);
|
M_ASN1_free_of(rek, CMS_RecipientEncryptedKey);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* 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 "internal/cryptlib.h"
|
||||||
|
#include "internal/thread_once.h"
|
||||||
|
|
||||||
|
struct openssl_ctx_st {
|
||||||
|
CRYPTO_RWLOCK *lock;
|
||||||
|
CRYPTO_EX_DATA data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static OPENSSL_CTX default_context;
|
||||||
|
|
||||||
|
static int context_init(OPENSSL_CTX *ctx)
|
||||||
|
{
|
||||||
|
return (ctx->lock = CRYPTO_THREAD_lock_new()) != NULL
|
||||||
|
&& CRYPTO_new_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,
|
||||||
|
&ctx->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int context_deinit(OPENSSL_CTX *ctx)
|
||||||
|
{
|
||||||
|
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, &ctx->data);
|
||||||
|
CRYPTO_THREAD_lock_free(ctx->lock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT;
|
||||||
|
static void do_default_context_deinit(void)
|
||||||
|
{
|
||||||
|
context_deinit(&default_context);
|
||||||
|
}
|
||||||
|
DEFINE_RUN_ONCE_STATIC(do_default_context_init)
|
||||||
|
{
|
||||||
|
return OPENSSL_init_crypto(0, NULL)
|
||||||
|
&& context_init(&default_context)
|
||||||
|
&& OPENSSL_atexit(do_default_context_deinit);
|
||||||
|
}
|
||||||
|
|
||||||
|
OPENSSL_CTX *OPENSSL_CTX_new(void)
|
||||||
|
{
|
||||||
|
OPENSSL_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
|
||||||
|
|
||||||
|
if (ctx != NULL && !context_init(ctx)) {
|
||||||
|
OPENSSL_CTX_free(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
}
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OPENSSL_CTX_free(OPENSSL_CTX *ctx)
|
||||||
|
{
|
||||||
|
if (ctx != NULL)
|
||||||
|
context_deinit(ctx);
|
||||||
|
OPENSSL_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void openssl_ctx_generic_new(void *parent_ign, void *ptr_ign,
|
||||||
|
CRYPTO_EX_DATA *ad, int index,
|
||||||
|
long argl_ign, void *argp)
|
||||||
|
{
|
||||||
|
const OPENSSL_CTX_METHOD *meth = argp;
|
||||||
|
void *ptr = meth->new_func();
|
||||||
|
|
||||||
|
if (ptr != NULL)
|
||||||
|
CRYPTO_set_ex_data(ad, index, ptr);
|
||||||
|
}
|
||||||
|
static void openssl_ctx_generic_free(void *parent_ign, void *ptr,
|
||||||
|
CRYPTO_EX_DATA *ad, int index,
|
||||||
|
long argl_ign, void *argp)
|
||||||
|
{
|
||||||
|
const OPENSSL_CTX_METHOD *meth = argp;
|
||||||
|
|
||||||
|
meth->free_func(ptr);
|
||||||
|
}
|
||||||
|
int openssl_ctx_new_index(const OPENSSL_CTX_METHOD *meth)
|
||||||
|
{
|
||||||
|
return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_OPENSSL_CTX, 0, (void *)meth,
|
||||||
|
openssl_ctx_generic_new, NULL,
|
||||||
|
openssl_ctx_generic_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index)
|
||||||
|
{
|
||||||
|
void *data = NULL;
|
||||||
|
|
||||||
|
if (ctx == NULL) {
|
||||||
|
if (!RUN_ONCE(&default_context_init, do_default_context_init))
|
||||||
|
return 0;
|
||||||
|
ctx = &default_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
CRYPTO_THREAD_read_lock(ctx->lock);
|
||||||
|
|
||||||
|
/* The alloc call ensures there's a value there */
|
||||||
|
if (CRYPTO_alloc_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,
|
||||||
|
&ctx->data, index))
|
||||||
|
data = CRYPTO_get_ex_data(&ctx->data, index);
|
||||||
|
|
||||||
|
CRYPTO_THREAD_unlock(ctx->lock);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -51,7 +51,6 @@ if ($flavour && $flavour ne "void") {
|
|||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
#include "arm_arch.h"
|
#include "arm_arch.h"
|
||||||
|
|
||||||
.text
|
|
||||||
#if defined(__thumb2__)
|
#if defined(__thumb2__)
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.thumb
|
.thumb
|
||||||
@@ -80,6 +79,7 @@ close TABLE;
|
|||||||
die "insane number of elements" if ($#arr != 64*16*37-1);
|
die "insane number of elements" if ($#arr != 64*16*37-1);
|
||||||
|
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
|
.rodata
|
||||||
.globl ecp_nistz256_precomputed
|
.globl ecp_nistz256_precomputed
|
||||||
.type ecp_nistz256_precomputed,%object
|
.type ecp_nistz256_precomputed,%object
|
||||||
.align 12
|
.align 12
|
||||||
@@ -104,6 +104,8 @@ for(1..37) {
|
|||||||
}
|
}
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
.size ecp_nistz256_precomputed,.-ecp_nistz256_precomputed
|
.size ecp_nistz256_precomputed,.-ecp_nistz256_precomputed
|
||||||
|
|
||||||
|
.text
|
||||||
.align 5
|
.align 5
|
||||||
.LRR: @ 2^512 mod P precomputed for NIST P256 polynomial
|
.LRR: @ 2^512 mod P precomputed for NIST P256 polynomial
|
||||||
.long 0x00000003, 0x00000000, 0xffffffff, 0xfffffffb
|
.long 0x00000003, 0x00000000, 0xffffffff, 0xfffffffb
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ $code.=<<___;
|
|||||||
.type ecp_nistz256_to_mont,%function
|
.type ecp_nistz256_to_mont,%function
|
||||||
.align 6
|
.align 6
|
||||||
ecp_nistz256_to_mont:
|
ecp_nistz256_to_mont:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-32]!
|
stp x29,x30,[sp,#-32]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp x19,x20,[sp,#16]
|
stp x19,x20,[sp,#16]
|
||||||
@@ -134,6 +135,7 @@ ecp_nistz256_to_mont:
|
|||||||
|
|
||||||
ldp x19,x20,[sp,#16]
|
ldp x19,x20,[sp,#16]
|
||||||
ldp x29,x30,[sp],#32
|
ldp x29,x30,[sp],#32
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont
|
.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont
|
||||||
|
|
||||||
@@ -142,6 +144,7 @@ ecp_nistz256_to_mont:
|
|||||||
.type ecp_nistz256_from_mont,%function
|
.type ecp_nistz256_from_mont,%function
|
||||||
.align 4
|
.align 4
|
||||||
ecp_nistz256_from_mont:
|
ecp_nistz256_from_mont:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-32]!
|
stp x29,x30,[sp,#-32]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp x19,x20,[sp,#16]
|
stp x19,x20,[sp,#16]
|
||||||
@@ -157,6 +160,7 @@ ecp_nistz256_from_mont:
|
|||||||
|
|
||||||
ldp x19,x20,[sp,#16]
|
ldp x19,x20,[sp,#16]
|
||||||
ldp x29,x30,[sp],#32
|
ldp x29,x30,[sp],#32
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ecp_nistz256_from_mont,.-ecp_nistz256_from_mont
|
.size ecp_nistz256_from_mont,.-ecp_nistz256_from_mont
|
||||||
|
|
||||||
@@ -166,6 +170,7 @@ ecp_nistz256_from_mont:
|
|||||||
.type ecp_nistz256_mul_mont,%function
|
.type ecp_nistz256_mul_mont,%function
|
||||||
.align 4
|
.align 4
|
||||||
ecp_nistz256_mul_mont:
|
ecp_nistz256_mul_mont:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-32]!
|
stp x29,x30,[sp,#-32]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp x19,x20,[sp,#16]
|
stp x19,x20,[sp,#16]
|
||||||
@@ -180,6 +185,7 @@ ecp_nistz256_mul_mont:
|
|||||||
|
|
||||||
ldp x19,x20,[sp,#16]
|
ldp x19,x20,[sp,#16]
|
||||||
ldp x29,x30,[sp],#32
|
ldp x29,x30,[sp],#32
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
|
.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
|
||||||
|
|
||||||
@@ -188,6 +194,7 @@ ecp_nistz256_mul_mont:
|
|||||||
.type ecp_nistz256_sqr_mont,%function
|
.type ecp_nistz256_sqr_mont,%function
|
||||||
.align 4
|
.align 4
|
||||||
ecp_nistz256_sqr_mont:
|
ecp_nistz256_sqr_mont:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-32]!
|
stp x29,x30,[sp,#-32]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp x19,x20,[sp,#16]
|
stp x19,x20,[sp,#16]
|
||||||
@@ -201,6 +208,7 @@ ecp_nistz256_sqr_mont:
|
|||||||
|
|
||||||
ldp x19,x20,[sp,#16]
|
ldp x19,x20,[sp,#16]
|
||||||
ldp x29,x30,[sp],#32
|
ldp x29,x30,[sp],#32
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
|
.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
|
||||||
|
|
||||||
@@ -210,6 +218,7 @@ ecp_nistz256_sqr_mont:
|
|||||||
.type ecp_nistz256_add,%function
|
.type ecp_nistz256_add,%function
|
||||||
.align 4
|
.align 4
|
||||||
ecp_nistz256_add:
|
ecp_nistz256_add:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -223,6 +232,7 @@ ecp_nistz256_add:
|
|||||||
bl __ecp_nistz256_add
|
bl __ecp_nistz256_add
|
||||||
|
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ecp_nistz256_add,.-ecp_nistz256_add
|
.size ecp_nistz256_add,.-ecp_nistz256_add
|
||||||
|
|
||||||
@@ -231,6 +241,7 @@ ecp_nistz256_add:
|
|||||||
.type ecp_nistz256_div_by_2,%function
|
.type ecp_nistz256_div_by_2,%function
|
||||||
.align 4
|
.align 4
|
||||||
ecp_nistz256_div_by_2:
|
ecp_nistz256_div_by_2:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -242,6 +253,7 @@ ecp_nistz256_div_by_2:
|
|||||||
bl __ecp_nistz256_div_by_2
|
bl __ecp_nistz256_div_by_2
|
||||||
|
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2
|
.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2
|
||||||
|
|
||||||
@@ -250,6 +262,7 @@ ecp_nistz256_div_by_2:
|
|||||||
.type ecp_nistz256_mul_by_2,%function
|
.type ecp_nistz256_mul_by_2,%function
|
||||||
.align 4
|
.align 4
|
||||||
ecp_nistz256_mul_by_2:
|
ecp_nistz256_mul_by_2:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -265,6 +278,7 @@ ecp_nistz256_mul_by_2:
|
|||||||
bl __ecp_nistz256_add // ret = a+a // 2*a
|
bl __ecp_nistz256_add // ret = a+a // 2*a
|
||||||
|
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
|
.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
|
||||||
|
|
||||||
@@ -273,6 +287,7 @@ ecp_nistz256_mul_by_2:
|
|||||||
.type ecp_nistz256_mul_by_3,%function
|
.type ecp_nistz256_mul_by_3,%function
|
||||||
.align 4
|
.align 4
|
||||||
ecp_nistz256_mul_by_3:
|
ecp_nistz256_mul_by_3:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -299,6 +314,7 @@ ecp_nistz256_mul_by_3:
|
|||||||
bl __ecp_nistz256_add // ret += a // 2*a+a=3*a
|
bl __ecp_nistz256_add // ret += a // 2*a+a=3*a
|
||||||
|
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
|
.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
|
||||||
|
|
||||||
@@ -308,6 +324,7 @@ ecp_nistz256_mul_by_3:
|
|||||||
.type ecp_nistz256_sub,%function
|
.type ecp_nistz256_sub,%function
|
||||||
.align 4
|
.align 4
|
||||||
ecp_nistz256_sub:
|
ecp_nistz256_sub:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -319,6 +336,7 @@ ecp_nistz256_sub:
|
|||||||
bl __ecp_nistz256_sub_from
|
bl __ecp_nistz256_sub_from
|
||||||
|
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ecp_nistz256_sub,.-ecp_nistz256_sub
|
.size ecp_nistz256_sub,.-ecp_nistz256_sub
|
||||||
|
|
||||||
@@ -327,6 +345,7 @@ ecp_nistz256_sub:
|
|||||||
.type ecp_nistz256_neg,%function
|
.type ecp_nistz256_neg,%function
|
||||||
.align 4
|
.align 4
|
||||||
ecp_nistz256_neg:
|
ecp_nistz256_neg:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -341,6 +360,7 @@ ecp_nistz256_neg:
|
|||||||
bl __ecp_nistz256_sub_from
|
bl __ecp_nistz256_sub_from
|
||||||
|
|
||||||
ldp x29,x30,[sp],#16
|
ldp x29,x30,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ecp_nistz256_neg,.-ecp_nistz256_neg
|
.size ecp_nistz256_neg,.-ecp_nistz256_neg
|
||||||
|
|
||||||
@@ -701,6 +721,7 @@ $code.=<<___;
|
|||||||
.type ecp_nistz256_point_double,%function
|
.type ecp_nistz256_point_double,%function
|
||||||
.align 5
|
.align 5
|
||||||
ecp_nistz256_point_double:
|
ecp_nistz256_point_double:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-80]!
|
stp x29,x30,[sp,#-80]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp x19,x20,[sp,#16]
|
stp x19,x20,[sp,#16]
|
||||||
@@ -835,6 +856,7 @@ ecp_nistz256_point_double:
|
|||||||
ldp x19,x20,[x29,#16]
|
ldp x19,x20,[x29,#16]
|
||||||
ldp x21,x22,[x29,#32]
|
ldp x21,x22,[x29,#32]
|
||||||
ldp x29,x30,[sp],#80
|
ldp x29,x30,[sp],#80
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ecp_nistz256_point_double,.-ecp_nistz256_point_double
|
.size ecp_nistz256_point_double,.-ecp_nistz256_point_double
|
||||||
___
|
___
|
||||||
@@ -857,6 +879,7 @@ $code.=<<___;
|
|||||||
.type ecp_nistz256_point_add,%function
|
.type ecp_nistz256_point_add,%function
|
||||||
.align 5
|
.align 5
|
||||||
ecp_nistz256_point_add:
|
ecp_nistz256_point_add:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-80]!
|
stp x29,x30,[sp,#-80]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp x19,x20,[sp,#16]
|
stp x19,x20,[sp,#16]
|
||||||
@@ -1100,6 +1123,7 @@ $code.=<<___;
|
|||||||
ldp x23,x24,[x29,#48]
|
ldp x23,x24,[x29,#48]
|
||||||
ldp x25,x26,[x29,#64]
|
ldp x25,x26,[x29,#64]
|
||||||
ldp x29,x30,[sp],#80
|
ldp x29,x30,[sp],#80
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ecp_nistz256_point_add,.-ecp_nistz256_point_add
|
.size ecp_nistz256_point_add,.-ecp_nistz256_point_add
|
||||||
___
|
___
|
||||||
@@ -1121,6 +1145,7 @@ $code.=<<___;
|
|||||||
.type ecp_nistz256_point_add_affine,%function
|
.type ecp_nistz256_point_add_affine,%function
|
||||||
.align 5
|
.align 5
|
||||||
ecp_nistz256_point_add_affine:
|
ecp_nistz256_point_add_affine:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-80]!
|
stp x29,x30,[sp,#-80]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp x19,x20,[sp,#16]
|
stp x19,x20,[sp,#16]
|
||||||
@@ -1309,6 +1334,7 @@ $code.=<<___;
|
|||||||
ldp x23,x24,[x29,#48]
|
ldp x23,x24,[x29,#48]
|
||||||
ldp x25,x26,[x29,#64]
|
ldp x25,x26,[x29,#64]
|
||||||
ldp x29,x30,[sp],#80
|
ldp x29,x30,[sp],#80
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine
|
.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine
|
||||||
___
|
___
|
||||||
@@ -1628,7 +1654,7 @@ ecp_nistz256_scatter_w5:
|
|||||||
|
|
||||||
ldp x4,x5,[$inp] // X
|
ldp x4,x5,[$inp] // X
|
||||||
ldp x6,x7,[$inp,#16]
|
ldp x6,x7,[$inp,#16]
|
||||||
str w4,[$out,#64*0-4]
|
stur w4,[$out,#64*0-4]
|
||||||
lsr x4,x4,#32
|
lsr x4,x4,#32
|
||||||
str w5,[$out,#64*1-4]
|
str w5,[$out,#64*1-4]
|
||||||
lsr x5,x5,#32
|
lsr x5,x5,#32
|
||||||
@@ -1644,7 +1670,7 @@ ecp_nistz256_scatter_w5:
|
|||||||
|
|
||||||
ldp x4,x5,[$inp,#32] // Y
|
ldp x4,x5,[$inp,#32] // Y
|
||||||
ldp x6,x7,[$inp,#48]
|
ldp x6,x7,[$inp,#48]
|
||||||
str w4,[$out,#64*0-4]
|
stur w4,[$out,#64*0-4]
|
||||||
lsr x4,x4,#32
|
lsr x4,x4,#32
|
||||||
str w5,[$out,#64*1-4]
|
str w5,[$out,#64*1-4]
|
||||||
lsr x5,x5,#32
|
lsr x5,x5,#32
|
||||||
@@ -1660,7 +1686,7 @@ ecp_nistz256_scatter_w5:
|
|||||||
|
|
||||||
ldp x4,x5,[$inp,#64] // Z
|
ldp x4,x5,[$inp,#64] // Z
|
||||||
ldp x6,x7,[$inp,#80]
|
ldp x6,x7,[$inp,#80]
|
||||||
str w4,[$out,#64*0-4]
|
stur w4,[$out,#64*0-4]
|
||||||
lsr x4,x4,#32
|
lsr x4,x4,#32
|
||||||
str w5,[$out,#64*1-4]
|
str w5,[$out,#64*1-4]
|
||||||
lsr x5,x5,#32
|
lsr x5,x5,#32
|
||||||
|
|||||||
@@ -1674,6 +1674,7 @@ $code.=<<___;
|
|||||||
.type __ecp_nistz256_mul_montq,\@abi-omnipotent
|
.type __ecp_nistz256_mul_montq,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
__ecp_nistz256_mul_montq:
|
__ecp_nistz256_mul_montq:
|
||||||
|
.cfi_startproc
|
||||||
########################################################################
|
########################################################################
|
||||||
# Multiply a by b[0]
|
# Multiply a by b[0]
|
||||||
mov %rax, $t1
|
mov %rax, $t1
|
||||||
@@ -1885,6 +1886,7 @@ __ecp_nistz256_mul_montq:
|
|||||||
mov $acc1, 8*3($r_ptr)
|
mov $acc1, 8*3($r_ptr)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size __ecp_nistz256_mul_montq,.-__ecp_nistz256_mul_montq
|
.size __ecp_nistz256_mul_montq,.-__ecp_nistz256_mul_montq
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@@ -1968,6 +1970,7 @@ $code.=<<___;
|
|||||||
.type __ecp_nistz256_sqr_montq,\@abi-omnipotent
|
.type __ecp_nistz256_sqr_montq,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
__ecp_nistz256_sqr_montq:
|
__ecp_nistz256_sqr_montq:
|
||||||
|
.cfi_startproc
|
||||||
mov %rax, $acc5
|
mov %rax, $acc5
|
||||||
mulq $acc6 # a[1]*a[0]
|
mulq $acc6 # a[1]*a[0]
|
||||||
mov %rax, $acc1
|
mov %rax, $acc1
|
||||||
@@ -2125,6 +2128,7 @@ __ecp_nistz256_sqr_montq:
|
|||||||
mov $acc7, 8*3($r_ptr)
|
mov $acc7, 8*3($r_ptr)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size __ecp_nistz256_sqr_montq,.-__ecp_nistz256_sqr_montq
|
.size __ecp_nistz256_sqr_montq,.-__ecp_nistz256_sqr_montq
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -2133,6 +2137,7 @@ $code.=<<___;
|
|||||||
.type __ecp_nistz256_mul_montx,\@abi-omnipotent
|
.type __ecp_nistz256_mul_montx,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
__ecp_nistz256_mul_montx:
|
__ecp_nistz256_mul_montx:
|
||||||
|
.cfi_startproc
|
||||||
########################################################################
|
########################################################################
|
||||||
# Multiply by b[0]
|
# Multiply by b[0]
|
||||||
mulx $acc1, $acc0, $acc1
|
mulx $acc1, $acc0, $acc1
|
||||||
@@ -2295,11 +2300,13 @@ __ecp_nistz256_mul_montx:
|
|||||||
mov $acc1, 8*3($r_ptr)
|
mov $acc1, 8*3($r_ptr)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size __ecp_nistz256_mul_montx,.-__ecp_nistz256_mul_montx
|
.size __ecp_nistz256_mul_montx,.-__ecp_nistz256_mul_montx
|
||||||
|
|
||||||
.type __ecp_nistz256_sqr_montx,\@abi-omnipotent
|
.type __ecp_nistz256_sqr_montx,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
__ecp_nistz256_sqr_montx:
|
__ecp_nistz256_sqr_montx:
|
||||||
|
.cfi_startproc
|
||||||
mulx $acc6, $acc1, $acc2 # a[0]*a[1]
|
mulx $acc6, $acc1, $acc2 # a[0]*a[1]
|
||||||
mulx $acc7, $t0, $acc3 # a[0]*a[2]
|
mulx $acc7, $t0, $acc3 # a[0]*a[2]
|
||||||
xor %eax, %eax
|
xor %eax, %eax
|
||||||
@@ -2423,6 +2430,7 @@ __ecp_nistz256_sqr_montx:
|
|||||||
mov $acc7, 8*3($r_ptr)
|
mov $acc7, 8*3($r_ptr)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size __ecp_nistz256_sqr_montx,.-__ecp_nistz256_sqr_montx
|
.size __ecp_nistz256_sqr_montx,.-__ecp_nistz256_sqr_montx
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -2578,6 +2586,7 @@ ecp_nistz256_scatter_w5:
|
|||||||
.type ecp_nistz256_gather_w5,\@abi-omnipotent
|
.type ecp_nistz256_gather_w5,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
ecp_nistz256_gather_w5:
|
ecp_nistz256_gather_w5:
|
||||||
|
.cfi_startproc
|
||||||
___
|
___
|
||||||
$code.=<<___ if ($avx>1);
|
$code.=<<___ if ($avx>1);
|
||||||
mov OPENSSL_ia32cap_P+8(%rip), %eax
|
mov OPENSSL_ia32cap_P+8(%rip), %eax
|
||||||
@@ -2666,6 +2675,7 @@ $code.=<<___ if ($win64);
|
|||||||
___
|
___
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.LSEH_end_ecp_nistz256_gather_w5:
|
.LSEH_end_ecp_nistz256_gather_w5:
|
||||||
.size ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5
|
.size ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5
|
||||||
|
|
||||||
@@ -2694,6 +2704,7 @@ ecp_nistz256_scatter_w7:
|
|||||||
.type ecp_nistz256_gather_w7,\@abi-omnipotent
|
.type ecp_nistz256_gather_w7,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
ecp_nistz256_gather_w7:
|
ecp_nistz256_gather_w7:
|
||||||
|
.cfi_startproc
|
||||||
___
|
___
|
||||||
$code.=<<___ if ($avx>1);
|
$code.=<<___ if ($avx>1);
|
||||||
mov OPENSSL_ia32cap_P+8(%rip), %eax
|
mov OPENSSL_ia32cap_P+8(%rip), %eax
|
||||||
@@ -2771,6 +2782,7 @@ $code.=<<___ if ($win64);
|
|||||||
___
|
___
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.LSEH_end_ecp_nistz256_gather_w7:
|
.LSEH_end_ecp_nistz256_gather_w7:
|
||||||
.size ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7
|
.size ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7
|
||||||
___
|
___
|
||||||
@@ -2787,6 +2799,7 @@ $code.=<<___;
|
|||||||
.type ecp_nistz256_avx2_gather_w5,\@abi-omnipotent
|
.type ecp_nistz256_avx2_gather_w5,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
ecp_nistz256_avx2_gather_w5:
|
ecp_nistz256_avx2_gather_w5:
|
||||||
|
.cfi_startproc
|
||||||
.Lavx2_gather_w5:
|
.Lavx2_gather_w5:
|
||||||
vzeroupper
|
vzeroupper
|
||||||
___
|
___
|
||||||
@@ -2874,6 +2887,7 @@ $code.=<<___ if ($win64);
|
|||||||
___
|
___
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.LSEH_end_ecp_nistz256_avx2_gather_w5:
|
.LSEH_end_ecp_nistz256_avx2_gather_w5:
|
||||||
.size ecp_nistz256_avx2_gather_w5,.-ecp_nistz256_avx2_gather_w5
|
.size ecp_nistz256_avx2_gather_w5,.-ecp_nistz256_avx2_gather_w5
|
||||||
___
|
___
|
||||||
@@ -2893,6 +2907,7 @@ $code.=<<___;
|
|||||||
.type ecp_nistz256_avx2_gather_w7,\@abi-omnipotent
|
.type ecp_nistz256_avx2_gather_w7,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
ecp_nistz256_avx2_gather_w7:
|
ecp_nistz256_avx2_gather_w7:
|
||||||
|
.cfi_startproc
|
||||||
.Lavx2_gather_w7:
|
.Lavx2_gather_w7:
|
||||||
vzeroupper
|
vzeroupper
|
||||||
___
|
___
|
||||||
@@ -2995,6 +3010,7 @@ $code.=<<___ if ($win64);
|
|||||||
___
|
___
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.LSEH_end_ecp_nistz256_avx2_gather_w7:
|
.LSEH_end_ecp_nistz256_avx2_gather_w7:
|
||||||
.size ecp_nistz256_avx2_gather_w7,.-ecp_nistz256_avx2_gather_w7
|
.size ecp_nistz256_avx2_gather_w7,.-ecp_nistz256_avx2_gather_w7
|
||||||
___
|
___
|
||||||
@@ -3064,6 +3080,7 @@ $code.=<<___;
|
|||||||
.type __ecp_nistz256_add_toq,\@abi-omnipotent
|
.type __ecp_nistz256_add_toq,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
__ecp_nistz256_add_toq:
|
__ecp_nistz256_add_toq:
|
||||||
|
.cfi_startproc
|
||||||
xor $t4,$t4
|
xor $t4,$t4
|
||||||
add 8*0($b_ptr), $a0
|
add 8*0($b_ptr), $a0
|
||||||
adc 8*1($b_ptr), $a1
|
adc 8*1($b_ptr), $a1
|
||||||
@@ -3091,11 +3108,13 @@ __ecp_nistz256_add_toq:
|
|||||||
mov $a3, 8*3($r_ptr)
|
mov $a3, 8*3($r_ptr)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size __ecp_nistz256_add_toq,.-__ecp_nistz256_add_toq
|
.size __ecp_nistz256_add_toq,.-__ecp_nistz256_add_toq
|
||||||
|
|
||||||
.type __ecp_nistz256_sub_fromq,\@abi-omnipotent
|
.type __ecp_nistz256_sub_fromq,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
__ecp_nistz256_sub_fromq:
|
__ecp_nistz256_sub_fromq:
|
||||||
|
.cfi_startproc
|
||||||
sub 8*0($b_ptr), $a0
|
sub 8*0($b_ptr), $a0
|
||||||
sbb 8*1($b_ptr), $a1
|
sbb 8*1($b_ptr), $a1
|
||||||
mov $a0, $t0
|
mov $a0, $t0
|
||||||
@@ -3122,11 +3141,13 @@ __ecp_nistz256_sub_fromq:
|
|||||||
mov $a3, 8*3($r_ptr)
|
mov $a3, 8*3($r_ptr)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size __ecp_nistz256_sub_fromq,.-__ecp_nistz256_sub_fromq
|
.size __ecp_nistz256_sub_fromq,.-__ecp_nistz256_sub_fromq
|
||||||
|
|
||||||
.type __ecp_nistz256_subq,\@abi-omnipotent
|
.type __ecp_nistz256_subq,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
__ecp_nistz256_subq:
|
__ecp_nistz256_subq:
|
||||||
|
.cfi_startproc
|
||||||
sub $a0, $t0
|
sub $a0, $t0
|
||||||
sbb $a1, $t1
|
sbb $a1, $t1
|
||||||
mov $t0, $a0
|
mov $t0, $a0
|
||||||
@@ -3149,11 +3170,13 @@ __ecp_nistz256_subq:
|
|||||||
cmovnz $t3, $a3
|
cmovnz $t3, $a3
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size __ecp_nistz256_subq,.-__ecp_nistz256_subq
|
.size __ecp_nistz256_subq,.-__ecp_nistz256_subq
|
||||||
|
|
||||||
.type __ecp_nistz256_mul_by_2q,\@abi-omnipotent
|
.type __ecp_nistz256_mul_by_2q,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
__ecp_nistz256_mul_by_2q:
|
__ecp_nistz256_mul_by_2q:
|
||||||
|
.cfi_startproc
|
||||||
xor $t4, $t4
|
xor $t4, $t4
|
||||||
add $a0, $a0 # a0:a3+a0:a3
|
add $a0, $a0 # a0:a3+a0:a3
|
||||||
adc $a1, $a1
|
adc $a1, $a1
|
||||||
@@ -3181,6 +3204,7 @@ __ecp_nistz256_mul_by_2q:
|
|||||||
mov $a3, 8*3($r_ptr)
|
mov $a3, 8*3($r_ptr)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size __ecp_nistz256_mul_by_2q,.-__ecp_nistz256_mul_by_2q
|
.size __ecp_nistz256_mul_by_2q,.-__ecp_nistz256_mul_by_2q
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -3620,7 +3644,9 @@ $code.=<<___;
|
|||||||
movq %xmm1, $a_ptr # restore $a_ptr
|
movq %xmm1, $a_ptr # restore $a_ptr
|
||||||
movq %xmm0, $r_ptr # restore $r_ptr
|
movq %xmm0, $r_ptr # restore $r_ptr
|
||||||
add \$`32*(18-5)`, %rsp # difference in frame sizes
|
add \$`32*(18-5)`, %rsp # difference in frame sizes
|
||||||
|
.cfi_adjust_cfa_offset `-32*(18-5)`
|
||||||
jmp .Lpoint_double_shortcut$x
|
jmp .Lpoint_double_shortcut$x
|
||||||
|
.cfi_adjust_cfa_offset `32*(18-5)`
|
||||||
|
|
||||||
.align 32
|
.align 32
|
||||||
.Ladd_proceed$x:
|
.Ladd_proceed$x:
|
||||||
@@ -4156,6 +4182,7 @@ $code.=<<___;
|
|||||||
.type __ecp_nistz256_add_tox,\@abi-omnipotent
|
.type __ecp_nistz256_add_tox,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
__ecp_nistz256_add_tox:
|
__ecp_nistz256_add_tox:
|
||||||
|
.cfi_startproc
|
||||||
xor $t4, $t4
|
xor $t4, $t4
|
||||||
adc 8*0($b_ptr), $a0
|
adc 8*0($b_ptr), $a0
|
||||||
adc 8*1($b_ptr), $a1
|
adc 8*1($b_ptr), $a1
|
||||||
@@ -4184,11 +4211,13 @@ __ecp_nistz256_add_tox:
|
|||||||
mov $a3, 8*3($r_ptr)
|
mov $a3, 8*3($r_ptr)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size __ecp_nistz256_add_tox,.-__ecp_nistz256_add_tox
|
.size __ecp_nistz256_add_tox,.-__ecp_nistz256_add_tox
|
||||||
|
|
||||||
.type __ecp_nistz256_sub_fromx,\@abi-omnipotent
|
.type __ecp_nistz256_sub_fromx,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
__ecp_nistz256_sub_fromx:
|
__ecp_nistz256_sub_fromx:
|
||||||
|
.cfi_startproc
|
||||||
xor $t4, $t4
|
xor $t4, $t4
|
||||||
sbb 8*0($b_ptr), $a0
|
sbb 8*0($b_ptr), $a0
|
||||||
sbb 8*1($b_ptr), $a1
|
sbb 8*1($b_ptr), $a1
|
||||||
@@ -4217,11 +4246,13 @@ __ecp_nistz256_sub_fromx:
|
|||||||
mov $a3, 8*3($r_ptr)
|
mov $a3, 8*3($r_ptr)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size __ecp_nistz256_sub_fromx,.-__ecp_nistz256_sub_fromx
|
.size __ecp_nistz256_sub_fromx,.-__ecp_nistz256_sub_fromx
|
||||||
|
|
||||||
.type __ecp_nistz256_subx,\@abi-omnipotent
|
.type __ecp_nistz256_subx,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
__ecp_nistz256_subx:
|
__ecp_nistz256_subx:
|
||||||
|
.cfi_startproc
|
||||||
xor $t4, $t4
|
xor $t4, $t4
|
||||||
sbb $a0, $t0
|
sbb $a0, $t0
|
||||||
sbb $a1, $t1
|
sbb $a1, $t1
|
||||||
@@ -4246,11 +4277,13 @@ __ecp_nistz256_subx:
|
|||||||
cmovc $t3, $a3
|
cmovc $t3, $a3
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size __ecp_nistz256_subx,.-__ecp_nistz256_subx
|
.size __ecp_nistz256_subx,.-__ecp_nistz256_subx
|
||||||
|
|
||||||
.type __ecp_nistz256_mul_by_2x,\@abi-omnipotent
|
.type __ecp_nistz256_mul_by_2x,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
__ecp_nistz256_mul_by_2x:
|
__ecp_nistz256_mul_by_2x:
|
||||||
|
.cfi_startproc
|
||||||
xor $t4, $t4
|
xor $t4, $t4
|
||||||
adc $a0, $a0 # a0:a3+a0:a3
|
adc $a0, $a0 # a0:a3+a0:a3
|
||||||
adc $a1, $a1
|
adc $a1, $a1
|
||||||
@@ -4279,6 +4312,7 @@ __ecp_nistz256_mul_by_2x:
|
|||||||
mov $a3, 8*3($r_ptr)
|
mov $a3, 8*3($r_ptr)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size __ecp_nistz256_mul_by_2x,.-__ecp_nistz256_mul_by_2x
|
.size __ecp_nistz256_mul_by_2x,.-__ecp_nistz256_mul_by_2x
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-1
@@ -810,7 +810,7 @@ int ec_GF2m_simple_ladder_post(const EC_GROUP *group,
|
|||||||
|| !group->meth->field_mul(group, t2, t2, t0, ctx)
|
|| !group->meth->field_mul(group, t2, t2, t0, ctx)
|
||||||
|| !BN_GF2m_add(t1, t2, t1)
|
|| !BN_GF2m_add(t1, t2, t1)
|
||||||
|| !group->meth->field_mul(group, t2, p->X, t0, ctx)
|
|| !group->meth->field_mul(group, t2, p->X, t0, ctx)
|
||||||
|| !BN_GF2m_mod_inv(t2, t2, group->field, ctx)
|
|| !group->meth->field_inv(group, t2, t2, ctx)
|
||||||
|| !group->meth->field_mul(group, t1, t1, t2, ctx)
|
|| !group->meth->field_mul(group, t1, t1, t2, ctx)
|
||||||
|| !group->meth->field_mul(group, r->X, r->Z, t2, ctx)
|
|| !group->meth->field_mul(group, r->X, r->Z, t2, ctx)
|
||||||
|| !BN_GF2m_add(t2, p->X, r->X)
|
|| !BN_GF2m_add(t2, p->X, r->X)
|
||||||
@@ -889,6 +889,21 @@ int ec_GF2m_simple_points_mul(const EC_GROUP *group, EC_POINT *r,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Computes the multiplicative inverse of a in GF(2^m), storing the result in r.
|
||||||
|
* If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error.
|
||||||
|
* SCA hardening is with blinding: BN_GF2m_mod_inv does that.
|
||||||
|
*/
|
||||||
|
static int ec_GF2m_simple_field_inv(const EC_GROUP *group, BIGNUM *r,
|
||||||
|
const BIGNUM *a, BN_CTX *ctx)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!(ret = BN_GF2m_mod_inv(r, a, group->field, ctx)))
|
||||||
|
ECerr(EC_F_EC_GF2M_SIMPLE_FIELD_INV, EC_R_CANNOT_INVERT);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
const EC_METHOD *EC_GF2m_simple_method(void)
|
const EC_METHOD *EC_GF2m_simple_method(void)
|
||||||
{
|
{
|
||||||
static const EC_METHOD ret = {
|
static const EC_METHOD ret = {
|
||||||
@@ -929,6 +944,7 @@ const EC_METHOD *EC_GF2m_simple_method(void)
|
|||||||
ec_GF2m_simple_field_mul,
|
ec_GF2m_simple_field_mul,
|
||||||
ec_GF2m_simple_field_sqr,
|
ec_GF2m_simple_field_sqr,
|
||||||
ec_GF2m_simple_field_div,
|
ec_GF2m_simple_field_div,
|
||||||
|
ec_GF2m_simple_field_inv,
|
||||||
0, /* field_encode */
|
0, /* field_encode */
|
||||||
0, /* field_decode */
|
0, /* field_decode */
|
||||||
0, /* field_set_to_one */
|
0, /* field_set_to_one */
|
||||||
|
|||||||
+8
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Generated by util/mkerr.pl DO NOT EDIT
|
* Generated by util/mkerr.pl DO NOT EDIT
|
||||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
* 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
|
* this file except in compliance with the License. You can obtain a copy
|
||||||
@@ -66,6 +66,8 @@ static const ERR_STRING_DATA EC_str_functs[] = {
|
|||||||
"ec_asn1_group2fieldid"},
|
"ec_asn1_group2fieldid"},
|
||||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, 0),
|
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, 0),
|
||||||
"ec_GF2m_montgomery_point_multiply"},
|
"ec_GF2m_montgomery_point_multiply"},
|
||||||
|
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_FIELD_INV, 0),
|
||||||
|
"ec_GF2m_simple_field_inv"},
|
||||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0),
|
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0),
|
||||||
"ec_GF2m_simple_group_check_discriminant"},
|
"ec_GF2m_simple_group_check_discriminant"},
|
||||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, 0),
|
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, 0),
|
||||||
@@ -90,6 +92,8 @@ static const ERR_STRING_DATA EC_str_functs[] = {
|
|||||||
"ec_GFp_mont_field_decode"},
|
"ec_GFp_mont_field_decode"},
|
||||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_ENCODE, 0),
|
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_ENCODE, 0),
|
||||||
"ec_GFp_mont_field_encode"},
|
"ec_GFp_mont_field_encode"},
|
||||||
|
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_INV, 0),
|
||||||
|
"ec_GFp_mont_field_inv"},
|
||||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_MUL, 0),
|
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_MUL, 0),
|
||||||
"ec_GFp_mont_field_mul"},
|
"ec_GFp_mont_field_mul"},
|
||||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, 0),
|
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, 0),
|
||||||
@@ -124,6 +128,8 @@ static const ERR_STRING_DATA EC_str_functs[] = {
|
|||||||
"ec_GFp_nist_group_set_curve"},
|
"ec_GFp_nist_group_set_curve"},
|
||||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, 0),
|
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, 0),
|
||||||
"ec_GFp_simple_blind_coordinates"},
|
"ec_GFp_simple_blind_coordinates"},
|
||||||
|
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_FIELD_INV, 0),
|
||||||
|
"ec_GFp_simple_field_inv"},
|
||||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0),
|
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0),
|
||||||
"ec_GFp_simple_group_check_discriminant"},
|
"ec_GFp_simple_group_check_discriminant"},
|
||||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, 0),
|
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, 0),
|
||||||
@@ -287,6 +293,7 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
|
|||||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_BAD_SIGNATURE), "bad signature"},
|
{ERR_PACK(ERR_LIB_EC, 0, EC_R_BAD_SIGNATURE), "bad signature"},
|
||||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"},
|
{ERR_PACK(ERR_LIB_EC, 0, EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"},
|
||||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_BUFFER_TOO_SMALL), "buffer too small"},
|
{ERR_PACK(ERR_LIB_EC, 0, EC_R_BUFFER_TOO_SMALL), "buffer too small"},
|
||||||
|
{ERR_PACK(ERR_LIB_EC, 0, EC_R_CANNOT_INVERT), "cannot invert"},
|
||||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_COORDINATES_OUT_OF_RANGE),
|
{ERR_PACK(ERR_LIB_EC, 0, EC_R_COORDINATES_OUT_OF_RANGE),
|
||||||
"coordinates out of range"},
|
"coordinates out of range"},
|
||||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH),
|
{ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH),
|
||||||
|
|||||||
@@ -154,6 +154,13 @@ struct ec_method_st {
|
|||||||
int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
|
int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
|
||||||
int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||||
const BIGNUM *b, BN_CTX *);
|
const BIGNUM *b, BN_CTX *);
|
||||||
|
/*-
|
||||||
|
* 'field_inv' computes the multipicative inverse of a in the field,
|
||||||
|
* storing the result in r.
|
||||||
|
*
|
||||||
|
* If 'a' is zero (or equivalent), you'll get an EC_R_CANNOT_INVERT error.
|
||||||
|
*/
|
||||||
|
int (*field_inv) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
|
||||||
/* e.g. to Montgomery */
|
/* e.g. to Montgomery */
|
||||||
int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||||
BN_CTX *);
|
BN_CTX *);
|
||||||
@@ -390,6 +397,8 @@ int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
|||||||
const BIGNUM *b, BN_CTX *);
|
const BIGNUM *b, BN_CTX *);
|
||||||
int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||||
BN_CTX *);
|
BN_CTX *);
|
||||||
|
int ec_GFp_simple_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||||
|
BN_CTX *);
|
||||||
int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
|
int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
|
||||||
BN_CTX *ctx);
|
BN_CTX *ctx);
|
||||||
int ec_GFp_simple_ladder_pre(const EC_GROUP *group,
|
int ec_GFp_simple_ladder_pre(const EC_GROUP *group,
|
||||||
@@ -413,6 +422,8 @@ int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
|||||||
const BIGNUM *b, BN_CTX *);
|
const BIGNUM *b, BN_CTX *);
|
||||||
int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||||
BN_CTX *);
|
BN_CTX *);
|
||||||
|
int ec_GFp_mont_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||||
|
BN_CTX *);
|
||||||
int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||||
BN_CTX *);
|
BN_CTX *);
|
||||||
int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||||
|
|||||||
@@ -364,6 +364,11 @@ int EC_GROUP_get_curve_name(const EC_GROUP *group)
|
|||||||
return group->curve_name;
|
return group->curve_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BIGNUM *EC_GROUP_get0_field(const EC_GROUP *group)
|
||||||
|
{
|
||||||
|
return group->field;
|
||||||
|
}
|
||||||
|
|
||||||
void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
|
void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
|
||||||
{
|
{
|
||||||
group->asn1_flag = flag;
|
group->asn1_flag = flag;
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ const EC_METHOD *EC_GFp_mont_method(void)
|
|||||||
ec_GFp_mont_field_mul,
|
ec_GFp_mont_field_mul,
|
||||||
ec_GFp_mont_field_sqr,
|
ec_GFp_mont_field_sqr,
|
||||||
0 /* field_div */ ,
|
0 /* field_div */ ,
|
||||||
|
ec_GFp_mont_field_inv,
|
||||||
ec_GFp_mont_field_encode,
|
ec_GFp_mont_field_encode,
|
||||||
ec_GFp_mont_field_decode,
|
ec_GFp_mont_field_decode,
|
||||||
ec_GFp_mont_field_set_to_one,
|
ec_GFp_mont_field_set_to_one,
|
||||||
@@ -206,6 +207,54 @@ int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
|||||||
return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
|
return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Computes the multiplicative inverse of a in GF(p), storing the result in r.
|
||||||
|
* If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error.
|
||||||
|
* We have a Mont structure, so SCA hardening is FLT inversion.
|
||||||
|
*/
|
||||||
|
int ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
||||||
|
BN_CTX *ctx)
|
||||||
|
{
|
||||||
|
BIGNUM *e = NULL;
|
||||||
|
BN_CTX *new_ctx = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (group->field_data1 == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
BN_CTX_start(ctx);
|
||||||
|
if ((e = BN_CTX_get(ctx)) == NULL)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Inverse in constant time with Fermats Little Theorem */
|
||||||
|
if (!BN_set_word(e, 2))
|
||||||
|
goto err;
|
||||||
|
if (!BN_sub(e, group->field, e))
|
||||||
|
goto err;
|
||||||
|
/*-
|
||||||
|
* Exponent e is public.
|
||||||
|
* No need for scatter-gather or BN_FLG_CONSTTIME.
|
||||||
|
*/
|
||||||
|
if (!BN_mod_exp_mont(r, a, e, group->field, ctx, group->field_data1))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* throw an error on zero */
|
||||||
|
if (BN_is_zero(r)) {
|
||||||
|
ECerr(EC_F_EC_GFP_MONT_FIELD_INV, EC_R_CANNOT_INVERT);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
BN_CTX_end(ctx);
|
||||||
|
BN_CTX_free(new_ctx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r,
|
int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r,
|
||||||
const BIGNUM *a, BN_CTX *ctx)
|
const BIGNUM *a, BN_CTX *ctx)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ const EC_METHOD *EC_GFp_nist_method(void)
|
|||||||
ec_GFp_nist_field_mul,
|
ec_GFp_nist_field_mul,
|
||||||
ec_GFp_nist_field_sqr,
|
ec_GFp_nist_field_sqr,
|
||||||
0 /* field_div */ ,
|
0 /* field_div */ ,
|
||||||
|
ec_GFp_simple_field_inv,
|
||||||
0 /* field_encode */ ,
|
0 /* field_encode */ ,
|
||||||
0 /* field_decode */ ,
|
0 /* field_decode */ ,
|
||||||
0, /* field_set_to_one */
|
0, /* field_set_to_one */
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ const EC_METHOD *EC_GFp_nistp224_method(void)
|
|||||||
ec_GFp_nist_field_mul,
|
ec_GFp_nist_field_mul,
|
||||||
ec_GFp_nist_field_sqr,
|
ec_GFp_nist_field_sqr,
|
||||||
0 /* field_div */ ,
|
0 /* field_div */ ,
|
||||||
|
ec_GFp_simple_field_inv,
|
||||||
0 /* field_encode */ ,
|
0 /* field_encode */ ,
|
||||||
0 /* field_decode */ ,
|
0 /* field_decode */ ,
|
||||||
0, /* field_set_to_one */
|
0, /* field_set_to_one */
|
||||||
|
|||||||
@@ -1810,6 +1810,7 @@ const EC_METHOD *EC_GFp_nistp256_method(void)
|
|||||||
ec_GFp_nist_field_mul,
|
ec_GFp_nist_field_mul,
|
||||||
ec_GFp_nist_field_sqr,
|
ec_GFp_nist_field_sqr,
|
||||||
0 /* field_div */ ,
|
0 /* field_div */ ,
|
||||||
|
ec_GFp_simple_field_inv,
|
||||||
0 /* field_encode */ ,
|
0 /* field_encode */ ,
|
||||||
0 /* field_decode */ ,
|
0 /* field_decode */ ,
|
||||||
0, /* field_set_to_one */
|
0, /* field_set_to_one */
|
||||||
|
|||||||
@@ -1647,6 +1647,7 @@ const EC_METHOD *EC_GFp_nistp521_method(void)
|
|||||||
ec_GFp_nist_field_mul,
|
ec_GFp_nist_field_mul,
|
||||||
ec_GFp_nist_field_sqr,
|
ec_GFp_nist_field_sqr,
|
||||||
0 /* field_div */ ,
|
0 /* field_div */ ,
|
||||||
|
ec_GFp_simple_field_inv,
|
||||||
0 /* field_encode */ ,
|
0 /* field_encode */ ,
|
||||||
0 /* field_decode */ ,
|
0 /* field_decode */ ,
|
||||||
0, /* field_set_to_one */
|
0, /* field_set_to_one */
|
||||||
|
|||||||
@@ -1677,6 +1677,7 @@ const EC_METHOD *EC_GFp_nistz256_method(void)
|
|||||||
ec_GFp_mont_field_mul,
|
ec_GFp_mont_field_mul,
|
||||||
ec_GFp_mont_field_sqr,
|
ec_GFp_mont_field_sqr,
|
||||||
0, /* field_div */
|
0, /* field_div */
|
||||||
|
ec_GFp_mont_field_inv,
|
||||||
ec_GFp_mont_field_encode,
|
ec_GFp_mont_field_encode,
|
||||||
ec_GFp_mont_field_decode,
|
ec_GFp_mont_field_decode,
|
||||||
ec_GFp_mont_field_set_to_one,
|
ec_GFp_mont_field_set_to_one,
|
||||||
|
|||||||
+47
-2
@@ -51,6 +51,7 @@ const EC_METHOD *EC_GFp_simple_method(void)
|
|||||||
ec_GFp_simple_field_mul,
|
ec_GFp_simple_field_mul,
|
||||||
ec_GFp_simple_field_sqr,
|
ec_GFp_simple_field_sqr,
|
||||||
0 /* field_div */ ,
|
0 /* field_div */ ,
|
||||||
|
ec_GFp_simple_field_inv,
|
||||||
0 /* field_encode */ ,
|
0 /* field_encode */ ,
|
||||||
0 /* field_decode */ ,
|
0 /* field_decode */ ,
|
||||||
0, /* field_set_to_one */
|
0, /* field_set_to_one */
|
||||||
@@ -553,7 +554,7 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!BN_mod_inverse(Z_1, Z_, group->field, ctx)) {
|
if (!group->meth->field_inv(group, Z_1, Z_, ctx)) {
|
||||||
ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
|
ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
|
||||||
ERR_R_BN_LIB);
|
ERR_R_BN_LIB);
|
||||||
goto err;
|
goto err;
|
||||||
@@ -1266,7 +1267,7 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
|
|||||||
* points[i]->Z by its inverse.
|
* points[i]->Z by its inverse.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!BN_mod_inverse(tmp, prod_Z[num - 1], group->field, ctx)) {
|
if (!group->meth->field_inv(group, tmp, prod_Z[num - 1], ctx)) {
|
||||||
ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
|
ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -1369,6 +1370,50 @@ int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
|||||||
return BN_mod_sqr(r, a, group->field, ctx);
|
return BN_mod_sqr(r, a, group->field, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Computes the multiplicative inverse of a in GF(p), storing the result in r.
|
||||||
|
* If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error.
|
||||||
|
* Since we don't have a Mont structure here, SCA hardening is with blinding.
|
||||||
|
*/
|
||||||
|
int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
||||||
|
BN_CTX *ctx)
|
||||||
|
{
|
||||||
|
BIGNUM *e = NULL;
|
||||||
|
BN_CTX *new_ctx = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
BN_CTX_start(ctx);
|
||||||
|
if ((e = BN_CTX_get(ctx)) == NULL)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (!BN_priv_rand_range(e, group->field))
|
||||||
|
goto err;
|
||||||
|
} while (BN_is_zero(e));
|
||||||
|
|
||||||
|
/* r := a * e */
|
||||||
|
if (!group->meth->field_mul(group, r, a, e, ctx))
|
||||||
|
goto err;
|
||||||
|
/* r := 1/(a * e) */
|
||||||
|
if (!BN_mod_inverse(r, r, group->field, ctx)) {
|
||||||
|
ECerr(EC_F_EC_GFP_SIMPLE_FIELD_INV, EC_R_CANNOT_INVERT);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
/* r := e/(a * e) = 1/a */
|
||||||
|
if (!group->meth->field_mul(group, r, r, e, ctx))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
BN_CTX_end(ctx);
|
||||||
|
BN_CTX_free(new_ctx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Apply randomization of EC point projective coordinates:
|
* Apply randomization of EC point projective coordinates:
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -6,6 +6,3 @@ SOURCE[../../libcrypto]=\
|
|||||||
tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c tb_eckey.c \
|
tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c tb_eckey.c \
|
||||||
eng_openssl.c eng_cnf.c eng_dyn.c \
|
eng_openssl.c eng_cnf.c eng_dyn.c \
|
||||||
eng_rdrand.c
|
eng_rdrand.c
|
||||||
IF[{- !$disabled{devcryptoeng} -}]
|
|
||||||
SOURCE[../../libcrypto]=eng_devcrypto.c
|
|
||||||
ENDIF
|
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
#include <openssl/kdferr.h>
|
#include <openssl/kdferr.h>
|
||||||
#include <openssl/storeerr.h>
|
#include <openssl/storeerr.h>
|
||||||
#include <openssl/esserr.h>
|
#include <openssl/esserr.h>
|
||||||
|
#include "internal/propertyerr.h"
|
||||||
|
|
||||||
int err_load_crypto_strings_int(void)
|
int err_load_crypto_strings_int(void)
|
||||||
{
|
{
|
||||||
@@ -96,7 +97,8 @@ int err_load_crypto_strings_int(void)
|
|||||||
ERR_load_ASYNC_strings() == 0 ||
|
ERR_load_ASYNC_strings() == 0 ||
|
||||||
#endif
|
#endif
|
||||||
ERR_load_KDF_strings() == 0 ||
|
ERR_load_KDF_strings() == 0 ||
|
||||||
ERR_load_OSSL_STORE_strings() == 0)
|
ERR_load_OSSL_STORE_strings() == 0 ||
|
||||||
|
ERR_load_PROP_strings() == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ L KDF include/openssl/kdf.h crypto/kdf/kdf_err.c
|
|||||||
L SM2 crypto/include/internal/sm2.h crypto/sm2/sm2_err.c
|
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 OSSL_STORE include/openssl/store.h crypto/store/store_err.c
|
||||||
L ESS include/openssl/ess.h crypto/ess/ess_err.c
|
L ESS include/openssl/ess.h crypto/ess/ess_err.c
|
||||||
|
L PROP include/internal/property.h crypto/property/property_err.c
|
||||||
|
|
||||||
# additional header files to be scanned for function names
|
# additional header files to be scanned for function names
|
||||||
L NONE include/openssl/x509_vfy.h NONE
|
L NONE include/openssl/x509_vfy.h NONE
|
||||||
|
|||||||
+50
-4
@@ -521,6 +521,7 @@ EC_F_ECX_PUB_ENCODE:268:ecx_pub_encode
|
|||||||
EC_F_EC_ASN1_GROUP2CURVE:153:ec_asn1_group2curve
|
EC_F_EC_ASN1_GROUP2CURVE:153:ec_asn1_group2curve
|
||||||
EC_F_EC_ASN1_GROUP2FIELDID:154:ec_asn1_group2fieldid
|
EC_F_EC_ASN1_GROUP2FIELDID:154:ec_asn1_group2fieldid
|
||||||
EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY:208:ec_GF2m_montgomery_point_multiply
|
EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY:208:ec_GF2m_montgomery_point_multiply
|
||||||
|
EC_F_EC_GF2M_SIMPLE_FIELD_INV:296:ec_GF2m_simple_field_inv
|
||||||
EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT:159:\
|
EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT:159:\
|
||||||
ec_GF2m_simple_group_check_discriminant
|
ec_GF2m_simple_group_check_discriminant
|
||||||
EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE:195:ec_GF2m_simple_group_set_curve
|
EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE:195:ec_GF2m_simple_group_set_curve
|
||||||
@@ -537,6 +538,7 @@ EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES:164:\
|
|||||||
ec_GF2m_simple_set_compressed_coordinates
|
ec_GF2m_simple_set_compressed_coordinates
|
||||||
EC_F_EC_GFP_MONT_FIELD_DECODE:133:ec_GFp_mont_field_decode
|
EC_F_EC_GFP_MONT_FIELD_DECODE:133:ec_GFp_mont_field_decode
|
||||||
EC_F_EC_GFP_MONT_FIELD_ENCODE:134:ec_GFp_mont_field_encode
|
EC_F_EC_GFP_MONT_FIELD_ENCODE:134:ec_GFp_mont_field_encode
|
||||||
|
EC_F_EC_GFP_MONT_FIELD_INV:297:ec_GFp_mont_field_inv
|
||||||
EC_F_EC_GFP_MONT_FIELD_MUL:131:ec_GFp_mont_field_mul
|
EC_F_EC_GFP_MONT_FIELD_MUL:131:ec_GFp_mont_field_mul
|
||||||
EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE:209:ec_GFp_mont_field_set_to_one
|
EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE:209:ec_GFp_mont_field_set_to_one
|
||||||
EC_F_EC_GFP_MONT_FIELD_SQR:132:ec_GFp_mont_field_sqr
|
EC_F_EC_GFP_MONT_FIELD_SQR:132:ec_GFp_mont_field_sqr
|
||||||
@@ -557,6 +559,7 @@ EC_F_EC_GFP_NIST_FIELD_MUL:200:ec_GFp_nist_field_mul
|
|||||||
EC_F_EC_GFP_NIST_FIELD_SQR:201:ec_GFp_nist_field_sqr
|
EC_F_EC_GFP_NIST_FIELD_SQR:201:ec_GFp_nist_field_sqr
|
||||||
EC_F_EC_GFP_NIST_GROUP_SET_CURVE:202:ec_GFp_nist_group_set_curve
|
EC_F_EC_GFP_NIST_GROUP_SET_CURVE:202:ec_GFp_nist_group_set_curve
|
||||||
EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES:287:ec_GFp_simple_blind_coordinates
|
EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES:287:ec_GFp_simple_blind_coordinates
|
||||||
|
EC_F_EC_GFP_SIMPLE_FIELD_INV:298:ec_GFp_simple_field_inv
|
||||||
EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT:165:\
|
EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT:165:\
|
||||||
ec_GFp_simple_group_check_discriminant
|
ec_GFp_simple_group_check_discriminant
|
||||||
EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE:166:ec_GFp_simple_group_set_curve
|
EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE:166:ec_GFp_simple_group_set_curve
|
||||||
@@ -753,6 +756,9 @@ EVP_F_EVP_DIGESTINIT_EX:128:EVP_DigestInit_ex
|
|||||||
EVP_F_EVP_ENCRYPTDECRYPTUPDATE:219:evp_EncryptDecryptUpdate
|
EVP_F_EVP_ENCRYPTDECRYPTUPDATE:219:evp_EncryptDecryptUpdate
|
||||||
EVP_F_EVP_ENCRYPTFINAL_EX:127:EVP_EncryptFinal_ex
|
EVP_F_EVP_ENCRYPTFINAL_EX:127:EVP_EncryptFinal_ex
|
||||||
EVP_F_EVP_ENCRYPTUPDATE:167:EVP_EncryptUpdate
|
EVP_F_EVP_ENCRYPTUPDATE:167:EVP_EncryptUpdate
|
||||||
|
EVP_F_EVP_KDF_CTRL:224:EVP_KDF_ctrl
|
||||||
|
EVP_F_EVP_KDF_CTRL_STR:225:EVP_KDF_ctrl_str
|
||||||
|
EVP_F_EVP_KDF_CTX_NEW_ID:226:EVP_KDF_CTX_new_id
|
||||||
EVP_F_EVP_MAC_CTRL:209:EVP_MAC_ctrl
|
EVP_F_EVP_MAC_CTRL:209:EVP_MAC_ctrl
|
||||||
EVP_F_EVP_MAC_CTRL_STR:210:EVP_MAC_ctrl_str
|
EVP_F_EVP_MAC_CTRL_STR:210:EVP_MAC_ctrl_str
|
||||||
EVP_F_EVP_MAC_CTX_COPY:211:EVP_MAC_CTX_copy
|
EVP_F_EVP_MAC_CTX_COPY:211:EVP_MAC_CTX_copy
|
||||||
@@ -823,6 +829,7 @@ EVP_F_PKCS5_PBE_KEYIVGEN:117:PKCS5_PBE_keyivgen
|
|||||||
EVP_F_PKCS5_V2_PBE_KEYIVGEN:118:PKCS5_v2_PBE_keyivgen
|
EVP_F_PKCS5_V2_PBE_KEYIVGEN:118:PKCS5_v2_PBE_keyivgen
|
||||||
EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN:164:PKCS5_v2_PBKDF2_keyivgen
|
EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN:164:PKCS5_v2_PBKDF2_keyivgen
|
||||||
EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN:180:PKCS5_v2_scrypt_keyivgen
|
EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN:180:PKCS5_v2_scrypt_keyivgen
|
||||||
|
EVP_F_PKEY_KDF_CTRL:227:pkey_kdf_ctrl
|
||||||
EVP_F_PKEY_MAC_INIT:214:pkey_mac_init
|
EVP_F_PKEY_MAC_INIT:214:pkey_mac_init
|
||||||
EVP_F_PKEY_SET_TYPE:158:pkey_set_type
|
EVP_F_PKEY_SET_TYPE:158:pkey_set_type
|
||||||
EVP_F_POLY1305_CTRL:216:poly1305_ctrl
|
EVP_F_POLY1305_CTRL:216:poly1305_ctrl
|
||||||
@@ -830,7 +837,25 @@ EVP_F_RC2_MAGIC_TO_METH:109:rc2_magic_to_meth
|
|||||||
EVP_F_RC5_CTRL:125:rc5_ctrl
|
EVP_F_RC5_CTRL:125:rc5_ctrl
|
||||||
EVP_F_S390X_AES_GCM_CTRL:201:s390x_aes_gcm_ctrl
|
EVP_F_S390X_AES_GCM_CTRL:201:s390x_aes_gcm_ctrl
|
||||||
EVP_F_S390X_AES_GCM_TLS_CIPHER:208:s390x_aes_gcm_tls_cipher
|
EVP_F_S390X_AES_GCM_TLS_CIPHER:208:s390x_aes_gcm_tls_cipher
|
||||||
|
EVP_F_SCRYPT_ALG:228:scrypt_alg
|
||||||
EVP_F_UPDATE:173:update
|
EVP_F_UPDATE:173:update
|
||||||
|
KDF_F_HKDF_EXTRACT:112:HKDF_Extract
|
||||||
|
KDF_F_KDF_HKDF_DERIVE:113:kdf_hkdf_derive
|
||||||
|
KDF_F_KDF_HKDF_NEW:114:kdf_hkdf_new
|
||||||
|
KDF_F_KDF_HKDF_SIZE:115:kdf_hkdf_size
|
||||||
|
KDF_F_KDF_MD2CTRL:116:kdf_md2ctrl
|
||||||
|
KDF_F_KDF_PBKDF2_CTRL_STR:117:kdf_pbkdf2_ctrl_str
|
||||||
|
KDF_F_KDF_PBKDF2_DERIVE:118:kdf_pbkdf2_derive
|
||||||
|
KDF_F_KDF_PBKDF2_NEW:119:kdf_pbkdf2_new
|
||||||
|
KDF_F_KDF_SCRYPT_CTRL_STR:120:kdf_scrypt_ctrl_str
|
||||||
|
KDF_F_KDF_SCRYPT_CTRL_UINT32:121:kdf_scrypt_ctrl_uint32
|
||||||
|
KDF_F_KDF_SCRYPT_CTRL_UINT64:122:kdf_scrypt_ctrl_uint64
|
||||||
|
KDF_F_KDF_SCRYPT_DERIVE:123:kdf_scrypt_derive
|
||||||
|
KDF_F_KDF_SCRYPT_NEW:124:kdf_scrypt_new
|
||||||
|
KDF_F_KDF_TLS1_PRF_CTRL_STR:125:kdf_tls1_prf_ctrl_str
|
||||||
|
KDF_F_KDF_TLS1_PRF_DERIVE:126:kdf_tls1_prf_derive
|
||||||
|
KDF_F_KDF_TLS1_PRF_NEW:127:kdf_tls1_prf_new
|
||||||
|
KDF_F_PBKDF2_SET_MEMBUF:128:pbkdf2_set_membuf
|
||||||
KDF_F_PKEY_HKDF_CTRL_STR:103:pkey_hkdf_ctrl_str
|
KDF_F_PKEY_HKDF_CTRL_STR:103:pkey_hkdf_ctrl_str
|
||||||
KDF_F_PKEY_HKDF_DERIVE:102:pkey_hkdf_derive
|
KDF_F_PKEY_HKDF_DERIVE:102:pkey_hkdf_derive
|
||||||
KDF_F_PKEY_HKDF_INIT:108:pkey_hkdf_init
|
KDF_F_PKEY_HKDF_INIT:108:pkey_hkdf_init
|
||||||
@@ -842,6 +867,7 @@ KDF_F_PKEY_SCRYPT_SET_MEMBUF:107:pkey_scrypt_set_membuf
|
|||||||
KDF_F_PKEY_TLS1_PRF_CTRL_STR:100:pkey_tls1_prf_ctrl_str
|
KDF_F_PKEY_TLS1_PRF_CTRL_STR:100:pkey_tls1_prf_ctrl_str
|
||||||
KDF_F_PKEY_TLS1_PRF_DERIVE:101:pkey_tls1_prf_derive
|
KDF_F_PKEY_TLS1_PRF_DERIVE:101:pkey_tls1_prf_derive
|
||||||
KDF_F_PKEY_TLS1_PRF_INIT:110:pkey_tls1_prf_init
|
KDF_F_PKEY_TLS1_PRF_INIT:110:pkey_tls1_prf_init
|
||||||
|
KDF_F_SCRYPT_SET_MEMBUF:129:scrypt_set_membuf
|
||||||
KDF_F_TLS1_PRF_ALG:111:tls1_prf_alg
|
KDF_F_TLS1_PRF_ALG:111:tls1_prf_alg
|
||||||
OBJ_F_OBJ_ADD_OBJECT:105:OBJ_add_object
|
OBJ_F_OBJ_ADD_OBJECT:105:OBJ_add_object
|
||||||
OBJ_F_OBJ_ADD_SIGID:107:OBJ_add_sigid
|
OBJ_F_OBJ_ADD_SIGID:107:OBJ_add_sigid
|
||||||
@@ -1018,6 +1044,14 @@ PKCS7_F_PKCS7_SIGNER_INFO_SIGN:139:PKCS7_SIGNER_INFO_sign
|
|||||||
PKCS7_F_PKCS7_SIGN_ADD_SIGNER:137:PKCS7_sign_add_signer
|
PKCS7_F_PKCS7_SIGN_ADD_SIGNER:137:PKCS7_sign_add_signer
|
||||||
PKCS7_F_PKCS7_SIMPLE_SMIMECAP:119:PKCS7_simple_smimecap
|
PKCS7_F_PKCS7_SIMPLE_SMIMECAP:119:PKCS7_simple_smimecap
|
||||||
PKCS7_F_PKCS7_VERIFY:117:PKCS7_verify
|
PKCS7_F_PKCS7_VERIFY:117:PKCS7_verify
|
||||||
|
PROP_F_OSSL_PARSE_PROPERTY:100:ossl_parse_property
|
||||||
|
PROP_F_OSSL_PARSE_QUERY:101:ossl_parse_query
|
||||||
|
PROP_F_PARSE_HEX:102:parse_hex
|
||||||
|
PROP_F_PARSE_NAME:103:parse_name
|
||||||
|
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
|
||||||
RAND_F_DRBG_BYTES:101:drbg_bytes
|
RAND_F_DRBG_BYTES:101:drbg_bytes
|
||||||
RAND_F_DRBG_GET_ENTROPY:105:drbg_get_entropy
|
RAND_F_DRBG_GET_ENTROPY:105:drbg_get_entropy
|
||||||
RAND_F_DRBG_SETUP:117:drbg_setup
|
RAND_F_DRBG_SETUP:117:drbg_setup
|
||||||
@@ -2134,6 +2168,7 @@ EC_R_ASN1_ERROR:115:asn1 error
|
|||||||
EC_R_BAD_SIGNATURE:156:bad signature
|
EC_R_BAD_SIGNATURE:156:bad signature
|
||||||
EC_R_BIGNUM_OUT_OF_RANGE:144:bignum out of range
|
EC_R_BIGNUM_OUT_OF_RANGE:144:bignum out of range
|
||||||
EC_R_BUFFER_TOO_SMALL:100:buffer too small
|
EC_R_BUFFER_TOO_SMALL:100:buffer too small
|
||||||
|
EC_R_CANNOT_INVERT:165:cannot invert
|
||||||
EC_R_COORDINATES_OUT_OF_RANGE:146:coordinates out of range
|
EC_R_COORDINATES_OUT_OF_RANGE:146:coordinates out of range
|
||||||
EC_R_CURVE_DOES_NOT_SUPPORT_ECDH:160:curve does not support ecdh
|
EC_R_CURVE_DOES_NOT_SUPPORT_ECDH:160:curve does not support ecdh
|
||||||
EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING:159:curve does not support signing
|
EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING:159:curve does not support signing
|
||||||
@@ -2284,6 +2319,7 @@ EVP_R_ONLY_ONESHOT_SUPPORTED:177:only oneshot supported
|
|||||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:150:\
|
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:150:\
|
||||||
operation not supported for this keytype
|
operation not supported for this keytype
|
||||||
EVP_R_OPERATON_NOT_INITIALIZED:151:operaton not initialized
|
EVP_R_OPERATON_NOT_INITIALIZED:151:operaton not initialized
|
||||||
|
EVP_R_PARAMETER_TOO_LARGE:187:parameter too large
|
||||||
EVP_R_PARTIALLY_OVERLAPPING:162:partially overlapping buffers
|
EVP_R_PARTIALLY_OVERLAPPING:162:partially overlapping buffers
|
||||||
EVP_R_PBKDF2_ERROR:181:pbkdf2 error
|
EVP_R_PBKDF2_ERROR:181:pbkdf2 error
|
||||||
EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED:179:\
|
EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED:179:\
|
||||||
@@ -2320,6 +2356,7 @@ KDF_R_MISSING_SEED:106:missing seed
|
|||||||
KDF_R_UNKNOWN_PARAMETER_TYPE:103:unknown parameter type
|
KDF_R_UNKNOWN_PARAMETER_TYPE:103:unknown parameter type
|
||||||
KDF_R_VALUE_ERROR:108:value error
|
KDF_R_VALUE_ERROR:108:value error
|
||||||
KDF_R_VALUE_MISSING:102:value missing
|
KDF_R_VALUE_MISSING:102:value missing
|
||||||
|
KDF_R_WRONG_OUTPUT_BUFFER_SIZE:112:wrong output buffer size
|
||||||
OBJ_R_OID_EXISTS:102:oid exists
|
OBJ_R_OID_EXISTS:102:oid exists
|
||||||
OBJ_R_UNKNOWN_NID:101:unknown nid
|
OBJ_R_UNKNOWN_NID:101:unknown nid
|
||||||
OCSP_R_CERTIFICATE_VERIFY_ERROR:101:certificate verify error
|
OCSP_R_CERTIFICATE_VERIFY_ERROR:101:certificate verify error
|
||||||
@@ -2468,6 +2505,17 @@ PKCS7_R_UNSUPPORTED_CIPHER_TYPE:111:unsupported cipher type
|
|||||||
PKCS7_R_UNSUPPORTED_CONTENT_TYPE:112:unsupported content type
|
PKCS7_R_UNSUPPORTED_CONTENT_TYPE:112:unsupported content type
|
||||||
PKCS7_R_WRONG_CONTENT_TYPE:113:wrong content type
|
PKCS7_R_WRONG_CONTENT_TYPE:113:wrong content type
|
||||||
PKCS7_R_WRONG_PKCS7_TYPE:114:wrong pkcs7 type
|
PKCS7_R_WRONG_PKCS7_TYPE:114:wrong pkcs7 type
|
||||||
|
PROP_R_NAME_TOO_LONG:100:name too long
|
||||||
|
PROP_R_NOT_AN_ASCII_CHARACTER:101:not an ascii character
|
||||||
|
PROP_R_NOT_AN_HEXADECIMAL_DIGIT:102:not an hexadecimal digit
|
||||||
|
PROP_R_NOT_AN_IDENTIFIER:103:not an identifier
|
||||||
|
PROP_R_NOT_AN_OCTAL_DIGIT:104:not an octal digit
|
||||||
|
PROP_R_NOT_A_DECIMAL_DIGIT:105:not a decimal digit
|
||||||
|
PROP_R_NO_MATCHING_STRING_DELIMETER:106:no matching string delimeter
|
||||||
|
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
|
||||||
RAND_R_ADDITIONAL_INPUT_TOO_LONG:102:additional input too long
|
RAND_R_ADDITIONAL_INPUT_TOO_LONG:102:additional input too long
|
||||||
RAND_R_ALREADY_INSTANTIATED:103:already instantiated
|
RAND_R_ALREADY_INSTANTIATED:103:already instantiated
|
||||||
RAND_R_ARGUMENT_OUT_OF_RANGE:105:argument out of range
|
RAND_R_ARGUMENT_OUT_OF_RANGE:105:argument out of range
|
||||||
@@ -2748,8 +2796,8 @@ SSL_R_MISSING_SRP_PARAM:358:can't find SRP server param
|
|||||||
SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION:209:missing supported groups extension
|
SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION:209:missing supported groups extension
|
||||||
SSL_R_MISSING_TMP_DH_KEY:171:missing tmp dh key
|
SSL_R_MISSING_TMP_DH_KEY:171:missing tmp dh key
|
||||||
SSL_R_MISSING_TMP_ECDH_KEY:311:missing tmp ecdh key
|
SSL_R_MISSING_TMP_ECDH_KEY:311:missing tmp ecdh key
|
||||||
SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:293:mixed special operator with groups
|
SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA:293:\
|
||||||
SSL_R_NESTED_GROUP:294:nested group
|
mixed handshake and non handshake data
|
||||||
SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary
|
SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary
|
||||||
SSL_R_NOT_REPLACING_CERTIFICATE:289:not replacing certificate
|
SSL_R_NOT_REPLACING_CERTIFICATE:289:not replacing certificate
|
||||||
SSL_R_NOT_SERVER:284:not server
|
SSL_R_NOT_SERVER:284:not server
|
||||||
@@ -2858,9 +2906,7 @@ SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES:242:unable to load ssl3 md5 routines
|
|||||||
SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines
|
SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines
|
||||||
SSL_R_UNEXPECTED_CCS_MESSAGE:262:unexpected ccs message
|
SSL_R_UNEXPECTED_CCS_MESSAGE:262:unexpected ccs message
|
||||||
SSL_R_UNEXPECTED_END_OF_EARLY_DATA:178:unexpected end of early data
|
SSL_R_UNEXPECTED_END_OF_EARLY_DATA:178:unexpected end of early data
|
||||||
SSL_R_UNEXPECTED_GROUP_CLOSE:295:unexpected group close
|
|
||||||
SSL_R_UNEXPECTED_MESSAGE:244:unexpected message
|
SSL_R_UNEXPECTED_MESSAGE:244:unexpected message
|
||||||
SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:296:unexpected operator in group
|
|
||||||
SSL_R_UNEXPECTED_RECORD:245:unexpected record
|
SSL_R_UNEXPECTED_RECORD:245:unexpected record
|
||||||
SSL_R_UNINITIALIZED:276:uninitialized
|
SSL_R_UNINITIALIZED:276:uninitialized
|
||||||
SSL_R_UNKNOWN_ALERT_TYPE:246:unknown alert type
|
SSL_R_UNKNOWN_ALERT_TYPE:246:unknown alert type
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ SOURCE[../../libcrypto]=\
|
|||||||
p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
|
p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
|
||||||
bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
|
bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
|
||||||
c_allc.c c_alld.c evp_lib.c bio_ok.c \
|
c_allc.c c_alld.c evp_lib.c bio_ok.c \
|
||||||
evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \
|
evp_pkey.c kdf_lib.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \
|
||||||
|
pkey_kdf.c \
|
||||||
e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \
|
e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \
|
||||||
e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
|
e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
|
||||||
e_chacha20_poly1305.c cmeth_lib.c \
|
e_chacha20_poly1305.c cmeth_lib.c \
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
# include <openssl/evp.h>
|
# include <openssl/evp.h>
|
||||||
# include <openssl/objects.h>
|
# include <openssl/objects.h>
|
||||||
# include "evp_locl.h"
|
|
||||||
# include "internal/evp_int.h"
|
# include "internal/evp_int.h"
|
||||||
|
# include "evp_locl.h"
|
||||||
# include "internal/chacha.h"
|
# include "internal/chacha.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
+1
-1
@@ -11,8 +11,8 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "internal/cryptlib.h"
|
#include "internal/cryptlib.h"
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include "evp_locl.h"
|
|
||||||
#include "internal/evp_int.h"
|
#include "internal/evp_int.h"
|
||||||
|
#include "evp_locl.h"
|
||||||
|
|
||||||
static unsigned char conv_ascii2bin(unsigned char a,
|
static unsigned char conv_ascii2bin(unsigned char a,
|
||||||
const unsigned char *table);
|
const unsigned char *table);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Generated by util/mkerr.pl DO NOT EDIT
|
* Generated by util/mkerr.pl DO NOT EDIT
|
||||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
* 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
|
* this file except in compliance with the License. You can obtain a copy
|
||||||
@@ -60,6 +60,9 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
|
|||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0),
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0),
|
||||||
"EVP_EncryptFinal_ex"},
|
"EVP_EncryptFinal_ex"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTUPDATE, 0), "EVP_EncryptUpdate"},
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTUPDATE, 0), "EVP_EncryptUpdate"},
|
||||||
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTRL, 0), "EVP_KDF_ctrl"},
|
||||||
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTRL_STR, 0), "EVP_KDF_ctrl_str"},
|
||||||
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTX_NEW_ID, 0), "EVP_KDF_CTX_new_id"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL, 0), "EVP_MAC_ctrl"},
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL, 0), "EVP_MAC_ctrl"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL_STR, 0), "EVP_MAC_ctrl_str"},
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL_STR, 0), "EVP_MAC_ctrl_str"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_COPY, 0), "EVP_MAC_CTX_copy"},
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_COPY, 0), "EVP_MAC_CTX_copy"},
|
||||||
@@ -159,6 +162,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
|
|||||||
"PKCS5_v2_PBKDF2_keyivgen"},
|
"PKCS5_v2_PBKDF2_keyivgen"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, 0),
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, 0),
|
||||||
"PKCS5_v2_scrypt_keyivgen"},
|
"PKCS5_v2_scrypt_keyivgen"},
|
||||||
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_KDF_CTRL, 0), "pkey_kdf_ctrl"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_MAC_INIT, 0), "pkey_mac_init"},
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_MAC_INIT, 0), "pkey_mac_init"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_SET_TYPE, 0), "pkey_set_type"},
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_SET_TYPE, 0), "pkey_set_type"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_POLY1305_CTRL, 0), "poly1305_ctrl"},
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_POLY1305_CTRL, 0), "poly1305_ctrl"},
|
||||||
@@ -167,6 +171,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
|
|||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_CTRL, 0), "s390x_aes_gcm_ctrl"},
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_CTRL, 0), "s390x_aes_gcm_ctrl"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_TLS_CIPHER, 0),
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_TLS_CIPHER, 0),
|
||||||
"s390x_aes_gcm_tls_cipher"},
|
"s390x_aes_gcm_tls_cipher"},
|
||||||
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_SCRYPT_ALG, 0), "scrypt_alg"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_UPDATE, 0), "update"},
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_UPDATE, 0), "update"},
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
@@ -254,6 +259,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
|||||||
"operation not supported for this keytype"},
|
"operation not supported for this keytype"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATON_NOT_INITIALIZED),
|
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATON_NOT_INITIALIZED),
|
||||||
"operaton not initialized"},
|
"operaton not initialized"},
|
||||||
|
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARAMETER_TOO_LARGE),
|
||||||
|
"parameter too large"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARTIALLY_OVERLAPPING),
|
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARTIALLY_OVERLAPPING),
|
||||||
"partially overlapping buffers"},
|
"partially overlapping buffers"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PBKDF2_ERROR), "pbkdf2 error"},
|
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PBKDF2_ERROR), "pbkdf2 error"},
|
||||||
|
|||||||
@@ -46,6 +46,11 @@ struct evp_mac_ctx_st {
|
|||||||
void *data; /* Individual method data */
|
void *data; /* Individual method data */
|
||||||
} /* EVP_MAC_CTX */;
|
} /* EVP_MAC_CTX */;
|
||||||
|
|
||||||
|
struct evp_kdf_ctx_st {
|
||||||
|
const EVP_KDF_METHOD *kmeth;
|
||||||
|
EVP_KDF_IMPL *impl; /* Algorithm-specific data */
|
||||||
|
} /* EVP_KDF_CTX */ ;
|
||||||
|
|
||||||
int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
|
int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
|
||||||
int passlen, ASN1_TYPE *param,
|
int passlen, ASN1_TYPE *param,
|
||||||
const EVP_CIPHER *c, const EVP_MD *md,
|
const EVP_CIPHER *c, const EVP_MD *md,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/pkcs12.h>
|
#include <openssl/pkcs12.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
|
#include "internal/evp_int.h"
|
||||||
#include "evp_locl.h"
|
#include "evp_locl.h"
|
||||||
|
|
||||||
/* Password based encryption (PBE) functions */
|
/* Password based encryption (PBE) functions */
|
||||||
|
|||||||
@@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "internal/cryptlib.h"
|
||||||
|
#include <openssl/engine.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include <openssl/kdf.h>
|
||||||
|
#include "internal/asn1_int.h"
|
||||||
|
#include "internal/evp_int.h"
|
||||||
|
#include "internal/numbers.h"
|
||||||
|
#include "evp_locl.h"
|
||||||
|
|
||||||
|
typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
|
||||||
|
|
||||||
|
/* This array needs to be in order of NIDs */
|
||||||
|
static const EVP_KDF_METHOD *standard_methods[] = {
|
||||||
|
&pbkdf2_kdf_meth,
|
||||||
|
#ifndef OPENSSL_NO_SCRYPT
|
||||||
|
&scrypt_kdf_meth,
|
||||||
|
#endif
|
||||||
|
&tls1_prf_kdf_meth,
|
||||||
|
&hkdf_kdf_meth
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_KDF_METHOD *, const EVP_KDF_METHOD *,
|
||||||
|
kmeth);
|
||||||
|
|
||||||
|
static int kmeth_cmp(const EVP_KDF_METHOD *const *a,
|
||||||
|
const EVP_KDF_METHOD *const *b)
|
||||||
|
{
|
||||||
|
return ((*a)->type - (*b)->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_KDF_METHOD *, const EVP_KDF_METHOD *,
|
||||||
|
kmeth);
|
||||||
|
|
||||||
|
static const EVP_KDF_METHOD *kdf_meth_find(int type)
|
||||||
|
{
|
||||||
|
EVP_KDF_METHOD tmp;
|
||||||
|
const EVP_KDF_METHOD *t = &tmp, **ret;
|
||||||
|
|
||||||
|
tmp.type = type;
|
||||||
|
ret = OBJ_bsearch_kmeth(&t, standard_methods,
|
||||||
|
OSSL_NELEM(standard_methods));
|
||||||
|
if (ret == NULL || *ret == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return *ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id)
|
||||||
|
{
|
||||||
|
EVP_KDF_CTX *ret;
|
||||||
|
const EVP_KDF_METHOD *kmeth;
|
||||||
|
|
||||||
|
kmeth = kdf_meth_find(id);
|
||||||
|
if (kmeth == NULL) {
|
||||||
|
EVPerr(EVP_F_EVP_KDF_CTX_NEW_ID, EVP_R_UNSUPPORTED_ALGORITHM);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = OPENSSL_zalloc(sizeof(*ret));
|
||||||
|
if (ret == NULL) {
|
||||||
|
EVPerr(EVP_F_EVP_KDF_CTX_NEW_ID, ERR_R_MALLOC_FAILURE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kmeth->new != NULL && (ret->impl = kmeth->new()) == NULL) {
|
||||||
|
EVP_KDF_CTX_free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->kmeth = kmeth;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx)
|
||||||
|
{
|
||||||
|
if (ctx == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ctx->kmeth->free(ctx->impl);
|
||||||
|
OPENSSL_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EVP_KDF_reset(EVP_KDF_CTX *ctx)
|
||||||
|
{
|
||||||
|
if (ctx == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ctx->kmeth->reset != NULL)
|
||||||
|
ctx->kmeth->reset(ctx->impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, cmd);
|
||||||
|
ret = EVP_KDF_vctrl(ctx, cmd, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if (ret == -2)
|
||||||
|
EVPerr(EVP_F_EVP_KDF_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args)
|
||||||
|
{
|
||||||
|
if (ctx == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return ctx->kmeth->ctrl(ctx->impl, cmd, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (ctx == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ctx->kmeth->ctrl_str == NULL) {
|
||||||
|
EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ctx->kmeth->ctrl_str(ctx->impl, type, value);
|
||||||
|
if (ret == -2)
|
||||||
|
EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t EVP_KDF_size(EVP_KDF_CTX *ctx)
|
||||||
|
{
|
||||||
|
if (ctx == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ctx->kmeth->size == NULL)
|
||||||
|
return SIZE_MAX;
|
||||||
|
|
||||||
|
return ctx->kmeth->size(ctx->impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen)
|
||||||
|
{
|
||||||
|
if (ctx == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return ctx->kmeth->derive(ctx->impl, key, keylen);
|
||||||
|
}
|
||||||
|
|
||||||
+28
-82
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
* 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
|
* this file except in compliance with the License. You can obtain a copy
|
||||||
@@ -10,105 +10,51 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "internal/cryptlib.h"
|
#include "internal/cryptlib.h"
|
||||||
# include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
# include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
# include <openssl/hmac.h>
|
#include <openssl/kdf.h>
|
||||||
# include "evp_locl.h"
|
#include <openssl/hmac.h>
|
||||||
|
#include "internal/evp_int.h"
|
||||||
|
#include "evp_locl.h"
|
||||||
|
|
||||||
/* set this to print out info about the keygen algorithm */
|
/* set this to print out info about the keygen algorithm */
|
||||||
/* #define OPENSSL_DEBUG_PKCS5V2 */
|
/* #define OPENSSL_DEBUG_PKCS5V2 */
|
||||||
|
|
||||||
# ifdef OPENSSL_DEBUG_PKCS5V2
|
#ifdef OPENSSL_DEBUG_PKCS5V2
|
||||||
static void h__dump(const unsigned char *p, int len);
|
static void h__dump(const unsigned char *p, int len);
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* This is an implementation of PKCS#5 v2.0 password based encryption key
|
|
||||||
* derivation function PBKDF2. SHA1 version verified against test vectors
|
|
||||||
* posted by Peter Gutmann to the PKCS-TNG mailing list.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
|
int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
|
||||||
const unsigned char *salt, int saltlen, int iter,
|
const unsigned char *salt, int saltlen, int iter,
|
||||||
const EVP_MD *digest, int keylen, unsigned char *out)
|
const EVP_MD *digest, int keylen, unsigned char *out)
|
||||||
{
|
{
|
||||||
const char *empty = "";
|
const char *empty = "";
|
||||||
unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
|
int rv = 1;
|
||||||
int cplen, j, k, tkeylen, mdlen;
|
EVP_KDF_CTX *kctx;
|
||||||
unsigned long i = 1;
|
|
||||||
HMAC_CTX *hctx_tpl = NULL, *hctx = NULL;
|
|
||||||
|
|
||||||
mdlen = EVP_MD_size(digest);
|
/* Keep documented behaviour. */
|
||||||
if (mdlen < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
hctx_tpl = HMAC_CTX_new();
|
|
||||||
if (hctx_tpl == NULL)
|
|
||||||
return 0;
|
|
||||||
p = out;
|
|
||||||
tkeylen = keylen;
|
|
||||||
if (pass == NULL) {
|
if (pass == NULL) {
|
||||||
pass = empty;
|
pass = empty;
|
||||||
passlen = 0;
|
passlen = 0;
|
||||||
} else if (passlen == -1) {
|
} else if (passlen == -1) {
|
||||||
passlen = strlen(pass);
|
passlen = strlen(pass);
|
||||||
}
|
}
|
||||||
if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) {
|
if (salt == NULL && saltlen == 0)
|
||||||
HMAC_CTX_free(hctx_tpl);
|
salt = (unsigned char *)empty;
|
||||||
|
|
||||||
|
kctx = EVP_KDF_CTX_new_id(EVP_KDF_PBKDF2);
|
||||||
|
if (kctx == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, pass, (size_t)passlen) != 1
|
||||||
hctx = HMAC_CTX_new();
|
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT,
|
||||||
if (hctx == NULL) {
|
salt, (size_t)saltlen) != 1
|
||||||
HMAC_CTX_free(hctx_tpl);
|
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, iter) != 1
|
||||||
return 0;
|
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, digest) != 1
|
||||||
}
|
|| EVP_KDF_derive(kctx, out, keylen) != 1)
|
||||||
while (tkeylen) {
|
rv = 0;
|
||||||
if (tkeylen > mdlen)
|
|
||||||
cplen = mdlen;
|
EVP_KDF_CTX_free(kctx);
|
||||||
else
|
|
||||||
cplen = tkeylen;
|
|
||||||
/*
|
|
||||||
* We are unlikely to ever use more than 256 blocks (5120 bits!) but
|
|
||||||
* just in case...
|
|
||||||
*/
|
|
||||||
itmp[0] = (unsigned char)((i >> 24) & 0xff);
|
|
||||||
itmp[1] = (unsigned char)((i >> 16) & 0xff);
|
|
||||||
itmp[2] = (unsigned char)((i >> 8) & 0xff);
|
|
||||||
itmp[3] = (unsigned char)(i & 0xff);
|
|
||||||
if (!HMAC_CTX_copy(hctx, hctx_tpl)) {
|
|
||||||
HMAC_CTX_free(hctx);
|
|
||||||
HMAC_CTX_free(hctx_tpl);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (!HMAC_Update(hctx, salt, saltlen)
|
|
||||||
|| !HMAC_Update(hctx, itmp, 4)
|
|
||||||
|| !HMAC_Final(hctx, digtmp, NULL)) {
|
|
||||||
HMAC_CTX_free(hctx);
|
|
||||||
HMAC_CTX_free(hctx_tpl);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memcpy(p, digtmp, cplen);
|
|
||||||
for (j = 1; j < iter; j++) {
|
|
||||||
if (!HMAC_CTX_copy(hctx, hctx_tpl)) {
|
|
||||||
HMAC_CTX_free(hctx);
|
|
||||||
HMAC_CTX_free(hctx_tpl);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (!HMAC_Update(hctx, digtmp, mdlen)
|
|
||||||
|| !HMAC_Final(hctx, digtmp, NULL)) {
|
|
||||||
HMAC_CTX_free(hctx);
|
|
||||||
HMAC_CTX_free(hctx_tpl);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
for (k = 0; k < cplen; k++)
|
|
||||||
p[k] ^= digtmp[k];
|
|
||||||
}
|
|
||||||
tkeylen -= cplen;
|
|
||||||
i++;
|
|
||||||
p += cplen;
|
|
||||||
}
|
|
||||||
HMAC_CTX_free(hctx);
|
|
||||||
HMAC_CTX_free(hctx_tpl);
|
|
||||||
# ifdef OPENSSL_DEBUG_PKCS5V2
|
# ifdef OPENSSL_DEBUG_PKCS5V2
|
||||||
fprintf(stderr, "Password:\n");
|
fprintf(stderr, "Password:\n");
|
||||||
h__dump(pass, passlen);
|
h__dump(pass, passlen);
|
||||||
@@ -118,7 +64,7 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
|
|||||||
fprintf(stderr, "Key:\n");
|
fprintf(stderr, "Key:\n");
|
||||||
h__dump(out, keylen);
|
h__dump(out, keylen);
|
||||||
# endif
|
# endif
|
||||||
return 1;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
|
int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
|
||||||
|
|||||||
+23
-214
@@ -7,135 +7,12 @@
|
|||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include "internal/numbers.h"
|
#include <openssl/kdf.h>
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_SCRYPT
|
#ifndef OPENSSL_NO_SCRYPT
|
||||||
|
|
||||||
#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
|
|
||||||
static void salsa208_word_specification(uint32_t inout[16])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
uint32_t x[16];
|
|
||||||
memcpy(x, inout, sizeof(x));
|
|
||||||
for (i = 8; i > 0; i -= 2) {
|
|
||||||
x[4] ^= R(x[0] + x[12], 7);
|
|
||||||
x[8] ^= R(x[4] + x[0], 9);
|
|
||||||
x[12] ^= R(x[8] + x[4], 13);
|
|
||||||
x[0] ^= R(x[12] + x[8], 18);
|
|
||||||
x[9] ^= R(x[5] + x[1], 7);
|
|
||||||
x[13] ^= R(x[9] + x[5], 9);
|
|
||||||
x[1] ^= R(x[13] + x[9], 13);
|
|
||||||
x[5] ^= R(x[1] + x[13], 18);
|
|
||||||
x[14] ^= R(x[10] + x[6], 7);
|
|
||||||
x[2] ^= R(x[14] + x[10], 9);
|
|
||||||
x[6] ^= R(x[2] + x[14], 13);
|
|
||||||
x[10] ^= R(x[6] + x[2], 18);
|
|
||||||
x[3] ^= R(x[15] + x[11], 7);
|
|
||||||
x[7] ^= R(x[3] + x[15], 9);
|
|
||||||
x[11] ^= R(x[7] + x[3], 13);
|
|
||||||
x[15] ^= R(x[11] + x[7], 18);
|
|
||||||
x[1] ^= R(x[0] + x[3], 7);
|
|
||||||
x[2] ^= R(x[1] + x[0], 9);
|
|
||||||
x[3] ^= R(x[2] + x[1], 13);
|
|
||||||
x[0] ^= R(x[3] + x[2], 18);
|
|
||||||
x[6] ^= R(x[5] + x[4], 7);
|
|
||||||
x[7] ^= R(x[6] + x[5], 9);
|
|
||||||
x[4] ^= R(x[7] + x[6], 13);
|
|
||||||
x[5] ^= R(x[4] + x[7], 18);
|
|
||||||
x[11] ^= R(x[10] + x[9], 7);
|
|
||||||
x[8] ^= R(x[11] + x[10], 9);
|
|
||||||
x[9] ^= R(x[8] + x[11], 13);
|
|
||||||
x[10] ^= R(x[9] + x[8], 18);
|
|
||||||
x[12] ^= R(x[15] + x[14], 7);
|
|
||||||
x[13] ^= R(x[12] + x[15], 9);
|
|
||||||
x[14] ^= R(x[13] + x[12], 13);
|
|
||||||
x[15] ^= R(x[14] + x[13], 18);
|
|
||||||
}
|
|
||||||
for (i = 0; i < 16; ++i)
|
|
||||||
inout[i] += x[i];
|
|
||||||
OPENSSL_cleanse(x, sizeof(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r)
|
|
||||||
{
|
|
||||||
uint64_t i, j;
|
|
||||||
uint32_t X[16], *pB;
|
|
||||||
|
|
||||||
memcpy(X, B + (r * 2 - 1) * 16, sizeof(X));
|
|
||||||
pB = B;
|
|
||||||
for (i = 0; i < r * 2; i++) {
|
|
||||||
for (j = 0; j < 16; j++)
|
|
||||||
X[j] ^= *pB++;
|
|
||||||
salsa208_word_specification(X);
|
|
||||||
memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X));
|
|
||||||
}
|
|
||||||
OPENSSL_cleanse(X, sizeof(X));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N,
|
|
||||||
uint32_t *X, uint32_t *T, uint32_t *V)
|
|
||||||
{
|
|
||||||
unsigned char *pB;
|
|
||||||
uint32_t *pV;
|
|
||||||
uint64_t i, k;
|
|
||||||
|
|
||||||
/* Convert from little endian input */
|
|
||||||
for (pV = V, i = 0, pB = B; i < 32 * r; i++, pV++) {
|
|
||||||
*pV = *pB++;
|
|
||||||
*pV |= *pB++ << 8;
|
|
||||||
*pV |= *pB++ << 16;
|
|
||||||
*pV |= (uint32_t)*pB++ << 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; i < N; i++, pV += 32 * r)
|
|
||||||
scryptBlockMix(pV, pV - 32 * r, r);
|
|
||||||
|
|
||||||
scryptBlockMix(X, V + (N - 1) * 32 * r, r);
|
|
||||||
|
|
||||||
for (i = 0; i < N; i++) {
|
|
||||||
uint32_t j;
|
|
||||||
j = X[16 * (2 * r - 1)] % N;
|
|
||||||
pV = V + 32 * r * j;
|
|
||||||
for (k = 0; k < 32 * r; k++)
|
|
||||||
T[k] = X[k] ^ *pV++;
|
|
||||||
scryptBlockMix(X, T, r);
|
|
||||||
}
|
|
||||||
/* Convert output to little endian */
|
|
||||||
for (i = 0, pB = B; i < 32 * r; i++) {
|
|
||||||
uint32_t xtmp = X[i];
|
|
||||||
*pB++ = xtmp & 0xff;
|
|
||||||
*pB++ = (xtmp >> 8) & 0xff;
|
|
||||||
*pB++ = (xtmp >> 16) & 0xff;
|
|
||||||
*pB++ = (xtmp >> 24) & 0xff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef SIZE_MAX
|
|
||||||
# define SIZE_MAX ((size_t)-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Maximum power of two that will fit in uint64_t: this should work on
|
|
||||||
* most (all?) platforms.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define LOG2_UINT64_MAX (sizeof(uint64_t) * 8 - 1)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Maximum value of p * r:
|
|
||||||
* p <= ((2^32-1) * hLen) / MFLen =>
|
|
||||||
* p <= ((2^32-1) * 32) / (128 * r) =>
|
|
||||||
* p * r <= (2^30-1)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SCRYPT_PR_MAX ((1 << 30) - 1)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maximum permitted memory allow this to be overridden with Configuration
|
* Maximum permitted memory allow this to be overridden with Configuration
|
||||||
* option: e.g. -DSCRYPT_MAX_MEM=0 for maximum possible.
|
* option: e.g. -DSCRYPT_MAX_MEM=0 for maximum possible.
|
||||||
@@ -160,107 +37,39 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen,
|
|||||||
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
|
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
|
||||||
unsigned char *key, size_t keylen)
|
unsigned char *key, size_t keylen)
|
||||||
{
|
{
|
||||||
int rv = 0;
|
const char *empty = "";
|
||||||
unsigned char *B;
|
int rv = 1;
|
||||||
uint32_t *X, *V, *T;
|
EVP_KDF_CTX *kctx;
|
||||||
uint64_t i, Blen, Vlen;
|
|
||||||
|
|
||||||
/* Sanity check parameters */
|
if (r > UINT32_MAX || p > UINT32_MAX) {
|
||||||
/* initial check, r,p must be non zero, N >= 2 and a power of 2 */
|
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PARAMETER_TOO_LARGE);
|
||||||
if (r == 0 || p == 0 || N < 2 || (N & (N - 1)))
|
|
||||||
return 0;
|
|
||||||
/* Check p * r < SCRYPT_PR_MAX avoiding overflow */
|
|
||||||
if (p > SCRYPT_PR_MAX / r) {
|
|
||||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Maintain existing behaviour. */
|
||||||
* Need to check N: if 2^(128 * r / 8) overflows limit this is
|
if (pass == NULL) {
|
||||||
* automatically satisfied since N <= UINT64_MAX.
|
pass = empty;
|
||||||
*/
|
passlen = 0;
|
||||||
|
|
||||||
if (16 * r <= LOG2_UINT64_MAX) {
|
|
||||||
if (N >= (((uint64_t)1) << (16 * r))) {
|
|
||||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Memory checks: check total allocated buffer size fits in uint64_t */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* B size in section 5 step 1.S
|
|
||||||
* Note: we know p * 128 * r < UINT64_MAX because we already checked
|
|
||||||
* p * r < SCRYPT_PR_MAX
|
|
||||||
*/
|
|
||||||
Blen = p * 128 * r;
|
|
||||||
/*
|
|
||||||
* Yet we pass it as integer to PKCS5_PBKDF2_HMAC... [This would
|
|
||||||
* have to be revised when/if PKCS5_PBKDF2_HMAC accepts size_t.]
|
|
||||||
*/
|
|
||||||
if (Blen > INT_MAX) {
|
|
||||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check 32 * r * (N + 2) * sizeof(uint32_t) fits in uint64_t
|
|
||||||
* This is combined size V, X and T (section 4)
|
|
||||||
*/
|
|
||||||
i = UINT64_MAX / (32 * sizeof(uint32_t));
|
|
||||||
if (N + 2 > i / r) {
|
|
||||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Vlen = 32 * r * (N + 2) * sizeof(uint32_t);
|
|
||||||
|
|
||||||
/* check total allocated size fits in uint64_t */
|
|
||||||
if (Blen > UINT64_MAX - Vlen) {
|
|
||||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxmem == 0)
|
if (maxmem == 0)
|
||||||
maxmem = SCRYPT_MAX_MEM;
|
maxmem = SCRYPT_MAX_MEM;
|
||||||
|
|
||||||
/* Check that the maximum memory doesn't exceed a size_t limits */
|
kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT);
|
||||||
if (maxmem > SIZE_MAX)
|
if (kctx == NULL)
|
||||||
maxmem = SIZE_MAX;
|
|
||||||
|
|
||||||
if (Blen + Vlen > maxmem) {
|
|
||||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
/* If no key return to indicate parameters are OK */
|
if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, pass, (size_t)passlen) != 1
|
||||||
if (key == NULL)
|
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT,
|
||||||
return 1;
|
salt, (size_t)saltlen) != 1
|
||||||
|
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_N, N) != 1
|
||||||
|
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_R, (uint32_t)r) != 1
|
||||||
|
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_P, (uint32_t)p) != 1
|
||||||
|
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAXMEM_BYTES, maxmem) != 1
|
||||||
|
|| EVP_KDF_derive(kctx, key, keylen) != 1)
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
B = OPENSSL_malloc((size_t)(Blen + Vlen));
|
EVP_KDF_CTX_free(kctx);
|
||||||
if (B == NULL) {
|
|
||||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, ERR_R_MALLOC_FAILURE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
X = (uint32_t *)(B + Blen);
|
|
||||||
T = X + 32 * r;
|
|
||||||
V = T + 32 * r;
|
|
||||||
if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(),
|
|
||||||
(int)Blen, B) == 0)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
for (i = 0; i < p; i++)
|
|
||||||
scryptROMix(B + 128 * r * i, r, N, X, T, V);
|
|
||||||
|
|
||||||
if (PKCS5_PBKDF2_HMAC(pass, passlen, B, (int)Blen, 1, EVP_sha256(),
|
|
||||||
keylen, key) == 0)
|
|
||||||
goto err;
|
|
||||||
rv = 1;
|
|
||||||
err:
|
|
||||||
if (rv == 0)
|
|
||||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PBKDF2_ERROR);
|
|
||||||
|
|
||||||
OPENSSL_clear_free(B, (size_t)(Blen + Vlen));
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,255 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. 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 <openssl/kdf.h>
|
||||||
|
#include "internal/evp_int.h"
|
||||||
|
|
||||||
|
static int pkey_kdf_init(EVP_PKEY_CTX *ctx)
|
||||||
|
{
|
||||||
|
EVP_KDF_CTX *kctx;
|
||||||
|
|
||||||
|
kctx = EVP_KDF_CTX_new_id(ctx->pmeth->pkey_id);
|
||||||
|
if (kctx == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ctx->data = kctx;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pkey_kdf_cleanup(EVP_PKEY_CTX *ctx)
|
||||||
|
{
|
||||||
|
EVP_KDF_CTX *kctx = ctx->data;
|
||||||
|
|
||||||
|
EVP_KDF_CTX_free(kctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pkey_kdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||||
|
{
|
||||||
|
EVP_KDF_CTX *kctx = ctx->data;
|
||||||
|
uint64_t u64_value;
|
||||||
|
int cmd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case EVP_PKEY_CTRL_PASS:
|
||||||
|
cmd = EVP_KDF_CTRL_SET_PASS;
|
||||||
|
break;
|
||||||
|
case EVP_PKEY_CTRL_HKDF_SALT:
|
||||||
|
case EVP_PKEY_CTRL_SCRYPT_SALT:
|
||||||
|
cmd = EVP_KDF_CTRL_SET_SALT;
|
||||||
|
break;
|
||||||
|
case EVP_PKEY_CTRL_TLS_MD:
|
||||||
|
case EVP_PKEY_CTRL_HKDF_MD:
|
||||||
|
cmd = EVP_KDF_CTRL_SET_MD;
|
||||||
|
break;
|
||||||
|
case EVP_PKEY_CTRL_TLS_SECRET:
|
||||||
|
cmd = EVP_KDF_CTRL_SET_TLS_SECRET;
|
||||||
|
ret = EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_RESET_TLS_SEED);
|
||||||
|
if (ret < 1)
|
||||||
|
return ret;
|
||||||
|
break;
|
||||||
|
case EVP_PKEY_CTRL_TLS_SEED:
|
||||||
|
cmd = EVP_KDF_CTRL_ADD_TLS_SEED;
|
||||||
|
break;
|
||||||
|
case EVP_PKEY_CTRL_HKDF_KEY:
|
||||||
|
cmd = EVP_KDF_CTRL_SET_KEY;
|
||||||
|
break;
|
||||||
|
case EVP_PKEY_CTRL_HKDF_INFO:
|
||||||
|
cmd = EVP_KDF_CTRL_ADD_HKDF_INFO;
|
||||||
|
break;
|
||||||
|
case EVP_PKEY_CTRL_HKDF_MODE:
|
||||||
|
cmd = EVP_KDF_CTRL_SET_HKDF_MODE;
|
||||||
|
break;
|
||||||
|
case EVP_PKEY_CTRL_SCRYPT_N:
|
||||||
|
cmd = EVP_KDF_CTRL_SET_SCRYPT_N;
|
||||||
|
break;
|
||||||
|
case EVP_PKEY_CTRL_SCRYPT_R:
|
||||||
|
cmd = EVP_KDF_CTRL_SET_SCRYPT_R;
|
||||||
|
break;
|
||||||
|
case EVP_PKEY_CTRL_SCRYPT_P:
|
||||||
|
cmd = EVP_KDF_CTRL_SET_SCRYPT_P;
|
||||||
|
break;
|
||||||
|
case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES:
|
||||||
|
cmd = EVP_KDF_CTRL_SET_MAXMEM_BYTES;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case EVP_KDF_CTRL_SET_PASS:
|
||||||
|
case EVP_KDF_CTRL_SET_SALT:
|
||||||
|
case EVP_KDF_CTRL_SET_KEY:
|
||||||
|
case EVP_KDF_CTRL_SET_TLS_SECRET:
|
||||||
|
case EVP_KDF_CTRL_ADD_TLS_SEED:
|
||||||
|
case EVP_KDF_CTRL_ADD_HKDF_INFO:
|
||||||
|
return EVP_KDF_ctrl(kctx, cmd, (const unsigned char *)p2, (size_t)p1);
|
||||||
|
|
||||||
|
case EVP_KDF_CTRL_SET_MD:
|
||||||
|
return EVP_KDF_ctrl(kctx, cmd, (const EVP_MD *)p2);
|
||||||
|
|
||||||
|
case EVP_KDF_CTRL_SET_HKDF_MODE:
|
||||||
|
return EVP_KDF_ctrl(kctx, cmd, (int)p1);
|
||||||
|
|
||||||
|
case EVP_KDF_CTRL_SET_SCRYPT_R:
|
||||||
|
case EVP_KDF_CTRL_SET_SCRYPT_P:
|
||||||
|
u64_value = *(uint64_t *)p2;
|
||||||
|
if (u64_value > UINT32_MAX) {
|
||||||
|
EVPerr(EVP_F_PKEY_KDF_CTRL, EVP_R_PARAMETER_TOO_LARGE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EVP_KDF_ctrl(kctx, cmd, (uint32_t)u64_value);
|
||||||
|
|
||||||
|
case EVP_KDF_CTRL_SET_SCRYPT_N:
|
||||||
|
case EVP_KDF_CTRL_SET_MAXMEM_BYTES:
|
||||||
|
return EVP_KDF_ctrl(kctx, cmd, *(uint64_t *)p2);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
|
||||||
|
const char *value)
|
||||||
|
{
|
||||||
|
EVP_KDF_CTX *kctx = ctx->data;
|
||||||
|
|
||||||
|
if (strcmp(type, "md") == 0)
|
||||||
|
return EVP_KDF_ctrl_str(kctx, "digest", value);
|
||||||
|
return EVP_KDF_ctrl_str(kctx, type, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pkey_kdf_derive_init(EVP_PKEY_CTX *ctx)
|
||||||
|
{
|
||||||
|
EVP_KDF_CTX *kctx = ctx->data;
|
||||||
|
|
||||||
|
EVP_KDF_reset(kctx);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For fixed-output algorithms the keylen parameter is an "out" parameter
|
||||||
|
* otherwise it is an "in" parameter.
|
||||||
|
*/
|
||||||
|
static int pkey_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||||
|
size_t *keylen)
|
||||||
|
{
|
||||||
|
EVP_KDF_CTX *kctx = ctx->data;
|
||||||
|
size_t outlen = EVP_KDF_size(kctx);
|
||||||
|
|
||||||
|
if (outlen == 0 || outlen == SIZE_MAX) {
|
||||||
|
/* Variable-output algorithm */
|
||||||
|
if (key == NULL)
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* Fixed-output algorithm */
|
||||||
|
*keylen = outlen;
|
||||||
|
if (key == NULL)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return EVP_KDF_derive(kctx, key, *keylen);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_SCRYPT
|
||||||
|
const EVP_PKEY_METHOD scrypt_pkey_meth = {
|
||||||
|
EVP_PKEY_SCRYPT,
|
||||||
|
0,
|
||||||
|
pkey_kdf_init,
|
||||||
|
0,
|
||||||
|
pkey_kdf_cleanup,
|
||||||
|
|
||||||
|
0, 0,
|
||||||
|
0, 0,
|
||||||
|
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
0, 0,
|
||||||
|
|
||||||
|
0, 0, 0, 0,
|
||||||
|
|
||||||
|
0, 0,
|
||||||
|
|
||||||
|
0, 0,
|
||||||
|
|
||||||
|
pkey_kdf_derive_init,
|
||||||
|
pkey_kdf_derive,
|
||||||
|
pkey_kdf_ctrl,
|
||||||
|
pkey_kdf_ctrl_str
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const EVP_PKEY_METHOD tls1_prf_pkey_meth = {
|
||||||
|
EVP_PKEY_TLS1_PRF,
|
||||||
|
0,
|
||||||
|
pkey_kdf_init,
|
||||||
|
0,
|
||||||
|
pkey_kdf_cleanup,
|
||||||
|
|
||||||
|
0, 0,
|
||||||
|
0, 0,
|
||||||
|
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
0, 0,
|
||||||
|
|
||||||
|
0, 0, 0, 0,
|
||||||
|
|
||||||
|
0, 0,
|
||||||
|
|
||||||
|
0, 0,
|
||||||
|
|
||||||
|
pkey_kdf_derive_init,
|
||||||
|
pkey_kdf_derive,
|
||||||
|
pkey_kdf_ctrl,
|
||||||
|
pkey_kdf_ctrl_str
|
||||||
|
};
|
||||||
|
|
||||||
|
const EVP_PKEY_METHOD hkdf_pkey_meth = {
|
||||||
|
EVP_PKEY_HKDF,
|
||||||
|
0,
|
||||||
|
pkey_kdf_init,
|
||||||
|
0,
|
||||||
|
pkey_kdf_cleanup,
|
||||||
|
|
||||||
|
0, 0,
|
||||||
|
0, 0,
|
||||||
|
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
0, 0,
|
||||||
|
|
||||||
|
0, 0, 0, 0,
|
||||||
|
|
||||||
|
0, 0,
|
||||||
|
|
||||||
|
0, 0,
|
||||||
|
|
||||||
|
pkey_kdf_derive_init,
|
||||||
|
pkey_kdf_derive,
|
||||||
|
pkey_kdf_ctrl,
|
||||||
|
pkey_kdf_ctrl_str
|
||||||
|
};
|
||||||
|
|
||||||
@@ -362,6 +362,36 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
|
|||||||
ad->sk = NULL;
|
ad->sk = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate a given CRYPTO_EX_DATA item using the class specific allocation
|
||||||
|
* function
|
||||||
|
*/
|
||||||
|
int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,
|
||||||
|
int idx)
|
||||||
|
{
|
||||||
|
EX_CALLBACK *f;
|
||||||
|
EX_CALLBACKS *ip;
|
||||||
|
void *curval;
|
||||||
|
|
||||||
|
curval = CRYPTO_get_ex_data(ad, idx);
|
||||||
|
|
||||||
|
/* Already there, no need to allocate */
|
||||||
|
if (curval != NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ip = get_and_lock(class_index);
|
||||||
|
f = sk_EX_CALLBACK_value(ip->meth, idx);
|
||||||
|
CRYPTO_THREAD_unlock(ex_data_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This should end up calling CRYPTO_set_ex_data(), which allocates
|
||||||
|
* everything necessary to support placing the new data in the right spot.
|
||||||
|
*/
|
||||||
|
f->new_func(obj, curval, ad, idx, f->argl, f->argp);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For a given CRYPTO_EX_DATA variable, set the value corresponding to a
|
* For a given CRYPTO_EX_DATA variable, set the value corresponding to a
|
||||||
* particular index in the class used by this variable
|
* particular index in the class used by this variable
|
||||||
|
|||||||
@@ -151,6 +151,24 @@ const EVP_MD *evp_keccak_kmac256(void);
|
|||||||
*/
|
*/
|
||||||
int EVP_add_mac(const EVP_MAC *mac);
|
int EVP_add_mac(const EVP_MAC *mac);
|
||||||
|
|
||||||
|
/* struct evp_kdf_impl_st is defined by the implementation */
|
||||||
|
typedef struct evp_kdf_impl_st EVP_KDF_IMPL;
|
||||||
|
typedef struct {
|
||||||
|
int type;
|
||||||
|
EVP_KDF_IMPL *(*new) (void);
|
||||||
|
void (*free) (EVP_KDF_IMPL *impl);
|
||||||
|
void (*reset) (EVP_KDF_IMPL *impl);
|
||||||
|
int (*ctrl) (EVP_KDF_IMPL *impl, int cmd, va_list args);
|
||||||
|
int (*ctrl_str) (EVP_KDF_IMPL *impl, const char *type, const char *value);
|
||||||
|
size_t (*size) (EVP_KDF_IMPL *impl);
|
||||||
|
int (*derive) (EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen);
|
||||||
|
} EVP_KDF_METHOD;
|
||||||
|
|
||||||
|
extern const EVP_KDF_METHOD pbkdf2_kdf_meth;
|
||||||
|
extern const EVP_KDF_METHOD scrypt_kdf_meth;
|
||||||
|
extern const EVP_KDF_METHOD tls1_prf_kdf_meth;
|
||||||
|
extern const EVP_KDF_METHOD hkdf_kdf_meth;
|
||||||
|
|
||||||
struct evp_md_st {
|
struct evp_md_st {
|
||||||
int type;
|
int type;
|
||||||
int pkey_type;
|
int pkey_type;
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
|
* Copyright (c) 2019, Oracle and/or its affiliates. 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_SPARSE_ARRAY_H
|
||||||
|
# define HEADER_SPARSE_ARRAY_H
|
||||||
|
|
||||||
|
# include <openssl/e_os2.h>
|
||||||
|
|
||||||
|
# ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define SPARSE_ARRAY_OF(type) struct sparse_array_st_ ## type
|
||||||
|
|
||||||
|
# define DEFINE_SPARSE_ARRAY_OF(type) \
|
||||||
|
SPARSE_ARRAY_OF(type); \
|
||||||
|
static ossl_unused ossl_inline SPARSE_ARRAY_OF(type) * \
|
||||||
|
ossl_sa_##type##_new(void) \
|
||||||
|
{ \
|
||||||
|
return (SPARSE_ARRAY_OF(type) *)OPENSSL_SA_new(); \
|
||||||
|
} \
|
||||||
|
static ossl_unused ossl_inline void ossl_sa_##type##_free(SPARSE_ARRAY_OF(type) *sa) \
|
||||||
|
{ \
|
||||||
|
OPENSSL_SA_free((OPENSSL_SA *)sa); \
|
||||||
|
} \
|
||||||
|
static ossl_unused ossl_inline void ossl_sa_##type##_free_leaves(SPARSE_ARRAY_OF(type) *sa) \
|
||||||
|
{ \
|
||||||
|
OPENSSL_SA_free_leaves((OPENSSL_SA *)sa); \
|
||||||
|
} \
|
||||||
|
static ossl_unused ossl_inline size_t ossl_sa_##type##_num(const SPARSE_ARRAY_OF(type) *sa) \
|
||||||
|
{ \
|
||||||
|
return OPENSSL_SA_num((OPENSSL_SA *)sa); \
|
||||||
|
} \
|
||||||
|
static ossl_unused ossl_inline void ossl_sa_##type##_doall(const SPARSE_ARRAY_OF(type) *sa, \
|
||||||
|
void (*leaf)(size_t, type *)) \
|
||||||
|
{ \
|
||||||
|
OPENSSL_SA_doall((OPENSSL_SA *)sa, (void (*)(size_t, void *))leaf); \
|
||||||
|
} \
|
||||||
|
static ossl_unused ossl_inline \
|
||||||
|
void ossl_sa_##type##_doall_arg(const SPARSE_ARRAY_OF(type) *sa, \
|
||||||
|
void (*leaf)(size_t, type *, void *), \
|
||||||
|
void *arg) \
|
||||||
|
{ \
|
||||||
|
OPENSSL_SA_doall_arg((OPENSSL_SA *)sa, (void (*)(size_t, void *, void *))leaf, \
|
||||||
|
arg); \
|
||||||
|
} \
|
||||||
|
static ossl_unused ossl_inline type *ossl_sa_##type##_get(const SPARSE_ARRAY_OF(type) *sa, \
|
||||||
|
size_t n) \
|
||||||
|
{ \
|
||||||
|
return (type *)OPENSSL_SA_get((OPENSSL_SA *)sa, n); \
|
||||||
|
} \
|
||||||
|
static ossl_unused ossl_inline int ossl_sa_##type##_set(SPARSE_ARRAY_OF(type) *sa, \
|
||||||
|
size_t n, type *val) \
|
||||||
|
{ \
|
||||||
|
return OPENSSL_SA_set((OPENSSL_SA *)sa, n, (void *)val); \
|
||||||
|
} \
|
||||||
|
SPARSE_ARRAY_OF(type)
|
||||||
|
|
||||||
|
typedef struct sparse_array_st OPENSSL_SA;
|
||||||
|
OPENSSL_SA *OPENSSL_SA_new(void);
|
||||||
|
void OPENSSL_SA_free(OPENSSL_SA *sa);
|
||||||
|
void OPENSSL_SA_free_leaves(OPENSSL_SA *sa);
|
||||||
|
size_t OPENSSL_SA_num(const OPENSSL_SA *sa);
|
||||||
|
void OPENSSL_SA_doall(const OPENSSL_SA *sa, void (*leaf)(size_t, void *));
|
||||||
|
void OPENSSL_SA_doall_arg(const OPENSSL_SA *sa,
|
||||||
|
void (*leaf)(size_t, void *, void *), void *);
|
||||||
|
void *OPENSSL_SA_get(const OPENSSL_SA *sa, size_t n);
|
||||||
|
int OPENSSL_SA_set(OPENSSL_SA *sa, size_t n, void *val);
|
||||||
|
|
||||||
|
# ifdef __cplusplus
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
+17
-17
@@ -353,18 +353,6 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
|
|||||||
engine_load_openssl_int();
|
engine_load_openssl_int();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
# ifndef OPENSSL_NO_DEVCRYPTOENG
|
|
||||||
static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
|
|
||||||
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
|
|
||||||
{
|
|
||||||
# ifdef OPENSSL_INIT_DEBUG
|
|
||||||
fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: "
|
|
||||||
"engine_load_devcrypto_int()\n");
|
|
||||||
# endif
|
|
||||||
engine_load_devcrypto_int();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef OPENSSL_NO_RDRAND
|
# ifndef OPENSSL_NO_RDRAND
|
||||||
static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
|
static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
|
||||||
@@ -389,6 +377,18 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
# ifndef OPENSSL_NO_STATIC_ENGINE
|
# ifndef OPENSSL_NO_STATIC_ENGINE
|
||||||
|
# ifndef OPENSSL_NO_DEVCRYPTOENG
|
||||||
|
static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
|
||||||
|
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
|
||||||
|
{
|
||||||
|
# ifdef OPENSSL_INIT_DEBUG
|
||||||
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: "
|
||||||
|
"engine_load_devcrypto_int()\n");
|
||||||
|
# endif
|
||||||
|
engine_load_devcrypto_int();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
|
# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
|
||||||
static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
|
static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
|
||||||
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
|
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
|
||||||
@@ -747,11 +747,6 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
|
|||||||
if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
|
if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
|
||||||
&& !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
|
&& !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
|
||||||
return 0;
|
return 0;
|
||||||
# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG)
|
|
||||||
if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
|
|
||||||
&& !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
|
|
||||||
return 0;
|
|
||||||
# endif
|
|
||||||
# ifndef OPENSSL_NO_RDRAND
|
# ifndef OPENSSL_NO_RDRAND
|
||||||
if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
|
if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
|
||||||
&& !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
|
&& !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
|
||||||
@@ -761,6 +756,11 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
|
|||||||
&& !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
|
&& !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
|
||||||
return 0;
|
return 0;
|
||||||
# ifndef OPENSSL_NO_STATIC_ENGINE
|
# ifndef OPENSSL_NO_STATIC_ENGINE
|
||||||
|
# ifndef OPENSSL_NO_DEVCRYPTOENG
|
||||||
|
if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
|
||||||
|
&& !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
|
||||||
|
return 0;
|
||||||
|
# endif
|
||||||
# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
|
# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
|
||||||
if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
|
if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
|
||||||
&& !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
|
&& !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
LIBS=../../libcrypto
|
LIBS=../../libcrypto
|
||||||
SOURCE[../../libcrypto]=\
|
SOURCE[../../libcrypto]=\
|
||||||
tls1_prf.c kdf_err.c hkdf.c scrypt.c
|
tls1_prf.c kdf_err.c kdf_util.c hkdf.c scrypt.c pbkdf2.c
|
||||||
+131
-157
@@ -8,32 +8,33 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
#include <openssl/kdf.h>
|
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/kdf.h>
|
||||||
#include "internal/cryptlib.h"
|
#include "internal/cryptlib.h"
|
||||||
#include "internal/evp_int.h"
|
#include "internal/evp_int.h"
|
||||||
|
#include "kdf_local.h"
|
||||||
|
|
||||||
#define HKDF_MAXBUF 1024
|
#define HKDF_MAXBUF 1024
|
||||||
|
|
||||||
static unsigned char *HKDF(const EVP_MD *evp_md,
|
static void kdf_hkdf_reset(EVP_KDF_IMPL *impl);
|
||||||
|
static int HKDF(const EVP_MD *evp_md,
|
||||||
const unsigned char *salt, size_t salt_len,
|
const unsigned char *salt, size_t salt_len,
|
||||||
const unsigned char *key, size_t key_len,
|
const unsigned char *key, size_t key_len,
|
||||||
const unsigned char *info, size_t info_len,
|
const unsigned char *info, size_t info_len,
|
||||||
unsigned char *okm, size_t okm_len);
|
unsigned char *okm, size_t okm_len);
|
||||||
|
static int HKDF_Extract(const EVP_MD *evp_md,
|
||||||
static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
|
|
||||||
const unsigned char *salt, size_t salt_len,
|
const unsigned char *salt, size_t salt_len,
|
||||||
const unsigned char *key, size_t key_len,
|
const unsigned char *key, size_t key_len,
|
||||||
unsigned char *prk, size_t *prk_len);
|
unsigned char *prk, size_t prk_len);
|
||||||
|
static int HKDF_Expand(const EVP_MD *evp_md,
|
||||||
static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
|
|
||||||
const unsigned char *prk, size_t prk_len,
|
const unsigned char *prk, size_t prk_len,
|
||||||
const unsigned char *info, size_t info_len,
|
const unsigned char *info, size_t info_len,
|
||||||
unsigned char *okm, size_t okm_len);
|
unsigned char *okm, size_t okm_len);
|
||||||
|
|
||||||
typedef struct {
|
struct evp_kdf_impl_st {
|
||||||
int mode;
|
int mode;
|
||||||
const EVP_MD *md;
|
const EVP_MD *md;
|
||||||
unsigned char *salt;
|
unsigned char *salt;
|
||||||
@@ -42,230 +43,208 @@ typedef struct {
|
|||||||
size_t key_len;
|
size_t key_len;
|
||||||
unsigned char info[HKDF_MAXBUF];
|
unsigned char info[HKDF_MAXBUF];
|
||||||
size_t info_len;
|
size_t info_len;
|
||||||
} HKDF_PKEY_CTX;
|
};
|
||||||
|
|
||||||
static int pkey_hkdf_init(EVP_PKEY_CTX *ctx)
|
static EVP_KDF_IMPL *kdf_hkdf_new(void)
|
||||||
{
|
{
|
||||||
HKDF_PKEY_CTX *kctx;
|
EVP_KDF_IMPL *impl;
|
||||||
|
|
||||||
if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL) {
|
if ((impl = OPENSSL_zalloc(sizeof(*impl))) == NULL)
|
||||||
KDFerr(KDF_F_PKEY_HKDF_INIT, ERR_R_MALLOC_FAILURE);
|
KDFerr(KDF_F_KDF_HKDF_NEW, ERR_R_MALLOC_FAILURE);
|
||||||
return 0;
|
return impl;
|
||||||
}
|
|
||||||
|
|
||||||
ctx->data = kctx;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pkey_hkdf_cleanup(EVP_PKEY_CTX *ctx)
|
static void kdf_hkdf_free(EVP_KDF_IMPL *impl)
|
||||||
{
|
{
|
||||||
HKDF_PKEY_CTX *kctx = ctx->data;
|
kdf_hkdf_reset(impl);
|
||||||
OPENSSL_clear_free(kctx->salt, kctx->salt_len);
|
OPENSSL_free(impl);
|
||||||
OPENSSL_clear_free(kctx->key, kctx->key_len);
|
|
||||||
OPENSSL_cleanse(kctx->info, kctx->info_len);
|
|
||||||
OPENSSL_free(kctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
static void kdf_hkdf_reset(EVP_KDF_IMPL *impl)
|
||||||
{
|
{
|
||||||
HKDF_PKEY_CTX *kctx = ctx->data;
|
OPENSSL_free(impl->salt);
|
||||||
|
OPENSSL_clear_free(impl->key, impl->key_len);
|
||||||
|
OPENSSL_cleanse(impl->info, impl->info_len);
|
||||||
|
memset(impl, 0, sizeof(*impl));
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
static int kdf_hkdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
|
||||||
case EVP_PKEY_CTRL_HKDF_MD:
|
{
|
||||||
if (p2 == NULL)
|
const unsigned char *p;
|
||||||
|
size_t len;
|
||||||
|
const EVP_MD *md;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case EVP_KDF_CTRL_SET_MD:
|
||||||
|
md = va_arg(args, const EVP_MD *);
|
||||||
|
if (md == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
kctx->md = p2;
|
impl->md = md;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case EVP_PKEY_CTRL_HKDF_MODE:
|
case EVP_KDF_CTRL_SET_HKDF_MODE:
|
||||||
kctx->mode = p1;
|
impl->mode = va_arg(args, int);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case EVP_PKEY_CTRL_HKDF_SALT:
|
case EVP_KDF_CTRL_SET_SALT:
|
||||||
if (p1 == 0 || p2 == NULL)
|
p = va_arg(args, const unsigned char *);
|
||||||
|
len = va_arg(args, size_t);
|
||||||
|
if (len == 0 || p == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (p1 < 0)
|
OPENSSL_free(impl->salt);
|
||||||
|
impl->salt = OPENSSL_memdup(p, len);
|
||||||
|
if (impl->salt == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (kctx->salt != NULL)
|
impl->salt_len = len;
|
||||||
OPENSSL_clear_free(kctx->salt, kctx->salt_len);
|
|
||||||
|
|
||||||
kctx->salt = OPENSSL_memdup(p2, p1);
|
|
||||||
if (kctx->salt == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
kctx->salt_len = p1;
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case EVP_PKEY_CTRL_HKDF_KEY:
|
case EVP_KDF_CTRL_SET_KEY:
|
||||||
if (p1 < 0)
|
p = va_arg(args, const unsigned char *);
|
||||||
|
len = va_arg(args, size_t);
|
||||||
|
OPENSSL_clear_free(impl->key, impl->key_len);
|
||||||
|
impl->key = OPENSSL_memdup(p, len);
|
||||||
|
if (impl->key == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (kctx->key != NULL)
|
impl->key_len = len;
|
||||||
OPENSSL_clear_free(kctx->key, kctx->key_len);
|
|
||||||
|
|
||||||
kctx->key = OPENSSL_memdup(p2, p1);
|
|
||||||
if (kctx->key == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
kctx->key_len = p1;
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case EVP_PKEY_CTRL_HKDF_INFO:
|
case EVP_KDF_CTRL_RESET_HKDF_INFO:
|
||||||
if (p1 == 0 || p2 == NULL)
|
OPENSSL_cleanse(impl->info, impl->info_len);
|
||||||
|
impl->info_len = 0;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - kctx->info_len))
|
case EVP_KDF_CTRL_ADD_HKDF_INFO:
|
||||||
|
p = va_arg(args, const unsigned char *);
|
||||||
|
len = va_arg(args, size_t);
|
||||||
|
if (len == 0 || p == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (len > (HKDF_MAXBUF - impl->info_len))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memcpy(kctx->info + kctx->info_len, p2, p1);
|
memcpy(impl->info + impl->info_len, p, len);
|
||||||
kctx->info_len += p1;
|
impl->info_len += len;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
|
static int kdf_hkdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type,
|
||||||
const char *value)
|
const char *value)
|
||||||
{
|
{
|
||||||
if (strcmp(type, "mode") == 0) {
|
if (strcmp(type, "mode") == 0) {
|
||||||
int mode;
|
int mode;
|
||||||
|
|
||||||
if (strcmp(value, "EXTRACT_AND_EXPAND") == 0)
|
if (strcmp(value, "EXTRACT_AND_EXPAND") == 0)
|
||||||
mode = EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND;
|
mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND;
|
||||||
else if (strcmp(value, "EXTRACT_ONLY") == 0)
|
else if (strcmp(value, "EXTRACT_ONLY") == 0)
|
||||||
mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY;
|
mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY;
|
||||||
else if (strcmp(value, "EXPAND_ONLY") == 0)
|
else if (strcmp(value, "EXPAND_ONLY") == 0)
|
||||||
mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;
|
mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return EVP_PKEY_CTX_hkdf_mode(ctx, mode);
|
return call_ctrl(kdf_hkdf_ctrl, impl, EVP_KDF_CTRL_SET_HKDF_MODE, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(type, "md") == 0)
|
if (strcmp(type, "digest") == 0)
|
||||||
return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_DERIVE,
|
return kdf_md2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_MD, value);
|
||||||
EVP_PKEY_CTRL_HKDF_MD, value);
|
|
||||||
|
|
||||||
if (strcmp(type, "salt") == 0)
|
if (strcmp(type, "salt") == 0)
|
||||||
return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
|
return kdf_str2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_SALT, value);
|
||||||
|
|
||||||
if (strcmp(type, "hexsalt") == 0)
|
if (strcmp(type, "hexsalt") == 0)
|
||||||
return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
|
return kdf_hex2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_SALT, value);
|
||||||
|
|
||||||
if (strcmp(type, "key") == 0)
|
if (strcmp(type, "key") == 0)
|
||||||
return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
|
return kdf_str2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_KEY, value);
|
||||||
|
|
||||||
if (strcmp(type, "hexkey") == 0)
|
if (strcmp(type, "hexkey") == 0)
|
||||||
return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
|
return kdf_hex2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_SET_KEY, value);
|
||||||
|
|
||||||
if (strcmp(type, "info") == 0)
|
if (strcmp(type, "info") == 0)
|
||||||
return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
|
return kdf_str2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_ADD_HKDF_INFO,
|
||||||
|
value);
|
||||||
|
|
||||||
if (strcmp(type, "hexinfo") == 0)
|
if (strcmp(type, "hexinfo") == 0)
|
||||||
return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
|
return kdf_hex2ctrl(impl, kdf_hkdf_ctrl, EVP_KDF_CTRL_ADD_HKDF_INFO,
|
||||||
|
value);
|
||||||
|
|
||||||
KDFerr(KDF_F_PKEY_HKDF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE);
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_hkdf_derive_init(EVP_PKEY_CTX *ctx)
|
static size_t kdf_hkdf_size(EVP_KDF_IMPL *impl)
|
||||||
{
|
{
|
||||||
HKDF_PKEY_CTX *kctx = ctx->data;
|
if (impl->mode != EVP_KDF_HKDF_MODE_EXTRACT_ONLY)
|
||||||
|
return SIZE_MAX;
|
||||||
|
|
||||||
OPENSSL_clear_free(kctx->key, kctx->key_len);
|
if (impl->md == NULL) {
|
||||||
OPENSSL_clear_free(kctx->salt, kctx->salt_len);
|
KDFerr(KDF_F_KDF_HKDF_SIZE, KDF_R_MISSING_MESSAGE_DIGEST);
|
||||||
OPENSSL_cleanse(kctx->info, kctx->info_len);
|
return 0;
|
||||||
memset(kctx, 0, sizeof(*kctx));
|
}
|
||||||
|
return EVP_MD_size(impl->md);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
static int kdf_hkdf_derive(EVP_KDF_IMPL *impl, unsigned char *key,
|
||||||
size_t *keylen)
|
size_t keylen)
|
||||||
{
|
{
|
||||||
HKDF_PKEY_CTX *kctx = ctx->data;
|
if (impl->md == NULL) {
|
||||||
|
KDFerr(KDF_F_KDF_HKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
|
||||||
if (kctx->md == NULL) {
|
|
||||||
KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (kctx->key == NULL) {
|
if (impl->key == NULL) {
|
||||||
KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_KEY);
|
KDFerr(KDF_F_KDF_HKDF_DERIVE, KDF_R_MISSING_KEY);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (kctx->mode) {
|
switch (impl->mode) {
|
||||||
case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND:
|
case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
|
||||||
return HKDF(kctx->md, kctx->salt, kctx->salt_len, kctx->key,
|
return HKDF(impl->md, impl->salt, impl->salt_len, impl->key,
|
||||||
kctx->key_len, kctx->info, kctx->info_len, key,
|
impl->key_len, impl->info, impl->info_len, key,
|
||||||
*keylen) != NULL;
|
keylen);
|
||||||
|
|
||||||
case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY:
|
case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
|
||||||
if (key == NULL) {
|
return HKDF_Extract(impl->md, impl->salt, impl->salt_len, impl->key,
|
||||||
*keylen = EVP_MD_size(kctx->md);
|
impl->key_len, key, keylen);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return HKDF_Extract(kctx->md, kctx->salt, kctx->salt_len, kctx->key,
|
|
||||||
kctx->key_len, key, keylen) != NULL;
|
|
||||||
|
|
||||||
case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY:
|
case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
|
||||||
return HKDF_Expand(kctx->md, kctx->key, kctx->key_len, kctx->info,
|
return HKDF_Expand(impl->md, impl->key, impl->key_len, impl->info,
|
||||||
kctx->info_len, key, *keylen) != NULL;
|
impl->info_len, key, keylen);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const EVP_PKEY_METHOD hkdf_pkey_meth = {
|
const EVP_KDF_METHOD hkdf_kdf_meth = {
|
||||||
EVP_PKEY_HKDF,
|
EVP_KDF_HKDF,
|
||||||
0,
|
kdf_hkdf_new,
|
||||||
pkey_hkdf_init,
|
kdf_hkdf_free,
|
||||||
0,
|
kdf_hkdf_reset,
|
||||||
pkey_hkdf_cleanup,
|
kdf_hkdf_ctrl,
|
||||||
|
kdf_hkdf_ctrl_str,
|
||||||
0, 0,
|
kdf_hkdf_size,
|
||||||
0, 0,
|
kdf_hkdf_derive
|
||||||
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
|
|
||||||
0, 0,
|
|
||||||
|
|
||||||
0, 0, 0, 0,
|
|
||||||
|
|
||||||
0, 0,
|
|
||||||
|
|
||||||
0, 0,
|
|
||||||
|
|
||||||
pkey_hkdf_derive_init,
|
|
||||||
pkey_hkdf_derive,
|
|
||||||
pkey_hkdf_ctrl,
|
|
||||||
pkey_hkdf_ctrl_str
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned char *HKDF(const EVP_MD *evp_md,
|
static int HKDF(const EVP_MD *evp_md,
|
||||||
const unsigned char *salt, size_t salt_len,
|
const unsigned char *salt, size_t salt_len,
|
||||||
const unsigned char *key, size_t key_len,
|
const unsigned char *key, size_t key_len,
|
||||||
const unsigned char *info, size_t info_len,
|
const unsigned char *info, size_t info_len,
|
||||||
unsigned char *okm, size_t okm_len)
|
unsigned char *okm, size_t okm_len)
|
||||||
{
|
{
|
||||||
unsigned char prk[EVP_MAX_MD_SIZE];
|
unsigned char prk[EVP_MAX_MD_SIZE];
|
||||||
unsigned char *ret;
|
int ret;
|
||||||
size_t prk_len;
|
size_t prk_len = EVP_MD_size(evp_md);
|
||||||
|
|
||||||
if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, &prk_len))
|
if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, prk_len))
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);
|
ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);
|
||||||
OPENSSL_cleanse(prk, sizeof(prk));
|
OPENSSL_cleanse(prk, sizeof(prk));
|
||||||
@@ -273,43 +252,38 @@ static unsigned char *HKDF(const EVP_MD *evp_md,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
|
static int HKDF_Extract(const EVP_MD *evp_md,
|
||||||
const unsigned char *salt, size_t salt_len,
|
const unsigned char *salt, size_t salt_len,
|
||||||
const unsigned char *key, size_t key_len,
|
const unsigned char *key, size_t key_len,
|
||||||
unsigned char *prk, size_t *prk_len)
|
unsigned char *prk, size_t prk_len)
|
||||||
{
|
{
|
||||||
unsigned int tmp_len;
|
if (prk_len != (size_t)EVP_MD_size(evp_md)) {
|
||||||
|
KDFerr(KDF_F_HKDF_EXTRACT, KDF_R_WRONG_OUTPUT_BUFFER_SIZE);
|
||||||
if (!HMAC(evp_md, salt, salt_len, key, key_len, prk, &tmp_len))
|
return 0;
|
||||||
return NULL;
|
}
|
||||||
|
return HMAC(evp_md, salt, salt_len, key, key_len, prk, NULL) != NULL;
|
||||||
*prk_len = tmp_len;
|
|
||||||
return prk;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
|
static int HKDF_Expand(const EVP_MD *evp_md,
|
||||||
const unsigned char *prk, size_t prk_len,
|
const unsigned char *prk, size_t prk_len,
|
||||||
const unsigned char *info, size_t info_len,
|
const unsigned char *info, size_t info_len,
|
||||||
unsigned char *okm, size_t okm_len)
|
unsigned char *okm, size_t okm_len)
|
||||||
{
|
{
|
||||||
HMAC_CTX *hmac;
|
HMAC_CTX *hmac;
|
||||||
unsigned char *ret = NULL;
|
int ret = 0;
|
||||||
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
unsigned char prev[EVP_MAX_MD_SIZE];
|
unsigned char prev[EVP_MAX_MD_SIZE];
|
||||||
|
|
||||||
size_t done_len = 0, dig_len = EVP_MD_size(evp_md);
|
size_t done_len = 0, dig_len = EVP_MD_size(evp_md);
|
||||||
|
|
||||||
size_t n = okm_len / dig_len;
|
size_t n = okm_len / dig_len;
|
||||||
|
|
||||||
if (okm_len % dig_len)
|
if (okm_len % dig_len)
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
if (n > 255 || okm == NULL)
|
if (n > 255 || okm == NULL)
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
if ((hmac = HMAC_CTX_new()) == NULL)
|
if ((hmac = HMAC_CTX_new()) == NULL)
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))
|
if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))
|
||||||
goto err;
|
goto err;
|
||||||
@@ -343,7 +317,7 @@ static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
|
|||||||
|
|
||||||
done_len += copy_len;
|
done_len += copy_len;
|
||||||
}
|
}
|
||||||
ret = okm;
|
ret = 1;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
OPENSSL_cleanse(prev, sizeof(prev));
|
OPENSSL_cleanse(prev, sizeof(prev));
|
||||||
|
|||||||
+27
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Generated by util/mkerr.pl DO NOT EDIT
|
* Generated by util/mkerr.pl DO NOT EDIT
|
||||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
* 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
|
* this file except in compliance with the License. You can obtain a copy
|
||||||
@@ -14,6 +14,29 @@
|
|||||||
#ifndef OPENSSL_NO_ERR
|
#ifndef OPENSSL_NO_ERR
|
||||||
|
|
||||||
static const ERR_STRING_DATA KDF_str_functs[] = {
|
static const ERR_STRING_DATA KDF_str_functs[] = {
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_HKDF_EXTRACT, 0), "HKDF_Extract"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_DERIVE, 0), "kdf_hkdf_derive"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_NEW, 0), "kdf_hkdf_new"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_HKDF_SIZE, 0), "kdf_hkdf_size"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_MD2CTRL, 0), "kdf_md2ctrl"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_CTRL_STR, 0),
|
||||||
|
"kdf_pbkdf2_ctrl_str"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_DERIVE, 0), "kdf_pbkdf2_derive"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_PBKDF2_NEW, 0), "kdf_pbkdf2_new"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_CTRL_STR, 0),
|
||||||
|
"kdf_scrypt_ctrl_str"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_CTRL_UINT32, 0),
|
||||||
|
"kdf_scrypt_ctrl_uint32"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_CTRL_UINT64, 0),
|
||||||
|
"kdf_scrypt_ctrl_uint64"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_DERIVE, 0), "kdf_scrypt_derive"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_SCRYPT_NEW, 0), "kdf_scrypt_new"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_CTRL_STR, 0),
|
||||||
|
"kdf_tls1_prf_ctrl_str"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_DERIVE, 0),
|
||||||
|
"kdf_tls1_prf_derive"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_KDF_TLS1_PRF_NEW, 0), "kdf_tls1_prf_new"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_PBKDF2_SET_MEMBUF, 0), "pbkdf2_set_membuf"},
|
||||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_CTRL_STR, 0), "pkey_hkdf_ctrl_str"},
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_CTRL_STR, 0), "pkey_hkdf_ctrl_str"},
|
||||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_DERIVE, 0), "pkey_hkdf_derive"},
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_DERIVE, 0), "pkey_hkdf_derive"},
|
||||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_INIT, 0), "pkey_hkdf_init"},
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_HKDF_INIT, 0), "pkey_hkdf_init"},
|
||||||
@@ -30,6 +53,7 @@ static const ERR_STRING_DATA KDF_str_functs[] = {
|
|||||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_DERIVE, 0),
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_DERIVE, 0),
|
||||||
"pkey_tls1_prf_derive"},
|
"pkey_tls1_prf_derive"},
|
||||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_INIT, 0), "pkey_tls1_prf_init"},
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_INIT, 0), "pkey_tls1_prf_init"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_SCRYPT_SET_MEMBUF, 0), "scrypt_set_membuf"},
|
||||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_TLS1_PRF_ALG, 0), "tls1_prf_alg"},
|
{ERR_PACK(ERR_LIB_KDF, KDF_F_TLS1_PRF_ALG, 0), "tls1_prf_alg"},
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
@@ -50,6 +74,8 @@ static const ERR_STRING_DATA KDF_str_reasons[] = {
|
|||||||
"unknown parameter type"},
|
"unknown parameter type"},
|
||||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_VALUE_ERROR), "value error"},
|
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_VALUE_ERROR), "value error"},
|
||||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_VALUE_MISSING), "value missing"},
|
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_VALUE_MISSING), "value missing"},
|
||||||
|
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_WRONG_OUTPUT_BUFFER_SIZE),
|
||||||
|
"wrong output buffer size"},
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
int call_ctrl(int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args),
|
||||||
|
EVP_KDF_IMPL *impl, int cmd, ...);
|
||||||
|
int kdf_str2ctrl(EVP_KDF_IMPL *impl,
|
||||||
|
int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args),
|
||||||
|
int cmd, const char *str);
|
||||||
|
int kdf_hex2ctrl(EVP_KDF_IMPL *impl,
|
||||||
|
int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args),
|
||||||
|
int cmd, const char *hex);
|
||||||
|
int kdf_md2ctrl(EVP_KDF_IMPL *impl,
|
||||||
|
int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args),
|
||||||
|
int cmd, const char *md_name);
|
||||||
|
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. 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 <stdarg.h>
|
||||||
|
#include <openssl/kdf.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include "internal/cryptlib.h"
|
||||||
|
#include "internal/evp_int.h"
|
||||||
|
#include "internal/numbers.h"
|
||||||
|
#include "kdf_local.h"
|
||||||
|
|
||||||
|
int call_ctrl(int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args),
|
||||||
|
EVP_KDF_IMPL *impl, int cmd, ...)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, cmd);
|
||||||
|
ret = ctrl(impl, cmd, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Utility functions to send a string or hex string to a ctrl */
|
||||||
|
|
||||||
|
int kdf_str2ctrl(EVP_KDF_IMPL *impl,
|
||||||
|
int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args),
|
||||||
|
int cmd, const char *str)
|
||||||
|
{
|
||||||
|
return call_ctrl(ctrl, impl, cmd, (const unsigned char *)str, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
int kdf_hex2ctrl(EVP_KDF_IMPL *impl,
|
||||||
|
int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args),
|
||||||
|
int cmd, const char *hex)
|
||||||
|
{
|
||||||
|
unsigned char *bin;
|
||||||
|
long binlen;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
bin = OPENSSL_hexstr2buf(hex, &binlen);
|
||||||
|
if (bin == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (binlen <= INT_MAX)
|
||||||
|
ret = call_ctrl(ctrl, impl, cmd, bin, (size_t)binlen);
|
||||||
|
OPENSSL_free(bin);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pass a message digest to a ctrl */
|
||||||
|
int kdf_md2ctrl(EVP_KDF_IMPL *impl,
|
||||||
|
int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args),
|
||||||
|
int cmd, const char *md_name)
|
||||||
|
{
|
||||||
|
const EVP_MD *md;
|
||||||
|
|
||||||
|
if (md_name == NULL || (md = EVP_get_digestbyname(md_name)) == NULL) {
|
||||||
|
KDFerr(KDF_F_KDF_MD2CTRL, KDF_R_INVALID_DIGEST);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return call_ctrl(ctrl, impl, cmd, md);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,264 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 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 <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/kdf.h>
|
||||||
|
#include "internal/cryptlib.h"
|
||||||
|
#include "internal/evp_int.h"
|
||||||
|
#include "kdf_local.h"
|
||||||
|
|
||||||
|
static void kdf_pbkdf2_reset(EVP_KDF_IMPL *impl);
|
||||||
|
static void kdf_pbkdf2_init(EVP_KDF_IMPL *impl);
|
||||||
|
static int pkcs5_pbkdf2_alg(const char *pass, size_t passlen,
|
||||||
|
const unsigned char *salt, int saltlen, int iter,
|
||||||
|
const EVP_MD *digest, unsigned char *key,
|
||||||
|
size_t keylen);
|
||||||
|
|
||||||
|
struct evp_kdf_impl_st {
|
||||||
|
unsigned char *pass;
|
||||||
|
size_t pass_len;
|
||||||
|
unsigned char *salt;
|
||||||
|
size_t salt_len;
|
||||||
|
int iter;
|
||||||
|
const EVP_MD *md;
|
||||||
|
};
|
||||||
|
|
||||||
|
static EVP_KDF_IMPL *kdf_pbkdf2_new(void)
|
||||||
|
{
|
||||||
|
EVP_KDF_IMPL *impl;
|
||||||
|
|
||||||
|
impl = OPENSSL_zalloc(sizeof(*impl));
|
||||||
|
if (impl == NULL) {
|
||||||
|
KDFerr(KDF_F_KDF_PBKDF2_NEW, ERR_R_MALLOC_FAILURE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
kdf_pbkdf2_init(impl);
|
||||||
|
return impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kdf_pbkdf2_free(EVP_KDF_IMPL *impl)
|
||||||
|
{
|
||||||
|
kdf_pbkdf2_reset(impl);
|
||||||
|
OPENSSL_free(impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kdf_pbkdf2_reset(EVP_KDF_IMPL *impl)
|
||||||
|
{
|
||||||
|
OPENSSL_free(impl->salt);
|
||||||
|
OPENSSL_clear_free(impl->pass, impl->pass_len);
|
||||||
|
memset(impl, 0, sizeof(*impl));
|
||||||
|
kdf_pbkdf2_init(impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kdf_pbkdf2_init(EVP_KDF_IMPL *impl)
|
||||||
|
{
|
||||||
|
impl->iter = PKCS5_DEFAULT_ITER;
|
||||||
|
impl->md = EVP_sha1();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pbkdf2_set_membuf(unsigned char **buffer, size_t *buflen,
|
||||||
|
const unsigned char *new_buffer,
|
||||||
|
size_t new_buflen)
|
||||||
|
{
|
||||||
|
if (new_buffer == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
OPENSSL_clear_free(*buffer, *buflen);
|
||||||
|
|
||||||
|
if (new_buflen > 0) {
|
||||||
|
*buffer = OPENSSL_memdup(new_buffer, new_buflen);
|
||||||
|
} else {
|
||||||
|
*buffer = OPENSSL_malloc(1);
|
||||||
|
}
|
||||||
|
if (*buffer == NULL) {
|
||||||
|
KDFerr(KDF_F_PBKDF2_SET_MEMBUF, ERR_R_MALLOC_FAILURE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buflen = new_buflen;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int kdf_pbkdf2_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
|
||||||
|
{
|
||||||
|
int iter;
|
||||||
|
const unsigned char *p;
|
||||||
|
size_t len;
|
||||||
|
const EVP_MD *md;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case EVP_KDF_CTRL_SET_PASS:
|
||||||
|
p = va_arg(args, const unsigned char *);
|
||||||
|
len = va_arg(args, size_t);
|
||||||
|
return pbkdf2_set_membuf(&impl->pass, &impl->pass_len, p, len);
|
||||||
|
|
||||||
|
case EVP_KDF_CTRL_SET_SALT:
|
||||||
|
p = va_arg(args, const unsigned char *);
|
||||||
|
len = va_arg(args, size_t);
|
||||||
|
return pbkdf2_set_membuf(&impl->salt, &impl->salt_len, p, len);
|
||||||
|
|
||||||
|
case EVP_KDF_CTRL_SET_ITER:
|
||||||
|
iter = va_arg(args, int);
|
||||||
|
if (iter < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
impl->iter = iter;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case EVP_KDF_CTRL_SET_MD:
|
||||||
|
md = va_arg(args, const EVP_MD *);
|
||||||
|
if (md == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
impl->md = md;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int kdf_pbkdf2_ctrl_str(EVP_KDF_IMPL *impl, const char *type,
|
||||||
|
const char *value)
|
||||||
|
{
|
||||||
|
if (value == NULL) {
|
||||||
|
KDFerr(KDF_F_KDF_PBKDF2_CTRL_STR, KDF_R_VALUE_MISSING);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(type, "pass") == 0)
|
||||||
|
return kdf_str2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_PASS,
|
||||||
|
value);
|
||||||
|
|
||||||
|
if (strcmp(type, "hexpass") == 0)
|
||||||
|
return kdf_hex2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_PASS,
|
||||||
|
value);
|
||||||
|
|
||||||
|
if (strcmp(type, "salt") == 0)
|
||||||
|
return kdf_str2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_SALT,
|
||||||
|
value);
|
||||||
|
|
||||||
|
if (strcmp(type, "hexsalt") == 0)
|
||||||
|
return kdf_hex2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_SALT,
|
||||||
|
value);
|
||||||
|
|
||||||
|
if (strcmp(type, "iter") == 0)
|
||||||
|
return call_ctrl(kdf_pbkdf2_ctrl, impl, EVP_KDF_CTRL_SET_ITER,
|
||||||
|
atoi(value));
|
||||||
|
|
||||||
|
if (strcmp(type, "digest") == 0)
|
||||||
|
return kdf_md2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_MD, value);
|
||||||
|
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int kdf_pbkdf2_derive(EVP_KDF_IMPL *impl, unsigned char *key,
|
||||||
|
size_t keylen)
|
||||||
|
{
|
||||||
|
if (impl->pass == NULL) {
|
||||||
|
KDFerr(KDF_F_KDF_PBKDF2_DERIVE, KDF_R_MISSING_PASS);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (impl->salt == NULL) {
|
||||||
|
KDFerr(KDF_F_KDF_PBKDF2_DERIVE, KDF_R_MISSING_SALT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pkcs5_pbkdf2_alg((char *)impl->pass, impl->pass_len,
|
||||||
|
impl->salt, impl->salt_len, impl->iter,
|
||||||
|
impl->md, key, keylen);
|
||||||
|
}
|
||||||
|
|
||||||
|
const EVP_KDF_METHOD pbkdf2_kdf_meth = {
|
||||||
|
EVP_KDF_PBKDF2,
|
||||||
|
kdf_pbkdf2_new,
|
||||||
|
kdf_pbkdf2_free,
|
||||||
|
kdf_pbkdf2_reset,
|
||||||
|
kdf_pbkdf2_ctrl,
|
||||||
|
kdf_pbkdf2_ctrl_str,
|
||||||
|
NULL,
|
||||||
|
kdf_pbkdf2_derive
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an implementation of PKCS#5 v2.0 password based encryption key
|
||||||
|
* derivation function PBKDF2. SHA1 version verified against test vectors
|
||||||
|
* posted by Peter Gutmann to the PKCS-TNG mailing list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int pkcs5_pbkdf2_alg(const char *pass, size_t passlen,
|
||||||
|
const unsigned char *salt, int saltlen, int iter,
|
||||||
|
const EVP_MD *digest, unsigned char *key,
|
||||||
|
size_t keylen)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
|
||||||
|
int cplen, j, k, tkeylen, mdlen;
|
||||||
|
unsigned long i = 1;
|
||||||
|
HMAC_CTX *hctx_tpl = NULL, *hctx = NULL;
|
||||||
|
|
||||||
|
mdlen = EVP_MD_size(digest);
|
||||||
|
if (mdlen < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
hctx_tpl = HMAC_CTX_new();
|
||||||
|
if (hctx_tpl == NULL)
|
||||||
|
return 0;
|
||||||
|
p = key;
|
||||||
|
tkeylen = keylen;
|
||||||
|
if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL))
|
||||||
|
goto err;
|
||||||
|
hctx = HMAC_CTX_new();
|
||||||
|
if (hctx == NULL)
|
||||||
|
goto err;
|
||||||
|
while (tkeylen) {
|
||||||
|
if (tkeylen > mdlen)
|
||||||
|
cplen = mdlen;
|
||||||
|
else
|
||||||
|
cplen = tkeylen;
|
||||||
|
/*
|
||||||
|
* We are unlikely to ever use more than 256 blocks (5120 bits!) but
|
||||||
|
* just in case...
|
||||||
|
*/
|
||||||
|
itmp[0] = (unsigned char)((i >> 24) & 0xff);
|
||||||
|
itmp[1] = (unsigned char)((i >> 16) & 0xff);
|
||||||
|
itmp[2] = (unsigned char)((i >> 8) & 0xff);
|
||||||
|
itmp[3] = (unsigned char)(i & 0xff);
|
||||||
|
if (!HMAC_CTX_copy(hctx, hctx_tpl))
|
||||||
|
goto err;
|
||||||
|
if (!HMAC_Update(hctx, salt, saltlen)
|
||||||
|
|| !HMAC_Update(hctx, itmp, 4)
|
||||||
|
|| !HMAC_Final(hctx, digtmp, NULL))
|
||||||
|
goto err;
|
||||||
|
memcpy(p, digtmp, cplen);
|
||||||
|
for (j = 1; j < iter; j++) {
|
||||||
|
if (!HMAC_CTX_copy(hctx, hctx_tpl))
|
||||||
|
goto err;
|
||||||
|
if (!HMAC_Update(hctx, digtmp, mdlen)
|
||||||
|
|| !HMAC_Final(hctx, digtmp, NULL))
|
||||||
|
goto err;
|
||||||
|
for (k = 0; k < cplen; k++)
|
||||||
|
p[k] ^= digtmp[k];
|
||||||
|
}
|
||||||
|
tkeylen -= cplen;
|
||||||
|
i++;
|
||||||
|
p += cplen;
|
||||||
|
}
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
HMAC_CTX_free(hctx);
|
||||||
|
HMAC_CTX_free(hctx_tpl);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
+368
-128
@@ -8,25 +8,34 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <openssl/hmac.h>
|
|
||||||
#include <openssl/kdf.h>
|
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include "internal/cryptlib.h"
|
#include <openssl/kdf.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
#include "internal/evp_int.h"
|
#include "internal/evp_int.h"
|
||||||
|
#include "internal/numbers.h"
|
||||||
|
#include "kdf_local.h"
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_SCRYPT
|
#ifndef OPENSSL_NO_SCRYPT
|
||||||
|
|
||||||
|
static void kdf_scrypt_reset(EVP_KDF_IMPL *impl);
|
||||||
|
static void kdf_scrypt_init(EVP_KDF_IMPL *impl);
|
||||||
static int atou64(const char *nptr, uint64_t *result);
|
static int atou64(const char *nptr, uint64_t *result);
|
||||||
|
static int scrypt_alg(const char *pass, size_t passlen,
|
||||||
|
const unsigned char *salt, size_t saltlen,
|
||||||
|
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
|
||||||
|
unsigned char *key, size_t keylen);
|
||||||
|
|
||||||
typedef struct {
|
struct evp_kdf_impl_st {
|
||||||
unsigned char *pass;
|
unsigned char *pass;
|
||||||
size_t pass_len;
|
size_t pass_len;
|
||||||
unsigned char *salt;
|
unsigned char *salt;
|
||||||
size_t salt_len;
|
size_t salt_len;
|
||||||
uint64_t N, r, p;
|
uint64_t N;
|
||||||
|
uint32_t r, p;
|
||||||
uint64_t maxmem_bytes;
|
uint64_t maxmem_bytes;
|
||||||
} SCRYPT_PKEY_CTX;
|
};
|
||||||
|
|
||||||
/* Custom uint64_t parser since we do not have strtoull */
|
/* Custom uint64_t parser since we do not have strtoull */
|
||||||
static int atou64(const char *nptr, uint64_t *result)
|
static int atou64(const char *nptr, uint64_t *result)
|
||||||
@@ -53,50 +62,52 @@ static int atou64(const char *nptr, uint64_t *result)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_scrypt_init(EVP_PKEY_CTX *ctx)
|
static EVP_KDF_IMPL *kdf_scrypt_new(void)
|
||||||
{
|
{
|
||||||
SCRYPT_PKEY_CTX *kctx;
|
EVP_KDF_IMPL *impl;
|
||||||
|
|
||||||
kctx = OPENSSL_zalloc(sizeof(*kctx));
|
impl = OPENSSL_zalloc(sizeof(*impl));
|
||||||
if (kctx == NULL) {
|
if (impl == NULL) {
|
||||||
KDFerr(KDF_F_PKEY_SCRYPT_INIT, ERR_R_MALLOC_FAILURE);
|
KDFerr(KDF_F_KDF_SCRYPT_NEW, ERR_R_MALLOC_FAILURE);
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
kdf_scrypt_init(impl);
|
||||||
|
return impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kdf_scrypt_free(EVP_KDF_IMPL *impl)
|
||||||
|
{
|
||||||
|
kdf_scrypt_reset(impl);
|
||||||
|
OPENSSL_free(impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kdf_scrypt_reset(EVP_KDF_IMPL *impl)
|
||||||
|
{
|
||||||
|
OPENSSL_free(impl->salt);
|
||||||
|
OPENSSL_clear_free(impl->pass, impl->pass_len);
|
||||||
|
memset(impl, 0, sizeof(*impl));
|
||||||
|
kdf_scrypt_init(impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kdf_scrypt_init(EVP_KDF_IMPL *impl)
|
||||||
|
{
|
||||||
/* Default values are the most conservative recommendation given in the
|
/* Default values are the most conservative recommendation given in the
|
||||||
* original paper of C. Percival. Derivation uses roughly 1 GiB of memory
|
* original paper of C. Percival. Derivation uses roughly 1 GiB of memory
|
||||||
* for this parameter choice (approx. 128 * r * (N + p) bytes).
|
* for this parameter choice (approx. 128 * r * N * p bytes).
|
||||||
*/
|
*/
|
||||||
kctx->N = 1 << 20;
|
impl->N = 1 << 20;
|
||||||
kctx->r = 8;
|
impl->r = 8;
|
||||||
kctx->p = 1;
|
impl->p = 1;
|
||||||
kctx->maxmem_bytes = 1025 * 1024 * 1024;
|
impl->maxmem_bytes = 1025 * 1024 * 1024;
|
||||||
|
|
||||||
ctx->data = kctx;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pkey_scrypt_cleanup(EVP_PKEY_CTX *ctx)
|
static int scrypt_set_membuf(unsigned char **buffer, size_t *buflen,
|
||||||
{
|
|
||||||
SCRYPT_PKEY_CTX *kctx = ctx->data;
|
|
||||||
|
|
||||||
OPENSSL_clear_free(kctx->salt, kctx->salt_len);
|
|
||||||
OPENSSL_clear_free(kctx->pass, kctx->pass_len);
|
|
||||||
OPENSSL_free(kctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pkey_scrypt_set_membuf(unsigned char **buffer, size_t *buflen,
|
|
||||||
const unsigned char *new_buffer,
|
const unsigned char *new_buffer,
|
||||||
const int new_buflen)
|
size_t new_buflen)
|
||||||
{
|
{
|
||||||
if (new_buffer == NULL)
|
if (new_buffer == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (new_buflen < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (*buffer != NULL)
|
|
||||||
OPENSSL_clear_free(*buffer, *buflen);
|
OPENSSL_clear_free(*buffer, *buflen);
|
||||||
|
|
||||||
if (new_buflen > 0) {
|
if (new_buflen > 0) {
|
||||||
@@ -105,7 +116,7 @@ static int pkey_scrypt_set_membuf(unsigned char **buffer, size_t *buflen,
|
|||||||
*buffer = OPENSSL_malloc(1);
|
*buffer = OPENSSL_malloc(1);
|
||||||
}
|
}
|
||||||
if (*buffer == NULL) {
|
if (*buffer == NULL) {
|
||||||
KDFerr(KDF_F_PKEY_SCRYPT_SET_MEMBUF, ERR_R_MALLOC_FAILURE);
|
KDFerr(KDF_F_SCRYPT_SET_MEMBUF, ERR_R_MALLOC_FAILURE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,149 +129,378 @@ static int is_power_of_two(uint64_t value)
|
|||||||
return (value != 0) && ((value & (value - 1)) == 0);
|
return (value != 0) && ((value & (value - 1)) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_scrypt_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
static int kdf_scrypt_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
|
||||||
{
|
{
|
||||||
SCRYPT_PKEY_CTX *kctx = ctx->data;
|
|
||||||
uint64_t u64_value;
|
uint64_t u64_value;
|
||||||
|
uint32_t value;
|
||||||
|
const unsigned char *p;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
switch (type) {
|
switch (cmd) {
|
||||||
case EVP_PKEY_CTRL_PASS:
|
case EVP_KDF_CTRL_SET_PASS:
|
||||||
return pkey_scrypt_set_membuf(&kctx->pass, &kctx->pass_len, p2, p1);
|
p = va_arg(args, const unsigned char *);
|
||||||
|
len = va_arg(args, size_t);
|
||||||
|
return scrypt_set_membuf(&impl->pass, &impl->pass_len, p, len);
|
||||||
|
|
||||||
case EVP_PKEY_CTRL_SCRYPT_SALT:
|
case EVP_KDF_CTRL_SET_SALT:
|
||||||
return pkey_scrypt_set_membuf(&kctx->salt, &kctx->salt_len, p2, p1);
|
p = va_arg(args, const unsigned char *);
|
||||||
|
len = va_arg(args, size_t);
|
||||||
|
return scrypt_set_membuf(&impl->salt, &impl->salt_len, p, len);
|
||||||
|
|
||||||
case EVP_PKEY_CTRL_SCRYPT_N:
|
case EVP_KDF_CTRL_SET_SCRYPT_N:
|
||||||
u64_value = *((uint64_t *)p2);
|
u64_value = va_arg(args, uint64_t);
|
||||||
if ((u64_value <= 1) || !is_power_of_two(u64_value))
|
if ((u64_value <= 1) || !is_power_of_two(u64_value))
|
||||||
return 0;
|
return 0;
|
||||||
kctx->N = u64_value;
|
|
||||||
|
impl->N = u64_value;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case EVP_PKEY_CTRL_SCRYPT_R:
|
case EVP_KDF_CTRL_SET_SCRYPT_R:
|
||||||
u64_value = *((uint64_t *)p2);
|
value = va_arg(args, uint32_t);
|
||||||
if (u64_value < 1)
|
if (value < 1)
|
||||||
return 0;
|
return 0;
|
||||||
kctx->r = u64_value;
|
|
||||||
|
impl->r = value;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case EVP_PKEY_CTRL_SCRYPT_P:
|
case EVP_KDF_CTRL_SET_SCRYPT_P:
|
||||||
u64_value = *((uint64_t *)p2);
|
value = va_arg(args, uint32_t);
|
||||||
if (u64_value < 1)
|
if (value < 1)
|
||||||
return 0;
|
return 0;
|
||||||
kctx->p = u64_value;
|
|
||||||
|
impl->p = value;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES:
|
case EVP_KDF_CTRL_SET_MAXMEM_BYTES:
|
||||||
u64_value = *((uint64_t *)p2);
|
u64_value = va_arg(args, uint64_t);
|
||||||
if (u64_value < 1)
|
if (u64_value < 1)
|
||||||
return 0;
|
return 0;
|
||||||
kctx->maxmem_bytes = u64_value;
|
|
||||||
|
impl->maxmem_bytes = u64_value;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_scrypt_ctrl_uint64(EVP_PKEY_CTX *ctx, int type,
|
static int kdf_scrypt_ctrl_uint32(EVP_KDF_IMPL *impl, int cmd,
|
||||||
const char *value)
|
const char *value)
|
||||||
{
|
{
|
||||||
uint64_t int_value;
|
int int_value = atoi(value);
|
||||||
|
|
||||||
if (!atou64(value, &int_value)) {
|
if (int_value < 0 || (uint64_t)int_value > UINT32_MAX) {
|
||||||
KDFerr(KDF_F_PKEY_SCRYPT_CTRL_UINT64, KDF_R_VALUE_ERROR);
|
KDFerr(KDF_F_KDF_SCRYPT_CTRL_UINT32, KDF_R_VALUE_ERROR);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return pkey_scrypt_ctrl(ctx, type, 0, &int_value);
|
return call_ctrl(kdf_scrypt_ctrl, impl, cmd, (uint32_t)int_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_scrypt_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
|
static int kdf_scrypt_ctrl_uint64(EVP_KDF_IMPL *impl, int cmd,
|
||||||
|
const char *value)
|
||||||
|
{
|
||||||
|
uint64_t u64_value;
|
||||||
|
|
||||||
|
if (!atou64(value, &u64_value)) {
|
||||||
|
KDFerr(KDF_F_KDF_SCRYPT_CTRL_UINT64, KDF_R_VALUE_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return call_ctrl(kdf_scrypt_ctrl, impl, cmd, u64_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int kdf_scrypt_ctrl_str(EVP_KDF_IMPL *impl, const char *type,
|
||||||
const char *value)
|
const char *value)
|
||||||
{
|
{
|
||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
KDFerr(KDF_F_PKEY_SCRYPT_CTRL_STR, KDF_R_VALUE_MISSING);
|
KDFerr(KDF_F_KDF_SCRYPT_CTRL_STR, KDF_R_VALUE_MISSING);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(type, "pass") == 0)
|
if (strcmp(type, "pass") == 0)
|
||||||
return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_PASS, value);
|
return kdf_str2ctrl(impl, kdf_scrypt_ctrl, EVP_KDF_CTRL_SET_PASS,
|
||||||
|
value);
|
||||||
if (strcmp(type, "hexpass") == 0)
|
|
||||||
return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_PASS, value);
|
if (strcmp(type, "hexpass") == 0)
|
||||||
|
return kdf_hex2ctrl(impl, kdf_scrypt_ctrl, EVP_KDF_CTRL_SET_PASS,
|
||||||
if (strcmp(type, "salt") == 0)
|
value);
|
||||||
return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SCRYPT_SALT, value);
|
|
||||||
|
if (strcmp(type, "salt") == 0)
|
||||||
if (strcmp(type, "hexsalt") == 0)
|
return kdf_str2ctrl(impl, kdf_scrypt_ctrl, EVP_KDF_CTRL_SET_SALT,
|
||||||
return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SCRYPT_SALT, value);
|
value);
|
||||||
|
|
||||||
if (strcmp(type, "N") == 0)
|
if (strcmp(type, "hexsalt") == 0)
|
||||||
return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_N, value);
|
return kdf_hex2ctrl(impl, kdf_scrypt_ctrl, EVP_KDF_CTRL_SET_SALT,
|
||||||
|
value);
|
||||||
if (strcmp(type, "r") == 0)
|
|
||||||
return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_R, value);
|
if (strcmp(type, "N") == 0)
|
||||||
|
return kdf_scrypt_ctrl_uint64(impl, EVP_KDF_CTRL_SET_SCRYPT_N, value);
|
||||||
if (strcmp(type, "p") == 0)
|
|
||||||
return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_P, value);
|
if (strcmp(type, "r") == 0)
|
||||||
|
return kdf_scrypt_ctrl_uint32(impl, EVP_KDF_CTRL_SET_SCRYPT_R, value);
|
||||||
if (strcmp(type, "maxmem_bytes") == 0)
|
|
||||||
return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES,
|
if (strcmp(type, "p") == 0)
|
||||||
|
return kdf_scrypt_ctrl_uint32(impl, EVP_KDF_CTRL_SET_SCRYPT_P, value);
|
||||||
|
|
||||||
|
if (strcmp(type, "maxmem_bytes") == 0)
|
||||||
|
return kdf_scrypt_ctrl_uint64(impl, EVP_KDF_CTRL_SET_MAXMEM_BYTES,
|
||||||
value);
|
value);
|
||||||
|
|
||||||
KDFerr(KDF_F_PKEY_SCRYPT_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE);
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_scrypt_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
static int kdf_scrypt_derive(EVP_KDF_IMPL *impl, unsigned char *key,
|
||||||
size_t *keylen)
|
size_t keylen)
|
||||||
{
|
{
|
||||||
SCRYPT_PKEY_CTX *kctx = ctx->data;
|
if (impl->pass == NULL) {
|
||||||
|
KDFerr(KDF_F_KDF_SCRYPT_DERIVE, KDF_R_MISSING_PASS);
|
||||||
if (kctx->pass == NULL) {
|
|
||||||
KDFerr(KDF_F_PKEY_SCRYPT_DERIVE, KDF_R_MISSING_PASS);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kctx->salt == NULL) {
|
if (impl->salt == NULL) {
|
||||||
KDFerr(KDF_F_PKEY_SCRYPT_DERIVE, KDF_R_MISSING_SALT);
|
KDFerr(KDF_F_KDF_SCRYPT_DERIVE, KDF_R_MISSING_SALT);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EVP_PBE_scrypt((char *)kctx->pass, kctx->pass_len, kctx->salt,
|
return scrypt_alg((char *)impl->pass, impl->pass_len, impl->salt,
|
||||||
kctx->salt_len, kctx->N, kctx->r, kctx->p,
|
impl->salt_len, impl->N, impl->r, impl->p,
|
||||||
kctx->maxmem_bytes, key, *keylen);
|
impl->maxmem_bytes, key, keylen);
|
||||||
}
|
}
|
||||||
|
|
||||||
const EVP_PKEY_METHOD scrypt_pkey_meth = {
|
const EVP_KDF_METHOD scrypt_kdf_meth = {
|
||||||
EVP_PKEY_SCRYPT,
|
EVP_KDF_SCRYPT,
|
||||||
0,
|
kdf_scrypt_new,
|
||||||
pkey_scrypt_init,
|
kdf_scrypt_free,
|
||||||
0,
|
kdf_scrypt_reset,
|
||||||
pkey_scrypt_cleanup,
|
kdf_scrypt_ctrl,
|
||||||
|
kdf_scrypt_ctrl_str,
|
||||||
0, 0,
|
NULL,
|
||||||
0, 0,
|
kdf_scrypt_derive
|
||||||
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
|
|
||||||
0, 0,
|
|
||||||
|
|
||||||
0, 0, 0, 0,
|
|
||||||
|
|
||||||
0, 0,
|
|
||||||
|
|
||||||
0, 0,
|
|
||||||
|
|
||||||
0,
|
|
||||||
pkey_scrypt_derive,
|
|
||||||
pkey_scrypt_ctrl,
|
|
||||||
pkey_scrypt_ctrl_str
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
|
||||||
|
static void salsa208_word_specification(uint32_t inout[16])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint32_t x[16];
|
||||||
|
|
||||||
|
memcpy(x, inout, sizeof(x));
|
||||||
|
for (i = 8; i > 0; i -= 2) {
|
||||||
|
x[4] ^= R(x[0] + x[12], 7);
|
||||||
|
x[8] ^= R(x[4] + x[0], 9);
|
||||||
|
x[12] ^= R(x[8] + x[4], 13);
|
||||||
|
x[0] ^= R(x[12] + x[8], 18);
|
||||||
|
x[9] ^= R(x[5] + x[1], 7);
|
||||||
|
x[13] ^= R(x[9] + x[5], 9);
|
||||||
|
x[1] ^= R(x[13] + x[9], 13);
|
||||||
|
x[5] ^= R(x[1] + x[13], 18);
|
||||||
|
x[14] ^= R(x[10] + x[6], 7);
|
||||||
|
x[2] ^= R(x[14] + x[10], 9);
|
||||||
|
x[6] ^= R(x[2] + x[14], 13);
|
||||||
|
x[10] ^= R(x[6] + x[2], 18);
|
||||||
|
x[3] ^= R(x[15] + x[11], 7);
|
||||||
|
x[7] ^= R(x[3] + x[15], 9);
|
||||||
|
x[11] ^= R(x[7] + x[3], 13);
|
||||||
|
x[15] ^= R(x[11] + x[7], 18);
|
||||||
|
x[1] ^= R(x[0] + x[3], 7);
|
||||||
|
x[2] ^= R(x[1] + x[0], 9);
|
||||||
|
x[3] ^= R(x[2] + x[1], 13);
|
||||||
|
x[0] ^= R(x[3] + x[2], 18);
|
||||||
|
x[6] ^= R(x[5] + x[4], 7);
|
||||||
|
x[7] ^= R(x[6] + x[5], 9);
|
||||||
|
x[4] ^= R(x[7] + x[6], 13);
|
||||||
|
x[5] ^= R(x[4] + x[7], 18);
|
||||||
|
x[11] ^= R(x[10] + x[9], 7);
|
||||||
|
x[8] ^= R(x[11] + x[10], 9);
|
||||||
|
x[9] ^= R(x[8] + x[11], 13);
|
||||||
|
x[10] ^= R(x[9] + x[8], 18);
|
||||||
|
x[12] ^= R(x[15] + x[14], 7);
|
||||||
|
x[13] ^= R(x[12] + x[15], 9);
|
||||||
|
x[14] ^= R(x[13] + x[12], 13);
|
||||||
|
x[15] ^= R(x[14] + x[13], 18);
|
||||||
|
}
|
||||||
|
for (i = 0; i < 16; ++i)
|
||||||
|
inout[i] += x[i];
|
||||||
|
OPENSSL_cleanse(x, sizeof(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r)
|
||||||
|
{
|
||||||
|
uint64_t i, j;
|
||||||
|
uint32_t X[16], *pB;
|
||||||
|
|
||||||
|
memcpy(X, B + (r * 2 - 1) * 16, sizeof(X));
|
||||||
|
pB = B;
|
||||||
|
for (i = 0; i < r * 2; i++) {
|
||||||
|
for (j = 0; j < 16; j++)
|
||||||
|
X[j] ^= *pB++;
|
||||||
|
salsa208_word_specification(X);
|
||||||
|
memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X));
|
||||||
|
}
|
||||||
|
OPENSSL_cleanse(X, sizeof(X));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N,
|
||||||
|
uint32_t *X, uint32_t *T, uint32_t *V)
|
||||||
|
{
|
||||||
|
unsigned char *pB;
|
||||||
|
uint32_t *pV;
|
||||||
|
uint64_t i, k;
|
||||||
|
|
||||||
|
/* Convert from little endian input */
|
||||||
|
for (pV = V, i = 0, pB = B; i < 32 * r; i++, pV++) {
|
||||||
|
*pV = *pB++;
|
||||||
|
*pV |= *pB++ << 8;
|
||||||
|
*pV |= *pB++ << 16;
|
||||||
|
*pV |= (uint32_t)*pB++ << 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < N; i++, pV += 32 * r)
|
||||||
|
scryptBlockMix(pV, pV - 32 * r, r);
|
||||||
|
|
||||||
|
scryptBlockMix(X, V + (N - 1) * 32 * r, r);
|
||||||
|
|
||||||
|
for (i = 0; i < N; i++) {
|
||||||
|
uint32_t j;
|
||||||
|
j = X[16 * (2 * r - 1)] % N;
|
||||||
|
pV = V + 32 * r * j;
|
||||||
|
for (k = 0; k < 32 * r; k++)
|
||||||
|
T[k] = X[k] ^ *pV++;
|
||||||
|
scryptBlockMix(X, T, r);
|
||||||
|
}
|
||||||
|
/* Convert output to little endian */
|
||||||
|
for (i = 0, pB = B; i < 32 * r; i++) {
|
||||||
|
uint32_t xtmp = X[i];
|
||||||
|
*pB++ = xtmp & 0xff;
|
||||||
|
*pB++ = (xtmp >> 8) & 0xff;
|
||||||
|
*pB++ = (xtmp >> 16) & 0xff;
|
||||||
|
*pB++ = (xtmp >> 24) & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SIZE_MAX
|
||||||
|
# define SIZE_MAX ((size_t)-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maximum power of two that will fit in uint64_t: this should work on
|
||||||
|
* most (all?) platforms.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG2_UINT64_MAX (sizeof(uint64_t) * 8 - 1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maximum value of p * r:
|
||||||
|
* p <= ((2^32-1) * hLen) / MFLen =>
|
||||||
|
* p <= ((2^32-1) * 32) / (128 * r) =>
|
||||||
|
* p * r <= (2^30-1)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SCRYPT_PR_MAX ((1 << 30) - 1)
|
||||||
|
|
||||||
|
static int scrypt_alg(const char *pass, size_t passlen,
|
||||||
|
const unsigned char *salt, size_t saltlen,
|
||||||
|
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
|
||||||
|
unsigned char *key, size_t keylen)
|
||||||
|
{
|
||||||
|
int rv = 0;
|
||||||
|
unsigned char *B;
|
||||||
|
uint32_t *X, *V, *T;
|
||||||
|
uint64_t i, Blen, Vlen;
|
||||||
|
|
||||||
|
/* Sanity check parameters */
|
||||||
|
/* initial check, r,p must be non zero, N >= 2 and a power of 2 */
|
||||||
|
if (r == 0 || p == 0 || N < 2 || (N & (N - 1)))
|
||||||
|
return 0;
|
||||||
|
/* Check p * r < SCRYPT_PR_MAX avoiding overflow */
|
||||||
|
if (p > SCRYPT_PR_MAX / r) {
|
||||||
|
EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need to check N: if 2^(128 * r / 8) overflows limit this is
|
||||||
|
* automatically satisfied since N <= UINT64_MAX.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (16 * r <= LOG2_UINT64_MAX) {
|
||||||
|
if (N >= (((uint64_t)1) << (16 * r))) {
|
||||||
|
EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Memory checks: check total allocated buffer size fits in uint64_t */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* B size in section 5 step 1.S
|
||||||
|
* Note: we know p * 128 * r < UINT64_MAX because we already checked
|
||||||
|
* p * r < SCRYPT_PR_MAX
|
||||||
|
*/
|
||||||
|
Blen = p * 128 * r;
|
||||||
|
/*
|
||||||
|
* Yet we pass it as integer to PKCS5_PBKDF2_HMAC... [This would
|
||||||
|
* have to be revised when/if PKCS5_PBKDF2_HMAC accepts size_t.]
|
||||||
|
*/
|
||||||
|
if (Blen > INT_MAX) {
|
||||||
|
EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check 32 * r * (N + 2) * sizeof(uint32_t) fits in uint64_t
|
||||||
|
* This is combined size V, X and T (section 4)
|
||||||
|
*/
|
||||||
|
i = UINT64_MAX / (32 * sizeof(uint32_t));
|
||||||
|
if (N + 2 > i / r) {
|
||||||
|
EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Vlen = 32 * r * (N + 2) * sizeof(uint32_t);
|
||||||
|
|
||||||
|
/* check total allocated size fits in uint64_t */
|
||||||
|
if (Blen > UINT64_MAX - Vlen) {
|
||||||
|
EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that the maximum memory doesn't exceed a size_t limits */
|
||||||
|
if (maxmem > SIZE_MAX)
|
||||||
|
maxmem = SIZE_MAX;
|
||||||
|
|
||||||
|
if (Blen + Vlen > maxmem) {
|
||||||
|
EVPerr(EVP_F_SCRYPT_ALG, EVP_R_MEMORY_LIMIT_EXCEEDED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no key return to indicate parameters are OK */
|
||||||
|
if (key == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
B = OPENSSL_malloc((size_t)(Blen + Vlen));
|
||||||
|
if (B == NULL) {
|
||||||
|
EVPerr(EVP_F_SCRYPT_ALG, ERR_R_MALLOC_FAILURE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
X = (uint32_t *)(B + Blen);
|
||||||
|
T = X + 32 * r;
|
||||||
|
V = T + 32 * r;
|
||||||
|
if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(),
|
||||||
|
(int)Blen, B) == 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
for (i = 0; i < p; i++)
|
||||||
|
scryptROMix(B + 128 * r * i, r, N, X, T, V);
|
||||||
|
|
||||||
|
if (PKCS5_PBKDF2_HMAC(pass, passlen, B, (int)Blen, 1, EVP_sha256(),
|
||||||
|
keylen, key) == 0)
|
||||||
|
goto err;
|
||||||
|
rv = 1;
|
||||||
|
err:
|
||||||
|
if (rv == 0)
|
||||||
|
EVPerr(EVP_F_SCRYPT_ALG, EVP_R_PBKDF2_ERROR);
|
||||||
|
|
||||||
|
OPENSSL_clear_free(B, (size_t)(Blen + Vlen));
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+95
-100
@@ -8,11 +8,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
#include "internal/cryptlib.h"
|
#include "internal/cryptlib.h"
|
||||||
#include <openssl/kdf.h>
|
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/kdf.h>
|
||||||
#include "internal/evp_int.h"
|
#include "internal/evp_int.h"
|
||||||
|
#include "kdf_local.h"
|
||||||
|
|
||||||
|
static void kdf_tls1_prf_reset(EVP_KDF_IMPL *impl);
|
||||||
static int tls1_prf_alg(const EVP_MD *md,
|
static int tls1_prf_alg(const EVP_MD *md,
|
||||||
const unsigned char *sec, size_t slen,
|
const unsigned char *sec, size_t slen,
|
||||||
const unsigned char *seed, size_t seed_len,
|
const unsigned char *seed, size_t seed_len,
|
||||||
@@ -20,9 +24,9 @@ static int tls1_prf_alg(const EVP_MD *md,
|
|||||||
|
|
||||||
#define TLS1_PRF_MAXBUF 1024
|
#define TLS1_PRF_MAXBUF 1024
|
||||||
|
|
||||||
/* TLS KDF pkey context structure */
|
/* TLS KDF kdf context structure */
|
||||||
|
|
||||||
typedef struct {
|
struct evp_kdf_impl_st {
|
||||||
/* Digest to use for PRF */
|
/* Digest to use for PRF */
|
||||||
const EVP_MD *md;
|
const EVP_MD *md;
|
||||||
/* Secret value to use for PRF */
|
/* Secret value to use for PRF */
|
||||||
@@ -31,145 +35,137 @@ typedef struct {
|
|||||||
/* Buffer of concatenated seed data */
|
/* Buffer of concatenated seed data */
|
||||||
unsigned char seed[TLS1_PRF_MAXBUF];
|
unsigned char seed[TLS1_PRF_MAXBUF];
|
||||||
size_t seedlen;
|
size_t seedlen;
|
||||||
} TLS1_PRF_PKEY_CTX;
|
};
|
||||||
|
|
||||||
static int pkey_tls1_prf_init(EVP_PKEY_CTX *ctx)
|
static EVP_KDF_IMPL *kdf_tls1_prf_new(void)
|
||||||
{
|
{
|
||||||
TLS1_PRF_PKEY_CTX *kctx;
|
EVP_KDF_IMPL *impl;
|
||||||
|
|
||||||
if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL) {
|
if ((impl = OPENSSL_zalloc(sizeof(*impl))) == NULL)
|
||||||
KDFerr(KDF_F_PKEY_TLS1_PRF_INIT, ERR_R_MALLOC_FAILURE);
|
KDFerr(KDF_F_KDF_TLS1_PRF_NEW, ERR_R_MALLOC_FAILURE);
|
||||||
return 0;
|
return impl;
|
||||||
}
|
|
||||||
ctx->data = kctx;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pkey_tls1_prf_cleanup(EVP_PKEY_CTX *ctx)
|
static void kdf_tls1_prf_free(EVP_KDF_IMPL *impl)
|
||||||
{
|
{
|
||||||
TLS1_PRF_PKEY_CTX *kctx = ctx->data;
|
kdf_tls1_prf_reset(impl);
|
||||||
OPENSSL_clear_free(kctx->sec, kctx->seclen);
|
OPENSSL_free(impl);
|
||||||
OPENSSL_cleanse(kctx->seed, kctx->seedlen);
|
|
||||||
OPENSSL_free(kctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_tls1_prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
static void kdf_tls1_prf_reset(EVP_KDF_IMPL *impl)
|
||||||
{
|
{
|
||||||
TLS1_PRF_PKEY_CTX *kctx = ctx->data;
|
OPENSSL_clear_free(impl->sec, impl->seclen);
|
||||||
switch (type) {
|
OPENSSL_cleanse(impl->seed, impl->seedlen);
|
||||||
case EVP_PKEY_CTRL_TLS_MD:
|
memset(impl, 0, sizeof(*impl));
|
||||||
kctx->md = p2;
|
}
|
||||||
|
|
||||||
|
static int kdf_tls1_prf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
|
||||||
|
{
|
||||||
|
const unsigned char *p;
|
||||||
|
size_t len;
|
||||||
|
const EVP_MD *md;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case EVP_KDF_CTRL_SET_MD:
|
||||||
|
md = va_arg(args, const EVP_MD *);
|
||||||
|
if (md == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
impl->md = md;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case EVP_PKEY_CTRL_TLS_SECRET:
|
case EVP_KDF_CTRL_SET_TLS_SECRET:
|
||||||
if (p1 < 0)
|
p = va_arg(args, const unsigned char *);
|
||||||
|
len = va_arg(args, size_t);
|
||||||
|
OPENSSL_clear_free(impl->sec, impl->seclen);
|
||||||
|
impl->sec = OPENSSL_memdup(p, len);
|
||||||
|
if (impl->sec == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
if (kctx->sec != NULL)
|
|
||||||
OPENSSL_clear_free(kctx->sec, kctx->seclen);
|
impl->seclen = len;
|
||||||
OPENSSL_cleanse(kctx->seed, kctx->seedlen);
|
|
||||||
kctx->seedlen = 0;
|
|
||||||
kctx->sec = OPENSSL_memdup(p2, p1);
|
|
||||||
if (kctx->sec == NULL)
|
|
||||||
return 0;
|
|
||||||
kctx->seclen = p1;
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case EVP_PKEY_CTRL_TLS_SEED:
|
case EVP_KDF_CTRL_RESET_TLS_SEED:
|
||||||
if (p1 == 0 || p2 == NULL)
|
OPENSSL_cleanse(impl->seed, impl->seedlen);
|
||||||
|
impl->seedlen = 0;
|
||||||
return 1;
|
return 1;
|
||||||
if (p1 < 0 || p1 > (int)(TLS1_PRF_MAXBUF - kctx->seedlen))
|
|
||||||
|
case EVP_KDF_CTRL_ADD_TLS_SEED:
|
||||||
|
p = va_arg(args, const unsigned char *);
|
||||||
|
len = va_arg(args, size_t);
|
||||||
|
if (len == 0 || p == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (len > (TLS1_PRF_MAXBUF - impl->seedlen))
|
||||||
return 0;
|
return 0;
|
||||||
memcpy(kctx->seed + kctx->seedlen, p2, p1);
|
|
||||||
kctx->seedlen += p1;
|
memcpy(impl->seed + impl->seedlen, p, len);
|
||||||
|
impl->seedlen += len;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_tls1_prf_ctrl_str(EVP_PKEY_CTX *ctx,
|
static int kdf_tls1_prf_ctrl_str(EVP_KDF_IMPL *impl,
|
||||||
const char *type, const char *value)
|
const char *type, const char *value)
|
||||||
{
|
{
|
||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING);
|
KDFerr(KDF_F_KDF_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (strcmp(type, "md") == 0) {
|
if (strcmp(type, "digest") == 0)
|
||||||
TLS1_PRF_PKEY_CTX *kctx = ctx->data;
|
return kdf_md2ctrl(impl, kdf_tls1_prf_ctrl, EVP_KDF_CTRL_SET_MD, value);
|
||||||
|
|
||||||
const EVP_MD *md = EVP_get_digestbyname(value);
|
|
||||||
if (md == NULL) {
|
|
||||||
KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_INVALID_DIGEST);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
kctx->md = md;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (strcmp(type, "secret") == 0)
|
if (strcmp(type, "secret") == 0)
|
||||||
return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value);
|
return kdf_str2ctrl(impl, kdf_tls1_prf_ctrl,
|
||||||
if (strcmp(type, "hexsecret") == 0)
|
EVP_KDF_CTRL_SET_TLS_SECRET, value);
|
||||||
return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value);
|
|
||||||
if (strcmp(type, "seed") == 0)
|
if (strcmp(type, "hexsecret") == 0)
|
||||||
return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value);
|
return kdf_hex2ctrl(impl, kdf_tls1_prf_ctrl,
|
||||||
if (strcmp(type, "hexseed") == 0)
|
EVP_KDF_CTRL_SET_TLS_SECRET, value);
|
||||||
return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value);
|
|
||||||
|
if (strcmp(type, "seed") == 0)
|
||||||
|
return kdf_str2ctrl(impl, kdf_tls1_prf_ctrl, EVP_KDF_CTRL_ADD_TLS_SEED,
|
||||||
|
value);
|
||||||
|
|
||||||
|
if (strcmp(type, "hexseed") == 0)
|
||||||
|
return kdf_hex2ctrl(impl, kdf_tls1_prf_ctrl, EVP_KDF_CTRL_ADD_TLS_SEED,
|
||||||
|
value);
|
||||||
|
|
||||||
KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE);
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_tls1_prf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
static int kdf_tls1_prf_derive(EVP_KDF_IMPL *impl, unsigned char *key,
|
||||||
size_t *keylen)
|
size_t keylen)
|
||||||
{
|
{
|
||||||
TLS1_PRF_PKEY_CTX *kctx = ctx->data;
|
if (impl->md == NULL) {
|
||||||
if (kctx->md == NULL) {
|
KDFerr(KDF_F_KDF_TLS1_PRF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
|
||||||
KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (kctx->sec == NULL) {
|
if (impl->sec == NULL) {
|
||||||
KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_SECRET);
|
KDFerr(KDF_F_KDF_TLS1_PRF_DERIVE, KDF_R_MISSING_SECRET);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (kctx->seedlen == 0) {
|
if (impl->seedlen == 0) {
|
||||||
KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_SEED);
|
KDFerr(KDF_F_KDF_TLS1_PRF_DERIVE, KDF_R_MISSING_SEED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return tls1_prf_alg(kctx->md, kctx->sec, kctx->seclen,
|
return tls1_prf_alg(impl->md, impl->sec, impl->seclen,
|
||||||
kctx->seed, kctx->seedlen,
|
impl->seed, impl->seedlen,
|
||||||
key, *keylen);
|
key, keylen);
|
||||||
}
|
}
|
||||||
|
|
||||||
const EVP_PKEY_METHOD tls1_prf_pkey_meth = {
|
const EVP_KDF_METHOD tls1_prf_kdf_meth = {
|
||||||
EVP_PKEY_TLS1_PRF,
|
EVP_KDF_TLS1_PRF,
|
||||||
0,
|
kdf_tls1_prf_new,
|
||||||
pkey_tls1_prf_init,
|
kdf_tls1_prf_free,
|
||||||
0,
|
kdf_tls1_prf_reset,
|
||||||
pkey_tls1_prf_cleanup,
|
kdf_tls1_prf_ctrl,
|
||||||
|
kdf_tls1_prf_ctrl_str,
|
||||||
0, 0,
|
NULL,
|
||||||
0, 0,
|
kdf_tls1_prf_derive
|
||||||
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
|
|
||||||
0, 0,
|
|
||||||
|
|
||||||
0, 0, 0, 0,
|
|
||||||
|
|
||||||
0, 0,
|
|
||||||
|
|
||||||
0, 0,
|
|
||||||
|
|
||||||
0,
|
|
||||||
pkey_tls1_prf_derive,
|
|
||||||
pkey_tls1_prf_ctrl,
|
|
||||||
pkey_tls1_prf_ctrl_str
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int tls1_prf_P_hash(const EVP_MD *md,
|
static int tls1_prf_P_hash(const EVP_MD *md,
|
||||||
@@ -249,7 +245,6 @@ static int tls1_prf_alg(const EVP_MD *md,
|
|||||||
const unsigned char *seed, size_t seed_len,
|
const unsigned char *seed, size_t seed_len,
|
||||||
unsigned char *out, size_t olen)
|
unsigned char *out, size_t olen)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (EVP_MD_type(md) == NID_md5_sha1) {
|
if (EVP_MD_type(md) == NID_md5_sha1) {
|
||||||
size_t i;
|
size_t i;
|
||||||
unsigned char *tmp;
|
unsigned char *tmp;
|
||||||
|
|||||||
+10
-2
@@ -74,6 +74,16 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OPENSSL_LH_free(OPENSSL_LHASH *lh)
|
void OPENSSL_LH_free(OPENSSL_LHASH *lh)
|
||||||
|
{
|
||||||
|
if (lh == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
OPENSSL_LH_flush(lh);
|
||||||
|
OPENSSL_free(lh->b);
|
||||||
|
OPENSSL_free(lh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OPENSSL_LH_flush(OPENSSL_LHASH *lh)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
OPENSSL_LH_NODE *n, *nn;
|
OPENSSL_LH_NODE *n, *nn;
|
||||||
@@ -89,8 +99,6 @@ void OPENSSL_LH_free(OPENSSL_LHASH *lh)
|
|||||||
n = nn;
|
n = nn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OPENSSL_free(lh->b);
|
|
||||||
OPENSSL_free(lh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data)
|
void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data)
|
||||||
|
|||||||
@@ -142,7 +142,6 @@ ___
|
|||||||
$code=<<___;
|
$code=<<___;
|
||||||
#include "arm_arch.h"
|
#include "arm_arch.h"
|
||||||
|
|
||||||
.text
|
|
||||||
#if defined(__thumb2__) || defined(__clang__)
|
#if defined(__thumb2__) || defined(__clang__)
|
||||||
.syntax unified
|
.syntax unified
|
||||||
#define ldrplb ldrbpl
|
#define ldrplb ldrbpl
|
||||||
@@ -154,6 +153,8 @@ $code=<<___;
|
|||||||
.code 32
|
.code 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
.type rem_4bit,%object
|
.type rem_4bit,%object
|
||||||
.align 5
|
.align 5
|
||||||
rem_4bit:
|
rem_4bit:
|
||||||
|
|||||||
@@ -529,6 +529,7 @@ $code.=<<___;
|
|||||||
.type gcm_init_clmul,\@abi-omnipotent
|
.type gcm_init_clmul,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
gcm_init_clmul:
|
gcm_init_clmul:
|
||||||
|
.cfi_startproc
|
||||||
.L_init_clmul:
|
.L_init_clmul:
|
||||||
___
|
___
|
||||||
$code.=<<___ if ($win64);
|
$code.=<<___ if ($win64);
|
||||||
@@ -598,6 +599,7 @@ $code.=<<___ if ($win64);
|
|||||||
___
|
___
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size gcm_init_clmul,.-gcm_init_clmul
|
.size gcm_init_clmul,.-gcm_init_clmul
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -609,6 +611,7 @@ $code.=<<___;
|
|||||||
.type gcm_gmult_clmul,\@abi-omnipotent
|
.type gcm_gmult_clmul,\@abi-omnipotent
|
||||||
.align 16
|
.align 16
|
||||||
gcm_gmult_clmul:
|
gcm_gmult_clmul:
|
||||||
|
.cfi_startproc
|
||||||
.L_gmult_clmul:
|
.L_gmult_clmul:
|
||||||
movdqu ($Xip),$Xi
|
movdqu ($Xip),$Xi
|
||||||
movdqa .Lbswap_mask(%rip),$T3
|
movdqa .Lbswap_mask(%rip),$T3
|
||||||
@@ -645,6 +648,7 @@ $code.=<<___;
|
|||||||
pshufb $T3,$Xi
|
pshufb $T3,$Xi
|
||||||
movdqu $Xi,($Xip)
|
movdqu $Xi,($Xip)
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size gcm_gmult_clmul,.-gcm_gmult_clmul
|
.size gcm_gmult_clmul,.-gcm_gmult_clmul
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -658,6 +662,7 @@ $code.=<<___;
|
|||||||
.type gcm_ghash_clmul,\@abi-omnipotent
|
.type gcm_ghash_clmul,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
gcm_ghash_clmul:
|
gcm_ghash_clmul:
|
||||||
|
.cfi_startproc
|
||||||
.L_ghash_clmul:
|
.L_ghash_clmul:
|
||||||
___
|
___
|
||||||
$code.=<<___ if ($win64);
|
$code.=<<___ if ($win64);
|
||||||
@@ -1005,6 +1010,7 @@ $code.=<<___ if ($win64);
|
|||||||
___
|
___
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size gcm_ghash_clmul,.-gcm_ghash_clmul
|
.size gcm_ghash_clmul,.-gcm_ghash_clmul
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -1014,6 +1020,7 @@ $code.=<<___;
|
|||||||
.type gcm_init_avx,\@abi-omnipotent
|
.type gcm_init_avx,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
gcm_init_avx:
|
gcm_init_avx:
|
||||||
|
.cfi_startproc
|
||||||
___
|
___
|
||||||
if ($avx) {
|
if ($avx) {
|
||||||
my ($Htbl,$Xip)=@_4args;
|
my ($Htbl,$Xip)=@_4args;
|
||||||
@@ -1142,11 +1149,13 @@ $code.=<<___ if ($win64);
|
|||||||
___
|
___
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size gcm_init_avx,.-gcm_init_avx
|
.size gcm_init_avx,.-gcm_init_avx
|
||||||
___
|
___
|
||||||
} else {
|
} else {
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
jmp .L_init_clmul
|
jmp .L_init_clmul
|
||||||
|
.cfi_endproc
|
||||||
.size gcm_init_avx,.-gcm_init_avx
|
.size gcm_init_avx,.-gcm_init_avx
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -1156,7 +1165,9 @@ $code.=<<___;
|
|||||||
.type gcm_gmult_avx,\@abi-omnipotent
|
.type gcm_gmult_avx,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
gcm_gmult_avx:
|
gcm_gmult_avx:
|
||||||
|
.cfi_startproc
|
||||||
jmp .L_gmult_clmul
|
jmp .L_gmult_clmul
|
||||||
|
.cfi_endproc
|
||||||
.size gcm_gmult_avx,.-gcm_gmult_avx
|
.size gcm_gmult_avx,.-gcm_gmult_avx
|
||||||
___
|
___
|
||||||
|
|
||||||
@@ -1165,6 +1176,7 @@ $code.=<<___;
|
|||||||
.type gcm_ghash_avx,\@abi-omnipotent
|
.type gcm_ghash_avx,\@abi-omnipotent
|
||||||
.align 32
|
.align 32
|
||||||
gcm_ghash_avx:
|
gcm_ghash_avx:
|
||||||
|
.cfi_startproc
|
||||||
___
|
___
|
||||||
if ($avx) {
|
if ($avx) {
|
||||||
my ($Xip,$Htbl,$inp,$len)=@_4args;
|
my ($Xip,$Htbl,$inp,$len)=@_4args;
|
||||||
@@ -1577,11 +1589,13 @@ $code.=<<___ if ($win64);
|
|||||||
___
|
___
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
.size gcm_ghash_avx,.-gcm_ghash_avx
|
.size gcm_ghash_avx,.-gcm_ghash_avx
|
||||||
___
|
___
|
||||||
} else {
|
} else {
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
jmp .L_ghash_clmul
|
jmp .L_ghash_clmul
|
||||||
|
.cfi_endproc
|
||||||
.size gcm_ghash_avx,.-gcm_ghash_avx
|
.size gcm_ghash_avx,.-gcm_ghash_avx
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,18 +66,26 @@ $inc="x12";
|
|||||||
{
|
{
|
||||||
my ($Xl,$Xm,$Xh,$IN)=map("q$_",(0..3));
|
my ($Xl,$Xm,$Xh,$IN)=map("q$_",(0..3));
|
||||||
my ($t0,$t1,$t2,$xC2,$H,$Hhl,$H2)=map("q$_",(8..14));
|
my ($t0,$t1,$t2,$xC2,$H,$Hhl,$H2)=map("q$_",(8..14));
|
||||||
|
my $_byte = ($flavour =~ /win/ ? "DCB" : ".byte");
|
||||||
|
|
||||||
$code=<<___;
|
$code=<<___;
|
||||||
#include "arm_arch.h"
|
#include "arm_arch.h"
|
||||||
|
|
||||||
#if __ARM_MAX_ARCH__>=7
|
#if __ARM_MAX_ARCH__>=7
|
||||||
.text
|
|
||||||
___
|
___
|
||||||
$code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/);
|
$code.=".arch armv8-a+crypto\n.text\n" if ($flavour =~ /64/);
|
||||||
$code.=<<___ if ($flavour !~ /64/);
|
$code.=<<___ if ($flavour !~ /64/);
|
||||||
.fpu neon
|
.fpu neon
|
||||||
|
#ifdef __thumb2__
|
||||||
|
.syntax unified
|
||||||
|
.thumb
|
||||||
|
# define INST(a,b,c,d) $_byte c,0xef,a,b
|
||||||
|
#else
|
||||||
.code 32
|
.code 32
|
||||||
#undef __thumb2__
|
# define INST(a,b,c,d) $_byte a,b,c,0xf2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
___
|
___
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@@ -752,7 +760,7 @@ if ($flavour =~ /64/) { ######## 64-bit code
|
|||||||
# since ARMv7 instructions are always encoded little-endian.
|
# since ARMv7 instructions are always encoded little-endian.
|
||||||
# correct solution is to use .inst directive, but older
|
# correct solution is to use .inst directive, but older
|
||||||
# assemblers don't implement it:-(
|
# assemblers don't implement it:-(
|
||||||
sprintf ".byte\t0x%02x,0x%02x,0x%02x,0x%02x\t@ %s %s",
|
sprintf "INST(0x%02x,0x%02x,0x%02x,0x%02x)\t@ %s %s",
|
||||||
$word&0xff,($word>>8)&0xff,
|
$word&0xff,($word>>8)&0xff,
|
||||||
($word>>16)&0xff,($word>>24)&0xff,
|
($word>>16)&0xff,($word>>24)&0xff,
|
||||||
$mnemonic,$arg;
|
$mnemonic,$arg;
|
||||||
@@ -767,13 +775,17 @@ if ($flavour =~ /64/) { ######## 64-bit code
|
|||||||
# fix up remaining new-style suffixes
|
# fix up remaining new-style suffixes
|
||||||
s/\],#[0-9]+/]!/o;
|
s/\],#[0-9]+/]!/o;
|
||||||
|
|
||||||
s/cclr\s+([^,]+),\s*([a-z]+)/mov$2 $1,#0/o or
|
s/cclr\s+([^,]+),\s*([a-z]+)/mov.$2 $1,#0/o or
|
||||||
s/vdup\.32\s+(.*)/unvdup32($1)/geo or
|
s/vdup\.32\s+(.*)/unvdup32($1)/geo or
|
||||||
s/v?(pmull2?)\.p64\s+(.*)/unvpmullp64($1,$2)/geo or
|
s/v?(pmull2?)\.p64\s+(.*)/unvpmullp64($1,$2)/geo or
|
||||||
s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo or
|
s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo or
|
||||||
s/^(\s+)b\./$1b/o or
|
s/^(\s+)b\./$1b/o or
|
||||||
s/^(\s+)ret/$1bx\tlr/o;
|
s/^(\s+)ret/$1bx\tlr/o;
|
||||||
|
|
||||||
|
if (s/^(\s+)mov\.([a-z]+)/$1mov$2/) {
|
||||||
|
print " it $2\n";
|
||||||
|
}
|
||||||
|
|
||||||
print $_,"\n";
|
print $_,"\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,13 @@ my $fpu = sub {
|
|||||||
if ($flavour =~ /linux/) { ".fpu\t".join(',',@_); }
|
if ($flavour =~ /linux/) { ".fpu\t".join(',',@_); }
|
||||||
else { ""; }
|
else { ""; }
|
||||||
};
|
};
|
||||||
|
my $rodata = sub {
|
||||||
|
SWITCH: for ($flavour) {
|
||||||
|
/linux/ && return ".section\t.rodata";
|
||||||
|
/ios/ && return ".section\t__TEXT,__const";
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
};
|
||||||
my $hidden = sub {
|
my $hidden = sub {
|
||||||
if ($flavour =~ /ios/) { ".private_extern\t".join(',',@_); }
|
if ($flavour =~ /ios/) { ".private_extern\t".join(',',@_); }
|
||||||
else { ".hidden\t".join(',',@_); }
|
else { ".hidden\t".join(',',@_); }
|
||||||
@@ -96,6 +103,12 @@ my $asciz = sub {
|
|||||||
{ ""; }
|
{ ""; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
my $adrp = sub {
|
||||||
|
my ($args,$comment) = split(m|\s*//|,shift);
|
||||||
|
"\tadrp\t$args\@PAGE";
|
||||||
|
} if ($flavour =~ /ios64/);
|
||||||
|
|
||||||
|
|
||||||
sub range {
|
sub range {
|
||||||
my ($r,$sfx,$start,$end) = @_;
|
my ($r,$sfx,$start,$end) = @_;
|
||||||
|
|
||||||
@@ -125,6 +138,10 @@ sub expand_line {
|
|||||||
|
|
||||||
$line =~ s/\b(\w+)/$GLOBALS{$1} or $1/ge;
|
$line =~ s/\b(\w+)/$GLOBALS{$1} or $1/ge;
|
||||||
|
|
||||||
|
if ($flavour =~ /ios64/) {
|
||||||
|
$line =~ s/#:lo12:(\w+)/$1\@PAGEOFF/;
|
||||||
|
}
|
||||||
|
|
||||||
return $line;
|
return $line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -541,6 +541,7 @@ my %globals;
|
|||||||
);
|
);
|
||||||
|
|
||||||
my ($cfa_reg, $cfa_rsp);
|
my ($cfa_reg, $cfa_rsp);
|
||||||
|
my @cfa_stack;
|
||||||
|
|
||||||
# [us]leb128 format is variable-length integer representation base
|
# [us]leb128 format is variable-length integer representation base
|
||||||
# 2^128, with most significant bit of each byte being 0 denoting
|
# 2^128, with most significant bit of each byte being 0 denoting
|
||||||
@@ -648,7 +649,13 @@ my %globals;
|
|||||||
# why it starts with -8. Recall that CFA is top of caller's
|
# why it starts with -8. Recall that CFA is top of caller's
|
||||||
# stack...
|
# stack...
|
||||||
/startproc/ && do { ($cfa_reg, $cfa_rsp) = ("%rsp", -8); last; };
|
/startproc/ && do { ($cfa_reg, $cfa_rsp) = ("%rsp", -8); last; };
|
||||||
/endproc/ && do { ($cfa_reg, $cfa_rsp) = ("%rsp", 0); last; };
|
/endproc/ && do { ($cfa_reg, $cfa_rsp) = ("%rsp", 0);
|
||||||
|
# .cfi_remember_state directives that are not
|
||||||
|
# matched with .cfi_restore_state are
|
||||||
|
# unnecessary.
|
||||||
|
die "unpaired .cfi_remember_state" if (@cfa_stack);
|
||||||
|
last;
|
||||||
|
};
|
||||||
/def_cfa_register/
|
/def_cfa_register/
|
||||||
&& do { $cfa_reg = $$line; last; };
|
&& do { $cfa_reg = $$line; last; };
|
||||||
/def_cfa_offset/
|
/def_cfa_offset/
|
||||||
@@ -688,6 +695,14 @@ my %globals;
|
|||||||
cfa_expression($$line)));
|
cfa_expression($$line)));
|
||||||
last;
|
last;
|
||||||
};
|
};
|
||||||
|
/remember_state/
|
||||||
|
&& do { push @cfa_stack, [$cfa_reg, $cfa_rsp];
|
||||||
|
last;
|
||||||
|
};
|
||||||
|
/restore_state/
|
||||||
|
&& do { ($cfa_reg, $cfa_rsp) = @{pop @cfa_stack};
|
||||||
|
last;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->{value} = ".cfi_$dir\t$$line" if ($dir);
|
$self->{value} = ".cfi_$dir\t$$line" if ($dir);
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ if ($flavour && $flavour ne "void") {
|
|||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
#include "arm_arch.h"
|
#include "arm_arch.h"
|
||||||
|
|
||||||
.text
|
|
||||||
#if defined(__thumb2__)
|
#if defined(__thumb2__)
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.thumb
|
.thumb
|
||||||
@@ -56,6 +55,8 @@ $code.=<<___;
|
|||||||
.code 32
|
.code 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
.globl poly1305_emit
|
.globl poly1305_emit
|
||||||
.globl poly1305_blocks
|
.globl poly1305_blocks
|
||||||
.globl poly1305_init
|
.globl poly1305_init
|
||||||
@@ -100,8 +101,10 @@ poly1305_init:
|
|||||||
and r4,r4,r10
|
and r4,r4,r10
|
||||||
|
|
||||||
#if __ARM_MAX_ARCH__>=7
|
#if __ARM_MAX_ARCH__>=7
|
||||||
|
# if !defined(_WIN32)
|
||||||
ldr r12,[r11,r12] @ OPENSSL_armcap_P
|
ldr r12,[r11,r12] @ OPENSSL_armcap_P
|
||||||
# ifdef __APPLE__
|
# endif
|
||||||
|
# if defined(__APPLE__) || defined(_WIN32)
|
||||||
ldr r12,[r12]
|
ldr r12,[r12]
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
@@ -116,31 +119,21 @@ poly1305_init:
|
|||||||
|
|
||||||
#if __ARM_MAX_ARCH__>=7
|
#if __ARM_MAX_ARCH__>=7
|
||||||
tst r12,#ARMV7_NEON @ check for NEON
|
tst r12,#ARMV7_NEON @ check for NEON
|
||||||
# ifdef __APPLE__
|
|
||||||
adr r9,poly1305_blocks_neon
|
|
||||||
adr r11,poly1305_blocks
|
|
||||||
# ifdef __thumb2__
|
# ifdef __thumb2__
|
||||||
it ne
|
adr r9,.Lpoly1305_blocks_neon
|
||||||
# endif
|
adr r11,.Lpoly1305_blocks
|
||||||
|
adr r12,.Lpoly1305_emit
|
||||||
|
adr r10,.Lpoly1305_emit_neon
|
||||||
|
itt ne
|
||||||
movne r11,r9
|
movne r11,r9
|
||||||
adr r12,poly1305_emit
|
|
||||||
adr r10,poly1305_emit_neon
|
|
||||||
# ifdef __thumb2__
|
|
||||||
it ne
|
|
||||||
# endif
|
|
||||||
movne r12,r10
|
movne r12,r10
|
||||||
|
orr r11,r11,#1 @ thumb-ify address
|
||||||
|
orr r12,r12,#1
|
||||||
# else
|
# else
|
||||||
# ifdef __thumb2__
|
addeq r12,r11,#(.Lpoly1305_emit-.Lpoly1305_init)
|
||||||
itete eq
|
addne r12,r11,#(.Lpoly1305_emit_neon-.Lpoly1305_init)
|
||||||
# endif
|
addeq r11,r11,#(.Lpoly1305_blocks-.Lpoly1305_init)
|
||||||
addeq r12,r11,#(poly1305_emit-.Lpoly1305_init)
|
addne r11,r11,#(.Lpoly1305_blocks_neon-.Lpoly1305_init)
|
||||||
addne r12,r11,#(poly1305_emit_neon-.Lpoly1305_init)
|
|
||||||
addeq r11,r11,#(poly1305_blocks-.Lpoly1305_init)
|
|
||||||
addne r11,r11,#(poly1305_blocks_neon-.Lpoly1305_init)
|
|
||||||
# endif
|
|
||||||
# ifdef __thumb2__
|
|
||||||
orr r12,r12,#1 @ thumb-ify address
|
|
||||||
orr r11,r11,#1
|
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
ldrb r9,[$inp,#11]
|
ldrb r9,[$inp,#11]
|
||||||
@@ -352,6 +345,7 @@ $code.=<<___;
|
|||||||
.type poly1305_emit,%function
|
.type poly1305_emit,%function
|
||||||
.align 5
|
.align 5
|
||||||
poly1305_emit:
|
poly1305_emit:
|
||||||
|
.Lpoly1305_emit:
|
||||||
stmdb sp!,{r4-r11}
|
stmdb sp!,{r4-r11}
|
||||||
.Lpoly1305_emit_enter:
|
.Lpoly1305_emit_enter:
|
||||||
|
|
||||||
@@ -671,6 +665,7 @@ poly1305_init_neon:
|
|||||||
.type poly1305_blocks_neon,%function
|
.type poly1305_blocks_neon,%function
|
||||||
.align 5
|
.align 5
|
||||||
poly1305_blocks_neon:
|
poly1305_blocks_neon:
|
||||||
|
.Lpoly1305_blocks_neon:
|
||||||
ldr ip,[$ctx,#36] @ is_base2_26
|
ldr ip,[$ctx,#36] @ is_base2_26
|
||||||
ands $len,$len,#-16
|
ands $len,$len,#-16
|
||||||
beq .Lno_data_neon
|
beq .Lno_data_neon
|
||||||
@@ -1157,6 +1152,7 @@ poly1305_blocks_neon:
|
|||||||
.type poly1305_emit_neon,%function
|
.type poly1305_emit_neon,%function
|
||||||
.align 5
|
.align 5
|
||||||
poly1305_emit_neon:
|
poly1305_emit_neon:
|
||||||
|
.Lpoly1305_emit_neon:
|
||||||
ldr ip,[$ctx,#36] @ is_base2_26
|
ldr ip,[$ctx,#36] @ is_base2_26
|
||||||
|
|
||||||
stmdb sp!,{r4-r11}
|
stmdb sp!,{r4-r11}
|
||||||
@@ -1229,7 +1225,11 @@ poly1305_emit_neon:
|
|||||||
.Lzeros:
|
.Lzeros:
|
||||||
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
.LOPENSSL_armcap:
|
.LOPENSSL_armcap:
|
||||||
|
# ifdef _WIN32
|
||||||
|
.word OPENSSL_armcap_P
|
||||||
|
# else
|
||||||
.word OPENSSL_armcap_P-.Lpoly1305_init
|
.word OPENSSL_armcap_P-.Lpoly1305_init
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
___
|
___
|
||||||
} }
|
} }
|
||||||
|
|||||||
@@ -71,17 +71,12 @@ poly1305_init:
|
|||||||
csel x0,xzr,x0,eq
|
csel x0,xzr,x0,eq
|
||||||
b.eq .Lno_key
|
b.eq .Lno_key
|
||||||
|
|
||||||
#ifdef __ILP32__
|
adrp x17,OPENSSL_armcap_P
|
||||||
ldrsw $t1,.LOPENSSL_armcap_P
|
ldr w17,[x17,#:lo12:OPENSSL_armcap_P]
|
||||||
#else
|
|
||||||
ldr $t1,.LOPENSSL_armcap_P
|
|
||||||
#endif
|
|
||||||
adr $t0,.LOPENSSL_armcap_P
|
|
||||||
|
|
||||||
ldp $r0,$r1,[$inp] // load key
|
ldp $r0,$r1,[$inp] // load key
|
||||||
mov $s1,#0xfffffffc0fffffff
|
mov $s1,#0xfffffffc0fffffff
|
||||||
movk $s1,#0x0fff,lsl#48
|
movk $s1,#0x0fff,lsl#48
|
||||||
ldr w17,[$t0,$t1]
|
|
||||||
#ifdef __ARMEB__
|
#ifdef __ARMEB__
|
||||||
rev $r0,$r0 // flip bytes
|
rev $r0,$r0 // flip bytes
|
||||||
rev $r1,$r1
|
rev $r1,$r1
|
||||||
@@ -93,10 +88,10 @@ poly1305_init:
|
|||||||
|
|
||||||
tst w17,#ARMV7_NEON
|
tst w17,#ARMV7_NEON
|
||||||
|
|
||||||
adr $d0,poly1305_blocks
|
adr $d0,.Lpoly1305_blocks
|
||||||
adr $r0,poly1305_blocks_neon
|
adr $r0,.Lpoly1305_blocks_neon
|
||||||
adr $d1,poly1305_emit
|
adr $d1,.Lpoly1305_emit
|
||||||
adr $r1,poly1305_emit_neon
|
adr $r1,.Lpoly1305_emit_neon
|
||||||
|
|
||||||
csel $d0,$d0,$r0,eq
|
csel $d0,$d0,$r0,eq
|
||||||
csel $d1,$d1,$r1,eq
|
csel $d1,$d1,$r1,eq
|
||||||
@@ -115,6 +110,7 @@ poly1305_init:
|
|||||||
.type poly1305_blocks,%function
|
.type poly1305_blocks,%function
|
||||||
.align 5
|
.align 5
|
||||||
poly1305_blocks:
|
poly1305_blocks:
|
||||||
|
.Lpoly1305_blocks:
|
||||||
ands $len,$len,#-16
|
ands $len,$len,#-16
|
||||||
b.eq .Lno_data
|
b.eq .Lno_data
|
||||||
|
|
||||||
@@ -179,6 +175,7 @@ poly1305_blocks:
|
|||||||
.type poly1305_emit,%function
|
.type poly1305_emit,%function
|
||||||
.align 5
|
.align 5
|
||||||
poly1305_emit:
|
poly1305_emit:
|
||||||
|
.Lpoly1305_emit:
|
||||||
ldp $h0,$h1,[$ctx] // load hash base 2^64
|
ldp $h0,$h1,[$ctx] // load hash base 2^64
|
||||||
ldr $h2,[$ctx,#16]
|
ldr $h2,[$ctx,#16]
|
||||||
ldp $t0,$t1,[$nonce] // load nonce
|
ldp $t0,$t1,[$nonce] // load nonce
|
||||||
@@ -285,12 +282,14 @@ poly1305_splat:
|
|||||||
.type poly1305_blocks_neon,%function
|
.type poly1305_blocks_neon,%function
|
||||||
.align 5
|
.align 5
|
||||||
poly1305_blocks_neon:
|
poly1305_blocks_neon:
|
||||||
|
.Lpoly1305_blocks_neon:
|
||||||
ldr $is_base2_26,[$ctx,#24]
|
ldr $is_base2_26,[$ctx,#24]
|
||||||
cmp $len,#128
|
cmp $len,#128
|
||||||
b.hs .Lblocks_neon
|
b.hs .Lblocks_neon
|
||||||
cbz $is_base2_26,poly1305_blocks
|
cbz $is_base2_26,.Lpoly1305_blocks
|
||||||
|
|
||||||
.Lblocks_neon:
|
.Lblocks_neon:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-80]!
|
stp x29,x30,[sp,#-80]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
|
|
||||||
@@ -430,7 +429,7 @@ poly1305_blocks_neon:
|
|||||||
csel $in2,$zeros,$in2,lo
|
csel $in2,$zeros,$in2,lo
|
||||||
|
|
||||||
mov x4,#1
|
mov x4,#1
|
||||||
str x4,[$ctx,#-24] // set is_base2_26
|
stur x4,[$ctx,#-24] // set is_base2_26
|
||||||
sub $ctx,$ctx,#48 // restore original $ctx
|
sub $ctx,$ctx,#48 // restore original $ctx
|
||||||
b .Ldo_neon
|
b .Ldo_neon
|
||||||
|
|
||||||
@@ -859,6 +858,7 @@ poly1305_blocks_neon:
|
|||||||
st1 {$ACC4}[0],[$ctx]
|
st1 {$ACC4}[0],[$ctx]
|
||||||
|
|
||||||
.Lno_data_neon:
|
.Lno_data_neon:
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ldr x29,[sp],#80
|
ldr x29,[sp],#80
|
||||||
ret
|
ret
|
||||||
.size poly1305_blocks_neon,.-poly1305_blocks_neon
|
.size poly1305_blocks_neon,.-poly1305_blocks_neon
|
||||||
@@ -866,6 +866,7 @@ poly1305_blocks_neon:
|
|||||||
.type poly1305_emit_neon,%function
|
.type poly1305_emit_neon,%function
|
||||||
.align 5
|
.align 5
|
||||||
poly1305_emit_neon:
|
poly1305_emit_neon:
|
||||||
|
.Lpoly1305_emit_neon:
|
||||||
ldr $is_base2_26,[$ctx,#24]
|
ldr $is_base2_26,[$ctx,#24]
|
||||||
cbz $is_base2_26,poly1305_emit
|
cbz $is_base2_26,poly1305_emit
|
||||||
|
|
||||||
@@ -918,12 +919,6 @@ poly1305_emit_neon:
|
|||||||
.align 5
|
.align 5
|
||||||
.Lzeros:
|
.Lzeros:
|
||||||
.long 0,0,0,0,0,0,0,0
|
.long 0,0,0,0,0,0,0,0
|
||||||
.LOPENSSL_armcap_P:
|
|
||||||
#ifdef __ILP32__
|
|
||||||
.long OPENSSL_armcap_P-.
|
|
||||||
#else
|
|
||||||
.quad OPENSSL_armcap_P-.
|
|
||||||
#endif
|
|
||||||
.asciz "Poly1305 for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
|
.asciz "Poly1305 for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
|
||||||
.align 2
|
.align 2
|
||||||
___
|
___
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
Properties are associated with algorithms and are used to select between different implementations dynamically.
|
||||||
|
|
||||||
|
This implementation is based on a number of assumptions:
|
||||||
|
|
||||||
|
* Property definition is uncommon. I.e. providers will be loaded and
|
||||||
|
unloaded relatively infrequently, if at all.
|
||||||
|
|
||||||
|
* The number of distinct property names will be small.
|
||||||
|
|
||||||
|
* Providers will often give the same implementation properties to most or
|
||||||
|
all of their implemented algorithms. E.g. the FIPS property would be set
|
||||||
|
across an entire provider. Likewise for, hardware, accelerated, software,
|
||||||
|
HSM and, perhaps, constant_time.
|
||||||
|
|
||||||
|
* There are a lot of algorithm implementations, therefore property
|
||||||
|
definitions should be space efficient. However...
|
||||||
|
|
||||||
|
* ... property queries are very common. These must be fast.
|
||||||
|
|
||||||
|
* Property queries come from a small set and are reused many times typically.
|
||||||
|
I.e. an application tends to use the same set of queries over and over,
|
||||||
|
rather than spanning a wide variety of queries.
|
||||||
|
|
||||||
|
* Property queries can never add new property definitions.
|
||||||
|
|
||||||
|
|
||||||
|
Some consequences of these assumptions are:
|
||||||
|
|
||||||
|
* That definition is uncommon and queries are very common, we can treat
|
||||||
|
the property definitions as almost immutable. Specifically, a query can
|
||||||
|
never change the state of the definitions.
|
||||||
|
|
||||||
|
* That definition is uncommon and needs to be space efficient, it will
|
||||||
|
be feasible to use a hash table to contain the names (and possibly also
|
||||||
|
values) of all properties and to reference these instead of duplicating
|
||||||
|
strings. Moreover, such a data structure need not be garbage collected.
|
||||||
|
By converting strings to integers using a structure such as this, string
|
||||||
|
comparison degenerates to integer comparison. Additionally, lists of
|
||||||
|
properties can be sorted by the string index which makes comparisons linear
|
||||||
|
time rather than quadratic time - the O(n log n) sort cost being amortised.
|
||||||
|
|
||||||
|
* A cache for property definitions is also viable, if only implementation
|
||||||
|
properties are used and not algorithm properties, or at least these are
|
||||||
|
maintained separately. This cache would be a hash table, indexed by
|
||||||
|
the property definition string, and algorithms with the same properties
|
||||||
|
would share their definition structure. Again, reducing space use.
|
||||||
|
|
||||||
|
* A query cache is desirable. This would be a hash table keyed by the
|
||||||
|
algorithm identifier and the entire query string and it would map to
|
||||||
|
the chosen algorithm. When a provider is loaded or unloaded, this cache
|
||||||
|
must be invalidated. The cache will also be invalidated when the global
|
||||||
|
properties are changed as doing so removes the need to index on both the
|
||||||
|
global and requested property strings.
|
||||||
|
|
||||||
|
|
||||||
|
The implementation:
|
||||||
|
|
||||||
|
* property_lock.c contains some wrapper functions to handle the global
|
||||||
|
lock more easily. The global lock is held for short periods of time with
|
||||||
|
per algorithm locking being used for longer intervals.
|
||||||
|
|
||||||
|
* property_string.c contains the string cache which converts property
|
||||||
|
names and values to small integer indices. Names and values are stored in
|
||||||
|
separate hash tables. The two Boolean values, the strings "yes" and "no",
|
||||||
|
are populated as the first two members of the value table. All property
|
||||||
|
names reserved by OpenSSL are also populated here. No functions are
|
||||||
|
provided to convert from an index back to the original string (this can be
|
||||||
|
done by maintaining parallel stacks of strings if required).
|
||||||
|
|
||||||
|
* property_parse.c contains the property definition and query parsers.
|
||||||
|
These convert ASCII strings into lists of properties. The resulting
|
||||||
|
lists are sorted by the name index. Some additional utility functions
|
||||||
|
for dealing with property lists are also included: comparison of a query
|
||||||
|
against a definition and merging two queries into a single larger query.
|
||||||
|
|
||||||
|
* property.c contains the main APIs for defining and using properties.
|
||||||
|
Algorithms are discovered from their NID and a query string.
|
||||||
|
The results are cached.
|
||||||
|
|
||||||
|
The caching of query results has to be efficient but it must also be robust
|
||||||
|
against a denial of service attack. The cache cannot be permitted to grow
|
||||||
|
without bounds and must garbage collect under-used entries. The garbage
|
||||||
|
collection does not have to be exact.
|
||||||
|
|
||||||
|
* defn_cache.c contains a cache that maps property definition strings to
|
||||||
|
parsed properties. It is used by property.c to improve performance when
|
||||||
|
the same definition appears multiple times.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
LIBS=../../libcrypto
|
||||||
|
SOURCE[../../libcrypto]=property_string.c property_parse.c property.c \
|
||||||
|
property_err.c defn_cache.c
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
|
* Copyright (c) 2019, Oracle and/or its affiliates. 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/err.h>
|
||||||
|
#include <openssl/lhash.h>
|
||||||
|
#include "internal/propertyerr.h"
|
||||||
|
#include "internal/property.h"
|
||||||
|
#include "property_lcl.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement a property definition cache.
|
||||||
|
* These functions assume that they are called under a write lock.
|
||||||
|
* No attempt is made to clean out the cache, except when it is shut down.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *prop;
|
||||||
|
OSSL_PROPERTY_LIST *defn;
|
||||||
|
char body[1];
|
||||||
|
} PROPERTY_DEFN_ELEM;
|
||||||
|
|
||||||
|
DEFINE_LHASH_OF(PROPERTY_DEFN_ELEM);
|
||||||
|
|
||||||
|
static LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns = NULL;
|
||||||
|
|
||||||
|
static unsigned long property_defn_hash(const PROPERTY_DEFN_ELEM *a)
|
||||||
|
{
|
||||||
|
return OPENSSL_LH_strhash(a->prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int property_defn_cmp(const PROPERTY_DEFN_ELEM *a,
|
||||||
|
const PROPERTY_DEFN_ELEM *b)
|
||||||
|
{
|
||||||
|
return strcmp(a->prop, b->prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void property_defn_free(PROPERTY_DEFN_ELEM *elem)
|
||||||
|
{
|
||||||
|
ossl_property_free(elem->defn);
|
||||||
|
OPENSSL_free(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_prop_defn_init(void)
|
||||||
|
{
|
||||||
|
property_defns = lh_PROPERTY_DEFN_ELEM_new(&property_defn_hash,
|
||||||
|
&property_defn_cmp);
|
||||||
|
return property_defns != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ossl_prop_defn_cleanup(void)
|
||||||
|
{
|
||||||
|
if (property_defns != NULL) {
|
||||||
|
lh_PROPERTY_DEFN_ELEM_doall(property_defns, &property_defn_free);
|
||||||
|
lh_PROPERTY_DEFN_ELEM_free(property_defns);
|
||||||
|
property_defns = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OSSL_PROPERTY_LIST *ossl_prop_defn_get(const char *prop)
|
||||||
|
{
|
||||||
|
PROPERTY_DEFN_ELEM elem, *r;
|
||||||
|
|
||||||
|
elem.prop = prop;
|
||||||
|
r = lh_PROPERTY_DEFN_ELEM_retrieve(property_defns, &elem);
|
||||||
|
return r != NULL ? r->defn : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_prop_defn_set(const char *prop, OSSL_PROPERTY_LIST *pl)
|
||||||
|
{
|
||||||
|
PROPERTY_DEFN_ELEM elem, *old, *p = NULL;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (prop == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (pl == NULL) {
|
||||||
|
elem.prop = prop;
|
||||||
|
lh_PROPERTY_DEFN_ELEM_delete(property_defns, &elem);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
len = strlen(prop);
|
||||||
|
p = OPENSSL_malloc(sizeof(*p) + len);
|
||||||
|
if (p != NULL) {
|
||||||
|
p->prop = p->body;
|
||||||
|
p->defn = pl;
|
||||||
|
memcpy(p->body, prop, len + 1);
|
||||||
|
old = lh_PROPERTY_DEFN_ELEM_insert(property_defns, p);
|
||||||
|
if (old != NULL) {
|
||||||
|
property_defn_free(old);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!lh_PROPERTY_DEFN_ELEM_error(property_defns))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
OPENSSL_free(p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
(* https://bottlecaps.de/rr/ui *)
|
||||||
|
|
||||||
|
Definition
|
||||||
|
::= PropertyName ( '=' Value )? ( ',' PropertyName ( '=' Value )? )*
|
||||||
|
Query ::= ( '-'? PropertyName | PropertyName ( '=' | '!=' ) Value )
|
||||||
|
( ',' ( '-'? PropertyName | PropertyName ( '=' | '!=' ) Value ) )*
|
||||||
|
Value ::= NumberLiteral
|
||||||
|
| StringLiteral
|
||||||
|
StringLiteral ::= QuotedString | UnquotedString
|
||||||
|
QuotedString ::= '"' [^"]* '"'
|
||||||
|
| "'" [^']* "'"
|
||||||
|
UnquotedString ::= [^{space},]+
|
||||||
|
NumberLiteral
|
||||||
|
::= '0' ( [0-7]* | 'x' [0-9A-Fa-f]+ )
|
||||||
|
| '-'? [1-9] [0-9]+
|
||||||
|
PropertyName
|
||||||
|
::= [A-Z] [A-Z0-9_]* ( '.' [A-Z] [A-Z0-9_]* )*
|
||||||
@@ -0,0 +1,685 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
|
||||||
|
<meta name="generator" content="Railroad Diagram Generator 1.56.1774" />
|
||||||
|
<style type="text/css">
|
||||||
|
::-moz-selection
|
||||||
|
{
|
||||||
|
color: #FFFCF0;
|
||||||
|
background: #0F0C00;
|
||||||
|
}
|
||||||
|
::selection
|
||||||
|
{
|
||||||
|
color: #FFFCF0;
|
||||||
|
background: #0F0C00;
|
||||||
|
}
|
||||||
|
.ebnf a, .grammar a
|
||||||
|
{
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.ebnf a:hover, .grammar a:hover
|
||||||
|
{
|
||||||
|
color: #050400;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.signature
|
||||||
|
{
|
||||||
|
color: #806600;
|
||||||
|
font-size: 11px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
body
|
||||||
|
{
|
||||||
|
font: normal 12px Verdana, sans-serif;
|
||||||
|
color: #0F0C00;
|
||||||
|
background: #FFFCF0;
|
||||||
|
}
|
||||||
|
a:link, a:visited
|
||||||
|
{
|
||||||
|
color: #0F0C00;
|
||||||
|
}
|
||||||
|
a:link.signature, a:visited.signature
|
||||||
|
{
|
||||||
|
color: #806600;
|
||||||
|
}
|
||||||
|
a.button, #tabs li a
|
||||||
|
{
|
||||||
|
padding: 0.25em 0.5em;
|
||||||
|
border: 1px solid #806600;
|
||||||
|
background: #F1E8C6;
|
||||||
|
color: #806600;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
a.button:hover, #tabs li a:hover
|
||||||
|
{
|
||||||
|
color: #050400;
|
||||||
|
background: #FFF6D1;
|
||||||
|
border-color: #050400;
|
||||||
|
}
|
||||||
|
#tabs
|
||||||
|
{
|
||||||
|
padding: 3px 10px;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-top: 58px;
|
||||||
|
border-bottom: 1px solid #0F0C00;
|
||||||
|
}
|
||||||
|
#tabs li
|
||||||
|
{
|
||||||
|
list-style: none;
|
||||||
|
margin-left: 5px;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
#tabs li a
|
||||||
|
{
|
||||||
|
border-bottom: 1px solid #0F0C00;
|
||||||
|
}
|
||||||
|
#tabs li a.active
|
||||||
|
{
|
||||||
|
color: #0F0C00;
|
||||||
|
background: #FFFCF0;
|
||||||
|
border-color: #0F0C00;
|
||||||
|
border-bottom: 1px solid #FFFCF0;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
#divs div
|
||||||
|
{
|
||||||
|
display: none;
|
||||||
|
overflow:auto;
|
||||||
|
}
|
||||||
|
#divs div.active
|
||||||
|
{
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
#text
|
||||||
|
{
|
||||||
|
border-color: #806600;
|
||||||
|
background: #FFFEFA;
|
||||||
|
color: #050400;
|
||||||
|
}
|
||||||
|
.small
|
||||||
|
{
|
||||||
|
vertical-align: top;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 9px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 120%;
|
||||||
|
}
|
||||||
|
td.small
|
||||||
|
{
|
||||||
|
padding-top: 0px;
|
||||||
|
}
|
||||||
|
.hidden
|
||||||
|
{
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
td:hover .hidden
|
||||||
|
{
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
div.download
|
||||||
|
{
|
||||||
|
display: none;
|
||||||
|
background: #FFFCF0;
|
||||||
|
position: absolute;
|
||||||
|
right: 34px;
|
||||||
|
top: 94px;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px dotted #0F0C00;
|
||||||
|
}
|
||||||
|
#divs div.ebnf, .ebnf code
|
||||||
|
{
|
||||||
|
display: block;
|
||||||
|
padding: 10px;
|
||||||
|
background: #FFF6D1;
|
||||||
|
width: 1000px;
|
||||||
|
}
|
||||||
|
#divs div.grammar
|
||||||
|
{
|
||||||
|
display: block;
|
||||||
|
padding-left: 16px;
|
||||||
|
padding-top: 2px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
background: #FFF6D1;
|
||||||
|
}
|
||||||
|
pre
|
||||||
|
{
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
.ebnf div
|
||||||
|
{
|
||||||
|
padding-left: 13ch;
|
||||||
|
text-indent: -13ch;
|
||||||
|
}
|
||||||
|
.ebnf code, .grammar code, textarea, pre
|
||||||
|
{
|
||||||
|
font:12px SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;
|
||||||
|
}
|
||||||
|
tr.option-line td:first-child
|
||||||
|
{
|
||||||
|
text-align: right
|
||||||
|
}
|
||||||
|
tr.option-text td
|
||||||
|
{
|
||||||
|
padding-bottom: 10px
|
||||||
|
}
|
||||||
|
table.palette
|
||||||
|
{
|
||||||
|
border-top: 1px solid #050400;
|
||||||
|
border-right: 1px solid #050400;
|
||||||
|
margin-bottom: 4px
|
||||||
|
}
|
||||||
|
td.palette
|
||||||
|
{
|
||||||
|
border-bottom: 1px solid #050400;
|
||||||
|
border-left: 1px solid #050400;
|
||||||
|
}
|
||||||
|
a.palette
|
||||||
|
{
|
||||||
|
padding: 2px 3px 2px 10px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.palette
|
||||||
|
{
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-o-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
}
|
||||||
|
</style><svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<style type="text/css">
|
||||||
|
@namespace "http://www.w3.org/2000/svg";
|
||||||
|
.line {fill: none; stroke: #332900;}
|
||||||
|
.bold-line {stroke: #141000; shape-rendering: crispEdges; stroke-width: 2; }
|
||||||
|
.thin-line {stroke: #1F1800; shape-rendering: crispEdges}
|
||||||
|
.filled {fill: #332900; stroke: none;}
|
||||||
|
text.terminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #141000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
text.nonterminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1A1400;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
text.regexp {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1F1800;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
rect, circle, polygon {fill: #332900; stroke: #332900;}
|
||||||
|
rect.terminal {fill: #FFDB4D; stroke: #332900;}
|
||||||
|
rect.nonterminal {fill: #FFEC9E; stroke: #332900;}
|
||||||
|
rect.text {fill: none; stroke: none;}
|
||||||
|
polygon.regexp {fill: #FFF4C7; stroke: #332900;}
|
||||||
|
</style>
|
||||||
|
</defs></svg></head>
|
||||||
|
<body>
|
||||||
|
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="Definition">Definition:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="375" height="113">
|
||||||
|
<defs>
|
||||||
|
<style type="text/css">
|
||||||
|
@namespace "http://www.w3.org/2000/svg";
|
||||||
|
.line {fill: none; stroke: #332900;}
|
||||||
|
.bold-line {stroke: #141000; shape-rendering: crispEdges; stroke-width: 2; }
|
||||||
|
.thin-line {stroke: #1F1800; shape-rendering: crispEdges}
|
||||||
|
.filled {fill: #332900; stroke: none;}
|
||||||
|
text.terminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #141000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
text.nonterminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1A1400;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
text.regexp {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1F1800;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
rect, circle, polygon {fill: #332900; stroke: #332900;}
|
||||||
|
rect.terminal {fill: #FFDB4D; stroke: #332900;}
|
||||||
|
rect.nonterminal {fill: #FFEC9E; stroke: #332900;}
|
||||||
|
rect.text {fill: none; stroke: none;}
|
||||||
|
polygon.regexp {fill: #FFF4C7; stroke: #332900;}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<polygon points="9 61 1 57 1 65"/>
|
||||||
|
<polygon points="17 61 9 57 9 65"/><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#PropertyName" xlink:title="PropertyName">
|
||||||
|
<rect x="51" y="47" width="110" height="32"/>
|
||||||
|
<rect x="49" y="45" width="110" height="32" class="nonterminal"/>
|
||||||
|
<text class="nonterminal" x="59" y="65">PropertyName</text></a><rect x="201" y="79" width="30" height="32" rx="10"/>
|
||||||
|
<rect x="199" y="77" width="30" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="209" y="97">=</text><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#Value" xlink:title="Value">
|
||||||
|
<rect x="251" y="79" width="56" height="32"/>
|
||||||
|
<rect x="249" y="77" width="56" height="32" class="nonterminal"/>
|
||||||
|
<text class="nonterminal" x="259" y="97">Value</text></a><rect x="51" y="3" width="24" height="32" rx="10"/>
|
||||||
|
<rect x="49" y="1" width="24" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="59" y="21">,</text>
|
||||||
|
<svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 61 h2 m20 0 h10 m110 0 h10 m20 0 h10 m0 0 h116 m-146 0 h20 m126 0 h20 m-166 0 q10 0 10 10 m146 0 q0 -10 10 -10 m-156 10 v12 m146 0 v-12 m-146 12 q0 10 10 10 m126 0 q10 0 10 -10 m-136 10 h10 m30 0 h10 m0 0 h10 m56 0 h10 m-296 -32 l20 0 m-1 0 q-9 0 -9 -10 l0 -24 q0 -10 10 -10 m296 44 l20 0 m-20 0 q10 0 10 -10 l0 -24 q0 -10 -10 -10 m-296 0 h10 m24 0 h10 m0 0 h252 m23 44 h-3"/>
|
||||||
|
<polygon points="365 61 373 57 373 65"/>
|
||||||
|
<polygon points="365 61 357 57 357 65"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||||
|
<xhtml:div class="ebnf"><xhtml:code>
|
||||||
|
<div><a href="#Definition" title="Definition">Definition</a></div>
|
||||||
|
<div> ::= <a href="#PropertyName" title="PropertyName">PropertyName</a> ( '=' <a href="#Value" title="Value">Value</a> )? ( ',' <a href="#PropertyName" title="PropertyName">PropertyName</a> ( '=' <a href="#Value" title="Value">Value</a> )? )*</div></xhtml:code></xhtml:div>
|
||||||
|
</xhtml:p>
|
||||||
|
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">no references</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="Query">Query:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="419" height="201">
|
||||||
|
<defs>
|
||||||
|
<style type="text/css">
|
||||||
|
@namespace "http://www.w3.org/2000/svg";
|
||||||
|
.line {fill: none; stroke: #332900;}
|
||||||
|
.bold-line {stroke: #141000; shape-rendering: crispEdges; stroke-width: 2; }
|
||||||
|
.thin-line {stroke: #1F1800; shape-rendering: crispEdges}
|
||||||
|
.filled {fill: #332900; stroke: none;}
|
||||||
|
text.terminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #141000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
text.nonterminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1A1400;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
text.regexp {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1F1800;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
rect, circle, polygon {fill: #332900; stroke: #332900;}
|
||||||
|
rect.terminal {fill: #FFDB4D; stroke: #332900;}
|
||||||
|
rect.nonterminal {fill: #FFEC9E; stroke: #332900;}
|
||||||
|
rect.text {fill: none; stroke: none;}
|
||||||
|
polygon.regexp {fill: #FFF4C7; stroke: #332900;}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<polygon points="9 61 1 57 1 65"/>
|
||||||
|
<polygon points="17 61 9 57 9 65"/>
|
||||||
|
<rect x="91" y="79" width="26" height="32" rx="10"/>
|
||||||
|
<rect x="89" y="77" width="26" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="99" y="97">-</text><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#PropertyName" xlink:title="PropertyName">
|
||||||
|
<rect x="157" y="47" width="110" height="32"/>
|
||||||
|
<rect x="155" y="45" width="110" height="32" class="nonterminal"/>
|
||||||
|
<text class="nonterminal" x="165" y="65">PropertyName</text></a><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#PropertyName" xlink:title="PropertyName">
|
||||||
|
<rect x="71" y="123" width="110" height="32"/>
|
||||||
|
<rect x="69" y="121" width="110" height="32" class="nonterminal"/>
|
||||||
|
<text class="nonterminal" x="79" y="141">PropertyName</text></a><rect x="221" y="123" width="30" height="32" rx="10"/>
|
||||||
|
<rect x="219" y="121" width="30" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="229" y="141">=</text>
|
||||||
|
<rect x="221" y="167" width="34" height="32" rx="10"/>
|
||||||
|
<rect x="219" y="165" width="34" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="229" y="185">!=</text><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#Value" xlink:title="Value">
|
||||||
|
<rect x="295" y="123" width="56" height="32"/>
|
||||||
|
<rect x="293" y="121" width="56" height="32" class="nonterminal"/>
|
||||||
|
<text class="nonterminal" x="303" y="141">Value</text></a><rect x="51" y="3" width="24" height="32" rx="10"/>
|
||||||
|
<rect x="49" y="1" width="24" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="59" y="21">,</text>
|
||||||
|
<svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 61 h2 m60 0 h10 m0 0 h36 m-66 0 h20 m46 0 h20 m-86 0 q10 0 10 10 m66 0 q0 -10 10 -10 m-76 10 v12 m66 0 v-12 m-66 12 q0 10 10 10 m46 0 q10 0 10 -10 m-56 10 h10 m26 0 h10 m20 -32 h10 m110 0 h10 m0 0 h84 m-320 0 h20 m300 0 h20 m-340 0 q10 0 10 10 m320 0 q0 -10 10 -10 m-330 10 v56 m320 0 v-56 m-320 56 q0 10 10 10 m300 0 q10 0 10 -10 m-310 10 h10 m110 0 h10 m20 0 h10 m30 0 h10 m0 0 h4 m-74 0 h20 m54 0 h20 m-94 0 q10 0 10 10 m74 0 q0 -10 10 -10 m-84 10 v24 m74 0 v-24 m-74 24 q0 10 10 10 m54 0 q10 0 10 -10 m-64 10 h10 m34 0 h10 m20 -44 h10 m56 0 h10 m-340 -76 l20 0 m-1 0 q-9 0 -9 -10 l0 -24 q0 -10 10 -10 m340 44 l20 0 m-20 0 q10 0 10 -10 l0 -24 q0 -10 -10 -10 m-340 0 h10 m24 0 h10 m0 0 h296 m23 44 h-3"/>
|
||||||
|
<polygon points="409 61 417 57 417 65"/>
|
||||||
|
<polygon points="409 61 401 57 401 65"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||||
|
<xhtml:div class="ebnf"><xhtml:code>
|
||||||
|
<div><a href="#Query" title="Query">Query</a> ::= ( '-'? <a href="#PropertyName" title="PropertyName">PropertyName</a> | <a href="#PropertyName" title="PropertyName">PropertyName</a> ( '=' | '!=' ) <a href="#Value" title="Value">Value</a> ) ( ',' ( '-'? <a href="#PropertyName" title="PropertyName">PropertyName</a> | <a href="#PropertyName" title="PropertyName">PropertyName</a> ( '=' | '!=' ) <a href="#Value" title="Value">Value</a> ) )*</div></xhtml:code></xhtml:div>
|
||||||
|
</xhtml:p>
|
||||||
|
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">no references</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="Value">Value:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="207" height="81">
|
||||||
|
<defs>
|
||||||
|
<style type="text/css">
|
||||||
|
@namespace "http://www.w3.org/2000/svg";
|
||||||
|
.line {fill: none; stroke: #332900;}
|
||||||
|
.bold-line {stroke: #141000; shape-rendering: crispEdges; stroke-width: 2; }
|
||||||
|
.thin-line {stroke: #1F1800; shape-rendering: crispEdges}
|
||||||
|
.filled {fill: #332900; stroke: none;}
|
||||||
|
text.terminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #141000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
text.nonterminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1A1400;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
text.regexp {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1F1800;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
rect, circle, polygon {fill: #332900; stroke: #332900;}
|
||||||
|
rect.terminal {fill: #FFDB4D; stroke: #332900;}
|
||||||
|
rect.nonterminal {fill: #FFEC9E; stroke: #332900;}
|
||||||
|
rect.text {fill: none; stroke: none;}
|
||||||
|
polygon.regexp {fill: #FFF4C7; stroke: #332900;}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<polygon points="9 17 1 13 1 21"/>
|
||||||
|
<polygon points="17 17 9 13 9 21"/><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#NumberLiteral" xlink:title="NumberLiteral">
|
||||||
|
<rect x="51" y="3" width="108" height="32"/>
|
||||||
|
<rect x="49" y="1" width="108" height="32" class="nonterminal"/>
|
||||||
|
<text class="nonterminal" x="59" y="21">NumberLiteral</text></a><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#StringLiteral" xlink:title="StringLiteral">
|
||||||
|
<rect x="51" y="47" width="96" height="32"/>
|
||||||
|
<rect x="49" y="45" width="96" height="32" class="nonterminal"/>
|
||||||
|
<text class="nonterminal" x="59" y="65">StringLiteral</text></a><svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 17 h2 m20 0 h10 m108 0 h10 m-148 0 h20 m128 0 h20 m-168 0 q10 0 10 10 m148 0 q0 -10 10 -10 m-158 10 v24 m148 0 v-24 m-148 24 q0 10 10 10 m128 0 q10 0 10 -10 m-138 10 h10 m96 0 h10 m0 0 h12 m23 -44 h-3"/>
|
||||||
|
<polygon points="197 17 205 13 205 21"/>
|
||||||
|
<polygon points="197 17 189 13 189 21"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||||
|
<xhtml:div class="ebnf"><xhtml:code>
|
||||||
|
<div><a href="#Value" title="Value">Value</a> ::= <a href="#NumberLiteral" title="NumberLiteral">NumberLiteral</a></div>
|
||||||
|
<div> | <a href="#StringLiteral" title="StringLiteral">StringLiteral</a></div></xhtml:code></xhtml:div>
|
||||||
|
</xhtml:p>
|
||||||
|
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">referenced by:
|
||||||
|
<xhtml:ul>
|
||||||
|
<xhtml:li><xhtml:a href="#Definition" title="Definition">Definition</xhtml:a></xhtml:li>
|
||||||
|
<xhtml:li><xhtml:a href="#Query" title="Query">Query</xhtml:a></xhtml:li>
|
||||||
|
</xhtml:ul>
|
||||||
|
</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="StringLiteral">StringLiteral:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="219" height="81">
|
||||||
|
<defs>
|
||||||
|
<style type="text/css">
|
||||||
|
@namespace "http://www.w3.org/2000/svg";
|
||||||
|
.line {fill: none; stroke: #332900;}
|
||||||
|
.bold-line {stroke: #141000; shape-rendering: crispEdges; stroke-width: 2; }
|
||||||
|
.thin-line {stroke: #1F1800; shape-rendering: crispEdges}
|
||||||
|
.filled {fill: #332900; stroke: none;}
|
||||||
|
text.terminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #141000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
text.nonterminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1A1400;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
text.regexp {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1F1800;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
rect, circle, polygon {fill: #332900; stroke: #332900;}
|
||||||
|
rect.terminal {fill: #FFDB4D; stroke: #332900;}
|
||||||
|
rect.nonterminal {fill: #FFEC9E; stroke: #332900;}
|
||||||
|
rect.text {fill: none; stroke: none;}
|
||||||
|
polygon.regexp {fill: #FFF4C7; stroke: #332900;}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<polygon points="9 17 1 13 1 21"/>
|
||||||
|
<polygon points="17 17 9 13 9 21"/><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#QuotedString" xlink:title="QuotedString">
|
||||||
|
<rect x="51" y="3" width="104" height="32"/>
|
||||||
|
<rect x="49" y="1" width="104" height="32" class="nonterminal"/>
|
||||||
|
<text class="nonterminal" x="59" y="21">QuotedString</text></a><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#UnquotedString" xlink:title="UnquotedString">
|
||||||
|
<rect x="51" y="47" width="120" height="32"/>
|
||||||
|
<rect x="49" y="45" width="120" height="32" class="nonterminal"/>
|
||||||
|
<text class="nonterminal" x="59" y="65">UnquotedString</text></a><svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 17 h2 m20 0 h10 m104 0 h10 m0 0 h16 m-160 0 h20 m140 0 h20 m-180 0 q10 0 10 10 m160 0 q0 -10 10 -10 m-170 10 v24 m160 0 v-24 m-160 24 q0 10 10 10 m140 0 q10 0 10 -10 m-150 10 h10 m120 0 h10 m23 -44 h-3"/>
|
||||||
|
<polygon points="209 17 217 13 217 21"/>
|
||||||
|
<polygon points="209 17 201 13 201 21"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||||
|
<xhtml:div class="ebnf"><xhtml:code>
|
||||||
|
<div><a href="#StringLiteral" title="StringLiteral">StringLiteral</a></div>
|
||||||
|
<div> ::= <a href="#QuotedString" title="QuotedString">QuotedString</a></div>
|
||||||
|
<div> | <a href="#UnquotedString" title="UnquotedString">UnquotedString</a></div></xhtml:code></xhtml:div>
|
||||||
|
</xhtml:p>
|
||||||
|
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">referenced by:
|
||||||
|
<xhtml:ul>
|
||||||
|
<xhtml:li><xhtml:a href="#Value" title="Value">Value</xhtml:a></xhtml:li>
|
||||||
|
</xhtml:ul>
|
||||||
|
</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="QuotedString">QuotedString:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="327" height="151">
|
||||||
|
<defs>
|
||||||
|
<style type="text/css">
|
||||||
|
@namespace "http://www.w3.org/2000/svg";
|
||||||
|
.line {fill: none; stroke: #332900;}
|
||||||
|
.bold-line {stroke: #141000; shape-rendering: crispEdges; stroke-width: 2; }
|
||||||
|
.thin-line {stroke: #1F1800; shape-rendering: crispEdges}
|
||||||
|
.filled {fill: #332900; stroke: none;}
|
||||||
|
text.terminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #141000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
text.nonterminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1A1400;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
text.regexp {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1F1800;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
rect, circle, polygon {fill: #332900; stroke: #332900;}
|
||||||
|
rect.terminal {fill: #FFDB4D; stroke: #332900;}
|
||||||
|
rect.nonterminal {fill: #FFEC9E; stroke: #332900;}
|
||||||
|
rect.text {fill: none; stroke: none;}
|
||||||
|
polygon.regexp {fill: #FFF4C7; stroke: #332900;}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<polygon points="9 33 1 29 1 37"/>
|
||||||
|
<polygon points="17 33 9 29 9 37"/>
|
||||||
|
<rect x="51" y="19" width="26" height="32" rx="10"/>
|
||||||
|
<rect x="49" y="17" width="26" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="59" y="37">"</text>
|
||||||
|
<polygon points="137 35 144 19 186 19 193 35 186 51 144 51"/>
|
||||||
|
<polygon points="135 33 142 17 184 17 191 33 184 49 142 49" class="regexp"/>
|
||||||
|
<text class="regexp" x="150" y="37">[^"]</text>
|
||||||
|
<rect x="253" y="19" width="26" height="32" rx="10"/>
|
||||||
|
<rect x="251" y="17" width="26" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="261" y="37">"</text>
|
||||||
|
<rect x="51" y="101" width="24" height="32" rx="10"/>
|
||||||
|
<rect x="49" y="99" width="24" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="59" y="119">'</text>
|
||||||
|
<polygon points="135 117 142 101 182 101 189 117 182 133 142 133"/>
|
||||||
|
<polygon points="133 115 140 99 180 99 187 115 180 131 140 131" class="regexp"/>
|
||||||
|
<text class="regexp" x="148" y="119">[^']</text>
|
||||||
|
<rect x="249" y="101" width="24" height="32" rx="10"/>
|
||||||
|
<rect x="247" y="99" width="24" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="257" y="119">'</text>
|
||||||
|
<svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 33 h2 m20 0 h10 m26 0 h10 m40 0 h10 m56 0 h10 m-96 0 l20 0 m-1 0 q-9 0 -9 -10 l0 -12 q0 -10 10 -10 m76 32 l20 0 m-20 0 q10 0 10 -10 l0 -12 q0 -10 -10 -10 m-76 0 h10 m0 0 h66 m-116 32 h20 m116 0 h20 m-156 0 q10 0 10 10 m136 0 q0 -10 10 -10 m-146 10 v14 m136 0 v-14 m-136 14 q0 10 10 10 m116 0 q10 0 10 -10 m-126 10 h10 m0 0 h106 m20 -34 h10 m26 0 h10 m-268 0 h20 m248 0 h20 m-288 0 q10 0 10 10 m268 0 q0 -10 10 -10 m-278 10 v62 m268 0 v-62 m-268 62 q0 10 10 10 m248 0 q10 0 10 -10 m-258 10 h10 m24 0 h10 m40 0 h10 m54 0 h10 m-94 0 l20 0 m-1 0 q-9 0 -9 -10 l0 -12 q0 -10 10 -10 m74 32 l20 0 m-20 0 q10 0 10 -10 l0 -12 q0 -10 -10 -10 m-74 0 h10 m0 0 h64 m-114 32 h20 m114 0 h20 m-154 0 q10 0 10 10 m134 0 q0 -10 10 -10 m-144 10 v14 m134 0 v-14 m-134 14 q0 10 10 10 m114 0 q10 0 10 -10 m-124 10 h10 m0 0 h104 m20 -34 h10 m24 0 h10 m0 0 h6 m23 -82 h-3"/>
|
||||||
|
<polygon points="317 33 325 29 325 37"/>
|
||||||
|
<polygon points="317 33 309 29 309 37"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||||
|
<xhtml:div class="ebnf"><xhtml:code>
|
||||||
|
<div><a href="#QuotedString" title="QuotedString">QuotedString</a></div>
|
||||||
|
<div> ::= '"' [^"]* '"'</div>
|
||||||
|
<div> | "'" [^']* "'"</div></xhtml:code></xhtml:div>
|
||||||
|
</xhtml:p>
|
||||||
|
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">referenced by:
|
||||||
|
<xhtml:ul>
|
||||||
|
<xhtml:li><xhtml:a href="#StringLiteral" title="StringLiteral">StringLiteral</xhtml:a></xhtml:li>
|
||||||
|
</xhtml:ul>
|
||||||
|
</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="UnquotedString">UnquotedString:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="207" height="53">
|
||||||
|
<defs>
|
||||||
|
<style type="text/css">
|
||||||
|
@namespace "http://www.w3.org/2000/svg";
|
||||||
|
.line {fill: none; stroke: #332900;}
|
||||||
|
.bold-line {stroke: #141000; shape-rendering: crispEdges; stroke-width: 2; }
|
||||||
|
.thin-line {stroke: #1F1800; shape-rendering: crispEdges}
|
||||||
|
.filled {fill: #332900; stroke: none;}
|
||||||
|
text.terminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #141000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
text.nonterminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1A1400;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
text.regexp {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1F1800;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
rect, circle, polygon {fill: #332900; stroke: #332900;}
|
||||||
|
rect.terminal {fill: #FFDB4D; stroke: #332900;}
|
||||||
|
rect.nonterminal {fill: #FFEC9E; stroke: #332900;}
|
||||||
|
rect.text {fill: none; stroke: none;}
|
||||||
|
polygon.regexp {fill: #FFF4C7; stroke: #332900;}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<polygon points="9 33 1 29 1 37"/>
|
||||||
|
<polygon points="17 33 9 29 9 37"/>
|
||||||
|
<polygon points="51 35 58 19 152 19 159 35 152 51 58 51"/>
|
||||||
|
<polygon points="49 33 56 17 150 17 157 33 150 49 56 49" class="regexp"/>
|
||||||
|
<text class="regexp" x="64" y="37">[^{space},]</text>
|
||||||
|
<svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 33 h2 m20 0 h10 m108 0 h10 m-148 0 l20 0 m-1 0 q-9 0 -9 -10 l0 -12 q0 -10 10 -10 m128 32 l20 0 m-20 0 q10 0 10 -10 l0 -12 q0 -10 -10 -10 m-128 0 h10 m0 0 h118 m23 32 h-3"/>
|
||||||
|
<polygon points="197 33 205 29 205 37"/>
|
||||||
|
<polygon points="197 33 189 29 189 37"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||||
|
<xhtml:div class="ebnf"><xhtml:code>
|
||||||
|
<div><a href="#UnquotedString" title="UnquotedString">UnquotedString</a></div>
|
||||||
|
<div> ::= [^{space},]+</div></xhtml:code></xhtml:div>
|
||||||
|
</xhtml:p>
|
||||||
|
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">referenced by:
|
||||||
|
<xhtml:ul>
|
||||||
|
<xhtml:li><xhtml:a href="#StringLiteral" title="StringLiteral">StringLiteral</xhtml:a></xhtml:li>
|
||||||
|
</xhtml:ul>
|
||||||
|
</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="NumberLiteral">NumberLiteral:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="377" height="305">
|
||||||
|
<defs>
|
||||||
|
<style type="text/css">
|
||||||
|
@namespace "http://www.w3.org/2000/svg";
|
||||||
|
.line {fill: none; stroke: #332900;}
|
||||||
|
.bold-line {stroke: #141000; shape-rendering: crispEdges; stroke-width: 2; }
|
||||||
|
.thin-line {stroke: #1F1800; shape-rendering: crispEdges}
|
||||||
|
.filled {fill: #332900; stroke: none;}
|
||||||
|
text.terminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #141000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
text.nonterminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1A1400;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
text.regexp {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1F1800;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
rect, circle, polygon {fill: #332900; stroke: #332900;}
|
||||||
|
rect.terminal {fill: #FFDB4D; stroke: #332900;}
|
||||||
|
rect.nonterminal {fill: #FFEC9E; stroke: #332900;}
|
||||||
|
rect.text {fill: none; stroke: none;}
|
||||||
|
polygon.regexp {fill: #FFF4C7; stroke: #332900;}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<polygon points="9 51 1 47 1 55"/>
|
||||||
|
<polygon points="17 51 9 47 9 55"/>
|
||||||
|
<rect x="51" y="37" width="28" height="32" rx="10"/>
|
||||||
|
<rect x="49" y="35" width="28" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="59" y="55">0</text>
|
||||||
|
<polygon points="139 19 146 3 194 3 201 19 194 35 146 35"/>
|
||||||
|
<polygon points="137 17 144 1 192 1 199 17 192 33 144 33" class="regexp"/>
|
||||||
|
<text class="regexp" x="152" y="21">[0-7]</text>
|
||||||
|
<rect x="119" y="85" width="28" height="32" rx="10"/>
|
||||||
|
<rect x="117" y="83" width="28" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="127" y="103">x</text>
|
||||||
|
<polygon points="207 101 214 85 262 85 269 101 262 117 214 117"/>
|
||||||
|
<polygon points="205 99 212 83 260 83 267 99 260 115 212 115" class="regexp"/>
|
||||||
|
<text class="regexp" x="220" y="103">[0-9]</text>
|
||||||
|
<polygon points="207 145 214 129 260 129 267 145 260 161 214 161"/>
|
||||||
|
<polygon points="205 143 212 127 258 127 265 143 258 159 212 159" class="regexp"/>
|
||||||
|
<text class="regexp" x="220" y="147">[A-F]</text>
|
||||||
|
<polygon points="207 189 214 173 258 173 265 189 258 205 214 205"/>
|
||||||
|
<polygon points="205 187 212 171 256 171 263 187 256 203 212 203" class="regexp"/>
|
||||||
|
<text class="regexp" x="220" y="191">[a-f]</text>
|
||||||
|
<rect x="71" y="271" width="26" height="32" rx="10"/>
|
||||||
|
<rect x="69" y="269" width="26" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="79" y="289">-</text>
|
||||||
|
<polygon points="137 255 144 239 192 239 199 255 192 271 144 271"/>
|
||||||
|
<polygon points="135 253 142 237 190 237 197 253 190 269 142 269" class="regexp"/>
|
||||||
|
<text class="regexp" x="150" y="257">[1-9]</text>
|
||||||
|
<polygon points="239 255 246 239 294 239 301 255 294 271 246 271"/>
|
||||||
|
<polygon points="237 253 244 237 292 237 299 253 292 269 244 269" class="regexp"/>
|
||||||
|
<text class="regexp" x="252" y="257">[0-9]</text>
|
||||||
|
<svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 51 h2 m20 0 h10 m28 0 h10 m40 0 h10 m0 0 h72 m-102 0 l20 0 m-1 0 q-9 0 -9 -10 l0 -14 q0 -10 10 -10 m82 34 l20 0 m-20 0 q10 0 10 -10 l0 -14 q0 -10 -10 -10 m-82 0 h10 m62 0 h10 m20 34 h88 m-230 0 h20 m210 0 h20 m-250 0 q10 0 10 10 m230 0 q0 -10 10 -10 m-240 10 v28 m230 0 v-28 m-230 28 q0 10 10 10 m210 0 q10 0 10 -10 m-220 10 h10 m28 0 h10 m40 0 h10 m62 0 h10 m-102 0 h20 m82 0 h20 m-122 0 q10 0 10 10 m102 0 q0 -10 10 -10 m-112 10 v24 m102 0 v-24 m-102 24 q0 10 10 10 m82 0 q10 0 10 -10 m-92 10 h10 m60 0 h10 m0 0 h2 m-92 -10 v20 m102 0 v-20 m-102 20 v24 m102 0 v-24 m-102 24 q0 10 10 10 m82 0 q10 0 10 -10 m-92 10 h10 m58 0 h10 m0 0 h4 m-122 -88 l20 0 m-1 0 q-9 0 -9 -10 l0 -12 q0 -10 10 -10 m122 32 l20 0 m-20 0 q10 0 10 -10 l0 -12 q0 -10 -10 -10 m-122 0 h10 m0 0 h112 m-278 -16 h20 m298 0 h20 m-338 0 q10 0 10 10 m318 0 q0 -10 10 -10 m-328 10 v182 m318 0 v-182 m-318 182 q0 10 10 10 m298 0 q10 0 10 -10 m-288 10 h10 m0 0 h36 m-66 0 h20 m46 0 h20 m-86 0 q10 0 10 10 m66 0 q0 -10 10 -10 m-76 10 v12 m66 0 v-12 m-66 12 q0 10 10 10 m46 0 q10 0 10 -10 m-56 10 h10 m26 0 h10 m20 -32 h10 m62 0 h10 m20 0 h10 m62 0 h10 m-102 0 l20 0 m-1 0 q-9 0 -9 -10 l0 -12 q0 -10 10 -10 m82 32 l20 0 m-20 0 q10 0 10 -10 l0 -12 q0 -10 -10 -10 m-82 0 h10 m0 0 h72 m20 32 h8 m23 -202 h-3"/>
|
||||||
|
<polygon points="367 51 375 47 375 55"/>
|
||||||
|
<polygon points="367 51 359 47 359 55"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||||
|
<xhtml:div class="ebnf"><xhtml:code>
|
||||||
|
<div><a href="#NumberLiteral" title="NumberLiteral">NumberLiteral</a></div>
|
||||||
|
<div> ::= '0' ( [0-7]* | 'x' [0-9A-Fa-f]+ )</div>
|
||||||
|
<div> | '-'? [1-9] [0-9]+</div></xhtml:code></xhtml:div>
|
||||||
|
</xhtml:p>
|
||||||
|
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">referenced by:
|
||||||
|
<xhtml:ul>
|
||||||
|
<xhtml:li><xhtml:a href="#Value" title="Value">Value</xhtml:a></xhtml:li>
|
||||||
|
</xhtml:ul>
|
||||||
|
</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml" style="font-size: 14px; font-weight:bold"><xhtml:a name="PropertyName">PropertyName:</xhtml:a></xhtml:p><svg xmlns="http://www.w3.org/2000/svg" width="283" height="203">
|
||||||
|
<defs>
|
||||||
|
<style type="text/css">
|
||||||
|
@namespace "http://www.w3.org/2000/svg";
|
||||||
|
.line {fill: none; stroke: #332900;}
|
||||||
|
.bold-line {stroke: #141000; shape-rendering: crispEdges; stroke-width: 2; }
|
||||||
|
.thin-line {stroke: #1F1800; shape-rendering: crispEdges}
|
||||||
|
.filled {fill: #332900; stroke: none;}
|
||||||
|
text.terminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #141000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
text.nonterminal {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1A1400;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
text.regexp {font-family: Verdana, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
fill: #1F1800;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
rect, circle, polygon {fill: #332900; stroke: #332900;}
|
||||||
|
rect.terminal {fill: #FFDB4D; stroke: #332900;}
|
||||||
|
rect.nonterminal {fill: #FFEC9E; stroke: #332900;}
|
||||||
|
rect.text {fill: none; stroke: none;}
|
||||||
|
polygon.regexp {fill: #FFF4C7; stroke: #332900;}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<polygon points="9 183 1 179 1 187"/>
|
||||||
|
<polygon points="17 183 9 179 9 187"/>
|
||||||
|
<polygon points="51 185 58 169 106 169 113 185 106 201 58 201"/>
|
||||||
|
<polygon points="49 183 56 167 104 167 111 183 104 199 56 199" class="regexp"/>
|
||||||
|
<text class="regexp" x="64" y="187">[A-Z]</text>
|
||||||
|
<polygon points="153 151 160 135 208 135 215 151 208 167 160 167"/>
|
||||||
|
<polygon points="151 149 158 133 206 133 213 149 206 165 158 165" class="regexp"/>
|
||||||
|
<text class="regexp" x="166" y="153">[A-Z]</text>
|
||||||
|
<polygon points="153 107 160 91 208 91 215 107 208 123 160 123"/>
|
||||||
|
<polygon points="151 105 158 89 206 89 213 105 206 121 158 121" class="regexp"/>
|
||||||
|
<text class="regexp" x="166" y="109">[0-9]</text>
|
||||||
|
<rect x="153" y="47" width="28" height="32" rx="10"/>
|
||||||
|
<rect x="151" y="45" width="28" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="161" y="65">_</text>
|
||||||
|
<rect x="51" y="3" width="24" height="32" rx="10"/>
|
||||||
|
<rect x="49" y="1" width="24" height="32" class="terminal" rx="10"/>
|
||||||
|
<text class="terminal" x="59" y="21">.</text>
|
||||||
|
<svg:path xmlns:svg="http://www.w3.org/2000/svg" class="line" d="m17 183 h2 m20 0 h10 m62 0 h10 m20 0 h10 m0 0 h72 m-102 0 l20 0 m-1 0 q-9 0 -9 -10 l0 -14 q0 -10 10 -10 m82 34 l20 0 m-20 0 q10 0 10 -10 l0 -14 q0 -10 -10 -10 m-82 0 h10 m62 0 h10 m-92 10 l0 -44 q0 -10 10 -10 m92 54 l0 -44 q0 -10 -10 -10 m-82 0 h10 m62 0 h10 m-92 10 l0 -44 q0 -10 10 -10 m92 54 l0 -44 q0 -10 -10 -10 m-82 0 h10 m28 0 h10 m0 0 h34 m-204 122 l20 0 m-1 0 q-9 0 -9 -10 l0 -146 q0 -10 10 -10 m204 166 l20 0 m-20 0 q10 0 10 -10 l0 -146 q0 -10 -10 -10 m-204 0 h10 m24 0 h10 m0 0 h160 m23 166 h-3"/>
|
||||||
|
<polygon points="273 183 281 179 281 187"/>
|
||||||
|
<polygon points="273 183 265 179 265 187"/></svg><xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||||
|
<xhtml:div class="ebnf"><xhtml:code>
|
||||||
|
<div><a href="#PropertyName" title="PropertyName">PropertyName</a></div>
|
||||||
|
<div> ::= [A-Z] [A-Z0-9_]* ( '.' [A-Z] [A-Z0-9_]* )*</div></xhtml:code></xhtml:div>
|
||||||
|
</xhtml:p>
|
||||||
|
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">referenced by:
|
||||||
|
<xhtml:ul>
|
||||||
|
<xhtml:li><xhtml:a href="#Definition" title="Definition">Definition</xhtml:a></xhtml:li>
|
||||||
|
<xhtml:li><xhtml:a href="#Query" title="Query">Query</xhtml:a></xhtml:li>
|
||||||
|
</xhtml:ul>
|
||||||
|
</xhtml:p><xhtml:br xmlns:xhtml="http://www.w3.org/1999/xhtml" /><xhtml:hr xmlns:xhtml="http://www.w3.org/1999/xhtml" />
|
||||||
|
<xhtml:p xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||||
|
<xhtml:table class="signature" border="0">
|
||||||
|
<xhtml:tr>
|
||||||
|
<xhtml:td style="width: 100%"> </xhtml:td>
|
||||||
|
<xhtml:td valign="top">
|
||||||
|
<xhtml:nobr class="signature">... generated by <xhtml:a name="Railroad-Diagram-Generator" class="signature" title="https://www.bottlecaps.de/rr/ui" href="https://www.bottlecaps.de/rr/ui" target="_blank">Railroad Diagram Generator</xhtml:a></xhtml:nobr>
|
||||||
|
</xhtml:td>
|
||||||
|
<xhtml:td><xhtml:a name="Railroad-Diagram-Generator" title="https://www.bottlecaps.de/rr/ui" href="https://www.bottlecaps.de/rr/ui" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
|
||||||
|
<g transform="scale(0.178)">
|
||||||
|
<circle cx="45" cy="45" r="45" style="stroke:none; fill:#FFCC00"/>
|
||||||
|
<circle cx="45" cy="45" r="42" style="stroke:#332900; stroke-width:2px; fill:#FFCC00"/>
|
||||||
|
<line x1="15" y1="15" x2="75" y2="75" stroke="#332900" style="stroke-width:9px;"/>
|
||||||
|
<line x1="15" y1="75" x2="75" y2="15" stroke="#332900" style="stroke-width:9px;"/>
|
||||||
|
<text x="7" y="54" style="font-size:26px; font-family:Arial, Sans-serif; font-weight:bold; fill: #332900">R</text>
|
||||||
|
<text x="64" y="54" style="font-size:26px; font-family:Arial, Sans-serif; font-weight:bold; fill: #332900">R</text>
|
||||||
|
</g></svg></xhtml:a></xhtml:td>
|
||||||
|
</xhtml:tr>
|
||||||
|
</xhtml:table>
|
||||||
|
</xhtml:p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,507 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
|
* Copyright (c) 2019, Oracle and/or its affiliates. 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 <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
#include "internal/property.h"
|
||||||
|
#include "internal/ctype.h"
|
||||||
|
#include <openssl/lhash.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include "internal/thread_once.h"
|
||||||
|
#include "internal/lhash.h"
|
||||||
|
#include "internal/sparse_array.h"
|
||||||
|
#include "property_lcl.h"
|
||||||
|
|
||||||
|
/* The number of elements in the query cache before we initiate a flush */
|
||||||
|
#define IMPL_CACHE_FLUSH_THRESHOLD 500
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
OSSL_PROPERTY_LIST *properties;
|
||||||
|
void *method;
|
||||||
|
void (*method_destruct)(void *);
|
||||||
|
} IMPLEMENTATION;
|
||||||
|
|
||||||
|
DEFINE_STACK_OF(IMPLEMENTATION)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *query;
|
||||||
|
void *method;
|
||||||
|
char body[1];
|
||||||
|
} QUERY;
|
||||||
|
|
||||||
|
DEFINE_LHASH_OF(QUERY);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int nid;
|
||||||
|
STACK_OF(IMPLEMENTATION) *impls;
|
||||||
|
LHASH_OF(QUERY) *cache;
|
||||||
|
} ALGORITHM;
|
||||||
|
|
||||||
|
struct ossl_method_store_st {
|
||||||
|
size_t nelem;
|
||||||
|
SPARSE_ARRAY_OF(ALGORITHM) *algs;
|
||||||
|
OSSL_PROPERTY_LIST *global_properties;
|
||||||
|
int need_flush;
|
||||||
|
unsigned int nbits;
|
||||||
|
unsigned char rand_bits[(IMPL_CACHE_FLUSH_THRESHOLD + 7) / 8];
|
||||||
|
CRYPTO_RWLOCK *lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
OSSL_METHOD_STORE *store;
|
||||||
|
LHASH_OF(QUERY) *cache;
|
||||||
|
size_t nelem;
|
||||||
|
} IMPL_CACHE_FLUSH;
|
||||||
|
|
||||||
|
DEFINE_SPARSE_ARRAY_OF(ALGORITHM);
|
||||||
|
|
||||||
|
static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid);
|
||||||
|
static void ossl_method_cache_flush_all(OSSL_METHOD_STORE *c);
|
||||||
|
|
||||||
|
int ossl_property_read_lock(OSSL_METHOD_STORE *p)
|
||||||
|
{
|
||||||
|
return p != NULL ? CRYPTO_THREAD_read_lock(p->lock) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_property_write_lock(OSSL_METHOD_STORE *p)
|
||||||
|
{
|
||||||
|
return p != NULL ? CRYPTO_THREAD_write_lock(p->lock) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_property_unlock(OSSL_METHOD_STORE *p)
|
||||||
|
{
|
||||||
|
return p != 0 ? CRYPTO_THREAD_unlock(p->lock) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_method_store_init(void)
|
||||||
|
{
|
||||||
|
if (ossl_property_string_init()
|
||||||
|
&& ossl_prop_defn_init()
|
||||||
|
&& ossl_property_parse_init())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ossl_method_store_cleanup();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ossl_method_store_cleanup(void)
|
||||||
|
{
|
||||||
|
ossl_property_string_cleanup();
|
||||||
|
ossl_prop_defn_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static CRYPTO_ONCE method_store_init_flag = CRYPTO_ONCE_STATIC_INIT;
|
||||||
|
DEFINE_RUN_ONCE_STATIC(do_method_store_init)
|
||||||
|
{
|
||||||
|
return OPENSSL_init_crypto(0, NULL)
|
||||||
|
&& ossl_method_store_init()
|
||||||
|
&& OPENSSL_atexit(&ossl_method_store_cleanup);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long query_hash(const QUERY *a)
|
||||||
|
{
|
||||||
|
return OPENSSL_LH_strhash(a->query);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int query_cmp(const QUERY *a, const QUERY *b)
|
||||||
|
{
|
||||||
|
return strcmp(a->query, b->query);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void impl_free(IMPLEMENTATION *impl)
|
||||||
|
{
|
||||||
|
if (impl != NULL) {
|
||||||
|
if (impl->method_destruct)
|
||||||
|
impl->method_destruct(impl->method);
|
||||||
|
OPENSSL_free(impl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void impl_cache_free(QUERY *elem)
|
||||||
|
{
|
||||||
|
OPENSSL_free(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void alg_cleanup(size_t idx, ALGORITHM *a)
|
||||||
|
{
|
||||||
|
if (a != NULL) {
|
||||||
|
sk_IMPLEMENTATION_pop_free(a->impls, &impl_free);
|
||||||
|
lh_QUERY_doall(a->cache, &impl_cache_free);
|
||||||
|
lh_QUERY_free(a->cache);
|
||||||
|
OPENSSL_free(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OSSL_METHOD_STORE *ossl_method_store_new(void)
|
||||||
|
{
|
||||||
|
OSSL_METHOD_STORE *res = OPENSSL_zalloc(sizeof(*res));
|
||||||
|
|
||||||
|
if (!RUN_ONCE(&method_store_init_flag, do_method_store_init))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (res != NULL) {
|
||||||
|
if ((res->algs = ossl_sa_ALGORITHM_new()) == NULL) {
|
||||||
|
OPENSSL_free(res);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if ((res->lock = CRYPTO_THREAD_lock_new()) == NULL) {
|
||||||
|
OPENSSL_free(res->algs);
|
||||||
|
OPENSSL_free(res);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ossl_method_store_free(OSSL_METHOD_STORE *store)
|
||||||
|
{
|
||||||
|
if (store != NULL) {
|
||||||
|
ossl_sa_ALGORITHM_doall(store->algs, &alg_cleanup);
|
||||||
|
ossl_sa_ALGORITHM_free(store->algs);
|
||||||
|
ossl_property_free(store->global_properties);
|
||||||
|
CRYPTO_THREAD_lock_free(store->lock);
|
||||||
|
OPENSSL_free(store);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALGORITHM *ossl_method_store_retrieve(OSSL_METHOD_STORE *store, int nid)
|
||||||
|
{
|
||||||
|
return ossl_sa_ALGORITHM_get(store->algs, nid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ossl_method_store_insert(OSSL_METHOD_STORE *store, ALGORITHM *alg)
|
||||||
|
{
|
||||||
|
return ossl_sa_ALGORITHM_set(store->algs, alg->nid, alg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_method_store_add(OSSL_METHOD_STORE *store,
|
||||||
|
int nid, const char *properties,
|
||||||
|
void *method, void (*method_destruct)(void *))
|
||||||
|
{
|
||||||
|
ALGORITHM *alg = NULL;
|
||||||
|
IMPLEMENTATION *impl;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (nid <= 0 || method == NULL || store == NULL)
|
||||||
|
return 0;
|
||||||
|
if (properties == NULL)
|
||||||
|
properties = "";
|
||||||
|
|
||||||
|
/* Create new entry */
|
||||||
|
impl = OPENSSL_malloc(sizeof(*impl));
|
||||||
|
if (impl == NULL)
|
||||||
|
return 0;
|
||||||
|
impl->method = method;
|
||||||
|
impl->method_destruct = method_destruct;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert into the hash table if required.
|
||||||
|
*
|
||||||
|
* A write lock is used unconditionally because we wend our way down to the
|
||||||
|
* property string code which isn't locking friendly.
|
||||||
|
*/
|
||||||
|
ossl_property_write_lock(store);
|
||||||
|
ossl_method_cache_flush(store, nid);
|
||||||
|
if ((impl->properties = ossl_prop_defn_get(properties)) == NULL) {
|
||||||
|
if ((impl->properties = ossl_parse_property(properties)) == NULL)
|
||||||
|
goto err;
|
||||||
|
ossl_prop_defn_set(properties, impl->properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
alg = ossl_method_store_retrieve(store, nid);
|
||||||
|
if (alg == NULL) {
|
||||||
|
if ((alg = OPENSSL_zalloc(sizeof(*alg))) == NULL
|
||||||
|
|| (alg->impls = sk_IMPLEMENTATION_new_null()) == NULL
|
||||||
|
|| (alg->cache = lh_QUERY_new(&query_hash, &query_cmp)) == NULL)
|
||||||
|
goto err;
|
||||||
|
alg->nid = nid;
|
||||||
|
if (!ossl_method_store_insert(store, alg))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Push onto stack */
|
||||||
|
if (sk_IMPLEMENTATION_push(alg->impls, impl))
|
||||||
|
ret = 1;
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
if (ret == 0)
|
||||||
|
impl_free(impl);
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
err:
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
alg_cleanup(0, alg);
|
||||||
|
impl_free(impl);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_method_store_remove(OSSL_METHOD_STORE *store, int nid,
|
||||||
|
const void *method)
|
||||||
|
{
|
||||||
|
ALGORITHM *alg = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (nid <= 0 || method == NULL || store == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ossl_property_write_lock(store);
|
||||||
|
ossl_method_cache_flush(store, nid);
|
||||||
|
alg = ossl_method_store_retrieve(store, nid);
|
||||||
|
if (alg == NULL) {
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A sorting find then a delete could be faster but these stacks should be
|
||||||
|
* relatively small, so we avoid the overhead. Sorting could also surprise
|
||||||
|
* users when result orderings change (even though they are not guaranteed).
|
||||||
|
*/
|
||||||
|
for (i = 0; i < sk_IMPLEMENTATION_num(alg->impls); i++) {
|
||||||
|
IMPLEMENTATION *impl = sk_IMPLEMENTATION_value(alg->impls, i);
|
||||||
|
|
||||||
|
if (impl->method == method) {
|
||||||
|
sk_IMPLEMENTATION_delete(alg->impls, i);
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
impl_free(impl);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid,
|
||||||
|
const char *prop_query, void **method)
|
||||||
|
{
|
||||||
|
ALGORITHM *alg;
|
||||||
|
IMPLEMENTATION *impl;
|
||||||
|
OSSL_PROPERTY_LIST *pq = NULL, *p2;
|
||||||
|
int ret = 0;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if (nid <= 0 || method == NULL || store == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This only needs to be a read lock, because queries never create property
|
||||||
|
* names or value and thus don't modify any of the property string layer.
|
||||||
|
*/
|
||||||
|
ossl_property_read_lock(store);
|
||||||
|
alg = ossl_method_store_retrieve(store, nid);
|
||||||
|
if (alg == NULL) {
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prop_query == NULL) {
|
||||||
|
if ((impl = sk_IMPLEMENTATION_value(alg->impls, 0)) != NULL) {
|
||||||
|
*method = impl->method;
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
goto fin;
|
||||||
|
}
|
||||||
|
pq = ossl_parse_query(prop_query);
|
||||||
|
if (pq == NULL)
|
||||||
|
goto fin;
|
||||||
|
if (store->global_properties != NULL) {
|
||||||
|
p2 = ossl_property_merge(pq, store->global_properties);
|
||||||
|
if (p2 == NULL)
|
||||||
|
goto fin;
|
||||||
|
ossl_property_free(pq);
|
||||||
|
pq = p2;
|
||||||
|
}
|
||||||
|
for (j = 0; j < sk_IMPLEMENTATION_num(alg->impls); j++) {
|
||||||
|
impl = sk_IMPLEMENTATION_value(alg->impls, j);
|
||||||
|
|
||||||
|
if (ossl_property_match(pq, impl->properties)) {
|
||||||
|
*method = impl->method;
|
||||||
|
ret = 1;
|
||||||
|
goto fin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fin:
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
ossl_property_free(pq);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_method_store_set_global_properties(OSSL_METHOD_STORE *store,
|
||||||
|
const char *prop_query) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (store == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ossl_property_write_lock(store);
|
||||||
|
ossl_method_cache_flush_all(store);
|
||||||
|
if (prop_query == NULL) {
|
||||||
|
ossl_property_free(store->global_properties);
|
||||||
|
store->global_properties = NULL;
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
store->global_properties = ossl_parse_query(prop_query);
|
||||||
|
ret = store->global_properties != NULL;
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void impl_cache_flush_alg(size_t idx, ALGORITHM *alg)
|
||||||
|
{
|
||||||
|
lh_QUERY_doall(alg->cache, &impl_cache_free);
|
||||||
|
lh_QUERY_flush(alg->cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid)
|
||||||
|
{
|
||||||
|
ALGORITHM *alg = ossl_method_store_retrieve(store, nid);
|
||||||
|
|
||||||
|
if (alg != NULL) {
|
||||||
|
store->nelem -= lh_QUERY_num_items(alg->cache);
|
||||||
|
impl_cache_flush_alg(0, alg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ossl_method_cache_flush_all(OSSL_METHOD_STORE *store)
|
||||||
|
{
|
||||||
|
ossl_sa_ALGORITHM_doall(store->algs, &impl_cache_flush_alg);
|
||||||
|
store->nelem = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_LHASH_DOALL_ARG(QUERY, IMPL_CACHE_FLUSH);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flush an element from the query cache (perhaps).
|
||||||
|
*
|
||||||
|
* In order to avoid taking a write lock to keep accurate LRU information or
|
||||||
|
* using atomic operations to approximate similar, the procedure used here
|
||||||
|
* is to stochastically flush approximately half the cache. Since generating
|
||||||
|
* random numbers is relatively expensive, we produce them in blocks and
|
||||||
|
* consume them as we go, saving generated bits between generations of flushes.
|
||||||
|
*
|
||||||
|
* This procedure isn't ideal, LRU would be better. However, in normal
|
||||||
|
* operation, reaching a full cache would be quite unexpected. It means
|
||||||
|
* that no steady state of algorithm queries has been reached. I.e. it is most
|
||||||
|
* likely an attack of some form. A suboptimal clearance strategy that doesn't
|
||||||
|
* degrade performance of the normal case is preferable to a more refined
|
||||||
|
* approach that imposes a performance impact.
|
||||||
|
*/
|
||||||
|
static void impl_cache_flush_cache(QUERY *c, IMPL_CACHE_FLUSH *state)
|
||||||
|
{
|
||||||
|
OSSL_METHOD_STORE *store = state->store;
|
||||||
|
unsigned int n;
|
||||||
|
|
||||||
|
if (store->nbits == 0) {
|
||||||
|
if (!RAND_bytes(store->rand_bits, sizeof(store->rand_bits)))
|
||||||
|
return;
|
||||||
|
store->nbits = sizeof(store->rand_bits) * 8;
|
||||||
|
}
|
||||||
|
n = --store->nbits;
|
||||||
|
if ((store->rand_bits[n >> 3] & (1 << (n & 7))) != 0)
|
||||||
|
OPENSSL_free(lh_QUERY_delete(state->cache, c));
|
||||||
|
else
|
||||||
|
state->nelem++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void impl_cache_flush_one_alg(size_t idx, ALGORITHM *alg, void *v)
|
||||||
|
{
|
||||||
|
IMPL_CACHE_FLUSH *state = (IMPL_CACHE_FLUSH *)v;
|
||||||
|
|
||||||
|
state->cache = alg->cache;
|
||||||
|
lh_QUERY_doall_IMPL_CACHE_FLUSH(state->cache, &impl_cache_flush_cache,
|
||||||
|
state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ossl_method_cache_flush_some(OSSL_METHOD_STORE *store)
|
||||||
|
{
|
||||||
|
IMPL_CACHE_FLUSH state;
|
||||||
|
|
||||||
|
state.nelem = 0;
|
||||||
|
state.store = store;
|
||||||
|
ossl_sa_ALGORITHM_doall_arg(store->algs, &impl_cache_flush_one_alg, &state);
|
||||||
|
store->need_flush = 0;
|
||||||
|
store->nelem = state.nelem;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, int nid,
|
||||||
|
const char *prop_query, void **method)
|
||||||
|
{
|
||||||
|
ALGORITHM *alg;
|
||||||
|
QUERY elem, *r;
|
||||||
|
|
||||||
|
if (nid <= 0 || store == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ossl_property_read_lock(store);
|
||||||
|
alg = ossl_method_store_retrieve(store, nid);
|
||||||
|
if (alg == NULL) {
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
elem.query = prop_query;
|
||||||
|
r = lh_QUERY_retrieve(alg->cache, &elem);
|
||||||
|
if (r == NULL) {
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*method = r->method;
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, int nid,
|
||||||
|
const char *prop_query, void *method)
|
||||||
|
{
|
||||||
|
QUERY elem, *old, *p = NULL;
|
||||||
|
ALGORITHM *alg;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (nid <= 0 || store == NULL)
|
||||||
|
return 0;
|
||||||
|
if (prop_query == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ossl_property_write_lock(store);
|
||||||
|
if (store->need_flush)
|
||||||
|
ossl_method_cache_flush_some(store);
|
||||||
|
alg = ossl_method_store_retrieve(store, nid);
|
||||||
|
if (alg == NULL) {
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method == NULL) {
|
||||||
|
elem.query = prop_query;
|
||||||
|
lh_QUERY_delete(alg->cache, &elem);
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
p = OPENSSL_malloc(sizeof(*p) + (len = strlen(prop_query)));
|
||||||
|
if (p != NULL) {
|
||||||
|
p->query = p->body;
|
||||||
|
p->method = method;
|
||||||
|
memcpy((char *)p->query, prop_query, len + 1);
|
||||||
|
if ((old = lh_QUERY_insert(alg->cache, p)) != NULL)
|
||||||
|
OPENSSL_free(old);
|
||||||
|
if (old != NULL || !lh_QUERY_error(alg->cache)) {
|
||||||
|
store->nelem++;
|
||||||
|
if (store->nelem >= IMPL_CACHE_FLUSH_THRESHOLD)
|
||||||
|
store->need_flush = 1;
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ossl_property_unlock(store);
|
||||||
|
OPENSSL_free(p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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/propertyerr.h"
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_ERR
|
||||||
|
|
||||||
|
static const ERR_STRING_DATA PROP_str_functs[] = {
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, PROP_F_OSSL_PARSE_PROPERTY, 0),
|
||||||
|
"ossl_parse_property"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, PROP_F_OSSL_PARSE_QUERY, 0), "ossl_parse_query"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_HEX, 0), "parse_hex"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_NAME, 0), "parse_name"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_NUMBER, 0), "parse_number"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_OCT, 0), "parse_oct"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_STRING, 0), "parse_string"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, PROP_F_PARSE_UNQUOTED, 0), "parse_unquoted"},
|
||||||
|
{0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const ERR_STRING_DATA PROP_str_reasons[] = {
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NAME_TOO_LONG), "name too long"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_ASCII_CHARACTER),
|
||||||
|
"not an ascii character"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_HEXADECIMAL_DIGIT),
|
||||||
|
"not an hexadecimal digit"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_IDENTIFIER), "not an identifier"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_OCTAL_DIGIT),
|
||||||
|
"not an octal digit"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_A_DECIMAL_DIGIT),
|
||||||
|
"not a decimal digit"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_MATCHING_STRING_DELIMETER),
|
||||||
|
"no matching string delimeter"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_VALUE), "no value"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_PARSE_FAILED), "parse failed"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_STRING_TOO_LONG), "string too long"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROP, 0, PROP_R_TRAILING_CHARACTERS),
|
||||||
|
"trailing characters"},
|
||||||
|
{0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int ERR_load_PROP_strings(void)
|
||||||
|
{
|
||||||
|
#ifndef OPENSSL_NO_ERR
|
||||||
|
if (ERR_func_error_string(PROP_str_functs[0].error) == NULL) {
|
||||||
|
ERR_load_strings_const(PROP_str_functs);
|
||||||
|
ERR_load_strings_const(PROP_str_reasons);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
|
* Copyright (c) 2019, Oracle and/or its affiliates. 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 "internal/property.h"
|
||||||
|
|
||||||
|
typedef struct ossl_property_list_st OSSL_PROPERTY_LIST;
|
||||||
|
typedef int OSSL_PROPERTY_IDX;
|
||||||
|
|
||||||
|
/* Initialisation and finalisation for subsystem */
|
||||||
|
int ossl_method_store_init(void);
|
||||||
|
void ossl_method_store_cleanup(void);
|
||||||
|
|
||||||
|
/* Property string functions */
|
||||||
|
OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create);
|
||||||
|
OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create);
|
||||||
|
int ossl_property_string_init(void);
|
||||||
|
void ossl_property_string_cleanup(void);
|
||||||
|
|
||||||
|
/* Property list functions */
|
||||||
|
int ossl_property_parse_init(void);
|
||||||
|
void ossl_property_free(OSSL_PROPERTY_LIST *p);
|
||||||
|
int ossl_property_match(const OSSL_PROPERTY_LIST *query,
|
||||||
|
const OSSL_PROPERTY_LIST *defn);
|
||||||
|
OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a,
|
||||||
|
const OSSL_PROPERTY_LIST *b);
|
||||||
|
|
||||||
|
/* Property definition functions */
|
||||||
|
OSSL_PROPERTY_LIST *ossl_parse_property(const char *s);
|
||||||
|
|
||||||
|
/* Property query functions */
|
||||||
|
OSSL_PROPERTY_LIST *ossl_parse_query(const char *s);
|
||||||
|
|
||||||
|
/* Property definition cache functions */
|
||||||
|
int ossl_prop_defn_init(void);
|
||||||
|
void ossl_prop_defn_cleanup(void);
|
||||||
|
OSSL_PROPERTY_LIST *ossl_prop_defn_get(const char *prop);
|
||||||
|
int ossl_prop_defn_set(const char *prop, OSSL_PROPERTY_LIST *pl);
|
||||||
|
|
||||||
|
/* Property cache lock / unlock */
|
||||||
|
int ossl_property_write_lock(OSSL_METHOD_STORE *);
|
||||||
|
int ossl_property_read_lock(OSSL_METHOD_STORE *);
|
||||||
|
int ossl_property_unlock(OSSL_METHOD_STORE *);
|
||||||
|
|
||||||
@@ -0,0 +1,545 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
|
* Copyright (c) 2019, Oracle and/or its affiliates. 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 <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include "internal/propertyerr.h"
|
||||||
|
#include "internal/property.h"
|
||||||
|
#include "internal/ctype.h"
|
||||||
|
#include "internal/nelem.h"
|
||||||
|
#include "property_lcl.h"
|
||||||
|
#include "e_os.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PROPERTY_TYPE_STRING, PROPERTY_TYPE_NUMBER,
|
||||||
|
PROPERTY_TYPE_VALUE_UNDEFINED
|
||||||
|
} PROPERTY_TYPE;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PROPERTY_OPER_EQ, PROPERTY_OPER_NE, PROPERTY_OVERRIDE
|
||||||
|
} PROPERTY_OPER;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
OSSL_PROPERTY_IDX name_idx;
|
||||||
|
PROPERTY_TYPE type;
|
||||||
|
PROPERTY_OPER oper;
|
||||||
|
union {
|
||||||
|
int64_t int_val; /* Signed integer */
|
||||||
|
OSSL_PROPERTY_IDX str_val; /* String */
|
||||||
|
} v;
|
||||||
|
} PROPERTY_DEFINITION;
|
||||||
|
|
||||||
|
struct ossl_property_list_st {
|
||||||
|
int n;
|
||||||
|
PROPERTY_DEFINITION properties[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
static OSSL_PROPERTY_IDX ossl_property_true, ossl_property_false;
|
||||||
|
|
||||||
|
DEFINE_STACK_OF(PROPERTY_DEFINITION)
|
||||||
|
|
||||||
|
static const char *skip_space(const char *s)
|
||||||
|
{
|
||||||
|
while (ossl_isspace(*s))
|
||||||
|
s++;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int match_ch(const char *t[], char m)
|
||||||
|
{
|
||||||
|
const char *s = *t;
|
||||||
|
|
||||||
|
if (*s == m) {
|
||||||
|
*t = skip_space(s + 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MATCH(s, m) match(s, m, sizeof(m) - 1)
|
||||||
|
|
||||||
|
static int match(const char *t[], const char m[], size_t m_len)
|
||||||
|
{
|
||||||
|
const char *s = *t;
|
||||||
|
|
||||||
|
if (strncasecmp(s, m, m_len) == 0) {
|
||||||
|
*t = skip_space(s + m_len);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_name(const char *t[], int create, OSSL_PROPERTY_IDX *idx)
|
||||||
|
{
|
||||||
|
char name[100];
|
||||||
|
int err = 0;
|
||||||
|
size_t i = 0;
|
||||||
|
const char *s = *t;
|
||||||
|
int user_name = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (!ossl_isalpha(*s)) {
|
||||||
|
PROPerr(PROP_F_PARSE_NAME, PROP_R_NOT_AN_IDENTIFIER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
if (i < sizeof(name) - 1)
|
||||||
|
name[i++] = ossl_tolower(*s);
|
||||||
|
else
|
||||||
|
err = 1;
|
||||||
|
} while (*++s == '_' || ossl_isalnum(*s));
|
||||||
|
if (*s != '.')
|
||||||
|
break;
|
||||||
|
user_name = 1;
|
||||||
|
if (i < sizeof(name) - 1)
|
||||||
|
name[i++] = *s;
|
||||||
|
else
|
||||||
|
err = 1;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
name[i] = '\0';
|
||||||
|
*t = skip_space(s);
|
||||||
|
if (!err) {
|
||||||
|
*idx = ossl_property_name(name, user_name && create);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
PROPerr(PROP_F_PARSE_NAME, PROP_R_NAME_TOO_LONG);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_number(const char *t[], PROPERTY_DEFINITION *res)
|
||||||
|
{
|
||||||
|
const char *s = *t;
|
||||||
|
int64_t v = 0;
|
||||||
|
|
||||||
|
if (!ossl_isdigit(*s))
|
||||||
|
return 0;
|
||||||
|
do {
|
||||||
|
v = v * 10 + (*s++ - '0');
|
||||||
|
} while (ossl_isdigit(*s));
|
||||||
|
if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
|
||||||
|
PROPerr(PROP_F_PARSE_NUMBER, PROP_R_NOT_A_DECIMAL_DIGIT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*t = skip_space(s);
|
||||||
|
res->type = PROPERTY_TYPE_NUMBER;
|
||||||
|
res->v.int_val = v;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_hex(const char *t[], PROPERTY_DEFINITION *res)
|
||||||
|
{
|
||||||
|
const char *s = *t;
|
||||||
|
int64_t v = 0;
|
||||||
|
|
||||||
|
if (!ossl_isxdigit(*s))
|
||||||
|
return 0;
|
||||||
|
do {
|
||||||
|
v <<= 4;
|
||||||
|
if (ossl_isdigit(*s))
|
||||||
|
v += *s - '0';
|
||||||
|
else
|
||||||
|
v += ossl_tolower(*s) - 'a';
|
||||||
|
} while (ossl_isxdigit(*++s));
|
||||||
|
if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
|
||||||
|
PROPerr(PROP_F_PARSE_HEX, PROP_R_NOT_AN_HEXADECIMAL_DIGIT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*t = skip_space(s);
|
||||||
|
res->type = PROPERTY_TYPE_NUMBER;
|
||||||
|
res->v.int_val = v;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_oct(const char *t[], PROPERTY_DEFINITION *res)
|
||||||
|
{
|
||||||
|
const char *s = *t;
|
||||||
|
int64_t v = 0;
|
||||||
|
|
||||||
|
if (*s == '9' || *s == '8' || !ossl_isdigit(*s))
|
||||||
|
return 0;
|
||||||
|
do {
|
||||||
|
v = (v << 3) + (*s - '0');
|
||||||
|
} while (ossl_isdigit(*++s) && *s != '9' && *s != '8');
|
||||||
|
if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
|
||||||
|
PROPerr(PROP_F_PARSE_OCT, PROP_R_NOT_AN_OCTAL_DIGIT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*t = skip_space(s);
|
||||||
|
res->type = PROPERTY_TYPE_NUMBER;
|
||||||
|
res->v.int_val = v;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_string(const char *t[], char delim, PROPERTY_DEFINITION *res,
|
||||||
|
const int create)
|
||||||
|
{
|
||||||
|
char v[1000];
|
||||||
|
const char *s = *t;
|
||||||
|
size_t i = 0;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
while (*s != '\0' && *s != delim) {
|
||||||
|
if (i < sizeof(v) - 1)
|
||||||
|
v[i++] = *s;
|
||||||
|
else
|
||||||
|
err = 1;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
if (*s == '\0') {
|
||||||
|
PROPerr(PROP_F_PARSE_STRING,
|
||||||
|
PROP_R_NO_MATCHING_STRING_DELIMETER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
v[i] = '\0';
|
||||||
|
*t = skip_space(s + 1);
|
||||||
|
if (err)
|
||||||
|
PROPerr(PROP_F_PARSE_STRING, PROP_R_STRING_TOO_LONG);
|
||||||
|
else
|
||||||
|
res->v.str_val = ossl_property_value(v, create);
|
||||||
|
res->type = PROPERTY_TYPE_STRING;
|
||||||
|
return !err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_unquoted(const char *t[], PROPERTY_DEFINITION *res,
|
||||||
|
const int create)
|
||||||
|
{
|
||||||
|
char v[1000];
|
||||||
|
const char *s = *t;
|
||||||
|
size_t i = 0;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (*s == '\0' || *s == ',')
|
||||||
|
return 0;
|
||||||
|
while (ossl_isprint(*s) && !ossl_isspace(*s) && *s != ',') {
|
||||||
|
if (i < sizeof(v) - 1)
|
||||||
|
v[i++] = ossl_tolower(*s);
|
||||||
|
else
|
||||||
|
err = 1;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
|
||||||
|
PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_NOT_AN_ASCII_CHARACTER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
v[i] = 0;
|
||||||
|
*t = skip_space(s);
|
||||||
|
if (err)
|
||||||
|
PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_STRING_TOO_LONG);
|
||||||
|
else
|
||||||
|
res->v.str_val = ossl_property_value(v, create);
|
||||||
|
res->type = PROPERTY_TYPE_STRING;
|
||||||
|
return !err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_value(const char *t[], PROPERTY_DEFINITION *res, int create)
|
||||||
|
{
|
||||||
|
const char *s = *t;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
if (*s == '"' || *s == '\'') {
|
||||||
|
s++;
|
||||||
|
r = parse_string(&s, s[-1], res, create);
|
||||||
|
} else if (*s == '+') {
|
||||||
|
s++;
|
||||||
|
r = parse_number(&s, res);
|
||||||
|
} else if (*s == '-') {
|
||||||
|
s++;
|
||||||
|
r = parse_number(&s, res);
|
||||||
|
res->v.int_val = -res->v.int_val;
|
||||||
|
} else if (*s == '0' && s[1] == 'x') {
|
||||||
|
s += 2;
|
||||||
|
r = parse_hex(&s, res);
|
||||||
|
} else if (*s == '0' && ossl_isdigit(s[1])) {
|
||||||
|
s++;
|
||||||
|
r = parse_oct(&s, res);
|
||||||
|
} else if (ossl_isdigit(*s)) {
|
||||||
|
return parse_number(t, res);
|
||||||
|
} else if (ossl_isalpha(*s))
|
||||||
|
return parse_unquoted(t, res, create);
|
||||||
|
if (r)
|
||||||
|
*t = s;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pd_compare(const PROPERTY_DEFINITION *const *p1,
|
||||||
|
const PROPERTY_DEFINITION *const *p2)
|
||||||
|
{
|
||||||
|
const PROPERTY_DEFINITION *pd1 = *p1;
|
||||||
|
const PROPERTY_DEFINITION *pd2 = *p2;
|
||||||
|
|
||||||
|
if (pd1->name_idx < pd2->name_idx)
|
||||||
|
return -1;
|
||||||
|
if (pd1->name_idx > pd2->name_idx)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pd_free(PROPERTY_DEFINITION *pd)
|
||||||
|
{
|
||||||
|
OPENSSL_free(pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a stack of property definitions and queries into a fixed array.
|
||||||
|
* The items are sorted for efficient query. The stack is not freed.
|
||||||
|
*/
|
||||||
|
static OSSL_PROPERTY_LIST *stack_to_property_list(STACK_OF(PROPERTY_DEFINITION)
|
||||||
|
*sk)
|
||||||
|
{
|
||||||
|
const int n = sk_PROPERTY_DEFINITION_num(sk);
|
||||||
|
OSSL_PROPERTY_LIST *r;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
r = OPENSSL_malloc(sizeof(*r)
|
||||||
|
+ (n == 0 ? 0 : n - 1) * sizeof(r->properties[0]));
|
||||||
|
if (r != NULL) {
|
||||||
|
sk_PROPERTY_DEFINITION_sort(sk);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
r->properties[i] = *sk_PROPERTY_DEFINITION_value(sk, i);
|
||||||
|
r->n = n;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn)
|
||||||
|
{
|
||||||
|
PROPERTY_DEFINITION *prop = NULL;
|
||||||
|
OSSL_PROPERTY_LIST *res = NULL;
|
||||||
|
STACK_OF(PROPERTY_DEFINITION) *sk;
|
||||||
|
const char *s = defn;
|
||||||
|
int done;
|
||||||
|
|
||||||
|
if (s == NULL || (sk = sk_PROPERTY_DEFINITION_new(&pd_compare)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
s = skip_space(s);
|
||||||
|
done = *s == '\0';
|
||||||
|
while (!done) {
|
||||||
|
prop = OPENSSL_malloc(sizeof(*prop));
|
||||||
|
if (prop == NULL)
|
||||||
|
goto err;
|
||||||
|
memset(&prop->v, 0, sizeof(prop->v));
|
||||||
|
if (!parse_name(&s, 1, &prop->name_idx))
|
||||||
|
goto err;
|
||||||
|
prop->oper = PROPERTY_OPER_EQ;
|
||||||
|
if (prop->name_idx == 0) {
|
||||||
|
PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_PARSE_FAILED);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (match_ch(&s, '=')) {
|
||||||
|
if (!parse_value(&s, prop, 1)) {
|
||||||
|
PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_NO_VALUE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* A name alone means a true Boolean */
|
||||||
|
prop->type = PROPERTY_TYPE_STRING;
|
||||||
|
prop->v.str_val = ossl_property_true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sk_PROPERTY_DEFINITION_push(sk, prop))
|
||||||
|
goto err;
|
||||||
|
prop = NULL;
|
||||||
|
done = !match_ch(&s, ',');
|
||||||
|
}
|
||||||
|
if (*s != '\0') {
|
||||||
|
PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_TRAILING_CHARACTERS);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
res = stack_to_property_list(sk);
|
||||||
|
|
||||||
|
err:
|
||||||
|
OPENSSL_free(prop);
|
||||||
|
sk_PROPERTY_DEFINITION_pop_free(sk, &pd_free);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
OSSL_PROPERTY_LIST *ossl_parse_query(const char *s)
|
||||||
|
{
|
||||||
|
STACK_OF(PROPERTY_DEFINITION) *sk;
|
||||||
|
OSSL_PROPERTY_LIST *res = NULL;
|
||||||
|
PROPERTY_DEFINITION *prop = NULL;
|
||||||
|
int done;
|
||||||
|
|
||||||
|
if (s == NULL || (sk = sk_PROPERTY_DEFINITION_new(&pd_compare)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
s = skip_space(s);
|
||||||
|
done = *s == '\0';
|
||||||
|
while (!done) {
|
||||||
|
prop = OPENSSL_malloc(sizeof(*prop));
|
||||||
|
if (prop == NULL)
|
||||||
|
goto err;
|
||||||
|
memset(&prop->v, 0, sizeof(prop->v));
|
||||||
|
|
||||||
|
if (match_ch(&s, '-')) {
|
||||||
|
prop->oper = PROPERTY_OVERRIDE;
|
||||||
|
if (!parse_name(&s, 0, &prop->name_idx))
|
||||||
|
goto err;
|
||||||
|
goto skip_value;
|
||||||
|
}
|
||||||
|
if (!parse_name(&s, 0, &prop->name_idx))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (match_ch(&s, '=')) {
|
||||||
|
prop->oper = PROPERTY_OPER_EQ;
|
||||||
|
} else if (MATCH(&s, "!=")) {
|
||||||
|
prop->oper = PROPERTY_OPER_NE;
|
||||||
|
} else {
|
||||||
|
/* A name alone is a Boolean comparison for true */
|
||||||
|
prop->oper = PROPERTY_OPER_EQ;
|
||||||
|
prop->type = PROPERTY_TYPE_STRING;
|
||||||
|
prop->v.str_val = ossl_property_true;
|
||||||
|
goto skip_value;
|
||||||
|
}
|
||||||
|
if (!parse_value(&s, prop, 0))
|
||||||
|
prop->type = PROPERTY_TYPE_VALUE_UNDEFINED;
|
||||||
|
|
||||||
|
skip_value:
|
||||||
|
if (!sk_PROPERTY_DEFINITION_push(sk, prop))
|
||||||
|
goto err;
|
||||||
|
prop = NULL;
|
||||||
|
done = !match_ch(&s, ',');
|
||||||
|
}
|
||||||
|
if (*s != '\0') {
|
||||||
|
PROPerr(PROP_F_OSSL_PARSE_QUERY, PROP_R_TRAILING_CHARACTERS);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
res = stack_to_property_list(sk);
|
||||||
|
|
||||||
|
err:
|
||||||
|
OPENSSL_free(prop);
|
||||||
|
sk_PROPERTY_DEFINITION_pop_free(sk, &pd_free);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_property_match(const OSSL_PROPERTY_LIST *query,
|
||||||
|
const OSSL_PROPERTY_LIST *defn)
|
||||||
|
{
|
||||||
|
const PROPERTY_DEFINITION *const q = query->properties;
|
||||||
|
const PROPERTY_DEFINITION *const d = defn->properties;
|
||||||
|
int i = 0, j = 0;
|
||||||
|
PROPERTY_OPER oper;
|
||||||
|
|
||||||
|
while (i < query->n) {
|
||||||
|
if ((oper = q[i].oper) == PROPERTY_OVERRIDE) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (j < defn->n) {
|
||||||
|
if (q[i].name_idx > d[j].name_idx) { /* skip defn, not in query */
|
||||||
|
j++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (q[i].name_idx == d[j].name_idx) { /* both in defn and query */
|
||||||
|
const int eq = q[i].type == d[j].type
|
||||||
|
&& memcmp(&q[i].v, &d[j].v, sizeof(q[i].v)) == 0;
|
||||||
|
|
||||||
|
if ((eq && oper != PROPERTY_OPER_EQ)
|
||||||
|
|| (!eq && oper != PROPERTY_OPER_NE))
|
||||||
|
return 0;
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle the cases of a missing value and a query with no corresponding
|
||||||
|
* definition. The former fails for any comparision except inequality,
|
||||||
|
* the latter is treated as a comparison against the Boolean false.
|
||||||
|
*/
|
||||||
|
if (q[i].type == PROPERTY_TYPE_VALUE_UNDEFINED) {
|
||||||
|
if (oper != PROPERTY_OPER_NE)
|
||||||
|
return 0;
|
||||||
|
} else if (q[i].type != PROPERTY_TYPE_STRING
|
||||||
|
|| (oper == PROPERTY_OPER_EQ
|
||||||
|
&& q[i].v.str_val != ossl_property_false)
|
||||||
|
|| (oper == PROPERTY_OPER_NE
|
||||||
|
&& q[i].v.str_val == ossl_property_false)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ossl_property_free(OSSL_PROPERTY_LIST *p)
|
||||||
|
{
|
||||||
|
OPENSSL_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Merge two property lists.
|
||||||
|
* If there is a common name, the one from the first list is used.
|
||||||
|
*/
|
||||||
|
OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a,
|
||||||
|
const OSSL_PROPERTY_LIST *b)
|
||||||
|
{
|
||||||
|
const PROPERTY_DEFINITION *const ap = a->properties;
|
||||||
|
const PROPERTY_DEFINITION *const bp = b->properties;
|
||||||
|
const PROPERTY_DEFINITION *copy;
|
||||||
|
OSSL_PROPERTY_LIST *r;
|
||||||
|
int i, j, n;
|
||||||
|
const int t = a->n + b->n;
|
||||||
|
|
||||||
|
r = OPENSSL_malloc(sizeof(*r)
|
||||||
|
+ (t == 0 ? 0 : t - 1) * sizeof(r->properties[0]));
|
||||||
|
if (r == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = j = n = 0; i < a->n || j < b->n; n++) {
|
||||||
|
if (i >= a->n) {
|
||||||
|
copy = &bp[j++];
|
||||||
|
} else if (j >= b->n) {
|
||||||
|
copy = &ap[i++];
|
||||||
|
} else if (ap[i].name_idx <= bp[j].name_idx) {
|
||||||
|
if (ap[i].name_idx == bp[j].name_idx)
|
||||||
|
j++;
|
||||||
|
copy = &ap[i++];
|
||||||
|
} else {
|
||||||
|
copy = &bp[j++];
|
||||||
|
}
|
||||||
|
memcpy(r->properties + n, copy, sizeof(r->properties[0]));
|
||||||
|
}
|
||||||
|
r->n = n;
|
||||||
|
if (n != t)
|
||||||
|
r = OPENSSL_realloc(r, sizeof(*r) + (n - 1) * sizeof(r->properties[0]));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_property_parse_init(void)
|
||||||
|
{
|
||||||
|
static const char *const predefined_names[] = {
|
||||||
|
"default", /* Being provided by the default built-in provider */
|
||||||
|
"provider", /* Name of provider (default, fips) */
|
||||||
|
"version", /* Version number of this provider */
|
||||||
|
"fips", /* FIPS supporting provider */
|
||||||
|
"engine", /* An old style engine masquerading as a provider */
|
||||||
|
};
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < OSSL_NELEM(predefined_names); i++)
|
||||||
|
if (ossl_property_name(predefined_names[i], 1) == 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Pre-populate the two Boolean values */
|
||||||
|
if ((ossl_property_true = ossl_property_value("yes", 1)) == 0
|
||||||
|
|| (ossl_property_false = ossl_property_value("no", 1)) == 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
err:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
|
* Copyright (c) 2019, Oracle and/or its affiliates. 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/lhash.h>
|
||||||
|
#include "internal/lhash.h"
|
||||||
|
#include "property_lcl.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Property strings are a consolidation of all strings seen by the property
|
||||||
|
* subsystem. There are two name spaces to keep property names separate from
|
||||||
|
* property values (numeric values are not expected to be cached however).
|
||||||
|
* They allow a rapid conversion from a string to a unique index and any
|
||||||
|
* subsequent string comparison can be done via an integer compare.
|
||||||
|
*
|
||||||
|
* This implementation uses OpenSSL's standard hash table. There are more
|
||||||
|
* space and time efficient algorithms if this becomes a bottleneck.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *s;
|
||||||
|
OSSL_PROPERTY_IDX idx;
|
||||||
|
char body[1];
|
||||||
|
} PROPERTY_STRING;
|
||||||
|
|
||||||
|
DEFINE_LHASH_OF(PROPERTY_STRING);
|
||||||
|
typedef LHASH_OF(PROPERTY_STRING) PROP_TABLE;
|
||||||
|
|
||||||
|
static PROP_TABLE *prop_names;
|
||||||
|
static PROP_TABLE *prop_values;
|
||||||
|
static OSSL_PROPERTY_IDX prop_name_idx = 0;
|
||||||
|
static OSSL_PROPERTY_IDX prop_value_idx = 0;
|
||||||
|
|
||||||
|
static unsigned long property_hash(const PROPERTY_STRING *a)
|
||||||
|
{
|
||||||
|
return OPENSSL_LH_strhash(a->s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int property_cmp(const PROPERTY_STRING *a, const PROPERTY_STRING *b)
|
||||||
|
{
|
||||||
|
return strcmp(a->s, b->s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void property_free(PROPERTY_STRING *ps)
|
||||||
|
{
|
||||||
|
OPENSSL_free(ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void property_table_free(PROP_TABLE **pt)
|
||||||
|
{
|
||||||
|
PROP_TABLE *t = *pt;
|
||||||
|
|
||||||
|
if (t != NULL) {
|
||||||
|
lh_PROPERTY_STRING_doall(t, &property_free);
|
||||||
|
lh_PROPERTY_STRING_free(t);
|
||||||
|
*pt = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static PROPERTY_STRING *new_property_string(const char *s,
|
||||||
|
OSSL_PROPERTY_IDX *pidx)
|
||||||
|
{
|
||||||
|
const size_t l = strlen(s);
|
||||||
|
PROPERTY_STRING *ps = OPENSSL_malloc(sizeof(*ps) + l);
|
||||||
|
|
||||||
|
if (ps != NULL) {
|
||||||
|
memcpy(ps->body, s, l + 1);
|
||||||
|
ps->s = ps->body;
|
||||||
|
ps->idx = ++*pidx;
|
||||||
|
if (ps->idx == 0) {
|
||||||
|
OPENSSL_free(ps);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ps;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OSSL_PROPERTY_IDX ossl_property_string(PROP_TABLE *t,
|
||||||
|
OSSL_PROPERTY_IDX *pidx,
|
||||||
|
const char *s)
|
||||||
|
{
|
||||||
|
PROPERTY_STRING p, *ps, *ps_new;
|
||||||
|
|
||||||
|
p.s = s;
|
||||||
|
ps = lh_PROPERTY_STRING_retrieve(t, &p);
|
||||||
|
if (ps == NULL && pidx != NULL)
|
||||||
|
if ((ps_new = new_property_string(s, pidx)) != NULL) {
|
||||||
|
lh_PROPERTY_STRING_insert(t, ps_new);
|
||||||
|
if (lh_PROPERTY_STRING_error(t)) {
|
||||||
|
property_free(ps_new);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ps = ps_new;
|
||||||
|
}
|
||||||
|
return ps != NULL ? ps->idx : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create)
|
||||||
|
{
|
||||||
|
return ossl_property_string(prop_names, create ? &prop_name_idx : NULL, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create)
|
||||||
|
{
|
||||||
|
return ossl_property_string(prop_values, create ? &prop_value_idx : NULL, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_property_string_init(void)
|
||||||
|
{
|
||||||
|
prop_names = lh_PROPERTY_STRING_new(&property_hash, &property_cmp);
|
||||||
|
if (prop_names == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
prop_values = lh_PROPERTY_STRING_new(&property_hash, &property_cmp);
|
||||||
|
if (prop_values == NULL)
|
||||||
|
goto err;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
ossl_property_string_cleanup();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ossl_property_string_cleanup(void)
|
||||||
|
{
|
||||||
|
property_table_free(&prop_names);
|
||||||
|
property_table_free(&prop_values);
|
||||||
|
prop_name_idx = prop_value_idx = 0;
|
||||||
|
}
|
||||||
@@ -113,8 +113,6 @@ my @T = map([ 8*$_, 8*($_+1), 8*($_+2), 8*($_+3), 8*($_+4) ], (30,35,40,45,50));
|
|||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
#include "arm_arch.h"
|
#include "arm_arch.h"
|
||||||
|
|
||||||
.text
|
|
||||||
|
|
||||||
#if defined(__thumb2__)
|
#if defined(__thumb2__)
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.thumb
|
.thumb
|
||||||
@@ -122,6 +120,8 @@ $code.=<<___;
|
|||||||
.code 32
|
.code 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
.type iotas32, %object
|
.type iotas32, %object
|
||||||
.align 5
|
.align 5
|
||||||
iotas32:
|
iotas32:
|
||||||
@@ -691,7 +691,14 @@ ___
|
|||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
blo .Lround2x
|
blo .Lround2x
|
||||||
|
|
||||||
|
#if __ARM_ARCH__>=5
|
||||||
ldr pc,[sp,#440]
|
ldr pc,[sp,#440]
|
||||||
|
#else
|
||||||
|
ldr lr,[sp,#440]
|
||||||
|
tst lr,#1
|
||||||
|
moveq pc,lr @ be binary compatible with V4, yet
|
||||||
|
bx lr @ interoperable with Thumb ISA:-)
|
||||||
|
#endif
|
||||||
.size KeccakF1600_int,.-KeccakF1600_int
|
.size KeccakF1600_int,.-KeccakF1600_int
|
||||||
|
|
||||||
.type KeccakF1600, %function
|
.type KeccakF1600, %function
|
||||||
@@ -730,7 +737,14 @@ KeccakF1600:
|
|||||||
stmia @E[1], {@C[0]-@C[9]}
|
stmia @E[1], {@C[0]-@C[9]}
|
||||||
|
|
||||||
add sp,sp,#440+20
|
add sp,sp,#440+20
|
||||||
|
#if __ARM_ARCH__>=5
|
||||||
ldmia sp!,{r4-r11,pc}
|
ldmia sp!,{r4-r11,pc}
|
||||||
|
#else
|
||||||
|
ldmia sp!,{r4-r11,lr}
|
||||||
|
tst lr,#1
|
||||||
|
moveq pc,lr @ be binary compatible with V4, yet
|
||||||
|
bx lr @ interoperable with Thumb ISA:-)
|
||||||
|
#endif
|
||||||
.size KeccakF1600,.-KeccakF1600
|
.size KeccakF1600,.-KeccakF1600
|
||||||
___
|
___
|
||||||
{ my ($A_flat,$inp,$len,$bsz) = map("r$_",(10..12,14));
|
{ my ($A_flat,$inp,$len,$bsz) = map("r$_",(10..12,14));
|
||||||
@@ -905,7 +919,14 @@ SHA3_absorb:
|
|||||||
.Labsorb_abort:
|
.Labsorb_abort:
|
||||||
add sp,sp,#456+32
|
add sp,sp,#456+32
|
||||||
mov r0,$len @ return value
|
mov r0,$len @ return value
|
||||||
|
#if __ARM_ARCH__>=5
|
||||||
ldmia sp!,{r4-r12,pc}
|
ldmia sp!,{r4-r12,pc}
|
||||||
|
#else
|
||||||
|
ldmia sp!,{r4-r12,lr}
|
||||||
|
tst lr,#1
|
||||||
|
moveq pc,lr @ be binary compatible with V4, yet
|
||||||
|
bx lr @ interoperable with Thumb ISA:-)
|
||||||
|
#endif
|
||||||
.size SHA3_absorb,.-SHA3_absorb
|
.size SHA3_absorb,.-SHA3_absorb
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -1055,7 +1076,14 @@ SHA3_squeeze:
|
|||||||
.align 4
|
.align 4
|
||||||
.Lsqueeze_done:
|
.Lsqueeze_done:
|
||||||
add sp,sp,#24
|
add sp,sp,#24
|
||||||
|
#if __ARM_ARCH__>=5
|
||||||
ldmia sp!,{r4-r10,pc}
|
ldmia sp!,{r4-r10,pc}
|
||||||
|
#else
|
||||||
|
ldmia sp!,{r4-r10,lr}
|
||||||
|
tst lr,#1
|
||||||
|
moveq pc,lr @ be binary compatible with V4, yet
|
||||||
|
bx lr @ interoperable with Thumb ISA:-)
|
||||||
|
#endif
|
||||||
.size SHA3_squeeze,.-SHA3_squeeze
|
.size SHA3_squeeze,.-SHA3_squeeze
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
@@ -1265,7 +1293,7 @@ KeccakF1600_neon:
|
|||||||
subs r3, r3, #1
|
subs r3, r3, #1
|
||||||
bne .Loop_neon
|
bne .Loop_neon
|
||||||
|
|
||||||
bx lr
|
ret
|
||||||
.size KeccakF1600_neon,.-KeccakF1600_neon
|
.size KeccakF1600_neon,.-KeccakF1600_neon
|
||||||
|
|
||||||
.global SHA3_absorb_neon
|
.global SHA3_absorb_neon
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ $code.=<<___;
|
|||||||
.align 5
|
.align 5
|
||||||
KeccakF1600_int:
|
KeccakF1600_int:
|
||||||
adr $C[2],iotas
|
adr $C[2],iotas
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp $C[2],x30,[sp,#16] // 32 bytes on top are mine
|
stp $C[2],x30,[sp,#16] // 32 bytes on top are mine
|
||||||
b .Loop
|
b .Loop
|
||||||
.align 4
|
.align 4
|
||||||
@@ -292,12 +293,14 @@ $code.=<<___;
|
|||||||
bne .Loop
|
bne .Loop
|
||||||
|
|
||||||
ldr x30,[sp,#24]
|
ldr x30,[sp,#24]
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size KeccakF1600_int,.-KeccakF1600_int
|
.size KeccakF1600_int,.-KeccakF1600_int
|
||||||
|
|
||||||
.type KeccakF1600,%function
|
.type KeccakF1600,%function
|
||||||
.align 5
|
.align 5
|
||||||
KeccakF1600:
|
KeccakF1600:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-128]!
|
stp x29,x30,[sp,#-128]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp x19,x20,[sp,#16]
|
stp x19,x20,[sp,#16]
|
||||||
@@ -347,6 +350,7 @@ KeccakF1600:
|
|||||||
ldp x25,x26,[x29,#64]
|
ldp x25,x26,[x29,#64]
|
||||||
ldp x27,x28,[x29,#80]
|
ldp x27,x28,[x29,#80]
|
||||||
ldp x29,x30,[sp],#128
|
ldp x29,x30,[sp],#128
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size KeccakF1600,.-KeccakF1600
|
.size KeccakF1600,.-KeccakF1600
|
||||||
|
|
||||||
@@ -354,6 +358,7 @@ KeccakF1600:
|
|||||||
.type SHA3_absorb,%function
|
.type SHA3_absorb,%function
|
||||||
.align 5
|
.align 5
|
||||||
SHA3_absorb:
|
SHA3_absorb:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-128]!
|
stp x29,x30,[sp,#-128]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp x19,x20,[sp,#16]
|
stp x19,x20,[sp,#16]
|
||||||
@@ -451,6 +456,7 @@ $code.=<<___;
|
|||||||
ldp x25,x26,[x29,#64]
|
ldp x25,x26,[x29,#64]
|
||||||
ldp x27,x28,[x29,#80]
|
ldp x27,x28,[x29,#80]
|
||||||
ldp x29,x30,[sp],#128
|
ldp x29,x30,[sp],#128
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size SHA3_absorb,.-SHA3_absorb
|
.size SHA3_absorb,.-SHA3_absorb
|
||||||
___
|
___
|
||||||
@@ -461,6 +467,7 @@ $code.=<<___;
|
|||||||
.type SHA3_squeeze,%function
|
.type SHA3_squeeze,%function
|
||||||
.align 5
|
.align 5
|
||||||
SHA3_squeeze:
|
SHA3_squeeze:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-48]!
|
stp x29,x30,[sp,#-48]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp x19,x20,[sp,#16]
|
stp x19,x20,[sp,#16]
|
||||||
@@ -523,6 +530,7 @@ SHA3_squeeze:
|
|||||||
ldp x19,x20,[sp,#16]
|
ldp x19,x20,[sp,#16]
|
||||||
ldp x21,x22,[sp,#32]
|
ldp x21,x22,[sp,#32]
|
||||||
ldp x29,x30,[sp],#48
|
ldp x29,x30,[sp],#48
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size SHA3_squeeze,.-SHA3_squeeze
|
.size SHA3_squeeze,.-SHA3_squeeze
|
||||||
___
|
___
|
||||||
@@ -641,6 +649,7 @@ KeccakF1600_ce:
|
|||||||
.type KeccakF1600_cext,%function
|
.type KeccakF1600_cext,%function
|
||||||
.align 5
|
.align 5
|
||||||
KeccakF1600_cext:
|
KeccakF1600_cext:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-80]!
|
stp x29,x30,[sp,#-80]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp d8,d9,[sp,#16] // per ABI requirement
|
stp d8,d9,[sp,#16] // per ABI requirement
|
||||||
@@ -673,6 +682,7 @@ $code.=<<___;
|
|||||||
ldp d12,d13,[sp,#48]
|
ldp d12,d13,[sp,#48]
|
||||||
ldp d14,d15,[sp,#64]
|
ldp d14,d15,[sp,#64]
|
||||||
ldr x29,[sp],#80
|
ldr x29,[sp],#80
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size KeccakF1600_cext,.-KeccakF1600_cext
|
.size KeccakF1600_cext,.-KeccakF1600_cext
|
||||||
___
|
___
|
||||||
@@ -685,6 +695,7 @@ $code.=<<___;
|
|||||||
.type SHA3_absorb_cext,%function
|
.type SHA3_absorb_cext,%function
|
||||||
.align 5
|
.align 5
|
||||||
SHA3_absorb_cext:
|
SHA3_absorb_cext:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-80]!
|
stp x29,x30,[sp,#-80]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
stp d8,d9,[sp,#16] // per ABI requirement
|
stp d8,d9,[sp,#16] // per ABI requirement
|
||||||
@@ -756,6 +767,7 @@ $code.=<<___;
|
|||||||
ldp d12,d13,[sp,#48]
|
ldp d12,d13,[sp,#48]
|
||||||
ldp d14,d15,[sp,#64]
|
ldp d14,d15,[sp,#64]
|
||||||
ldp x29,x30,[sp],#80
|
ldp x29,x30,[sp],#80
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size SHA3_absorb_cext,.-SHA3_absorb_cext
|
.size SHA3_absorb_cext,.-SHA3_absorb_cext
|
||||||
___
|
___
|
||||||
@@ -767,6 +779,7 @@ $code.=<<___;
|
|||||||
.type SHA3_squeeze_cext,%function
|
.type SHA3_squeeze_cext,%function
|
||||||
.align 5
|
.align 5
|
||||||
SHA3_squeeze_cext:
|
SHA3_squeeze_cext:
|
||||||
|
.inst 0xd503233f // paciasp
|
||||||
stp x29,x30,[sp,#-16]!
|
stp x29,x30,[sp,#-16]!
|
||||||
add x29,sp,#0
|
add x29,sp,#0
|
||||||
mov x9,$ctx
|
mov x9,$ctx
|
||||||
@@ -822,6 +835,7 @@ SHA3_squeeze_cext:
|
|||||||
|
|
||||||
.Lsqueeze_done_ce:
|
.Lsqueeze_done_ce:
|
||||||
ldr x29,[sp],#16
|
ldr x29,[sp],#16
|
||||||
|
.inst 0xd50323bf // autiasp
|
||||||
ret
|
ret
|
||||||
.size SHA3_squeeze_cext,.-SHA3_squeeze_cext
|
.size SHA3_squeeze_cext,.-SHA3_squeeze_cext
|
||||||
___
|
___
|
||||||
|
|||||||
@@ -187,7 +187,6 @@ ___
|
|||||||
$code=<<___;
|
$code=<<___;
|
||||||
#include "arm_arch.h"
|
#include "arm_arch.h"
|
||||||
|
|
||||||
.text
|
|
||||||
#if defined(__thumb2__)
|
#if defined(__thumb2__)
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.thumb
|
.thumb
|
||||||
@@ -195,6 +194,8 @@ $code=<<___;
|
|||||||
.code 32
|
.code 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
.global sha1_block_data_order
|
.global sha1_block_data_order
|
||||||
.type sha1_block_data_order,%function
|
.type sha1_block_data_order,%function
|
||||||
|
|
||||||
@@ -202,12 +203,14 @@ $code=<<___;
|
|||||||
sha1_block_data_order:
|
sha1_block_data_order:
|
||||||
#if __ARM_MAX_ARCH__>=7
|
#if __ARM_MAX_ARCH__>=7
|
||||||
.Lsha1_block:
|
.Lsha1_block:
|
||||||
adr r3,.Lsha1_block
|
|
||||||
ldr r12,.LOPENSSL_armcap
|
ldr r12,.LOPENSSL_armcap
|
||||||
|
# if !defined(_WIN32)
|
||||||
|
adr r3,.Lsha1_block
|
||||||
ldr r12,[r3,r12] @ OPENSSL_armcap_P
|
ldr r12,[r3,r12] @ OPENSSL_armcap_P
|
||||||
#ifdef __APPLE__
|
# endif
|
||||||
|
# if defined(__APPLE__) || defined(_WIN32)
|
||||||
ldr r12,[r12]
|
ldr r12,[r12]
|
||||||
#endif
|
# endif
|
||||||
tst r12,#ARMV8_SHA1
|
tst r12,#ARMV8_SHA1
|
||||||
bne .LARMv8
|
bne .LARMv8
|
||||||
tst r12,#ARMV7_NEON
|
tst r12,#ARMV7_NEON
|
||||||
@@ -311,7 +314,11 @@ $code.=<<___;
|
|||||||
.LK_60_79: .word 0xca62c1d6
|
.LK_60_79: .word 0xca62c1d6
|
||||||
#if __ARM_MAX_ARCH__>=7
|
#if __ARM_MAX_ARCH__>=7
|
||||||
.LOPENSSL_armcap:
|
.LOPENSSL_armcap:
|
||||||
|
# ifdef _WIN32
|
||||||
|
.word OPENSSL_armcap_P
|
||||||
|
# else
|
||||||
.word OPENSSL_armcap_P-.Lsha1_block
|
.word OPENSSL_armcap_P-.Lsha1_block
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
.asciz "SHA1 block transform for ARMv4/NEON/ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
|
.asciz "SHA1 block transform for ARMv4/NEON/ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
|
||||||
.align 5
|
.align 5
|
||||||
@@ -613,14 +620,15 @@ my ($ABCD,$E,$E0,$E1)=map("q$_",(0..3));
|
|||||||
my @MSG=map("q$_",(4..7));
|
my @MSG=map("q$_",(4..7));
|
||||||
my @Kxx=map("q$_",(8..11));
|
my @Kxx=map("q$_",(8..11));
|
||||||
my ($W0,$W1,$ABCD_SAVE)=map("q$_",(12..14));
|
my ($W0,$W1,$ABCD_SAVE)=map("q$_",(12..14));
|
||||||
|
my $_byte = ($flavour =~ /win/ ? "DCB" : ".byte");
|
||||||
|
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
#if __ARM_MAX_ARCH__>=7
|
#if __ARM_MAX_ARCH__>=7
|
||||||
|
|
||||||
# if defined(__thumb2__)
|
# if defined(__thumb2__)
|
||||||
# define INST(a,b,c,d) .byte c,d|0xf,a,b
|
# define INST(a,b,c,d) $_byte c,d|0xf,a,b
|
||||||
# else
|
# else
|
||||||
# define INST(a,b,c,d) .byte a,b,c,d|0x10
|
# define INST(a,b,c,d) $_byte a,b,c,d|0x10
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
.type sha1_block_data_order_armv8,%function
|
.type sha1_block_data_order_armv8,%function
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ $code.=<<___ if ($i<15 && !($i&1));
|
|||||||
lsr @Xx[$i+1],@Xx[$i],#32
|
lsr @Xx[$i+1],@Xx[$i],#32
|
||||||
___
|
___
|
||||||
$code.=<<___ if ($i<14 && !($i&1));
|
$code.=<<___ if ($i<14 && !($i&1));
|
||||||
ldr @Xx[$i+2],[$inp,#`($i+2)*4-64`]
|
ldur @Xx[$i+2],[$inp,#`($i+2)*4-64`]
|
||||||
___
|
___
|
||||||
$code.=<<___ if ($i<14 && ($i&1));
|
$code.=<<___ if ($i<14 && ($i&1));
|
||||||
#ifdef __ARMEB__
|
#ifdef __AARCH64EB__
|
||||||
ror @Xx[$i+1],@Xx[$i+1],#32
|
ror @Xx[$i+1],@Xx[$i+1],#32
|
||||||
#else
|
#else
|
||||||
rev32 @Xx[$i+1],@Xx[$i+1]
|
rev32 @Xx[$i+1],@Xx[$i+1]
|
||||||
@@ -171,23 +171,19 @@ ___
|
|||||||
}
|
}
|
||||||
|
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
#include "arm_arch.h"
|
#ifndef __KERNEL__
|
||||||
|
# include "arm_arch.h"
|
||||||
|
.extern OPENSSL_armcap_P
|
||||||
|
#endif
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
.extern OPENSSL_armcap_P
|
|
||||||
.globl sha1_block_data_order
|
.globl sha1_block_data_order
|
||||||
.type sha1_block_data_order,%function
|
.type sha1_block_data_order,%function
|
||||||
.align 6
|
.align 6
|
||||||
sha1_block_data_order:
|
sha1_block_data_order:
|
||||||
#ifdef __ILP32__
|
adrp x16,OPENSSL_armcap_P
|
||||||
ldrsw x16,.LOPENSSL_armcap_P
|
ldr w16,[x16,#:lo12:OPENSSL_armcap_P]
|
||||||
#else
|
|
||||||
ldr x16,.LOPENSSL_armcap_P
|
|
||||||
#endif
|
|
||||||
adr x17,.LOPENSSL_armcap_P
|
|
||||||
add x16,x16,x17
|
|
||||||
ldr w16,[x16]
|
|
||||||
tst w16,#ARMV8_SHA1
|
tst w16,#ARMV8_SHA1
|
||||||
b.ne .Lv8_entry
|
b.ne .Lv8_entry
|
||||||
|
|
||||||
@@ -208,7 +204,7 @@ sha1_block_data_order:
|
|||||||
movz $K,#0x7999
|
movz $K,#0x7999
|
||||||
sub $num,$num,#1
|
sub $num,$num,#1
|
||||||
movk $K,#0x5a82,lsl#16
|
movk $K,#0x5a82,lsl#16
|
||||||
#ifdef __ARMEB__
|
#ifdef __AARCH64EB__
|
||||||
ror $Xx[0],@Xx[0],#32
|
ror $Xx[0],@Xx[0],#32
|
||||||
#else
|
#else
|
||||||
rev32 @Xx[0],@Xx[0]
|
rev32 @Xx[0],@Xx[0]
|
||||||
@@ -321,15 +317,11 @@ $code.=<<___;
|
|||||||
.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 //K_20_39
|
.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 //K_20_39
|
||||||
.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc //K_40_59
|
.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc //K_40_59
|
||||||
.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 //K_60_79
|
.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 //K_60_79
|
||||||
.LOPENSSL_armcap_P:
|
|
||||||
#ifdef __ILP32__
|
|
||||||
.long OPENSSL_armcap_P-.
|
|
||||||
#else
|
|
||||||
.quad OPENSSL_armcap_P-.
|
|
||||||
#endif
|
|
||||||
.asciz "SHA1 block transform for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
|
.asciz "SHA1 block transform for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
|
||||||
.align 2
|
.align 2
|
||||||
|
#if !defined(__KERNELL__) && !defined(_WIN64)
|
||||||
.comm OPENSSL_armcap_P,4,4
|
.comm OPENSSL_armcap_P,4,4
|
||||||
|
#endif
|
||||||
___
|
___
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
|||||||
@@ -181,7 +181,6 @@ $code=<<___;
|
|||||||
# define __ARM_MAX_ARCH__ 7
|
# define __ARM_MAX_ARCH__ 7
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.text
|
|
||||||
#if defined(__thumb2__)
|
#if defined(__thumb2__)
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.thumb
|
.thumb
|
||||||
@@ -189,6 +188,8 @@ $code=<<___;
|
|||||||
.code 32
|
.code 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
.type K256,%object
|
.type K256,%object
|
||||||
.align 5
|
.align 5
|
||||||
K256:
|
K256:
|
||||||
@@ -212,7 +213,11 @@ K256:
|
|||||||
.word 0 @ terminator
|
.word 0 @ terminator
|
||||||
#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
|
#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
|
||||||
.LOPENSSL_armcap:
|
.LOPENSSL_armcap:
|
||||||
|
# ifdef _WIN32
|
||||||
|
.word OPENSSL_armcap_P
|
||||||
|
# else
|
||||||
.word OPENSSL_armcap_P-.Lsha256_block_data_order
|
.word OPENSSL_armcap_P-.Lsha256_block_data_order
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
.align 5
|
.align 5
|
||||||
|
|
||||||
@@ -227,10 +232,12 @@ sha256_block_data_order:
|
|||||||
#endif
|
#endif
|
||||||
#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
|
#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
|
||||||
ldr r12,.LOPENSSL_armcap
|
ldr r12,.LOPENSSL_armcap
|
||||||
|
# if !defined(_WIN32)
|
||||||
ldr r12,[r3,r12] @ OPENSSL_armcap_P
|
ldr r12,[r3,r12] @ OPENSSL_armcap_P
|
||||||
#ifdef __APPLE__
|
# endif
|
||||||
|
# if defined(__APPLE__) || defined(_WIN32)
|
||||||
ldr r12,[r12]
|
ldr r12,[r12]
|
||||||
#endif
|
# endif
|
||||||
tst r12,#ARMV8_SHA256
|
tst r12,#ARMV8_SHA256
|
||||||
bne .LARMv8
|
bne .LARMv8
|
||||||
tst r12,#ARMV7_NEON
|
tst r12,#ARMV7_NEON
|
||||||
@@ -598,14 +605,15 @@ my ($ABCD,$EFGH,$abcd)=map("q$_",(0..2));
|
|||||||
my @MSG=map("q$_",(8..11));
|
my @MSG=map("q$_",(8..11));
|
||||||
my ($W0,$W1,$ABCD_SAVE,$EFGH_SAVE)=map("q$_",(12..15));
|
my ($W0,$W1,$ABCD_SAVE,$EFGH_SAVE)=map("q$_",(12..15));
|
||||||
my $Ktbl="r3";
|
my $Ktbl="r3";
|
||||||
|
my $_byte = ($flavour =~ /win/ ? "DCB" : ".byte");
|
||||||
|
|
||||||
$code.=<<___;
|
$code.=<<___;
|
||||||
#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
|
#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
|
||||||
|
|
||||||
# if defined(__thumb2__)
|
# if defined(__thumb2__)
|
||||||
# define INST(a,b,c,d) .byte c,d|0xc,a,b
|
# define INST(a,b,c,d) $_byte c,d|0xc,a,b
|
||||||
# else
|
# else
|
||||||
# define INST(a,b,c,d) .byte a,b,c,d
|
# define INST(a,b,c,d) $_byte a,b,c,d
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
.type sha256_block_data_order_armv8,%function
|
.type sha256_block_data_order_armv8,%function
|
||||||
|
|||||||
@@ -196,6 +196,9 @@ $code.=<<___;
|
|||||||
add $Ktbl,$Ktbl,#8
|
add $Ktbl,$Ktbl,#8
|
||||||
___
|
___
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $_word = ($flavour =~ /win/ ? "DCDU" : ".word");
|
||||||
|
|
||||||
$code=<<___;
|
$code=<<___;
|
||||||
#ifndef __KERNEL__
|
#ifndef __KERNEL__
|
||||||
# include "arm_arch.h"
|
# include "arm_arch.h"
|
||||||
@@ -211,14 +214,13 @@ $code=<<___;
|
|||||||
#ifdef __ARMEL__
|
#ifdef __ARMEL__
|
||||||
# define LO 0
|
# define LO 0
|
||||||
# define HI 4
|
# define HI 4
|
||||||
# define WORD64(hi0,lo0,hi1,lo1) .word lo0,hi0, lo1,hi1
|
# define WORD64(hi0,lo0,hi1,lo1) $_word lo0,hi0, lo1,hi1
|
||||||
#else
|
#else
|
||||||
# define HI 0
|
# define HI 0
|
||||||
# define LO 4
|
# define LO 4
|
||||||
# define WORD64(hi0,lo0,hi1,lo1) .word hi0,lo0, hi1,lo1
|
# define WORD64(hi0,lo0,hi1,lo1) $_word hi0,lo0, hi1,lo1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.text
|
|
||||||
#if defined(__thumb2__)
|
#if defined(__thumb2__)
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.thumb
|
.thumb
|
||||||
@@ -227,6 +229,8 @@ $code=<<___;
|
|||||||
.code 32
|
.code 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
.type K512,%object
|
.type K512,%object
|
||||||
.align 5
|
.align 5
|
||||||
K512:
|
K512:
|
||||||
@@ -273,7 +277,11 @@ WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817)
|
|||||||
.size K512,.-K512
|
.size K512,.-K512
|
||||||
#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
|
#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
|
||||||
.LOPENSSL_armcap:
|
.LOPENSSL_armcap:
|
||||||
|
# ifdef _WIN32
|
||||||
|
.word OPENSSL_armcap_P
|
||||||
|
# else
|
||||||
.word OPENSSL_armcap_P-.Lsha512_block_data_order
|
.word OPENSSL_armcap_P-.Lsha512_block_data_order
|
||||||
|
# endif
|
||||||
.skip 32-4
|
.skip 32-4
|
||||||
#else
|
#else
|
||||||
.skip 32
|
.skip 32
|
||||||
@@ -290,10 +298,12 @@ sha512_block_data_order:
|
|||||||
#endif
|
#endif
|
||||||
#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
|
#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
|
||||||
ldr r12,.LOPENSSL_armcap
|
ldr r12,.LOPENSSL_armcap
|
||||||
|
# if !defined(_WIN32)
|
||||||
ldr r12,[r3,r12] @ OPENSSL_armcap_P
|
ldr r12,[r3,r12] @ OPENSSL_armcap_P
|
||||||
#ifdef __APPLE__
|
# endif
|
||||||
|
# if defined(__APPLE__) || defined(_WIN32)
|
||||||
ldr r12,[r12]
|
ldr r12,[r12]
|
||||||
#endif
|
# endif
|
||||||
tst r12,#ARMV7_NEON
|
tst r12,#ARMV7_NEON
|
||||||
bne .LNEON
|
bne .LNEON
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user