Latest update
This commit is contained in:
@@ -9,6 +9,9 @@
|
|||||||
|
|
||||||
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
|
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
|
||||||
|
|
||||||
|
*) Move strictness check from EVP_PKEY_asn1_new() to EVP_PKEY_asn1_add0().
|
||||||
|
[Richard Levitte]
|
||||||
|
|
||||||
*) Change the license to the Apache License v2.0.
|
*) Change the license to the Apache License v2.0.
|
||||||
[Richard Levitte]
|
[Richard Levitte]
|
||||||
|
|
||||||
@@ -33,6 +36,9 @@
|
|||||||
and retain API/ABI compatibility.
|
and retain API/ABI compatibility.
|
||||||
[Richard Levitte]
|
[Richard Levitte]
|
||||||
|
|
||||||
|
*) Add support for RFC5297 SIV mode (siv128), including AES-SIV.
|
||||||
|
[Todd Short]
|
||||||
|
|
||||||
*) Remove the 'dist' target and add a tarball building script. The
|
*) Remove the 'dist' target and add a tarball building script. The
|
||||||
'dist' target has fallen out of use, and it shouldn't be
|
'dist' target has fallen out of use, and it shouldn't be
|
||||||
necessary to configure just to create a source distribution.
|
necessary to configure just to create a source distribution.
|
||||||
@@ -84,6 +90,11 @@
|
|||||||
list of built in objects, i.e. OIDs with names.
|
list of built in objects, i.e. OIDs with names.
|
||||||
[Richard Levitte]
|
[Richard Levitte]
|
||||||
|
|
||||||
|
*) Added support for Linux Kernel TLS data-path. The Linux Kernel data-path
|
||||||
|
improves application performance by removing data copies and providing
|
||||||
|
applications with zero-copy system calls such as sendfile and splice.
|
||||||
|
[Boris Pismenny]
|
||||||
|
|
||||||
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
|
||||||
@@ -11488,7 +11499,7 @@ des-cbc 3624.96k 5258.21k 5530.91k 5624.30k 5628.26k
|
|||||||
(still largely untested)
|
(still largely untested)
|
||||||
[Bodo Moeller]
|
[Bodo Moeller]
|
||||||
|
|
||||||
*) New function ANS1_tag2str() to convert an ASN1 tag to a descriptive
|
*) New function ASN1_tag2str() to convert an ASN1 tag to a descriptive
|
||||||
ASCII string. This was handled independently in various places before.
|
ASCII string. This was handled independently in various places before.
|
||||||
[Steve Henson]
|
[Steve Henson]
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
our $osslprefix = 'OSSL$';
|
our $osslprefix = 'OSSL$';
|
||||||
(our $osslprefix_q = $osslprefix) =~ s/\$/\\\$/;
|
(our $osslprefix_q = $osslprefix) =~ s/\$/\\\$/;
|
||||||
|
|
||||||
our $sover_dirname = sprintf "%02d%02d", split(/\./, $config{shlib_version_number});
|
our $sover_dirname = sprintf "%02d%02d", split(/\./, $config{shlib_version});
|
||||||
our $osslver = sprintf "%02d%02d", split(/\./, $config{version});
|
our $osslver = sprintf "%02d%02d", split(/\./, $config{version});
|
||||||
|
|
||||||
our $sourcedir = $config{sourcedir};
|
our $sourcedir = $config{sourcedir};
|
||||||
@@ -104,7 +104,7 @@ BLDDIR={- $config{builddir} -}
|
|||||||
# to testing.
|
# to testing.
|
||||||
VERBOSE=$(V)
|
VERBOSE=$(V)
|
||||||
|
|
||||||
VERSION={- "$config{major}.$config{minor}.$config{patch}$config{prerelease}$config{build_metadata}" -}
|
VERSION={- "$config{full_version}" -}
|
||||||
MAJOR={- $config{major} -}
|
MAJOR={- $config{major} -}
|
||||||
MINOR={- $config{minor} -}
|
MINOR={- $config{minor} -}
|
||||||
SHLIB_VERSION_NUMBER={- $config{shlib_version} -}
|
SHLIB_VERSION_NUMBER={- $config{shlib_version} -}
|
||||||
@@ -639,7 +639,7 @@ vmsconfig.pm : configdata.pm
|
|||||||
WRITE CONFIG "our %config = ("
|
WRITE CONFIG "our %config = ("
|
||||||
WRITE CONFIG " target => '","{- $config{target} -}","',"
|
WRITE CONFIG " target => '","{- $config{target} -}","',"
|
||||||
WRITE CONFIG " version => '","{- $config{version} -}","',"
|
WRITE CONFIG " version => '","{- $config{version} -}","',"
|
||||||
WRITE CONFIG " shlib_version_number => '","{- $config{shlib_version_number} -}","',"
|
WRITE CONFIG " shlib_version => '","{- $config{shlib_version} -}","',"
|
||||||
WRITE CONFIG " shlib_major => '","{- $config{shlib_major} -}","',"
|
WRITE CONFIG " shlib_major => '","{- $config{shlib_major} -}","',"
|
||||||
WRITE CONFIG " shlib_minor => '","{- $config{shlib_minor} -}","',"
|
WRITE CONFIG " shlib_minor => '","{- $config{shlib_minor} -}","',"
|
||||||
WRITE CONFIG " no_shared => '","{- $disabled{shared} -}","',"
|
WRITE CONFIG " no_shared => '","{- $disabled{shared} -}","',"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
# libcrypto.a and use libcrypto_a.a as static one.
|
# libcrypto.a and use libcrypto_a.a as static one.
|
||||||
sub sharedaix { !$disabled{shared} && $config{target} =~ /^aix/ }
|
sub sharedaix { !$disabled{shared} && $config{target} =~ /^aix/ }
|
||||||
|
|
||||||
our $sover_dirname = $config{shlib_version_number};
|
our $sover_dirname = $config{shlib_version};
|
||||||
$sover_dirname =~ s|\.|_|g
|
$sover_dirname =~ s|\.|_|g
|
||||||
if $config{target} =~ /^mingw/;
|
if $config{target} =~ /^mingw/;
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ CONFIGURE_ARGS=({- join(", ",quotify_l(@{$config{perlargv}})) -})
|
|||||||
SRCDIR={- $config{sourcedir} -}
|
SRCDIR={- $config{sourcedir} -}
|
||||||
BLDDIR={- $config{builddir} -}
|
BLDDIR={- $config{builddir} -}
|
||||||
|
|
||||||
VERSION={- "$config{major}.$config{minor}.$config{patch}$config{prerelease}$config{build_metadata}" -}
|
VERSION={- "$config{full_version}" -}
|
||||||
MAJOR={- $config{major} -}
|
MAJOR={- $config{major} -}
|
||||||
MINOR={- $config{minor} -}
|
MINOR={- $config{minor} -}
|
||||||
SHLIB_VERSION_NUMBER={- $config{shlib_version} -}
|
SHLIB_VERSION_NUMBER={- $config{shlib_version} -}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
our $shlibextimport = $target{shared_import_extension} || ".lib";
|
our $shlibextimport = $target{shared_import_extension} || ".lib";
|
||||||
our $dsoext = $target{dso_extension} || ".dll";
|
our $dsoext = $target{dso_extension} || ".dll";
|
||||||
|
|
||||||
(our $sover_dirname = $config{shlib_version_number}) =~ s|\.|_|g;
|
(our $sover_dirname = $config{shlib_version}) =~ s|\.|_|g;
|
||||||
|
|
||||||
my $build_scheme = $target{build_scheme};
|
my $build_scheme = $target{build_scheme};
|
||||||
my $install_flavour = $build_scheme->[$#$build_scheme]; # last element
|
my $install_flavour = $build_scheme->[$#$build_scheme]; # last element
|
||||||
@@ -71,7 +71,7 @@ PLATFORM={- $config{target} -}
|
|||||||
SRCDIR={- $config{sourcedir} -}
|
SRCDIR={- $config{sourcedir} -}
|
||||||
BLDDIR={- $config{builddir} -}
|
BLDDIR={- $config{builddir} -}
|
||||||
|
|
||||||
VERSION={- "$config{major}.$config{minor}.$config{patch}$config{prerelease}$config{build_metadata}" -}
|
VERSION={- "$config{full_version}" -}
|
||||||
MAJOR={- $config{major} -}
|
MAJOR={- $config{major} -}
|
||||||
MINOR={- $config{minor} -}
|
MINOR={- $config{minor} -}
|
||||||
|
|
||||||
|
|||||||
@@ -276,6 +276,9 @@ die "erroneous version information in opensslv.h: ",
|
|||||||
|| $config{patch} eq "unknown"
|
|| $config{patch} eq "unknown"
|
||||||
|| $config{shlib_version} eq "unknown");
|
|| $config{shlib_version} eq "unknown");
|
||||||
|
|
||||||
|
$config{version} = "$config{major}.$config{minor}.$config{patch}";
|
||||||
|
$config{full_version} = "$config{version}$config{prerelease}$config{build_metadata}";
|
||||||
|
|
||||||
# Collect target configurations
|
# Collect target configurations
|
||||||
|
|
||||||
my $pattern = catfile(dirname($0), "Configurations", "*.conf");
|
my $pattern = catfile(dirname($0), "Configurations", "*.conf");
|
||||||
@@ -318,6 +321,7 @@ my @dtls = qw(dtls1 dtls1_2);
|
|||||||
# For developers: keep it sorted alphabetically
|
# For developers: keep it sorted alphabetically
|
||||||
|
|
||||||
my @disablables = (
|
my @disablables = (
|
||||||
|
"ktls",
|
||||||
"afalgeng",
|
"afalgeng",
|
||||||
"aria",
|
"aria",
|
||||||
"asan",
|
"asan",
|
||||||
@@ -387,6 +391,7 @@ my @disablables = (
|
|||||||
"seed",
|
"seed",
|
||||||
"shared",
|
"shared",
|
||||||
"siphash",
|
"siphash",
|
||||||
|
"siv",
|
||||||
"sm2",
|
"sm2",
|
||||||
"sm3",
|
"sm3",
|
||||||
"sm4",
|
"sm4",
|
||||||
@@ -448,6 +453,7 @@ our %disabled = ( # "what" => "comment"
|
|||||||
"weak-ssl-ciphers" => "default",
|
"weak-ssl-ciphers" => "default",
|
||||||
"zlib" => "default",
|
"zlib" => "default",
|
||||||
"zlib-dynamic" => "default",
|
"zlib-dynamic" => "default",
|
||||||
|
"ktls" => "default",
|
||||||
);
|
);
|
||||||
|
|
||||||
# Note: => pair form used for aesthetics, not to truly make a hash table
|
# Note: => pair form used for aesthetics, not to truly make a hash table
|
||||||
@@ -493,6 +499,8 @@ my @disable_cascades = (
|
|||||||
sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
|
sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
|
||||||
|
|
||||||
sub { !$disabled{"msan"} } => [ "asm" ],
|
sub { !$disabled{"msan"} } => [ "asm" ],
|
||||||
|
|
||||||
|
sub { $disabled{cmac}; } => [ "siv" ],
|
||||||
);
|
);
|
||||||
|
|
||||||
# Avoid protocol support holes. Also disable all versions below N, if version
|
# Avoid protocol support holes. Also disable all versions below N, if version
|
||||||
@@ -997,8 +1005,8 @@ if ($target eq "HASH") {
|
|||||||
exit 0;
|
exit 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
print "Configuring OpenSSL version $config{version} ($config{version_num}) ";
|
print "Configuring OpenSSL version $config{full_version} ";
|
||||||
print "for $target\n";
|
print "for target $target\n";
|
||||||
|
|
||||||
if (scalar(@seed_sources) == 0) {
|
if (scalar(@seed_sources) == 0) {
|
||||||
print "Using os-specific seed configuration\n";
|
print "Using os-specific seed configuration\n";
|
||||||
@@ -1570,6 +1578,27 @@ unless ($disabled{afalgeng}) {
|
|||||||
|
|
||||||
push @{$config{openssl_feature_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
|
push @{$config{openssl_feature_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
|
||||||
|
|
||||||
|
unless ($disabled{ktls}) {
|
||||||
|
$config{ktls}="";
|
||||||
|
if ($target =~ m/^linux/) {
|
||||||
|
my $usr = "/usr/$config{cross_compile_prefix}";
|
||||||
|
chop($usr);
|
||||||
|
if ($config{cross_compile_prefix} eq "") {
|
||||||
|
$usr = "/usr";
|
||||||
|
}
|
||||||
|
my $minver = (4 << 16) + (13 << 8) + 0;
|
||||||
|
my @verstr = split(" ",`cat $usr/include/linux/version.h | grep LINUX_VERSION_CODE`);
|
||||||
|
|
||||||
|
if ($verstr[2] < $minver) {
|
||||||
|
$disabled{ktls} = "too-old-kernel";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$disabled{ktls} = "not-linux";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
|
||||||
|
|
||||||
# Finish up %config by appending things the user gave us on the command line
|
# Finish up %config by appending things the user gave us on the command line
|
||||||
# apart from "make variables"
|
# apart from "make variables"
|
||||||
foreach (keys %useradd) {
|
foreach (keys %useradd) {
|
||||||
|
|||||||
@@ -250,6 +250,15 @@
|
|||||||
Don't build the AFALG engine. This option will be forced if
|
Don't build the AFALG engine. This option will be forced if
|
||||||
on a platform that does not support AFALG.
|
on a platform that does not support AFALG.
|
||||||
|
|
||||||
|
enable-ktls
|
||||||
|
Build with Kernel TLS support. This option will enable the
|
||||||
|
use of the Kernel TLS data-path, which can improve
|
||||||
|
performance and allow for the use of sendfile and splice
|
||||||
|
system calls on TLS sockets. The Kernel may use TLS
|
||||||
|
accelerators if any are available on the system.
|
||||||
|
This option will be forced off on systems that do not support
|
||||||
|
the Kernel TLS data-path.
|
||||||
|
|
||||||
enable-asan
|
enable-asan
|
||||||
Build with the Address sanitiser. This is a developer option
|
Build with the Address sanitiser. This is a developer option
|
||||||
only. It may not work on all platforms and should never be
|
only. It may not work on all platforms and should never be
|
||||||
@@ -326,6 +335,11 @@
|
|||||||
Don't build support for datagram based BIOs. Selecting this
|
Don't build support for datagram based BIOs. Selecting this
|
||||||
option will also force the disabling of DTLS.
|
option will also force the disabling of DTLS.
|
||||||
|
|
||||||
|
enable-devcryptoeng
|
||||||
|
Build the /dev/crypto engine. It is automatically selected
|
||||||
|
on BSD implementations, in which case it can be disabled with
|
||||||
|
no-devcryptoeng.
|
||||||
|
|
||||||
no-dso
|
no-dso
|
||||||
Don't build support for loading Dynamic Shared Objects.
|
Don't build support for loading Dynamic Shared Objects.
|
||||||
|
|
||||||
@@ -542,9 +556,9 @@
|
|||||||
Build without support for the specified algorithm, where
|
Build without support for the specified algorithm, where
|
||||||
<alg> is one of: aria, bf, blake2, camellia, cast, chacha,
|
<alg> is one of: aria, bf, blake2, camellia, cast, chacha,
|
||||||
cmac, des, dh, dsa, ecdh, ecdsa, idea, md4, mdc2, ocb,
|
cmac, des, dh, dsa, ecdh, ecdsa, idea, md4, mdc2, ocb,
|
||||||
poly1305, rc2, rc4, rmd160, scrypt, seed, siphash, sm2, sm3,
|
poly1305, rc2, rc4, rmd160, scrypt, seed, siphash, siv, sm2,
|
||||||
sm4 or whirlpool. The "ripemd" algorithm is deprecated and
|
sm3, sm4 or whirlpool. The "ripemd" algorithm is deprecated
|
||||||
if used is synonymous with rmd160.
|
and if used is synonymous with rmd160.
|
||||||
|
|
||||||
-Dxxx, -Ixxx, -Wp, -lxxx, -Lxxx, -Wl, -rpath, -R, -framework, -static
|
-Dxxx, -Ixxx, -Wp, -lxxx, -Lxxx, -Wl, -rpath, -R, -framework, -static
|
||||||
These system specific options will be recognised and
|
These system specific options will be recognised and
|
||||||
|
|||||||
@@ -3245,6 +3245,10 @@ static void print_stuff(BIO *bio, SSL *s, int full)
|
|||||||
BIO_printf(bio, "Expansion: %s\n",
|
BIO_printf(bio, "Expansion: %s\n",
|
||||||
expansion ? SSL_COMP_get_name(expansion) : "NONE");
|
expansion ? SSL_COMP_get_name(expansion) : "NONE");
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef OPENSSL_NO_KTLS
|
||||||
|
if (BIO_get_ktls_send(SSL_get_wbio(s)))
|
||||||
|
BIO_printf(bio_err, "Using Kernel TLS for sending\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SSL_DEBUG
|
#ifdef SSL_DEBUG
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2911,6 +2911,10 @@ static void print_connection_info(SSL *con)
|
|||||||
}
|
}
|
||||||
OPENSSL_free(exportedkeymat);
|
OPENSSL_free(exportedkeymat);
|
||||||
}
|
}
|
||||||
|
#ifndef OPENSSL_NO_KTLS
|
||||||
|
if (BIO_get_ktls_send(SSL_get_wbio(con)))
|
||||||
|
BIO_printf(bio_err, "Using Kernel TLS for sending\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
(void)BIO_flush(bio_s_out);
|
(void)BIO_flush(bio_s_out);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2657,6 +2657,10 @@ int speed_main(int argc, char **argv)
|
|||||||
EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
|
EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
|
||||||
loopargs[k].key, NULL, -1);
|
loopargs[k].key, NULL, -1);
|
||||||
OPENSSL_clear_free(loopargs[k].key, keylen);
|
OPENSSL_clear_free(loopargs[k].key, keylen);
|
||||||
|
|
||||||
|
/* SIV mode only allows for a single Update operation */
|
||||||
|
if (EVP_CIPHER_mode(evp_cipher) == EVP_CIPH_SIV_MODE)
|
||||||
|
EVP_CIPHER_CTX_ctrl(loopargs[k].ctx, EVP_CTRL_SET_SPEED, 1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Time_F(START);
|
Time_F(START);
|
||||||
|
|||||||
+1
-1
@@ -47,7 +47,7 @@ sub create_curl {
|
|||||||
$curl->setopt(CURLOPT_VERBOSE, 1) if $options{d};
|
$curl->setopt(CURLOPT_VERBOSE, 1) if $options{d};
|
||||||
$curl->setopt(CURLOPT_FAILONERROR, 1);
|
$curl->setopt(CURLOPT_FAILONERROR, 1);
|
||||||
$curl->setopt(CURLOPT_USERAGENT,
|
$curl->setopt(CURLOPT_USERAGENT,
|
||||||
"OpenTSA tsget.pl/openssl-{- $config{version} -}");
|
"OpenTSA tsget.pl/openssl-{- $config{full_version} -}");
|
||||||
|
|
||||||
# Options for POST method.
|
# Options for POST method.
|
||||||
$curl->setopt(CURLOPT_UPLOAD, 1);
|
$curl->setopt(CURLOPT_UPLOAD, 1);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
/* This is the primary function used to parse ASN1_UTCTIME */
|
/* This is the primary function used to parse ASN1_UTCTIME */
|
||||||
int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
|
int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
|
||||||
{
|
{
|
||||||
/* wrapper around ans1_time_to_tm */
|
/* wrapper around asn1_time_to_tm */
|
||||||
if (d->type != V_ASN1_UTCTIME)
|
if (d->type != V_ASN1_UTCTIME)
|
||||||
return 0;
|
return 0;
|
||||||
return asn1_time_to_tm(tm, d);
|
return asn1_time_to_tm(tm, d);
|
||||||
|
|||||||
+16
-12
@@ -140,6 +140,22 @@ int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
|
|||||||
{
|
{
|
||||||
EVP_PKEY_ASN1_METHOD tmp = { 0, };
|
EVP_PKEY_ASN1_METHOD tmp = { 0, };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One of the following must be true:
|
||||||
|
*
|
||||||
|
* pem_str == NULL AND ASN1_PKEY_ALIAS is set
|
||||||
|
* pem_str != NULL AND ASN1_PKEY_ALIAS is clear
|
||||||
|
*
|
||||||
|
* Anything else is an error and may lead to a corrupt ASN1 method table
|
||||||
|
*/
|
||||||
|
if (!((ameth->pem_str == NULL
|
||||||
|
&& (ameth->pkey_flags & ASN1_PKEY_ALIAS) != 0)
|
||||||
|
|| (ameth->pem_str != NULL
|
||||||
|
&& (ameth->pkey_flags & ASN1_PKEY_ALIAS) == 0))) {
|
||||||
|
EVPerr(EVP_F_EVP_PKEY_ASN1_ADD0, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (app_methods == NULL) {
|
if (app_methods == NULL) {
|
||||||
app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
|
app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
|
||||||
if (app_methods == NULL)
|
if (app_methods == NULL)
|
||||||
@@ -216,18 +232,6 @@ EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* One of the following must be true:
|
|
||||||
*
|
|
||||||
* pem_str == NULL AND ASN1_PKEY_ALIAS is set
|
|
||||||
* pem_str != NULL AND ASN1_PKEY_ALIAS is clear
|
|
||||||
*
|
|
||||||
* Anything else is an error and may lead to a corrupt ASN1 method table
|
|
||||||
*/
|
|
||||||
if (!((pem_str == NULL && (flags & ASN1_PKEY_ALIAS) != 0)
|
|
||||||
|| (pem_str != NULL && (flags & ASN1_PKEY_ALIAS) == 0)))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (pem_str) {
|
if (pem_str) {
|
||||||
ameth->pem_str = OPENSSL_strdup(pem_str);
|
ameth->pem_str = OPENSSL_strdup(pem_str);
|
||||||
if (!ameth->pem_str)
|
if (!ameth->pem_str)
|
||||||
|
|||||||
+46
-2
@@ -11,6 +11,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "bio_lcl.h"
|
#include "bio_lcl.h"
|
||||||
#include "internal/cryptlib.h"
|
#include "internal/cryptlib.h"
|
||||||
|
#include "internal/ktls.h"
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_SOCK
|
#ifndef OPENSSL_NO_SOCK
|
||||||
|
|
||||||
@@ -64,6 +65,17 @@ BIO *BIO_new_socket(int fd, int close_flag)
|
|||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
BIO_set_fd(ret, fd, close_flag);
|
BIO_set_fd(ret, fd, close_flag);
|
||||||
|
# ifndef OPENSSL_NO_KTLS
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The new socket is created successfully regardless of ktls_enable.
|
||||||
|
* ktls_enable doesn't change any functionality of the socket, except
|
||||||
|
* changing the setsockopt to enable the processing of ktls_start.
|
||||||
|
* Thus, it is not a problem to call it for non-TLS sockets.
|
||||||
|
*/
|
||||||
|
ktls_enable(fd);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,10 +120,20 @@ static int sock_read(BIO *b, char *out, int outl)
|
|||||||
|
|
||||||
static int sock_write(BIO *b, const char *in, int inl)
|
static int sock_write(BIO *b, const char *in, int inl)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
clear_socket_error();
|
clear_socket_error();
|
||||||
ret = writesocket(b->num, in, inl);
|
# ifndef OPENSSL_NO_KTLS
|
||||||
|
if (BIO_should_ktls_ctrl_msg_flag(b)) {
|
||||||
|
unsigned char record_type = (intptr_t)b->ptr;
|
||||||
|
ret = ktls_send_ctrl_message(b->num, record_type, in, inl);
|
||||||
|
if (ret >= 0) {
|
||||||
|
ret = inl;
|
||||||
|
BIO_clear_ktls_ctrl_msg_flag(b);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
# endif
|
||||||
|
ret = writesocket(b->num, in, inl);
|
||||||
BIO_clear_retry_flags(b);
|
BIO_clear_retry_flags(b);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
if (BIO_sock_should_retry(ret))
|
if (BIO_sock_should_retry(ret))
|
||||||
@@ -124,6 +146,9 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
|
|||||||
{
|
{
|
||||||
long ret = 1;
|
long ret = 1;
|
||||||
int *ip;
|
int *ip;
|
||||||
|
# ifndef OPENSSL_NO_KTLS
|
||||||
|
struct tls12_crypto_info_aes_gcm_128 *crypto_info;
|
||||||
|
# endif
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case BIO_C_SET_FD:
|
case BIO_C_SET_FD:
|
||||||
@@ -151,6 +176,25 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
|
|||||||
case BIO_CTRL_FLUSH:
|
case BIO_CTRL_FLUSH:
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
|
# ifndef OPENSSL_NO_KTLS
|
||||||
|
case BIO_CTRL_SET_KTLS_SEND:
|
||||||
|
crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr;
|
||||||
|
ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num);
|
||||||
|
if (ret)
|
||||||
|
BIO_set_ktls_flag(b);
|
||||||
|
break;
|
||||||
|
case BIO_CTRL_GET_KTLS_SEND:
|
||||||
|
return BIO_should_ktls_flag(b);
|
||||||
|
case BIO_CTRL_SET_KTLS_SEND_CTRL_MSG:
|
||||||
|
BIO_set_ktls_ctrl_msg_flag(b);
|
||||||
|
b->ptr = (void *)num;
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
case BIO_CTRL_CLEAR_KTLS_CTRL_MSG:
|
||||||
|
BIO_clear_ktls_ctrl_msg_flag(b);
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
# endif
|
||||||
default:
|
default:
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "dso_locl.h"
|
#include "dso_locl.h"
|
||||||
|
#include "e_os.h"
|
||||||
|
|
||||||
#ifdef DSO_DLFCN
|
#ifdef DSO_DLFCN
|
||||||
|
|
||||||
@@ -99,6 +100,7 @@ static int dlfcn_load(DSO *dso)
|
|||||||
/* See applicable comments in dso_dl.c */
|
/* See applicable comments in dso_dl.c */
|
||||||
char *filename = DSO_convert_filename(dso, NULL);
|
char *filename = DSO_convert_filename(dso, NULL);
|
||||||
int flags = DLOPEN_FLAG;
|
int flags = DLOPEN_FLAG;
|
||||||
|
int saveerrno = get_last_sys_error();
|
||||||
|
|
||||||
if (filename == NULL) {
|
if (filename == NULL) {
|
||||||
DSOerr(DSO_F_DLFCN_LOAD, DSO_R_NO_FILENAME);
|
DSOerr(DSO_F_DLFCN_LOAD, DSO_R_NO_FILENAME);
|
||||||
@@ -118,6 +120,11 @@ static int dlfcn_load(DSO *dso)
|
|||||||
ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
|
ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Some dlopen() implementations (e.g. solaris) do no preserve errno, even
|
||||||
|
* on a successful call.
|
||||||
|
*/
|
||||||
|
set_sys_error(saveerrno);
|
||||||
if (!sk_void_push(dso->meth_data, (char *)ptr)) {
|
if (!sk_void_push(dso->meth_data, (char *)ptr)) {
|
||||||
DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR);
|
DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR);
|
||||||
goto err;
|
goto err;
|
||||||
|
|||||||
+2232
-2126
@@ -744,91 +744,99 @@ static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32],
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Reference base 2^25.5 implementation.
|
* Reference base 2^25.5 implementation.
|
||||||
*/
|
*
|
||||||
/*
|
|
||||||
* This code is mostly taken from the ref10 version of Ed25519 in SUPERCOP
|
* This code is mostly taken from the ref10 version of Ed25519 in SUPERCOP
|
||||||
* 20141124 (http://bench.cr.yp.to/supercop.html).
|
* 20141124 (http://bench.cr.yp.to/supercop.html).
|
||||||
*
|
*
|
||||||
* The field functions are shared by Ed25519 and X25519 where possible.
|
* The field functions are shared by Ed25519 and X25519 where possible.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* fe means field element. Here the field is \Z/(2^255-19). An element t,
|
/*
|
||||||
|
* fe means field element. Here the field is \Z/(2^255-19). An element t,
|
||||||
* entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
|
* entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
|
||||||
* t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
|
* t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
|
||||||
* context. */
|
* context.
|
||||||
|
*/
|
||||||
typedef int32_t fe[10];
|
typedef int32_t fe[10];
|
||||||
|
|
||||||
|
static const int64_t kBottom21Bits = 0x1fffffLL;
|
||||||
static const int64_t kBottom25Bits = 0x1ffffffLL;
|
static const int64_t kBottom25Bits = 0x1ffffffLL;
|
||||||
static const int64_t kBottom26Bits = 0x3ffffffLL;
|
static const int64_t kBottom26Bits = 0x3ffffffLL;
|
||||||
static const int64_t kTop39Bits = 0xfffffffffe000000LL;
|
static const int64_t kTop39Bits = 0xfffffffffe000000LL;
|
||||||
static const int64_t kTop38Bits = 0xfffffffffc000000LL;
|
static const int64_t kTop38Bits = 0xfffffffffc000000LL;
|
||||||
|
|
||||||
static uint64_t load_3(const uint8_t *in) {
|
static uint64_t load_3(const uint8_t *in)
|
||||||
uint64_t result;
|
{
|
||||||
result = (uint64_t)in[0];
|
uint64_t result;
|
||||||
result |= ((uint64_t)in[1]) << 8;
|
|
||||||
result |= ((uint64_t)in[2]) << 16;
|
result = ((uint64_t)in[0]);
|
||||||
return result;
|
result |= ((uint64_t)in[1]) << 8;
|
||||||
|
result |= ((uint64_t)in[2]) << 16;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t load_4(const uint8_t *in) {
|
static uint64_t load_4(const uint8_t *in)
|
||||||
uint64_t result;
|
{
|
||||||
result = (uint64_t)in[0];
|
uint64_t result;
|
||||||
result |= ((uint64_t)in[1]) << 8;
|
|
||||||
result |= ((uint64_t)in[2]) << 16;
|
result = ((uint64_t)in[0]);
|
||||||
result |= ((uint64_t)in[3]) << 24;
|
result |= ((uint64_t)in[1]) << 8;
|
||||||
return result;
|
result |= ((uint64_t)in[2]) << 16;
|
||||||
|
result |= ((uint64_t)in[3]) << 24;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fe_frombytes(fe h, const uint8_t *s) {
|
static void fe_frombytes(fe h, const uint8_t *s)
|
||||||
/* Ignores top bit of h. */
|
{
|
||||||
int64_t h0 = load_4(s);
|
/* Ignores top bit of h. */
|
||||||
int64_t h1 = load_3(s + 4) << 6;
|
int64_t h0 = load_4(s);
|
||||||
int64_t h2 = load_3(s + 7) << 5;
|
int64_t h1 = load_3(s + 4) << 6;
|
||||||
int64_t h3 = load_3(s + 10) << 3;
|
int64_t h2 = load_3(s + 7) << 5;
|
||||||
int64_t h4 = load_3(s + 13) << 2;
|
int64_t h3 = load_3(s + 10) << 3;
|
||||||
int64_t h5 = load_4(s + 16);
|
int64_t h4 = load_3(s + 13) << 2;
|
||||||
int64_t h6 = load_3(s + 20) << 7;
|
int64_t h5 = load_4(s + 16);
|
||||||
int64_t h7 = load_3(s + 23) << 5;
|
int64_t h6 = load_3(s + 20) << 7;
|
||||||
int64_t h8 = load_3(s + 26) << 4;
|
int64_t h7 = load_3(s + 23) << 5;
|
||||||
int64_t h9 = (load_3(s + 29) & 8388607) << 2;
|
int64_t h8 = load_3(s + 26) << 4;
|
||||||
int64_t carry0;
|
int64_t h9 = (load_3(s + 29) & 0x7fffff) << 2;
|
||||||
int64_t carry1;
|
int64_t carry0;
|
||||||
int64_t carry2;
|
int64_t carry1;
|
||||||
int64_t carry3;
|
int64_t carry2;
|
||||||
int64_t carry4;
|
int64_t carry3;
|
||||||
int64_t carry5;
|
int64_t carry4;
|
||||||
int64_t carry6;
|
int64_t carry5;
|
||||||
int64_t carry7;
|
int64_t carry6;
|
||||||
int64_t carry8;
|
int64_t carry7;
|
||||||
int64_t carry9;
|
int64_t carry8;
|
||||||
|
int64_t carry9;
|
||||||
|
|
||||||
carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
|
carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
|
||||||
carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
|
carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
|
||||||
carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
|
carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
|
||||||
carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
|
carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
|
||||||
carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
|
carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
|
||||||
|
|
||||||
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
||||||
carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
|
carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
|
||||||
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
||||||
carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
|
carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
|
||||||
carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
|
carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
|
||||||
|
|
||||||
h[0] = (int32_t)h0;
|
h[0] = (int32_t)h0;
|
||||||
h[1] = (int32_t)h1;
|
h[1] = (int32_t)h1;
|
||||||
h[2] = (int32_t)h2;
|
h[2] = (int32_t)h2;
|
||||||
h[3] = (int32_t)h3;
|
h[3] = (int32_t)h3;
|
||||||
h[4] = (int32_t)h4;
|
h[4] = (int32_t)h4;
|
||||||
h[5] = (int32_t)h5;
|
h[5] = (int32_t)h5;
|
||||||
h[6] = (int32_t)h6;
|
h[6] = (int32_t)h6;
|
||||||
h[7] = (int32_t)h7;
|
h[7] = (int32_t)h7;
|
||||||
h[8] = (int32_t)h8;
|
h[8] = (int32_t)h8;
|
||||||
h[9] = (int32_t)h9;
|
h[9] = (int32_t)h9;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Preconditions:
|
/*
|
||||||
* |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
* Preconditions:
|
||||||
|
* |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||||
*
|
*
|
||||||
* Write p=2^255-19; q=floor(h/p).
|
* Write p=2^255-19; q=floor(h/p).
|
||||||
* Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
|
* Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
|
||||||
@@ -848,102 +856,112 @@ static void fe_frombytes(fe h, const uint8_t *s) {
|
|||||||
* Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
|
* Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
|
||||||
*
|
*
|
||||||
* Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
|
* Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
|
||||||
* so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q. */
|
* so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
|
||||||
static void fe_tobytes(uint8_t *s, const fe h) {
|
*/
|
||||||
int32_t h0 = h[0];
|
static void fe_tobytes(uint8_t *s, const fe h)
|
||||||
int32_t h1 = h[1];
|
{
|
||||||
int32_t h2 = h[2];
|
int32_t h0 = h[0];
|
||||||
int32_t h3 = h[3];
|
int32_t h1 = h[1];
|
||||||
int32_t h4 = h[4];
|
int32_t h2 = h[2];
|
||||||
int32_t h5 = h[5];
|
int32_t h3 = h[3];
|
||||||
int32_t h6 = h[6];
|
int32_t h4 = h[4];
|
||||||
int32_t h7 = h[7];
|
int32_t h5 = h[5];
|
||||||
int32_t h8 = h[8];
|
int32_t h6 = h[6];
|
||||||
int32_t h9 = h[9];
|
int32_t h7 = h[7];
|
||||||
int32_t q;
|
int32_t h8 = h[8];
|
||||||
|
int32_t h9 = h[9];
|
||||||
|
int32_t q;
|
||||||
|
|
||||||
q = (19 * h9 + (((int32_t) 1) << 24)) >> 25;
|
q = (19 * h9 + (((int32_t) 1) << 24)) >> 25;
|
||||||
q = (h0 + q) >> 26;
|
q = (h0 + q) >> 26;
|
||||||
q = (h1 + q) >> 25;
|
q = (h1 + q) >> 25;
|
||||||
q = (h2 + q) >> 26;
|
q = (h2 + q) >> 26;
|
||||||
q = (h3 + q) >> 25;
|
q = (h3 + q) >> 25;
|
||||||
q = (h4 + q) >> 26;
|
q = (h4 + q) >> 26;
|
||||||
q = (h5 + q) >> 25;
|
q = (h5 + q) >> 25;
|
||||||
q = (h6 + q) >> 26;
|
q = (h6 + q) >> 26;
|
||||||
q = (h7 + q) >> 25;
|
q = (h7 + q) >> 25;
|
||||||
q = (h8 + q) >> 26;
|
q = (h8 + q) >> 26;
|
||||||
q = (h9 + q) >> 25;
|
q = (h9 + q) >> 25;
|
||||||
|
|
||||||
/* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
|
/* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
|
||||||
h0 += 19 * q;
|
h0 += 19 * q;
|
||||||
/* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
|
/* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
|
||||||
|
|
||||||
h1 += h0 >> 26; h0 &= kBottom26Bits;
|
h1 += h0 >> 26; h0 &= kBottom26Bits;
|
||||||
h2 += h1 >> 25; h1 &= kBottom25Bits;
|
h2 += h1 >> 25; h1 &= kBottom25Bits;
|
||||||
h3 += h2 >> 26; h2 &= kBottom26Bits;
|
h3 += h2 >> 26; h2 &= kBottom26Bits;
|
||||||
h4 += h3 >> 25; h3 &= kBottom25Bits;
|
h4 += h3 >> 25; h3 &= kBottom25Bits;
|
||||||
h5 += h4 >> 26; h4 &= kBottom26Bits;
|
h5 += h4 >> 26; h4 &= kBottom26Bits;
|
||||||
h6 += h5 >> 25; h5 &= kBottom25Bits;
|
h6 += h5 >> 25; h5 &= kBottom25Bits;
|
||||||
h7 += h6 >> 26; h6 &= kBottom26Bits;
|
h7 += h6 >> 26; h6 &= kBottom26Bits;
|
||||||
h8 += h7 >> 25; h7 &= kBottom25Bits;
|
h8 += h7 >> 25; h7 &= kBottom25Bits;
|
||||||
h9 += h8 >> 26; h8 &= kBottom26Bits;
|
h9 += h8 >> 26; h8 &= kBottom26Bits;
|
||||||
h9 &= kBottom25Bits;
|
h9 &= kBottom25Bits;
|
||||||
/* h10 = carry9 */
|
/* h10 = carry9 */
|
||||||
|
|
||||||
/* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
|
/*
|
||||||
* Have h0+...+2^230 h9 between 0 and 2^255-1;
|
* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
|
||||||
* evidently 2^255 h10-2^255 q = 0.
|
* Have h0+...+2^230 h9 between 0 and 2^255-1;
|
||||||
* Goal: Output h0+...+2^230 h9. */
|
* evidently 2^255 h10-2^255 q = 0.
|
||||||
|
* Goal: Output h0+...+2^230 h9.
|
||||||
s[0] = (uint8_t)(h0 >> 0);
|
*/
|
||||||
s[1] = (uint8_t)(h0 >> 8);
|
s[ 0] = (uint8_t) (h0 >> 0);
|
||||||
s[2] = (uint8_t)(h0 >> 16);
|
s[ 1] = (uint8_t) (h0 >> 8);
|
||||||
s[3] = (uint8_t)((h0 >> 24) | ((uint32_t)(h1) << 2));
|
s[ 2] = (uint8_t) (h0 >> 16);
|
||||||
s[4] = (uint8_t)(h1 >> 6);
|
s[ 3] = (uint8_t)((h0 >> 24) | ((uint32_t)(h1) << 2));
|
||||||
s[5] = (uint8_t)(h1 >> 14);
|
s[ 4] = (uint8_t) (h1 >> 6);
|
||||||
s[6] = (uint8_t)((h1 >> 22) | ((uint32_t)(h2) << 3));
|
s[ 5] = (uint8_t) (h1 >> 14);
|
||||||
s[7] = (uint8_t)(h2 >> 5);
|
s[ 6] = (uint8_t)((h1 >> 22) | ((uint32_t)(h2) << 3));
|
||||||
s[8] = (uint8_t)(h2 >> 13);
|
s[ 7] = (uint8_t) (h2 >> 5);
|
||||||
s[9] = (uint8_t)((h2 >> 21) | ((uint32_t)(h3) << 5));
|
s[ 8] = (uint8_t) (h2 >> 13);
|
||||||
s[10] = (uint8_t)(h3 >> 3);
|
s[ 9] = (uint8_t)((h2 >> 21) | ((uint32_t)(h3) << 5));
|
||||||
s[11] = (uint8_t)(h3 >> 11);
|
s[10] = (uint8_t) (h3 >> 3);
|
||||||
s[12] = (uint8_t)((h3 >> 19) | ((uint32_t)(h4) << 6));
|
s[11] = (uint8_t) (h3 >> 11);
|
||||||
s[13] = (uint8_t)(h4 >> 2);
|
s[12] = (uint8_t)((h3 >> 19) | ((uint32_t)(h4) << 6));
|
||||||
s[14] = (uint8_t)(h4 >> 10);
|
s[13] = (uint8_t) (h4 >> 2);
|
||||||
s[15] = (uint8_t)(h4 >> 18);
|
s[14] = (uint8_t) (h4 >> 10);
|
||||||
s[16] = (uint8_t)(h5 >> 0);
|
s[15] = (uint8_t) (h4 >> 18);
|
||||||
s[17] = (uint8_t)(h5 >> 8);
|
s[16] = (uint8_t) (h5 >> 0);
|
||||||
s[18] = (uint8_t)(h5 >> 16);
|
s[17] = (uint8_t) (h5 >> 8);
|
||||||
s[19] = (uint8_t)((h5 >> 24) | ((uint32_t)(h6) << 1));
|
s[18] = (uint8_t) (h5 >> 16);
|
||||||
s[20] = (uint8_t)(h6 >> 7);
|
s[19] = (uint8_t)((h5 >> 24) | ((uint32_t)(h6) << 1));
|
||||||
s[21] = (uint8_t)(h6 >> 15);
|
s[20] = (uint8_t) (h6 >> 7);
|
||||||
s[22] = (uint8_t)((h6 >> 23) | ((uint32_t)(h7) << 3));
|
s[21] = (uint8_t) (h6 >> 15);
|
||||||
s[23] = (uint8_t)(h7 >> 5);
|
s[22] = (uint8_t)((h6 >> 23) | ((uint32_t)(h7) << 3));
|
||||||
s[24] = (uint8_t)(h7 >> 13);
|
s[23] = (uint8_t) (h7 >> 5);
|
||||||
s[25] = (uint8_t)((h7 >> 21) | ((uint32_t)(h8) << 4));
|
s[24] = (uint8_t) (h7 >> 13);
|
||||||
s[26] = (uint8_t)(h8 >> 4);
|
s[25] = (uint8_t)((h7 >> 21) | ((uint32_t)(h8) << 4));
|
||||||
s[27] = (uint8_t)(h8 >> 12);
|
s[26] = (uint8_t) (h8 >> 4);
|
||||||
s[28] = (uint8_t)((h8 >> 20) | ((uint32_t)(h9) << 6));
|
s[27] = (uint8_t) (h8 >> 12);
|
||||||
s[29] = (uint8_t)(h9 >> 2);
|
s[28] = (uint8_t)((h8 >> 20) | ((uint32_t)(h9) << 6));
|
||||||
s[30] = (uint8_t)(h9 >> 10);
|
s[29] = (uint8_t) (h9 >> 2);
|
||||||
s[31] = (uint8_t)(h9 >> 18);
|
s[30] = (uint8_t) (h9 >> 10);
|
||||||
|
s[31] = (uint8_t) (h9 >> 18);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* h = f */
|
/* h = f */
|
||||||
static void fe_copy(fe h, const fe f) {
|
static void fe_copy(fe h, const fe f)
|
||||||
memmove(h, f, sizeof(int32_t) * 10);
|
{
|
||||||
|
memmove(h, f, sizeof(int32_t) * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* h = 0 */
|
/* h = 0 */
|
||||||
static void fe_0(fe h) { memset(h, 0, sizeof(int32_t) * 10); }
|
static void fe_0(fe h)
|
||||||
|
{
|
||||||
|
memset(h, 0, sizeof(int32_t) * 10);
|
||||||
|
}
|
||||||
|
|
||||||
/* h = 1 */
|
/* h = 1 */
|
||||||
static void fe_1(fe h) {
|
static void fe_1(fe h)
|
||||||
memset(h, 0, sizeof(int32_t) * 10);
|
{
|
||||||
h[0] = 1;
|
memset(h, 0, sizeof(int32_t) * 10);
|
||||||
|
h[0] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* h = f + g
|
/*
|
||||||
|
* h = f + g
|
||||||
|
*
|
||||||
* Can overlap h with f or g.
|
* Can overlap h with f or g.
|
||||||
*
|
*
|
||||||
* Preconditions:
|
* Preconditions:
|
||||||
@@ -951,15 +969,20 @@ static void fe_1(fe h) {
|
|||||||
* |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
* |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||||
*
|
*
|
||||||
* Postconditions:
|
* Postconditions:
|
||||||
* |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
|
* |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||||
static void fe_add(fe h, const fe f, const fe g) {
|
*/
|
||||||
unsigned i;
|
static void fe_add(fe h, const fe f, const fe g)
|
||||||
for (i = 0; i < 10; i++) {
|
{
|
||||||
h[i] = f[i] + g[i];
|
unsigned i;
|
||||||
}
|
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
h[i] = f[i] + g[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* h = f - g
|
/*
|
||||||
|
* h = f - g
|
||||||
|
*
|
||||||
* Can overlap h with f or g.
|
* Can overlap h with f or g.
|
||||||
*
|
*
|
||||||
* Preconditions:
|
* Preconditions:
|
||||||
@@ -967,15 +990,20 @@ static void fe_add(fe h, const fe f, const fe g) {
|
|||||||
* |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
* |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||||
*
|
*
|
||||||
* Postconditions:
|
* Postconditions:
|
||||||
* |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
|
* |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||||
static void fe_sub(fe h, const fe f, const fe g) {
|
*/
|
||||||
unsigned i;
|
static void fe_sub(fe h, const fe f, const fe g)
|
||||||
for (i = 0; i < 10; i++) {
|
{
|
||||||
h[i] = f[i] - g[i];
|
unsigned i;
|
||||||
}
|
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
h[i] = f[i] - g[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* h = f * g
|
/*
|
||||||
|
* h = f * g
|
||||||
|
*
|
||||||
* Can overlap h with f or g.
|
* Can overlap h with f or g.
|
||||||
*
|
*
|
||||||
* Preconditions:
|
* Preconditions:
|
||||||
@@ -1001,224 +1029,228 @@ static void fe_sub(fe h, const fe f, const fe g) {
|
|||||||
* 10 of them are 2-way parallelizable and vectorizable.
|
* 10 of them are 2-way parallelizable and vectorizable.
|
||||||
* Can get away with 11 carries, but then data flow is much deeper.
|
* Can get away with 11 carries, but then data flow is much deeper.
|
||||||
*
|
*
|
||||||
* With tighter constraints on inputs can squeeze carries into int32. */
|
* With tighter constraints on inputs can squeeze carries into int32.
|
||||||
static void fe_mul(fe h, const fe f, const fe g) {
|
*/
|
||||||
int32_t f0 = f[0];
|
static void fe_mul(fe h, const fe f, const fe g)
|
||||||
int32_t f1 = f[1];
|
{
|
||||||
int32_t f2 = f[2];
|
int32_t f0 = f[0];
|
||||||
int32_t f3 = f[3];
|
int32_t f1 = f[1];
|
||||||
int32_t f4 = f[4];
|
int32_t f2 = f[2];
|
||||||
int32_t f5 = f[5];
|
int32_t f3 = f[3];
|
||||||
int32_t f6 = f[6];
|
int32_t f4 = f[4];
|
||||||
int32_t f7 = f[7];
|
int32_t f5 = f[5];
|
||||||
int32_t f8 = f[8];
|
int32_t f6 = f[6];
|
||||||
int32_t f9 = f[9];
|
int32_t f7 = f[7];
|
||||||
int32_t g0 = g[0];
|
int32_t f8 = f[8];
|
||||||
int32_t g1 = g[1];
|
int32_t f9 = f[9];
|
||||||
int32_t g2 = g[2];
|
int32_t g0 = g[0];
|
||||||
int32_t g3 = g[3];
|
int32_t g1 = g[1];
|
||||||
int32_t g4 = g[4];
|
int32_t g2 = g[2];
|
||||||
int32_t g5 = g[5];
|
int32_t g3 = g[3];
|
||||||
int32_t g6 = g[6];
|
int32_t g4 = g[4];
|
||||||
int32_t g7 = g[7];
|
int32_t g5 = g[5];
|
||||||
int32_t g8 = g[8];
|
int32_t g6 = g[6];
|
||||||
int32_t g9 = g[9];
|
int32_t g7 = g[7];
|
||||||
int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */
|
int32_t g8 = g[8];
|
||||||
int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
|
int32_t g9 = g[9];
|
||||||
int32_t g3_19 = 19 * g3;
|
int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */
|
||||||
int32_t g4_19 = 19 * g4;
|
int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
|
||||||
int32_t g5_19 = 19 * g5;
|
int32_t g3_19 = 19 * g3;
|
||||||
int32_t g6_19 = 19 * g6;
|
int32_t g4_19 = 19 * g4;
|
||||||
int32_t g7_19 = 19 * g7;
|
int32_t g5_19 = 19 * g5;
|
||||||
int32_t g8_19 = 19 * g8;
|
int32_t g6_19 = 19 * g6;
|
||||||
int32_t g9_19 = 19 * g9;
|
int32_t g7_19 = 19 * g7;
|
||||||
int32_t f1_2 = 2 * f1;
|
int32_t g8_19 = 19 * g8;
|
||||||
int32_t f3_2 = 2 * f3;
|
int32_t g9_19 = 19 * g9;
|
||||||
int32_t f5_2 = 2 * f5;
|
int32_t f1_2 = 2 * f1;
|
||||||
int32_t f7_2 = 2 * f7;
|
int32_t f3_2 = 2 * f3;
|
||||||
int32_t f9_2 = 2 * f9;
|
int32_t f5_2 = 2 * f5;
|
||||||
int64_t f0g0 = f0 * (int64_t) g0;
|
int32_t f7_2 = 2 * f7;
|
||||||
int64_t f0g1 = f0 * (int64_t) g1;
|
int32_t f9_2 = 2 * f9;
|
||||||
int64_t f0g2 = f0 * (int64_t) g2;
|
int64_t f0g0 = f0 * (int64_t) g0;
|
||||||
int64_t f0g3 = f0 * (int64_t) g3;
|
int64_t f0g1 = f0 * (int64_t) g1;
|
||||||
int64_t f0g4 = f0 * (int64_t) g4;
|
int64_t f0g2 = f0 * (int64_t) g2;
|
||||||
int64_t f0g5 = f0 * (int64_t) g5;
|
int64_t f0g3 = f0 * (int64_t) g3;
|
||||||
int64_t f0g6 = f0 * (int64_t) g6;
|
int64_t f0g4 = f0 * (int64_t) g4;
|
||||||
int64_t f0g7 = f0 * (int64_t) g7;
|
int64_t f0g5 = f0 * (int64_t) g5;
|
||||||
int64_t f0g8 = f0 * (int64_t) g8;
|
int64_t f0g6 = f0 * (int64_t) g6;
|
||||||
int64_t f0g9 = f0 * (int64_t) g9;
|
int64_t f0g7 = f0 * (int64_t) g7;
|
||||||
int64_t f1g0 = f1 * (int64_t) g0;
|
int64_t f0g8 = f0 * (int64_t) g8;
|
||||||
int64_t f1g1_2 = f1_2 * (int64_t) g1;
|
int64_t f0g9 = f0 * (int64_t) g9;
|
||||||
int64_t f1g2 = f1 * (int64_t) g2;
|
int64_t f1g0 = f1 * (int64_t) g0;
|
||||||
int64_t f1g3_2 = f1_2 * (int64_t) g3;
|
int64_t f1g1_2 = f1_2 * (int64_t) g1;
|
||||||
int64_t f1g4 = f1 * (int64_t) g4;
|
int64_t f1g2 = f1 * (int64_t) g2;
|
||||||
int64_t f1g5_2 = f1_2 * (int64_t) g5;
|
int64_t f1g3_2 = f1_2 * (int64_t) g3;
|
||||||
int64_t f1g6 = f1 * (int64_t) g6;
|
int64_t f1g4 = f1 * (int64_t) g4;
|
||||||
int64_t f1g7_2 = f1_2 * (int64_t) g7;
|
int64_t f1g5_2 = f1_2 * (int64_t) g5;
|
||||||
int64_t f1g8 = f1 * (int64_t) g8;
|
int64_t f1g6 = f1 * (int64_t) g6;
|
||||||
int64_t f1g9_38 = f1_2 * (int64_t) g9_19;
|
int64_t f1g7_2 = f1_2 * (int64_t) g7;
|
||||||
int64_t f2g0 = f2 * (int64_t) g0;
|
int64_t f1g8 = f1 * (int64_t) g8;
|
||||||
int64_t f2g1 = f2 * (int64_t) g1;
|
int64_t f1g9_38 = f1_2 * (int64_t) g9_19;
|
||||||
int64_t f2g2 = f2 * (int64_t) g2;
|
int64_t f2g0 = f2 * (int64_t) g0;
|
||||||
int64_t f2g3 = f2 * (int64_t) g3;
|
int64_t f2g1 = f2 * (int64_t) g1;
|
||||||
int64_t f2g4 = f2 * (int64_t) g4;
|
int64_t f2g2 = f2 * (int64_t) g2;
|
||||||
int64_t f2g5 = f2 * (int64_t) g5;
|
int64_t f2g3 = f2 * (int64_t) g3;
|
||||||
int64_t f2g6 = f2 * (int64_t) g6;
|
int64_t f2g4 = f2 * (int64_t) g4;
|
||||||
int64_t f2g7 = f2 * (int64_t) g7;
|
int64_t f2g5 = f2 * (int64_t) g5;
|
||||||
int64_t f2g8_19 = f2 * (int64_t) g8_19;
|
int64_t f2g6 = f2 * (int64_t) g6;
|
||||||
int64_t f2g9_19 = f2 * (int64_t) g9_19;
|
int64_t f2g7 = f2 * (int64_t) g7;
|
||||||
int64_t f3g0 = f3 * (int64_t) g0;
|
int64_t f2g8_19 = f2 * (int64_t) g8_19;
|
||||||
int64_t f3g1_2 = f3_2 * (int64_t) g1;
|
int64_t f2g9_19 = f2 * (int64_t) g9_19;
|
||||||
int64_t f3g2 = f3 * (int64_t) g2;
|
int64_t f3g0 = f3 * (int64_t) g0;
|
||||||
int64_t f3g3_2 = f3_2 * (int64_t) g3;
|
int64_t f3g1_2 = f3_2 * (int64_t) g1;
|
||||||
int64_t f3g4 = f3 * (int64_t) g4;
|
int64_t f3g2 = f3 * (int64_t) g2;
|
||||||
int64_t f3g5_2 = f3_2 * (int64_t) g5;
|
int64_t f3g3_2 = f3_2 * (int64_t) g3;
|
||||||
int64_t f3g6 = f3 * (int64_t) g6;
|
int64_t f3g4 = f3 * (int64_t) g4;
|
||||||
int64_t f3g7_38 = f3_2 * (int64_t) g7_19;
|
int64_t f3g5_2 = f3_2 * (int64_t) g5;
|
||||||
int64_t f3g8_19 = f3 * (int64_t) g8_19;
|
int64_t f3g6 = f3 * (int64_t) g6;
|
||||||
int64_t f3g9_38 = f3_2 * (int64_t) g9_19;
|
int64_t f3g7_38 = f3_2 * (int64_t) g7_19;
|
||||||
int64_t f4g0 = f4 * (int64_t) g0;
|
int64_t f3g8_19 = f3 * (int64_t) g8_19;
|
||||||
int64_t f4g1 = f4 * (int64_t) g1;
|
int64_t f3g9_38 = f3_2 * (int64_t) g9_19;
|
||||||
int64_t f4g2 = f4 * (int64_t) g2;
|
int64_t f4g0 = f4 * (int64_t) g0;
|
||||||
int64_t f4g3 = f4 * (int64_t) g3;
|
int64_t f4g1 = f4 * (int64_t) g1;
|
||||||
int64_t f4g4 = f4 * (int64_t) g4;
|
int64_t f4g2 = f4 * (int64_t) g2;
|
||||||
int64_t f4g5 = f4 * (int64_t) g5;
|
int64_t f4g3 = f4 * (int64_t) g3;
|
||||||
int64_t f4g6_19 = f4 * (int64_t) g6_19;
|
int64_t f4g4 = f4 * (int64_t) g4;
|
||||||
int64_t f4g7_19 = f4 * (int64_t) g7_19;
|
int64_t f4g5 = f4 * (int64_t) g5;
|
||||||
int64_t f4g8_19 = f4 * (int64_t) g8_19;
|
int64_t f4g6_19 = f4 * (int64_t) g6_19;
|
||||||
int64_t f4g9_19 = f4 * (int64_t) g9_19;
|
int64_t f4g7_19 = f4 * (int64_t) g7_19;
|
||||||
int64_t f5g0 = f5 * (int64_t) g0;
|
int64_t f4g8_19 = f4 * (int64_t) g8_19;
|
||||||
int64_t f5g1_2 = f5_2 * (int64_t) g1;
|
int64_t f4g9_19 = f4 * (int64_t) g9_19;
|
||||||
int64_t f5g2 = f5 * (int64_t) g2;
|
int64_t f5g0 = f5 * (int64_t) g0;
|
||||||
int64_t f5g3_2 = f5_2 * (int64_t) g3;
|
int64_t f5g1_2 = f5_2 * (int64_t) g1;
|
||||||
int64_t f5g4 = f5 * (int64_t) g4;
|
int64_t f5g2 = f5 * (int64_t) g2;
|
||||||
int64_t f5g5_38 = f5_2 * (int64_t) g5_19;
|
int64_t f5g3_2 = f5_2 * (int64_t) g3;
|
||||||
int64_t f5g6_19 = f5 * (int64_t) g6_19;
|
int64_t f5g4 = f5 * (int64_t) g4;
|
||||||
int64_t f5g7_38 = f5_2 * (int64_t) g7_19;
|
int64_t f5g5_38 = f5_2 * (int64_t) g5_19;
|
||||||
int64_t f5g8_19 = f5 * (int64_t) g8_19;
|
int64_t f5g6_19 = f5 * (int64_t) g6_19;
|
||||||
int64_t f5g9_38 = f5_2 * (int64_t) g9_19;
|
int64_t f5g7_38 = f5_2 * (int64_t) g7_19;
|
||||||
int64_t f6g0 = f6 * (int64_t) g0;
|
int64_t f5g8_19 = f5 * (int64_t) g8_19;
|
||||||
int64_t f6g1 = f6 * (int64_t) g1;
|
int64_t f5g9_38 = f5_2 * (int64_t) g9_19;
|
||||||
int64_t f6g2 = f6 * (int64_t) g2;
|
int64_t f6g0 = f6 * (int64_t) g0;
|
||||||
int64_t f6g3 = f6 * (int64_t) g3;
|
int64_t f6g1 = f6 * (int64_t) g1;
|
||||||
int64_t f6g4_19 = f6 * (int64_t) g4_19;
|
int64_t f6g2 = f6 * (int64_t) g2;
|
||||||
int64_t f6g5_19 = f6 * (int64_t) g5_19;
|
int64_t f6g3 = f6 * (int64_t) g3;
|
||||||
int64_t f6g6_19 = f6 * (int64_t) g6_19;
|
int64_t f6g4_19 = f6 * (int64_t) g4_19;
|
||||||
int64_t f6g7_19 = f6 * (int64_t) g7_19;
|
int64_t f6g5_19 = f6 * (int64_t) g5_19;
|
||||||
int64_t f6g8_19 = f6 * (int64_t) g8_19;
|
int64_t f6g6_19 = f6 * (int64_t) g6_19;
|
||||||
int64_t f6g9_19 = f6 * (int64_t) g9_19;
|
int64_t f6g7_19 = f6 * (int64_t) g7_19;
|
||||||
int64_t f7g0 = f7 * (int64_t) g0;
|
int64_t f6g8_19 = f6 * (int64_t) g8_19;
|
||||||
int64_t f7g1_2 = f7_2 * (int64_t) g1;
|
int64_t f6g9_19 = f6 * (int64_t) g9_19;
|
||||||
int64_t f7g2 = f7 * (int64_t) g2;
|
int64_t f7g0 = f7 * (int64_t) g0;
|
||||||
int64_t f7g3_38 = f7_2 * (int64_t) g3_19;
|
int64_t f7g1_2 = f7_2 * (int64_t) g1;
|
||||||
int64_t f7g4_19 = f7 * (int64_t) g4_19;
|
int64_t f7g2 = f7 * (int64_t) g2;
|
||||||
int64_t f7g5_38 = f7_2 * (int64_t) g5_19;
|
int64_t f7g3_38 = f7_2 * (int64_t) g3_19;
|
||||||
int64_t f7g6_19 = f7 * (int64_t) g6_19;
|
int64_t f7g4_19 = f7 * (int64_t) g4_19;
|
||||||
int64_t f7g7_38 = f7_2 * (int64_t) g7_19;
|
int64_t f7g5_38 = f7_2 * (int64_t) g5_19;
|
||||||
int64_t f7g8_19 = f7 * (int64_t) g8_19;
|
int64_t f7g6_19 = f7 * (int64_t) g6_19;
|
||||||
int64_t f7g9_38 = f7_2 * (int64_t) g9_19;
|
int64_t f7g7_38 = f7_2 * (int64_t) g7_19;
|
||||||
int64_t f8g0 = f8 * (int64_t) g0;
|
int64_t f7g8_19 = f7 * (int64_t) g8_19;
|
||||||
int64_t f8g1 = f8 * (int64_t) g1;
|
int64_t f7g9_38 = f7_2 * (int64_t) g9_19;
|
||||||
int64_t f8g2_19 = f8 * (int64_t) g2_19;
|
int64_t f8g0 = f8 * (int64_t) g0;
|
||||||
int64_t f8g3_19 = f8 * (int64_t) g3_19;
|
int64_t f8g1 = f8 * (int64_t) g1;
|
||||||
int64_t f8g4_19 = f8 * (int64_t) g4_19;
|
int64_t f8g2_19 = f8 * (int64_t) g2_19;
|
||||||
int64_t f8g5_19 = f8 * (int64_t) g5_19;
|
int64_t f8g3_19 = f8 * (int64_t) g3_19;
|
||||||
int64_t f8g6_19 = f8 * (int64_t) g6_19;
|
int64_t f8g4_19 = f8 * (int64_t) g4_19;
|
||||||
int64_t f8g7_19 = f8 * (int64_t) g7_19;
|
int64_t f8g5_19 = f8 * (int64_t) g5_19;
|
||||||
int64_t f8g8_19 = f8 * (int64_t) g8_19;
|
int64_t f8g6_19 = f8 * (int64_t) g6_19;
|
||||||
int64_t f8g9_19 = f8 * (int64_t) g9_19;
|
int64_t f8g7_19 = f8 * (int64_t) g7_19;
|
||||||
int64_t f9g0 = f9 * (int64_t) g0;
|
int64_t f8g8_19 = f8 * (int64_t) g8_19;
|
||||||
int64_t f9g1_38 = f9_2 * (int64_t) g1_19;
|
int64_t f8g9_19 = f8 * (int64_t) g9_19;
|
||||||
int64_t f9g2_19 = f9 * (int64_t) g2_19;
|
int64_t f9g0 = f9 * (int64_t) g0;
|
||||||
int64_t f9g3_38 = f9_2 * (int64_t) g3_19;
|
int64_t f9g1_38 = f9_2 * (int64_t) g1_19;
|
||||||
int64_t f9g4_19 = f9 * (int64_t) g4_19;
|
int64_t f9g2_19 = f9 * (int64_t) g2_19;
|
||||||
int64_t f9g5_38 = f9_2 * (int64_t) g5_19;
|
int64_t f9g3_38 = f9_2 * (int64_t) g3_19;
|
||||||
int64_t f9g6_19 = f9 * (int64_t) g6_19;
|
int64_t f9g4_19 = f9 * (int64_t) g4_19;
|
||||||
int64_t f9g7_38 = f9_2 * (int64_t) g7_19;
|
int64_t f9g5_38 = f9_2 * (int64_t) g5_19;
|
||||||
int64_t f9g8_19 = f9 * (int64_t) g8_19;
|
int64_t f9g6_19 = f9 * (int64_t) g6_19;
|
||||||
int64_t f9g9_38 = f9_2 * (int64_t) g9_19;
|
int64_t f9g7_38 = f9_2 * (int64_t) g7_19;
|
||||||
int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38;
|
int64_t f9g8_19 = f9 * (int64_t) g8_19;
|
||||||
int64_t h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19;
|
int64_t f9g9_38 = f9_2 * (int64_t) g9_19;
|
||||||
int64_t h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38;
|
int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38;
|
||||||
int64_t h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19;
|
int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19;
|
||||||
int64_t h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38;
|
int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38;
|
||||||
int64_t h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19;
|
int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19;
|
||||||
int64_t h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38;
|
int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38;
|
||||||
int64_t h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19;
|
int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19;
|
||||||
int64_t h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38;
|
int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38;
|
||||||
int64_t h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ;
|
int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19;
|
||||||
int64_t carry0;
|
int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38;
|
||||||
int64_t carry1;
|
int64_t h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 ;
|
||||||
int64_t carry2;
|
int64_t carry0;
|
||||||
int64_t carry3;
|
int64_t carry1;
|
||||||
int64_t carry4;
|
int64_t carry2;
|
||||||
int64_t carry5;
|
int64_t carry3;
|
||||||
int64_t carry6;
|
int64_t carry4;
|
||||||
int64_t carry7;
|
int64_t carry5;
|
||||||
int64_t carry8;
|
int64_t carry6;
|
||||||
int64_t carry9;
|
int64_t carry7;
|
||||||
|
int64_t carry8;
|
||||||
|
int64_t carry9;
|
||||||
|
|
||||||
/* |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))
|
/* |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))
|
||||||
* i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8
|
* i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8
|
||||||
* |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
|
* |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
|
||||||
* i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 */
|
* i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 */
|
||||||
|
|
||||||
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
||||||
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
||||||
/* |h0| <= 2^25 */
|
/* |h0| <= 2^25 */
|
||||||
/* |h4| <= 2^25 */
|
/* |h4| <= 2^25 */
|
||||||
/* |h1| <= 1.71*2^59 */
|
/* |h1| <= 1.71*2^59 */
|
||||||
/* |h5| <= 1.71*2^59 */
|
/* |h5| <= 1.71*2^59 */
|
||||||
|
|
||||||
carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
|
carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
|
||||||
carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
|
carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
|
||||||
/* |h1| <= 2^24; from now on fits into int32 */
|
/* |h1| <= 2^24; from now on fits into int32 */
|
||||||
/* |h5| <= 2^24; from now on fits into int32 */
|
/* |h5| <= 2^24; from now on fits into int32 */
|
||||||
/* |h2| <= 1.41*2^60 */
|
/* |h2| <= 1.41*2^60 */
|
||||||
/* |h6| <= 1.41*2^60 */
|
/* |h6| <= 1.41*2^60 */
|
||||||
|
|
||||||
carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
|
carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
|
||||||
carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
|
carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
|
||||||
/* |h2| <= 2^25; from now on fits into int32 unchanged */
|
/* |h2| <= 2^25; from now on fits into int32 unchanged */
|
||||||
/* |h6| <= 2^25; from now on fits into int32 unchanged */
|
/* |h6| <= 2^25; from now on fits into int32 unchanged */
|
||||||
/* |h3| <= 1.71*2^59 */
|
/* |h3| <= 1.71*2^59 */
|
||||||
/* |h7| <= 1.71*2^59 */
|
/* |h7| <= 1.71*2^59 */
|
||||||
|
|
||||||
carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
|
carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
|
||||||
carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
|
carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
|
||||||
/* |h3| <= 2^24; from now on fits into int32 unchanged */
|
/* |h3| <= 2^24; from now on fits into int32 unchanged */
|
||||||
/* |h7| <= 2^24; from now on fits into int32 unchanged */
|
/* |h7| <= 2^24; from now on fits into int32 unchanged */
|
||||||
/* |h4| <= 1.72*2^34 */
|
/* |h4| <= 1.72*2^34 */
|
||||||
/* |h8| <= 1.41*2^60 */
|
/* |h8| <= 1.41*2^60 */
|
||||||
|
|
||||||
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
||||||
carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
|
carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
|
||||||
/* |h4| <= 2^25; from now on fits into int32 unchanged */
|
/* |h4| <= 2^25; from now on fits into int32 unchanged */
|
||||||
/* |h8| <= 2^25; from now on fits into int32 unchanged */
|
/* |h8| <= 2^25; from now on fits into int32 unchanged */
|
||||||
/* |h5| <= 1.01*2^24 */
|
/* |h5| <= 1.01*2^24 */
|
||||||
/* |h9| <= 1.71*2^59 */
|
/* |h9| <= 1.71*2^59 */
|
||||||
|
|
||||||
carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
|
carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
|
||||||
/* |h9| <= 2^24; from now on fits into int32 unchanged */
|
/* |h9| <= 2^24; from now on fits into int32 unchanged */
|
||||||
/* |h0| <= 1.1*2^39 */
|
/* |h0| <= 1.1*2^39 */
|
||||||
|
|
||||||
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
||||||
/* |h0| <= 2^25; from now on fits into int32 unchanged */
|
/* |h0| <= 2^25; from now on fits into int32 unchanged */
|
||||||
/* |h1| <= 1.01*2^24 */
|
/* |h1| <= 1.01*2^24 */
|
||||||
|
|
||||||
h[0] = (int32_t)h0;
|
h[0] = (int32_t)h0;
|
||||||
h[1] = (int32_t)h1;
|
h[1] = (int32_t)h1;
|
||||||
h[2] = (int32_t)h2;
|
h[2] = (int32_t)h2;
|
||||||
h[3] = (int32_t)h3;
|
h[3] = (int32_t)h3;
|
||||||
h[4] = (int32_t)h4;
|
h[4] = (int32_t)h4;
|
||||||
h[5] = (int32_t)h5;
|
h[5] = (int32_t)h5;
|
||||||
h[6] = (int32_t)h6;
|
h[6] = (int32_t)h6;
|
||||||
h[7] = (int32_t)h7;
|
h[7] = (int32_t)h7;
|
||||||
h[8] = (int32_t)h8;
|
h[8] = (int32_t)h8;
|
||||||
h[9] = (int32_t)h9;
|
h[9] = (int32_t)h9;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* h = f * f
|
/*
|
||||||
|
* h = f * f
|
||||||
|
*
|
||||||
* Can overlap h with f.
|
* Can overlap h with f.
|
||||||
*
|
*
|
||||||
* Preconditions:
|
* Preconditions:
|
||||||
@@ -1227,286 +1259,307 @@ static void fe_mul(fe h, const fe f, const fe g) {
|
|||||||
* Postconditions:
|
* Postconditions:
|
||||||
* |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
|
* |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
|
||||||
*
|
*
|
||||||
* See fe_mul.c for discussion of implementation strategy. */
|
* See fe_mul.c for discussion of implementation strategy.
|
||||||
static void fe_sq(fe h, const fe f) {
|
*/
|
||||||
int32_t f0 = f[0];
|
static void fe_sq(fe h, const fe f)
|
||||||
int32_t f1 = f[1];
|
{
|
||||||
int32_t f2 = f[2];
|
int32_t f0 = f[0];
|
||||||
int32_t f3 = f[3];
|
int32_t f1 = f[1];
|
||||||
int32_t f4 = f[4];
|
int32_t f2 = f[2];
|
||||||
int32_t f5 = f[5];
|
int32_t f3 = f[3];
|
||||||
int32_t f6 = f[6];
|
int32_t f4 = f[4];
|
||||||
int32_t f7 = f[7];
|
int32_t f5 = f[5];
|
||||||
int32_t f8 = f[8];
|
int32_t f6 = f[6];
|
||||||
int32_t f9 = f[9];
|
int32_t f7 = f[7];
|
||||||
int32_t f0_2 = 2 * f0;
|
int32_t f8 = f[8];
|
||||||
int32_t f1_2 = 2 * f1;
|
int32_t f9 = f[9];
|
||||||
int32_t f2_2 = 2 * f2;
|
int32_t f0_2 = 2 * f0;
|
||||||
int32_t f3_2 = 2 * f3;
|
int32_t f1_2 = 2 * f1;
|
||||||
int32_t f4_2 = 2 * f4;
|
int32_t f2_2 = 2 * f2;
|
||||||
int32_t f5_2 = 2 * f5;
|
int32_t f3_2 = 2 * f3;
|
||||||
int32_t f6_2 = 2 * f6;
|
int32_t f4_2 = 2 * f4;
|
||||||
int32_t f7_2 = 2 * f7;
|
int32_t f5_2 = 2 * f5;
|
||||||
int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
|
int32_t f6_2 = 2 * f6;
|
||||||
int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
|
int32_t f7_2 = 2 * f7;
|
||||||
int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
|
int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
|
||||||
int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
|
int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
|
||||||
int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
|
int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
|
||||||
int64_t f0f0 = f0 * (int64_t) f0;
|
int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
|
||||||
int64_t f0f1_2 = f0_2 * (int64_t) f1;
|
int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
|
||||||
int64_t f0f2_2 = f0_2 * (int64_t) f2;
|
int64_t f0f0 = f0 * (int64_t) f0;
|
||||||
int64_t f0f3_2 = f0_2 * (int64_t) f3;
|
int64_t f0f1_2 = f0_2 * (int64_t) f1;
|
||||||
int64_t f0f4_2 = f0_2 * (int64_t) f4;
|
int64_t f0f2_2 = f0_2 * (int64_t) f2;
|
||||||
int64_t f0f5_2 = f0_2 * (int64_t) f5;
|
int64_t f0f3_2 = f0_2 * (int64_t) f3;
|
||||||
int64_t f0f6_2 = f0_2 * (int64_t) f6;
|
int64_t f0f4_2 = f0_2 * (int64_t) f4;
|
||||||
int64_t f0f7_2 = f0_2 * (int64_t) f7;
|
int64_t f0f5_2 = f0_2 * (int64_t) f5;
|
||||||
int64_t f0f8_2 = f0_2 * (int64_t) f8;
|
int64_t f0f6_2 = f0_2 * (int64_t) f6;
|
||||||
int64_t f0f9_2 = f0_2 * (int64_t) f9;
|
int64_t f0f7_2 = f0_2 * (int64_t) f7;
|
||||||
int64_t f1f1_2 = f1_2 * (int64_t) f1;
|
int64_t f0f8_2 = f0_2 * (int64_t) f8;
|
||||||
int64_t f1f2_2 = f1_2 * (int64_t) f2;
|
int64_t f0f9_2 = f0_2 * (int64_t) f9;
|
||||||
int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
|
int64_t f1f1_2 = f1_2 * (int64_t) f1;
|
||||||
int64_t f1f4_2 = f1_2 * (int64_t) f4;
|
int64_t f1f2_2 = f1_2 * (int64_t) f2;
|
||||||
int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
|
int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
|
||||||
int64_t f1f6_2 = f1_2 * (int64_t) f6;
|
int64_t f1f4_2 = f1_2 * (int64_t) f4;
|
||||||
int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
|
int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
|
||||||
int64_t f1f8_2 = f1_2 * (int64_t) f8;
|
int64_t f1f6_2 = f1_2 * (int64_t) f6;
|
||||||
int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
|
int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
|
||||||
int64_t f2f2 = f2 * (int64_t) f2;
|
int64_t f1f8_2 = f1_2 * (int64_t) f8;
|
||||||
int64_t f2f3_2 = f2_2 * (int64_t) f3;
|
int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
|
||||||
int64_t f2f4_2 = f2_2 * (int64_t) f4;
|
int64_t f2f2 = f2 * (int64_t) f2;
|
||||||
int64_t f2f5_2 = f2_2 * (int64_t) f5;
|
int64_t f2f3_2 = f2_2 * (int64_t) f3;
|
||||||
int64_t f2f6_2 = f2_2 * (int64_t) f6;
|
int64_t f2f4_2 = f2_2 * (int64_t) f4;
|
||||||
int64_t f2f7_2 = f2_2 * (int64_t) f7;
|
int64_t f2f5_2 = f2_2 * (int64_t) f5;
|
||||||
int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
|
int64_t f2f6_2 = f2_2 * (int64_t) f6;
|
||||||
int64_t f2f9_38 = f2 * (int64_t) f9_38;
|
int64_t f2f7_2 = f2_2 * (int64_t) f7;
|
||||||
int64_t f3f3_2 = f3_2 * (int64_t) f3;
|
int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
|
||||||
int64_t f3f4_2 = f3_2 * (int64_t) f4;
|
int64_t f2f9_38 = f2 * (int64_t) f9_38;
|
||||||
int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
|
int64_t f3f3_2 = f3_2 * (int64_t) f3;
|
||||||
int64_t f3f6_2 = f3_2 * (int64_t) f6;
|
int64_t f3f4_2 = f3_2 * (int64_t) f4;
|
||||||
int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
|
int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
|
||||||
int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
|
int64_t f3f6_2 = f3_2 * (int64_t) f6;
|
||||||
int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
|
int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
|
||||||
int64_t f4f4 = f4 * (int64_t) f4;
|
int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
|
||||||
int64_t f4f5_2 = f4_2 * (int64_t) f5;
|
int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
|
||||||
int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
|
int64_t f4f4 = f4 * (int64_t) f4;
|
||||||
int64_t f4f7_38 = f4 * (int64_t) f7_38;
|
int64_t f4f5_2 = f4_2 * (int64_t) f5;
|
||||||
int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
|
int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
|
||||||
int64_t f4f9_38 = f4 * (int64_t) f9_38;
|
int64_t f4f7_38 = f4 * (int64_t) f7_38;
|
||||||
int64_t f5f5_38 = f5 * (int64_t) f5_38;
|
int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
|
||||||
int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
|
int64_t f4f9_38 = f4 * (int64_t) f9_38;
|
||||||
int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
|
int64_t f5f5_38 = f5 * (int64_t) f5_38;
|
||||||
int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
|
int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
|
||||||
int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
|
int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
|
||||||
int64_t f6f6_19 = f6 * (int64_t) f6_19;
|
int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
|
||||||
int64_t f6f7_38 = f6 * (int64_t) f7_38;
|
int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
|
||||||
int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
|
int64_t f6f6_19 = f6 * (int64_t) f6_19;
|
||||||
int64_t f6f9_38 = f6 * (int64_t) f9_38;
|
int64_t f6f7_38 = f6 * (int64_t) f7_38;
|
||||||
int64_t f7f7_38 = f7 * (int64_t) f7_38;
|
int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
|
||||||
int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
|
int64_t f6f9_38 = f6 * (int64_t) f9_38;
|
||||||
int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
|
int64_t f7f7_38 = f7 * (int64_t) f7_38;
|
||||||
int64_t f8f8_19 = f8 * (int64_t) f8_19;
|
int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
|
||||||
int64_t f8f9_38 = f8 * (int64_t) f9_38;
|
int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
|
||||||
int64_t f9f9_38 = f9 * (int64_t) f9_38;
|
int64_t f8f8_19 = f8 * (int64_t) f8_19;
|
||||||
int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
|
int64_t f8f9_38 = f8 * (int64_t) f9_38;
|
||||||
int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
|
int64_t f9f9_38 = f9 * (int64_t) f9_38;
|
||||||
int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
|
int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
|
||||||
int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
|
int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
|
||||||
int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
|
int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
|
||||||
int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
|
int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
|
||||||
int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
|
int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
|
||||||
int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
|
int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
|
||||||
int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
|
int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
|
||||||
int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
|
int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
|
||||||
int64_t carry0;
|
int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
|
||||||
int64_t carry1;
|
int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
|
||||||
int64_t carry2;
|
int64_t carry0;
|
||||||
int64_t carry3;
|
int64_t carry1;
|
||||||
int64_t carry4;
|
int64_t carry2;
|
||||||
int64_t carry5;
|
int64_t carry3;
|
||||||
int64_t carry6;
|
int64_t carry4;
|
||||||
int64_t carry7;
|
int64_t carry5;
|
||||||
int64_t carry8;
|
int64_t carry6;
|
||||||
int64_t carry9;
|
int64_t carry7;
|
||||||
|
int64_t carry8;
|
||||||
|
int64_t carry9;
|
||||||
|
|
||||||
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
||||||
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
||||||
|
|
||||||
carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
|
carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
|
||||||
carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
|
carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
|
||||||
|
|
||||||
carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
|
carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
|
||||||
carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
|
carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
|
||||||
|
|
||||||
carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
|
carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
|
||||||
carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
|
carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
|
||||||
|
|
||||||
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
||||||
carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
|
carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
|
||||||
|
|
||||||
carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
|
carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
|
||||||
|
|
||||||
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
||||||
|
|
||||||
h[0] = (int32_t)h0;
|
h[0] = (int32_t)h0;
|
||||||
h[1] = (int32_t)h1;
|
h[1] = (int32_t)h1;
|
||||||
h[2] = (int32_t)h2;
|
h[2] = (int32_t)h2;
|
||||||
h[3] = (int32_t)h3;
|
h[3] = (int32_t)h3;
|
||||||
h[4] = (int32_t)h4;
|
h[4] = (int32_t)h4;
|
||||||
h[5] = (int32_t)h5;
|
h[5] = (int32_t)h5;
|
||||||
h[6] = (int32_t)h6;
|
h[6] = (int32_t)h6;
|
||||||
h[7] = (int32_t)h7;
|
h[7] = (int32_t)h7;
|
||||||
h[8] = (int32_t)h8;
|
h[8] = (int32_t)h8;
|
||||||
h[9] = (int32_t)h9;
|
h[9] = (int32_t)h9;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fe_invert(fe out, const fe z) {
|
static void fe_invert(fe out, const fe z)
|
||||||
fe t0;
|
{
|
||||||
fe t1;
|
fe t0;
|
||||||
fe t2;
|
fe t1;
|
||||||
fe t3;
|
fe t2;
|
||||||
int i;
|
fe t3;
|
||||||
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute z ** -1 = z ** (2 ** 255 - 19 - 2) with the exponent as
|
* Compute z ** -1 = z ** (2 ** 255 - 19 - 2) with the exponent as
|
||||||
* 2 ** 255 - 21 = (2 ** 5) * (2 ** 250 - 1) + 11.
|
* 2 ** 255 - 21 = (2 ** 5) * (2 ** 250 - 1) + 11.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* t0 = z ** 2 */
|
/* t0 = z ** 2 */
|
||||||
fe_sq(t0, z);
|
fe_sq(t0, z);
|
||||||
|
|
||||||
/* t1 = t0 ** (2 ** 2) = z ** 8 */
|
/* t1 = t0 ** (2 ** 2) = z ** 8 */
|
||||||
fe_sq(t1, t0);
|
fe_sq(t1, t0);
|
||||||
fe_sq(t1, t1);
|
|
||||||
|
|
||||||
/* t1 = z * t1 = z ** 9 */
|
|
||||||
fe_mul(t1, z, t1);
|
|
||||||
/* t0 = t0 * t1 = z ** 11 -- stash t0 away for the end. */
|
|
||||||
fe_mul(t0, t0, t1);
|
|
||||||
|
|
||||||
/* t2 = t0 ** 2 = z ** 22 */
|
|
||||||
fe_sq(t2, t0);
|
|
||||||
|
|
||||||
/* t1 = t1 * t2 = z ** (2 ** 5 - 1) */
|
|
||||||
fe_mul(t1, t1, t2);
|
|
||||||
|
|
||||||
/* t2 = t1 ** (2 ** 5) = z ** ((2 ** 5) * (2 ** 5 - 1)) */
|
|
||||||
fe_sq(t2, t1);
|
|
||||||
for (i = 1; i < 5; ++i) {
|
|
||||||
fe_sq(t2, t2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* t1 = t1 * t2 = z ** ((2 ** 5 + 1) * (2 ** 5 - 1)) = z ** (2 ** 10 - 1) */
|
|
||||||
fe_mul(t1, t2, t1);
|
|
||||||
|
|
||||||
/* Continuing similarly... */
|
|
||||||
|
|
||||||
/* t2 = z ** (2 ** 20 - 1) */
|
|
||||||
fe_sq(t2, t1);
|
|
||||||
for (i = 1; i < 10; ++i) {
|
|
||||||
fe_sq(t2, t2);
|
|
||||||
}
|
|
||||||
fe_mul(t2, t2, t1);
|
|
||||||
|
|
||||||
/* t2 = z ** (2 ** 40 - 1) */
|
|
||||||
fe_sq(t3, t2);
|
|
||||||
for (i = 1; i < 20; ++i) {
|
|
||||||
fe_sq(t3, t3);
|
|
||||||
}
|
|
||||||
fe_mul(t2, t3, t2);
|
|
||||||
|
|
||||||
/* t2 = z ** (2 ** 10) * (2 ** 40 - 1) */
|
|
||||||
for (i = 0; i < 10; ++i) {
|
|
||||||
fe_sq(t2, t2);
|
|
||||||
}
|
|
||||||
/* t1 = z ** (2 ** 50 - 1) */
|
|
||||||
fe_mul(t1, t2, t1);
|
|
||||||
|
|
||||||
/* t2 = z ** (2 ** 100 - 1) */
|
|
||||||
fe_sq(t2, t1);
|
|
||||||
for (i = 1; i < 50; ++i) {
|
|
||||||
fe_sq(t2, t2);
|
|
||||||
}
|
|
||||||
fe_mul(t2, t2, t1);
|
|
||||||
|
|
||||||
/* t2 = z ** (2 ** 200 - 1) */
|
|
||||||
fe_sq(t3, t2);
|
|
||||||
for (i = 1; i < 100; ++i) {
|
|
||||||
fe_sq(t3, t3);
|
|
||||||
}
|
|
||||||
fe_mul(t2, t3, t2);
|
|
||||||
|
|
||||||
/* t2 = z ** ((2 ** 50) * (2 ** 200 - 1) */
|
|
||||||
fe_sq(t2, t2);
|
|
||||||
for (i = 1; i < 50; ++i) {
|
|
||||||
fe_sq(t2, t2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* t1 = z ** (2 ** 250 - 1) */
|
|
||||||
fe_mul(t1, t2, t1);
|
|
||||||
|
|
||||||
/* t1 = z ** ((2 ** 5) * (2 ** 250 - 1)) */
|
|
||||||
fe_sq(t1, t1);
|
|
||||||
for (i = 1; i < 5; ++i) {
|
|
||||||
fe_sq(t1, t1);
|
fe_sq(t1, t1);
|
||||||
}
|
|
||||||
|
|
||||||
/* Recall t0 = z ** 11; out = z ** (2 ** 255 - 21) */
|
/* t1 = z * t1 = z ** 9 */
|
||||||
fe_mul(out, t1, t0);
|
fe_mul(t1, z, t1);
|
||||||
|
/* t0 = t0 * t1 = z ** 11 -- stash t0 away for the end. */
|
||||||
|
fe_mul(t0, t0, t1);
|
||||||
|
|
||||||
|
/* t2 = t0 ** 2 = z ** 22 */
|
||||||
|
fe_sq(t2, t0);
|
||||||
|
|
||||||
|
/* t1 = t1 * t2 = z ** (2 ** 5 - 1) */
|
||||||
|
fe_mul(t1, t1, t2);
|
||||||
|
|
||||||
|
/* t2 = t1 ** (2 ** 5) = z ** ((2 ** 5) * (2 ** 5 - 1)) */
|
||||||
|
fe_sq(t2, t1);
|
||||||
|
for (i = 1; i < 5; ++i) {
|
||||||
|
fe_sq(t2, t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* t1 = t1 * t2 = z ** ((2 ** 5 + 1) * (2 ** 5 - 1)) = z ** (2 ** 10 - 1) */
|
||||||
|
fe_mul(t1, t2, t1);
|
||||||
|
|
||||||
|
/* Continuing similarly... */
|
||||||
|
|
||||||
|
/* t2 = z ** (2 ** 20 - 1) */
|
||||||
|
fe_sq(t2, t1);
|
||||||
|
for (i = 1; i < 10; ++i) {
|
||||||
|
fe_sq(t2, t2);
|
||||||
|
}
|
||||||
|
fe_mul(t2, t2, t1);
|
||||||
|
|
||||||
|
/* t2 = z ** (2 ** 40 - 1) */
|
||||||
|
fe_sq(t3, t2);
|
||||||
|
for (i = 1; i < 20; ++i) {
|
||||||
|
fe_sq(t3, t3);
|
||||||
|
}
|
||||||
|
fe_mul(t2, t3, t2);
|
||||||
|
|
||||||
|
/* t2 = z ** (2 ** 10) * (2 ** 40 - 1) */
|
||||||
|
for (i = 0; i < 10; ++i) {
|
||||||
|
fe_sq(t2, t2);
|
||||||
|
}
|
||||||
|
/* t1 = z ** (2 ** 50 - 1) */
|
||||||
|
fe_mul(t1, t2, t1);
|
||||||
|
|
||||||
|
/* t2 = z ** (2 ** 100 - 1) */
|
||||||
|
fe_sq(t2, t1);
|
||||||
|
for (i = 1; i < 50; ++i) {
|
||||||
|
fe_sq(t2, t2);
|
||||||
|
}
|
||||||
|
fe_mul(t2, t2, t1);
|
||||||
|
|
||||||
|
/* t2 = z ** (2 ** 200 - 1) */
|
||||||
|
fe_sq(t3, t2);
|
||||||
|
for (i = 1; i < 100; ++i) {
|
||||||
|
fe_sq(t3, t3);
|
||||||
|
}
|
||||||
|
fe_mul(t2, t3, t2);
|
||||||
|
|
||||||
|
/* t2 = z ** ((2 ** 50) * (2 ** 200 - 1) */
|
||||||
|
fe_sq(t2, t2);
|
||||||
|
for (i = 1; i < 50; ++i) {
|
||||||
|
fe_sq(t2, t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* t1 = z ** (2 ** 250 - 1) */
|
||||||
|
fe_mul(t1, t2, t1);
|
||||||
|
|
||||||
|
/* t1 = z ** ((2 ** 5) * (2 ** 250 - 1)) */
|
||||||
|
fe_sq(t1, t1);
|
||||||
|
for (i = 1; i < 5; ++i) {
|
||||||
|
fe_sq(t1, t1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recall t0 = z ** 11; out = z ** (2 ** 255 - 21) */
|
||||||
|
fe_mul(out, t1, t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* h = -f
|
/*
|
||||||
|
* h = -f
|
||||||
*
|
*
|
||||||
* Preconditions:
|
* Preconditions:
|
||||||
* |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
* |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||||
*
|
*
|
||||||
* Postconditions:
|
* Postconditions:
|
||||||
* |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */
|
* |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||||
static void fe_neg(fe h, const fe f) {
|
*/
|
||||||
unsigned i;
|
static void fe_neg(fe h, const fe f)
|
||||||
for (i = 0; i < 10; i++) {
|
{
|
||||||
h[i] = -f[i];
|
unsigned i;
|
||||||
}
|
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
h[i] = -f[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Replace (f,g) with (g,g) if b == 1;
|
/*
|
||||||
|
* Replace (f,g) with (g,g) if b == 1;
|
||||||
* replace (f,g) with (f,g) if b == 0.
|
* replace (f,g) with (f,g) if b == 0.
|
||||||
*
|
*
|
||||||
* Preconditions: b in {0,1}. */
|
* Preconditions: b in {0,1}.
|
||||||
static void fe_cmov(fe f, const fe g, unsigned b) {
|
*/
|
||||||
size_t i;
|
static void fe_cmov(fe f, const fe g, unsigned b)
|
||||||
b = 0-b;
|
{
|
||||||
for (i = 0; i < 10; i++) {
|
size_t i;
|
||||||
int32_t x = f[i] ^ g[i];
|
|
||||||
x &= b;
|
b = 0-b;
|
||||||
f[i] ^= x;
|
for (i = 0; i < 10; i++) {
|
||||||
}
|
int32_t x = f[i] ^ g[i];
|
||||||
|
x &= b;
|
||||||
|
f[i] ^= x;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return 0 if f == 0
|
/*
|
||||||
|
* return 0 if f == 0
|
||||||
* return 1 if f != 0
|
* return 1 if f != 0
|
||||||
*
|
*
|
||||||
* Preconditions:
|
* Preconditions:
|
||||||
* |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
|
* |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||||
static int fe_isnonzero(const fe f) {
|
*/
|
||||||
uint8_t s[32];
|
static int fe_isnonzero(const fe f)
|
||||||
static const uint8_t zero[32] = {0};
|
{
|
||||||
fe_tobytes(s, f);
|
uint8_t s[32];
|
||||||
|
static const uint8_t zero[32] = {0};
|
||||||
|
|
||||||
return CRYPTO_memcmp(s, zero, sizeof(zero)) != 0;
|
fe_tobytes(s, f);
|
||||||
|
|
||||||
|
return CRYPTO_memcmp(s, zero, sizeof(zero)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return 1 if f is in {1,3,5,...,q-2}
|
/*
|
||||||
|
* return 1 if f is in {1,3,5,...,q-2}
|
||||||
* return 0 if f is in {0,2,4,...,q-1}
|
* return 0 if f is in {0,2,4,...,q-1}
|
||||||
*
|
*
|
||||||
* Preconditions:
|
* Preconditions:
|
||||||
* |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
|
* |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||||
static int fe_isnegative(const fe f) {
|
*/
|
||||||
uint8_t s[32];
|
static int fe_isnegative(const fe f)
|
||||||
fe_tobytes(s, f);
|
{
|
||||||
return s[0] & 1;
|
uint8_t s[32];
|
||||||
|
|
||||||
|
fe_tobytes(s, f);
|
||||||
|
return s[0] & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* h = 2 * f * f
|
/*
|
||||||
|
* h = 2 * f * f
|
||||||
|
*
|
||||||
* Can overlap h with f.
|
* Can overlap h with f.
|
||||||
*
|
*
|
||||||
* Preconditions:
|
* Preconditions:
|
||||||
@@ -1515,208 +1568,212 @@ static int fe_isnegative(const fe f) {
|
|||||||
* Postconditions:
|
* Postconditions:
|
||||||
* |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
|
* |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
|
||||||
*
|
*
|
||||||
* See fe_mul.c for discussion of implementation strategy. */
|
* See fe_mul.c for discussion of implementation strategy.
|
||||||
static void fe_sq2(fe h, const fe f) {
|
*/
|
||||||
int32_t f0 = f[0];
|
static void fe_sq2(fe h, const fe f)
|
||||||
int32_t f1 = f[1];
|
{
|
||||||
int32_t f2 = f[2];
|
int32_t f0 = f[0];
|
||||||
int32_t f3 = f[3];
|
int32_t f1 = f[1];
|
||||||
int32_t f4 = f[4];
|
int32_t f2 = f[2];
|
||||||
int32_t f5 = f[5];
|
int32_t f3 = f[3];
|
||||||
int32_t f6 = f[6];
|
int32_t f4 = f[4];
|
||||||
int32_t f7 = f[7];
|
int32_t f5 = f[5];
|
||||||
int32_t f8 = f[8];
|
int32_t f6 = f[6];
|
||||||
int32_t f9 = f[9];
|
int32_t f7 = f[7];
|
||||||
int32_t f0_2 = 2 * f0;
|
int32_t f8 = f[8];
|
||||||
int32_t f1_2 = 2 * f1;
|
int32_t f9 = f[9];
|
||||||
int32_t f2_2 = 2 * f2;
|
int32_t f0_2 = 2 * f0;
|
||||||
int32_t f3_2 = 2 * f3;
|
int32_t f1_2 = 2 * f1;
|
||||||
int32_t f4_2 = 2 * f4;
|
int32_t f2_2 = 2 * f2;
|
||||||
int32_t f5_2 = 2 * f5;
|
int32_t f3_2 = 2 * f3;
|
||||||
int32_t f6_2 = 2 * f6;
|
int32_t f4_2 = 2 * f4;
|
||||||
int32_t f7_2 = 2 * f7;
|
int32_t f5_2 = 2 * f5;
|
||||||
int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
|
int32_t f6_2 = 2 * f6;
|
||||||
int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
|
int32_t f7_2 = 2 * f7;
|
||||||
int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
|
int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
|
||||||
int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
|
int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
|
||||||
int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
|
int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
|
||||||
int64_t f0f0 = f0 * (int64_t) f0;
|
int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
|
||||||
int64_t f0f1_2 = f0_2 * (int64_t) f1;
|
int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
|
||||||
int64_t f0f2_2 = f0_2 * (int64_t) f2;
|
int64_t f0f0 = f0 * (int64_t) f0;
|
||||||
int64_t f0f3_2 = f0_2 * (int64_t) f3;
|
int64_t f0f1_2 = f0_2 * (int64_t) f1;
|
||||||
int64_t f0f4_2 = f0_2 * (int64_t) f4;
|
int64_t f0f2_2 = f0_2 * (int64_t) f2;
|
||||||
int64_t f0f5_2 = f0_2 * (int64_t) f5;
|
int64_t f0f3_2 = f0_2 * (int64_t) f3;
|
||||||
int64_t f0f6_2 = f0_2 * (int64_t) f6;
|
int64_t f0f4_2 = f0_2 * (int64_t) f4;
|
||||||
int64_t f0f7_2 = f0_2 * (int64_t) f7;
|
int64_t f0f5_2 = f0_2 * (int64_t) f5;
|
||||||
int64_t f0f8_2 = f0_2 * (int64_t) f8;
|
int64_t f0f6_2 = f0_2 * (int64_t) f6;
|
||||||
int64_t f0f9_2 = f0_2 * (int64_t) f9;
|
int64_t f0f7_2 = f0_2 * (int64_t) f7;
|
||||||
int64_t f1f1_2 = f1_2 * (int64_t) f1;
|
int64_t f0f8_2 = f0_2 * (int64_t) f8;
|
||||||
int64_t f1f2_2 = f1_2 * (int64_t) f2;
|
int64_t f0f9_2 = f0_2 * (int64_t) f9;
|
||||||
int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
|
int64_t f1f1_2 = f1_2 * (int64_t) f1;
|
||||||
int64_t f1f4_2 = f1_2 * (int64_t) f4;
|
int64_t f1f2_2 = f1_2 * (int64_t) f2;
|
||||||
int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
|
int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
|
||||||
int64_t f1f6_2 = f1_2 * (int64_t) f6;
|
int64_t f1f4_2 = f1_2 * (int64_t) f4;
|
||||||
int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
|
int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
|
||||||
int64_t f1f8_2 = f1_2 * (int64_t) f8;
|
int64_t f1f6_2 = f1_2 * (int64_t) f6;
|
||||||
int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
|
int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
|
||||||
int64_t f2f2 = f2 * (int64_t) f2;
|
int64_t f1f8_2 = f1_2 * (int64_t) f8;
|
||||||
int64_t f2f3_2 = f2_2 * (int64_t) f3;
|
int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
|
||||||
int64_t f2f4_2 = f2_2 * (int64_t) f4;
|
int64_t f2f2 = f2 * (int64_t) f2;
|
||||||
int64_t f2f5_2 = f2_2 * (int64_t) f5;
|
int64_t f2f3_2 = f2_2 * (int64_t) f3;
|
||||||
int64_t f2f6_2 = f2_2 * (int64_t) f6;
|
int64_t f2f4_2 = f2_2 * (int64_t) f4;
|
||||||
int64_t f2f7_2 = f2_2 * (int64_t) f7;
|
int64_t f2f5_2 = f2_2 * (int64_t) f5;
|
||||||
int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
|
int64_t f2f6_2 = f2_2 * (int64_t) f6;
|
||||||
int64_t f2f9_38 = f2 * (int64_t) f9_38;
|
int64_t f2f7_2 = f2_2 * (int64_t) f7;
|
||||||
int64_t f3f3_2 = f3_2 * (int64_t) f3;
|
int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
|
||||||
int64_t f3f4_2 = f3_2 * (int64_t) f4;
|
int64_t f2f9_38 = f2 * (int64_t) f9_38;
|
||||||
int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
|
int64_t f3f3_2 = f3_2 * (int64_t) f3;
|
||||||
int64_t f3f6_2 = f3_2 * (int64_t) f6;
|
int64_t f3f4_2 = f3_2 * (int64_t) f4;
|
||||||
int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
|
int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
|
||||||
int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
|
int64_t f3f6_2 = f3_2 * (int64_t) f6;
|
||||||
int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
|
int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
|
||||||
int64_t f4f4 = f4 * (int64_t) f4;
|
int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
|
||||||
int64_t f4f5_2 = f4_2 * (int64_t) f5;
|
int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
|
||||||
int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
|
int64_t f4f4 = f4 * (int64_t) f4;
|
||||||
int64_t f4f7_38 = f4 * (int64_t) f7_38;
|
int64_t f4f5_2 = f4_2 * (int64_t) f5;
|
||||||
int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
|
int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
|
||||||
int64_t f4f9_38 = f4 * (int64_t) f9_38;
|
int64_t f4f7_38 = f4 * (int64_t) f7_38;
|
||||||
int64_t f5f5_38 = f5 * (int64_t) f5_38;
|
int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
|
||||||
int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
|
int64_t f4f9_38 = f4 * (int64_t) f9_38;
|
||||||
int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
|
int64_t f5f5_38 = f5 * (int64_t) f5_38;
|
||||||
int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
|
int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
|
||||||
int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
|
int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
|
||||||
int64_t f6f6_19 = f6 * (int64_t) f6_19;
|
int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
|
||||||
int64_t f6f7_38 = f6 * (int64_t) f7_38;
|
int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
|
||||||
int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
|
int64_t f6f6_19 = f6 * (int64_t) f6_19;
|
||||||
int64_t f6f9_38 = f6 * (int64_t) f9_38;
|
int64_t f6f7_38 = f6 * (int64_t) f7_38;
|
||||||
int64_t f7f7_38 = f7 * (int64_t) f7_38;
|
int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
|
||||||
int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
|
int64_t f6f9_38 = f6 * (int64_t) f9_38;
|
||||||
int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
|
int64_t f7f7_38 = f7 * (int64_t) f7_38;
|
||||||
int64_t f8f8_19 = f8 * (int64_t) f8_19;
|
int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
|
||||||
int64_t f8f9_38 = f8 * (int64_t) f9_38;
|
int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
|
||||||
int64_t f9f9_38 = f9 * (int64_t) f9_38;
|
int64_t f8f8_19 = f8 * (int64_t) f8_19;
|
||||||
int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
|
int64_t f8f9_38 = f8 * (int64_t) f9_38;
|
||||||
int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
|
int64_t f9f9_38 = f9 * (int64_t) f9_38;
|
||||||
int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
|
int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
|
||||||
int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
|
int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
|
||||||
int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
|
int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
|
||||||
int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
|
int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
|
||||||
int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
|
int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
|
||||||
int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
|
int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
|
||||||
int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
|
int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
|
||||||
int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
|
int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
|
||||||
int64_t carry0;
|
int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
|
||||||
int64_t carry1;
|
int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
|
||||||
int64_t carry2;
|
int64_t carry0;
|
||||||
int64_t carry3;
|
int64_t carry1;
|
||||||
int64_t carry4;
|
int64_t carry2;
|
||||||
int64_t carry5;
|
int64_t carry3;
|
||||||
int64_t carry6;
|
int64_t carry4;
|
||||||
int64_t carry7;
|
int64_t carry5;
|
||||||
int64_t carry8;
|
int64_t carry6;
|
||||||
int64_t carry9;
|
int64_t carry7;
|
||||||
|
int64_t carry8;
|
||||||
|
int64_t carry9;
|
||||||
|
|
||||||
h0 += h0;
|
h0 += h0;
|
||||||
h1 += h1;
|
h1 += h1;
|
||||||
h2 += h2;
|
h2 += h2;
|
||||||
h3 += h3;
|
h3 += h3;
|
||||||
h4 += h4;
|
h4 += h4;
|
||||||
h5 += h5;
|
h5 += h5;
|
||||||
h6 += h6;
|
h6 += h6;
|
||||||
h7 += h7;
|
h7 += h7;
|
||||||
h8 += h8;
|
h8 += h8;
|
||||||
h9 += h9;
|
h9 += h9;
|
||||||
|
|
||||||
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
||||||
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
||||||
|
|
||||||
carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
|
carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
|
||||||
carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
|
carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
|
||||||
|
|
||||||
carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
|
carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
|
||||||
carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
|
carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
|
||||||
|
|
||||||
carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
|
carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
|
||||||
carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
|
carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
|
||||||
|
|
||||||
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
||||||
carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
|
carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
|
||||||
|
|
||||||
carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
|
carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
|
||||||
|
|
||||||
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
||||||
|
|
||||||
h[0] = (int32_t)h0;
|
h[0] = (int32_t)h0;
|
||||||
h[1] = (int32_t)h1;
|
h[1] = (int32_t)h1;
|
||||||
h[2] = (int32_t)h2;
|
h[2] = (int32_t)h2;
|
||||||
h[3] = (int32_t)h3;
|
h[3] = (int32_t)h3;
|
||||||
h[4] = (int32_t)h4;
|
h[4] = (int32_t)h4;
|
||||||
h[5] = (int32_t)h5;
|
h[5] = (int32_t)h5;
|
||||||
h[6] = (int32_t)h6;
|
h[6] = (int32_t)h6;
|
||||||
h[7] = (int32_t)h7;
|
h[7] = (int32_t)h7;
|
||||||
h[8] = (int32_t)h8;
|
h[8] = (int32_t)h8;
|
||||||
h[9] = (int32_t)h9;
|
h[9] = (int32_t)h9;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fe_pow22523(fe out, const fe z) {
|
static void fe_pow22523(fe out, const fe z)
|
||||||
fe t0;
|
{
|
||||||
fe t1;
|
fe t0;
|
||||||
fe t2;
|
fe t1;
|
||||||
int i;
|
fe t2;
|
||||||
|
int i;
|
||||||
|
|
||||||
fe_sq(t0, z);
|
fe_sq(t0, z);
|
||||||
fe_sq(t1, t0);
|
fe_sq(t1, t0);
|
||||||
for (i = 1; i < 2; ++i) {
|
for (i = 1; i < 2; ++i) {
|
||||||
fe_sq(t1, t1);
|
fe_sq(t1, t1);
|
||||||
}
|
}
|
||||||
fe_mul(t1, z, t1);
|
fe_mul(t1, z, t1);
|
||||||
fe_mul(t0, t0, t1);
|
fe_mul(t0, t0, t1);
|
||||||
fe_sq(t0, t0);
|
|
||||||
fe_mul(t0, t1, t0);
|
|
||||||
fe_sq(t1, t0);
|
|
||||||
for (i = 1; i < 5; ++i) {
|
|
||||||
fe_sq(t1, t1);
|
|
||||||
}
|
|
||||||
fe_mul(t0, t1, t0);
|
|
||||||
fe_sq(t1, t0);
|
|
||||||
for (i = 1; i < 10; ++i) {
|
|
||||||
fe_sq(t1, t1);
|
|
||||||
}
|
|
||||||
fe_mul(t1, t1, t0);
|
|
||||||
fe_sq(t2, t1);
|
|
||||||
for (i = 1; i < 20; ++i) {
|
|
||||||
fe_sq(t2, t2);
|
|
||||||
}
|
|
||||||
fe_mul(t1, t2, t1);
|
|
||||||
fe_sq(t1, t1);
|
|
||||||
for (i = 1; i < 10; ++i) {
|
|
||||||
fe_sq(t1, t1);
|
|
||||||
}
|
|
||||||
fe_mul(t0, t1, t0);
|
|
||||||
fe_sq(t1, t0);
|
|
||||||
for (i = 1; i < 50; ++i) {
|
|
||||||
fe_sq(t1, t1);
|
|
||||||
}
|
|
||||||
fe_mul(t1, t1, t0);
|
|
||||||
fe_sq(t2, t1);
|
|
||||||
for (i = 1; i < 100; ++i) {
|
|
||||||
fe_sq(t2, t2);
|
|
||||||
}
|
|
||||||
fe_mul(t1, t2, t1);
|
|
||||||
fe_sq(t1, t1);
|
|
||||||
for (i = 1; i < 50; ++i) {
|
|
||||||
fe_sq(t1, t1);
|
|
||||||
}
|
|
||||||
fe_mul(t0, t1, t0);
|
|
||||||
fe_sq(t0, t0);
|
|
||||||
for (i = 1; i < 2; ++i) {
|
|
||||||
fe_sq(t0, t0);
|
fe_sq(t0, t0);
|
||||||
}
|
fe_mul(t0, t1, t0);
|
||||||
fe_mul(out, t0, z);
|
fe_sq(t1, t0);
|
||||||
|
for (i = 1; i < 5; ++i) {
|
||||||
|
fe_sq(t1, t1);
|
||||||
|
}
|
||||||
|
fe_mul(t0, t1, t0);
|
||||||
|
fe_sq(t1, t0);
|
||||||
|
for (i = 1; i < 10; ++i) {
|
||||||
|
fe_sq(t1, t1);
|
||||||
|
}
|
||||||
|
fe_mul(t1, t1, t0);
|
||||||
|
fe_sq(t2, t1);
|
||||||
|
for (i = 1; i < 20; ++i) {
|
||||||
|
fe_sq(t2, t2);
|
||||||
|
}
|
||||||
|
fe_mul(t1, t2, t1);
|
||||||
|
fe_sq(t1, t1);
|
||||||
|
for (i = 1; i < 10; ++i) {
|
||||||
|
fe_sq(t1, t1);
|
||||||
|
}
|
||||||
|
fe_mul(t0, t1, t0);
|
||||||
|
fe_sq(t1, t0);
|
||||||
|
for (i = 1; i < 50; ++i) {
|
||||||
|
fe_sq(t1, t1);
|
||||||
|
}
|
||||||
|
fe_mul(t1, t1, t0);
|
||||||
|
fe_sq(t2, t1);
|
||||||
|
for (i = 1; i < 100; ++i) {
|
||||||
|
fe_sq(t2, t2);
|
||||||
|
}
|
||||||
|
fe_mul(t1, t2, t1);
|
||||||
|
fe_sq(t1, t1);
|
||||||
|
for (i = 1; i < 50; ++i) {
|
||||||
|
fe_sq(t1, t1);
|
||||||
|
}
|
||||||
|
fe_mul(t0, t1, t0);
|
||||||
|
fe_sq(t0, t0);
|
||||||
|
for (i = 1; i < 2; ++i) {
|
||||||
|
fe_sq(t0, t0);
|
||||||
|
}
|
||||||
|
fe_mul(out, t0, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ge means group element.
|
/*
|
||||||
|
* ge means group element.
|
||||||
|
*
|
||||||
* Here the group is the set of pairs (x,y) of field elements (see fe.h)
|
* Here the group is the set of pairs (x,y) of field elements (see fe.h)
|
||||||
* satisfying -x^2 + y^2 = 1 + d x^2y^2
|
* satisfying -x^2 + y^2 = 1 + d x^2y^2
|
||||||
* where d = -121665/121666.
|
* where d = -121665/121666.
|
||||||
@@ -1725,268 +1782,292 @@ static void fe_pow22523(fe out, const fe z) {
|
|||||||
* ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
|
* ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
|
||||||
* ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
|
* ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
|
||||||
* ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
|
* ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
|
||||||
* ge_precomp (Duif): (y+x,y-x,2dxy) */
|
* ge_precomp (Duif): (y+x,y-x,2dxy)
|
||||||
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
fe X;
|
fe X;
|
||||||
fe Y;
|
fe Y;
|
||||||
fe Z;
|
fe Z;
|
||||||
} ge_p2;
|
} ge_p2;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
fe X;
|
fe X;
|
||||||
fe Y;
|
fe Y;
|
||||||
fe Z;
|
fe Z;
|
||||||
fe T;
|
fe T;
|
||||||
} ge_p3;
|
} ge_p3;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
fe X;
|
fe X;
|
||||||
fe Y;
|
fe Y;
|
||||||
fe Z;
|
fe Z;
|
||||||
fe T;
|
fe T;
|
||||||
} ge_p1p1;
|
} ge_p1p1;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
fe yplusx;
|
fe yplusx;
|
||||||
fe yminusx;
|
fe yminusx;
|
||||||
fe xy2d;
|
fe xy2d;
|
||||||
} ge_precomp;
|
} ge_precomp;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
fe YplusX;
|
fe YplusX;
|
||||||
fe YminusX;
|
fe YminusX;
|
||||||
fe Z;
|
fe Z;
|
||||||
fe T2d;
|
fe T2d;
|
||||||
} ge_cached;
|
} ge_cached;
|
||||||
|
|
||||||
static void ge_tobytes(uint8_t *s, const ge_p2 *h) {
|
static void ge_tobytes(uint8_t *s, const ge_p2 *h)
|
||||||
fe recip;
|
{
|
||||||
fe x;
|
fe recip;
|
||||||
fe y;
|
fe x;
|
||||||
|
fe y;
|
||||||
|
|
||||||
fe_invert(recip, h->Z);
|
fe_invert(recip, h->Z);
|
||||||
fe_mul(x, h->X, recip);
|
fe_mul(x, h->X, recip);
|
||||||
fe_mul(y, h->Y, recip);
|
fe_mul(y, h->Y, recip);
|
||||||
fe_tobytes(s, y);
|
fe_tobytes(s, y);
|
||||||
s[31] ^= fe_isnegative(x) << 7;
|
s[31] ^= fe_isnegative(x) << 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ge_p3_tobytes(uint8_t *s, const ge_p3 *h) {
|
static void ge_p3_tobytes(uint8_t *s, const ge_p3 *h)
|
||||||
fe recip;
|
{
|
||||||
fe x;
|
fe recip;
|
||||||
fe y;
|
fe x;
|
||||||
|
fe y;
|
||||||
|
|
||||||
fe_invert(recip, h->Z);
|
fe_invert(recip, h->Z);
|
||||||
fe_mul(x, h->X, recip);
|
fe_mul(x, h->X, recip);
|
||||||
fe_mul(y, h->Y, recip);
|
fe_mul(y, h->Y, recip);
|
||||||
fe_tobytes(s, y);
|
fe_tobytes(s, y);
|
||||||
s[31] ^= fe_isnegative(x) << 7;
|
s[31] ^= fe_isnegative(x) << 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const fe d = {-10913610, 13857413, -15372611, 6949391, 114729,
|
static const fe d = {
|
||||||
-8787816, -6275908, -3247719, -18696448, -12055116};
|
-10913610, 13857413, -15372611, 6949391, 114729,
|
||||||
|
-8787816, -6275908, -3247719, -18696448, -12055116
|
||||||
|
};
|
||||||
|
|
||||||
static const fe sqrtm1 = {-32595792, -7943725, 9377950, 3500415, 12389472,
|
static const fe sqrtm1 = {
|
||||||
-272473, -25146209, -2005654, 326686, 11406482};
|
-32595792, -7943725, 9377950, 3500415, 12389472,
|
||||||
|
-272473, -25146209, -2005654, 326686, 11406482
|
||||||
|
};
|
||||||
|
|
||||||
static int ge_frombytes_vartime(ge_p3 *h, const uint8_t *s) {
|
static int ge_frombytes_vartime(ge_p3 *h, const uint8_t *s)
|
||||||
fe u;
|
{
|
||||||
fe v;
|
fe u;
|
||||||
fe v3;
|
fe v;
|
||||||
fe vxx;
|
fe v3;
|
||||||
fe check;
|
fe vxx;
|
||||||
|
fe check;
|
||||||
|
|
||||||
fe_frombytes(h->Y, s);
|
fe_frombytes(h->Y, s);
|
||||||
fe_1(h->Z);
|
fe_1(h->Z);
|
||||||
fe_sq(u, h->Y);
|
fe_sq(u, h->Y);
|
||||||
fe_mul(v, u, d);
|
fe_mul(v, u, d);
|
||||||
fe_sub(u, u, h->Z); /* u = y^2-1 */
|
fe_sub(u, u, h->Z); /* u = y^2-1 */
|
||||||
fe_add(v, v, h->Z); /* v = dy^2+1 */
|
fe_add(v, v, h->Z); /* v = dy^2+1 */
|
||||||
|
|
||||||
fe_sq(v3, v);
|
fe_sq(v3, v);
|
||||||
fe_mul(v3, v3, v); /* v3 = v^3 */
|
fe_mul(v3, v3, v); /* v3 = v^3 */
|
||||||
fe_sq(h->X, v3);
|
fe_sq(h->X, v3);
|
||||||
fe_mul(h->X, h->X, v);
|
fe_mul(h->X, h->X, v);
|
||||||
fe_mul(h->X, h->X, u); /* x = uv^7 */
|
fe_mul(h->X, h->X, u); /* x = uv^7 */
|
||||||
|
|
||||||
fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
|
fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
|
||||||
fe_mul(h->X, h->X, v3);
|
fe_mul(h->X, h->X, v3);
|
||||||
fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
|
fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
|
||||||
|
|
||||||
fe_sq(vxx, h->X);
|
fe_sq(vxx, h->X);
|
||||||
fe_mul(vxx, vxx, v);
|
fe_mul(vxx, vxx, v);
|
||||||
fe_sub(check, vxx, u); /* vx^2-u */
|
fe_sub(check, vxx, u); /* vx^2-u */
|
||||||
if (fe_isnonzero(check)) {
|
|
||||||
fe_add(check, vxx, u); /* vx^2+u */
|
|
||||||
if (fe_isnonzero(check)) {
|
if (fe_isnonzero(check)) {
|
||||||
return -1;
|
fe_add(check, vxx, u); /* vx^2+u */
|
||||||
|
if (fe_isnonzero(check)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fe_mul(h->X, h->X, sqrtm1);
|
||||||
}
|
}
|
||||||
fe_mul(h->X, h->X, sqrtm1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fe_isnegative(h->X) != (s[31] >> 7)) {
|
if (fe_isnegative(h->X) != (s[31] >> 7)) {
|
||||||
fe_neg(h->X, h->X);
|
fe_neg(h->X, h->X);
|
||||||
}
|
}
|
||||||
|
|
||||||
fe_mul(h->T, h->X, h->Y);
|
fe_mul(h->T, h->X, h->Y);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ge_p2_0(ge_p2 *h) {
|
static void ge_p2_0(ge_p2 *h)
|
||||||
fe_0(h->X);
|
{
|
||||||
fe_1(h->Y);
|
fe_0(h->X);
|
||||||
fe_1(h->Z);
|
fe_1(h->Y);
|
||||||
|
fe_1(h->Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ge_p3_0(ge_p3 *h) {
|
static void ge_p3_0(ge_p3 *h)
|
||||||
fe_0(h->X);
|
{
|
||||||
fe_1(h->Y);
|
fe_0(h->X);
|
||||||
fe_1(h->Z);
|
fe_1(h->Y);
|
||||||
fe_0(h->T);
|
fe_1(h->Z);
|
||||||
|
fe_0(h->T);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ge_precomp_0(ge_precomp *h) {
|
static void ge_precomp_0(ge_precomp *h)
|
||||||
fe_1(h->yplusx);
|
{
|
||||||
fe_1(h->yminusx);
|
fe_1(h->yplusx);
|
||||||
fe_0(h->xy2d);
|
fe_1(h->yminusx);
|
||||||
|
fe_0(h->xy2d);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* r = p */
|
/* r = p */
|
||||||
static void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
|
static void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p)
|
||||||
fe_copy(r->X, p->X);
|
{
|
||||||
fe_copy(r->Y, p->Y);
|
fe_copy(r->X, p->X);
|
||||||
fe_copy(r->Z, p->Z);
|
fe_copy(r->Y, p->Y);
|
||||||
|
fe_copy(r->Z, p->Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const fe d2 = {-21827239, -5839606, -30745221, 13898782, 229458,
|
static const fe d2 = {
|
||||||
15978800, -12551817, -6495438, 29715968, 9444199};
|
-21827239, -5839606, -30745221, 13898782, 229458,
|
||||||
|
15978800, -12551817, -6495438, 29715968, 9444199
|
||||||
|
};
|
||||||
|
|
||||||
/* r = p */
|
/* r = p */
|
||||||
static void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
|
static void ge_p3_to_cached(ge_cached *r, const ge_p3 *p)
|
||||||
fe_add(r->YplusX, p->Y, p->X);
|
{
|
||||||
fe_sub(r->YminusX, p->Y, p->X);
|
fe_add(r->YplusX, p->Y, p->X);
|
||||||
fe_copy(r->Z, p->Z);
|
fe_sub(r->YminusX, p->Y, p->X);
|
||||||
fe_mul(r->T2d, p->T, d2);
|
fe_copy(r->Z, p->Z);
|
||||||
|
fe_mul(r->T2d, p->T, d2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* r = p */
|
/* r = p */
|
||||||
static void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
|
static void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p)
|
||||||
fe_mul(r->X, p->X, p->T);
|
{
|
||||||
fe_mul(r->Y, p->Y, p->Z);
|
fe_mul(r->X, p->X, p->T);
|
||||||
fe_mul(r->Z, p->Z, p->T);
|
fe_mul(r->Y, p->Y, p->Z);
|
||||||
|
fe_mul(r->Z, p->Z, p->T);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* r = p */
|
/* r = p */
|
||||||
static void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
|
static void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p)
|
||||||
fe_mul(r->X, p->X, p->T);
|
{
|
||||||
fe_mul(r->Y, p->Y, p->Z);
|
fe_mul(r->X, p->X, p->T);
|
||||||
fe_mul(r->Z, p->Z, p->T);
|
fe_mul(r->Y, p->Y, p->Z);
|
||||||
fe_mul(r->T, p->X, p->Y);
|
fe_mul(r->Z, p->Z, p->T);
|
||||||
|
fe_mul(r->T, p->X, p->Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* r = 2 * p */
|
/* r = 2 * p */
|
||||||
static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
|
static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p)
|
||||||
fe t0;
|
{
|
||||||
|
fe t0;
|
||||||
|
|
||||||
fe_sq(r->X, p->X);
|
fe_sq(r->X, p->X);
|
||||||
fe_sq(r->Z, p->Y);
|
fe_sq(r->Z, p->Y);
|
||||||
fe_sq2(r->T, p->Z);
|
fe_sq2(r->T, p->Z);
|
||||||
fe_add(r->Y, p->X, p->Y);
|
fe_add(r->Y, p->X, p->Y);
|
||||||
fe_sq(t0, r->Y);
|
fe_sq(t0, r->Y);
|
||||||
fe_add(r->Y, r->Z, r->X);
|
fe_add(r->Y, r->Z, r->X);
|
||||||
fe_sub(r->Z, r->Z, r->X);
|
fe_sub(r->Z, r->Z, r->X);
|
||||||
fe_sub(r->X, t0, r->Y);
|
fe_sub(r->X, t0, r->Y);
|
||||||
fe_sub(r->T, r->T, r->Z);
|
fe_sub(r->T, r->T, r->Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* r = 2 * p */
|
/* r = 2 * p */
|
||||||
static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) {
|
static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p)
|
||||||
ge_p2 q;
|
{
|
||||||
ge_p3_to_p2(&q, p);
|
ge_p2 q;
|
||||||
ge_p2_dbl(r, &q);
|
ge_p3_to_p2(&q, p);
|
||||||
|
ge_p2_dbl(r, &q);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* r = p + q */
|
/* r = p + q */
|
||||||
static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
|
static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q)
|
||||||
fe t0;
|
{
|
||||||
|
fe t0;
|
||||||
|
|
||||||
fe_add(r->X, p->Y, p->X);
|
fe_add(r->X, p->Y, p->X);
|
||||||
fe_sub(r->Y, p->Y, p->X);
|
fe_sub(r->Y, p->Y, p->X);
|
||||||
fe_mul(r->Z, r->X, q->yplusx);
|
fe_mul(r->Z, r->X, q->yplusx);
|
||||||
fe_mul(r->Y, r->Y, q->yminusx);
|
fe_mul(r->Y, r->Y, q->yminusx);
|
||||||
fe_mul(r->T, q->xy2d, p->T);
|
fe_mul(r->T, q->xy2d, p->T);
|
||||||
fe_add(t0, p->Z, p->Z);
|
fe_add(t0, p->Z, p->Z);
|
||||||
fe_sub(r->X, r->Z, r->Y);
|
fe_sub(r->X, r->Z, r->Y);
|
||||||
fe_add(r->Y, r->Z, r->Y);
|
fe_add(r->Y, r->Z, r->Y);
|
||||||
fe_add(r->Z, t0, r->T);
|
fe_add(r->Z, t0, r->T);
|
||||||
fe_sub(r->T, t0, r->T);
|
fe_sub(r->T, t0, r->T);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* r = p - q */
|
/* r = p - q */
|
||||||
static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
|
static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q)
|
||||||
fe t0;
|
{
|
||||||
|
fe t0;
|
||||||
|
|
||||||
fe_add(r->X, p->Y, p->X);
|
fe_add(r->X, p->Y, p->X);
|
||||||
fe_sub(r->Y, p->Y, p->X);
|
fe_sub(r->Y, p->Y, p->X);
|
||||||
fe_mul(r->Z, r->X, q->yminusx);
|
fe_mul(r->Z, r->X, q->yminusx);
|
||||||
fe_mul(r->Y, r->Y, q->yplusx);
|
fe_mul(r->Y, r->Y, q->yplusx);
|
||||||
fe_mul(r->T, q->xy2d, p->T);
|
fe_mul(r->T, q->xy2d, p->T);
|
||||||
fe_add(t0, p->Z, p->Z);
|
fe_add(t0, p->Z, p->Z);
|
||||||
fe_sub(r->X, r->Z, r->Y);
|
fe_sub(r->X, r->Z, r->Y);
|
||||||
fe_add(r->Y, r->Z, r->Y);
|
fe_add(r->Y, r->Z, r->Y);
|
||||||
fe_sub(r->Z, t0, r->T);
|
fe_sub(r->Z, t0, r->T);
|
||||||
fe_add(r->T, t0, r->T);
|
fe_add(r->T, t0, r->T);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* r = p + q */
|
/* r = p + q */
|
||||||
static void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
|
static void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q)
|
||||||
fe t0;
|
{
|
||||||
|
fe t0;
|
||||||
|
|
||||||
fe_add(r->X, p->Y, p->X);
|
fe_add(r->X, p->Y, p->X);
|
||||||
fe_sub(r->Y, p->Y, p->X);
|
fe_sub(r->Y, p->Y, p->X);
|
||||||
fe_mul(r->Z, r->X, q->YplusX);
|
fe_mul(r->Z, r->X, q->YplusX);
|
||||||
fe_mul(r->Y, r->Y, q->YminusX);
|
fe_mul(r->Y, r->Y, q->YminusX);
|
||||||
fe_mul(r->T, q->T2d, p->T);
|
fe_mul(r->T, q->T2d, p->T);
|
||||||
fe_mul(r->X, p->Z, q->Z);
|
fe_mul(r->X, p->Z, q->Z);
|
||||||
fe_add(t0, r->X, r->X);
|
fe_add(t0, r->X, r->X);
|
||||||
fe_sub(r->X, r->Z, r->Y);
|
fe_sub(r->X, r->Z, r->Y);
|
||||||
fe_add(r->Y, r->Z, r->Y);
|
fe_add(r->Y, r->Z, r->Y);
|
||||||
fe_add(r->Z, t0, r->T);
|
fe_add(r->Z, t0, r->T);
|
||||||
fe_sub(r->T, t0, r->T);
|
fe_sub(r->T, t0, r->T);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* r = p - q */
|
/* r = p - q */
|
||||||
static void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
|
static void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q)
|
||||||
fe t0;
|
{
|
||||||
|
fe t0;
|
||||||
|
|
||||||
fe_add(r->X, p->Y, p->X);
|
fe_add(r->X, p->Y, p->X);
|
||||||
fe_sub(r->Y, p->Y, p->X);
|
fe_sub(r->Y, p->Y, p->X);
|
||||||
fe_mul(r->Z, r->X, q->YminusX);
|
fe_mul(r->Z, r->X, q->YminusX);
|
||||||
fe_mul(r->Y, r->Y, q->YplusX);
|
fe_mul(r->Y, r->Y, q->YplusX);
|
||||||
fe_mul(r->T, q->T2d, p->T);
|
fe_mul(r->T, q->T2d, p->T);
|
||||||
fe_mul(r->X, p->Z, q->Z);
|
fe_mul(r->X, p->Z, q->Z);
|
||||||
fe_add(t0, r->X, r->X);
|
fe_add(t0, r->X, r->X);
|
||||||
fe_sub(r->X, r->Z, r->Y);
|
fe_sub(r->X, r->Z, r->Y);
|
||||||
fe_add(r->Y, r->Z, r->Y);
|
fe_add(r->Y, r->Z, r->Y);
|
||||||
fe_sub(r->Z, t0, r->T);
|
fe_sub(r->Z, t0, r->T);
|
||||||
fe_add(r->T, t0, r->T);
|
fe_add(r->T, t0, r->T);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t equal(signed char b, signed char c) {
|
static uint8_t equal(signed char b, signed char c)
|
||||||
uint8_t ub = b;
|
{
|
||||||
uint8_t uc = c;
|
uint8_t ub = b;
|
||||||
uint8_t x = ub ^ uc; /* 0: yes; 1..255: no */
|
uint8_t uc = c;
|
||||||
uint32_t y = x; /* 0: yes; 1..255: no */
|
uint8_t x = ub ^ uc; /* 0: yes; 1..255: no */
|
||||||
y -= 1; /* 4294967295: yes; 0..254: no */
|
uint32_t y = x; /* 0: yes; 1..255: no */
|
||||||
y >>= 31; /* 1: yes; 0: no */
|
y -= 1; /* 4294967295: yes; 0..254: no */
|
||||||
return y;
|
y >>= 31; /* 1: yes; 0: no */
|
||||||
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b) {
|
static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b)
|
||||||
fe_cmov(t->yplusx, u->yplusx, b);
|
{
|
||||||
fe_cmov(t->yminusx, u->yminusx, b);
|
fe_cmov(t->yplusx, u->yplusx, b);
|
||||||
fe_cmov(t->xy2d, u->xy2d, b);
|
fe_cmov(t->yminusx, u->yminusx, b);
|
||||||
|
fe_cmov(t->xy2d, u->xy2d, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* k25519Precomp[i][j] = (j+1)*256^i*B */
|
/* k25519Precomp[i][j] = (j+1)*256^i*B */
|
||||||
@@ -4105,257 +4186,273 @@ static const ge_precomp k25519Precomp[32][8] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint8_t negative(signed char b) {
|
static uint8_t negative(signed char b)
|
||||||
uint32_t x = b;
|
{
|
||||||
x >>= 31; /* 1: yes; 0: no */
|
uint32_t x = b;
|
||||||
return x;
|
|
||||||
|
x >>= 31; /* 1: yes; 0: no */
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void table_select(ge_precomp *t, int pos, signed char b) {
|
static void table_select(ge_precomp *t, int pos, signed char b)
|
||||||
ge_precomp minust;
|
{
|
||||||
uint8_t bnegative = negative(b);
|
ge_precomp minust;
|
||||||
uint8_t babs = b - ((uint8_t)((-bnegative) & b) << 1);
|
uint8_t bnegative = negative(b);
|
||||||
|
uint8_t babs = b - ((uint8_t)((-bnegative) & b) << 1);
|
||||||
|
|
||||||
ge_precomp_0(t);
|
ge_precomp_0(t);
|
||||||
cmov(t, &k25519Precomp[pos][0], equal(babs, 1));
|
cmov(t, &k25519Precomp[pos][0], equal(babs, 1));
|
||||||
cmov(t, &k25519Precomp[pos][1], equal(babs, 2));
|
cmov(t, &k25519Precomp[pos][1], equal(babs, 2));
|
||||||
cmov(t, &k25519Precomp[pos][2], equal(babs, 3));
|
cmov(t, &k25519Precomp[pos][2], equal(babs, 3));
|
||||||
cmov(t, &k25519Precomp[pos][3], equal(babs, 4));
|
cmov(t, &k25519Precomp[pos][3], equal(babs, 4));
|
||||||
cmov(t, &k25519Precomp[pos][4], equal(babs, 5));
|
cmov(t, &k25519Precomp[pos][4], equal(babs, 5));
|
||||||
cmov(t, &k25519Precomp[pos][5], equal(babs, 6));
|
cmov(t, &k25519Precomp[pos][5], equal(babs, 6));
|
||||||
cmov(t, &k25519Precomp[pos][6], equal(babs, 7));
|
cmov(t, &k25519Precomp[pos][6], equal(babs, 7));
|
||||||
cmov(t, &k25519Precomp[pos][7], equal(babs, 8));
|
cmov(t, &k25519Precomp[pos][7], equal(babs, 8));
|
||||||
fe_copy(minust.yplusx, t->yminusx);
|
fe_copy(minust.yplusx, t->yminusx);
|
||||||
fe_copy(minust.yminusx, t->yplusx);
|
fe_copy(minust.yminusx, t->yplusx);
|
||||||
fe_neg(minust.xy2d, t->xy2d);
|
fe_neg(minust.xy2d, t->xy2d);
|
||||||
cmov(t, &minust, bnegative);
|
cmov(t, &minust, bnegative);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* h = a * B
|
/*
|
||||||
|
* h = a * B
|
||||||
|
*
|
||||||
* where a = a[0]+256*a[1]+...+256^31 a[31]
|
* where a = a[0]+256*a[1]+...+256^31 a[31]
|
||||||
* B is the Ed25519 base point (x,4/5) with x positive.
|
* B is the Ed25519 base point (x,4/5) with x positive.
|
||||||
*
|
*
|
||||||
* Preconditions:
|
* Preconditions:
|
||||||
* a[31] <= 127 */
|
* a[31] <= 127
|
||||||
static void ge_scalarmult_base(ge_p3 *h, const uint8_t *a) {
|
*/
|
||||||
signed char e[64];
|
static void ge_scalarmult_base(ge_p3 *h, const uint8_t *a)
|
||||||
signed char carry;
|
{
|
||||||
ge_p1p1 r;
|
signed char e[64];
|
||||||
ge_p2 s;
|
signed char carry;
|
||||||
ge_precomp t;
|
ge_p1p1 r;
|
||||||
int i;
|
ge_p2 s;
|
||||||
|
ge_precomp t;
|
||||||
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 32; ++i) {
|
for (i = 0; i < 32; ++i) {
|
||||||
e[2 * i + 0] = (a[i] >> 0) & 15;
|
e[2 * i + 0] = (a[i] >> 0) & 15;
|
||||||
e[2 * i + 1] = (a[i] >> 4) & 15;
|
e[2 * i + 1] = (a[i] >> 4) & 15;
|
||||||
}
|
}
|
||||||
/* each e[i] is between 0 and 15 */
|
/* each e[i] is between 0 and 15 */
|
||||||
/* e[63] is between 0 and 7 */
|
/* e[63] is between 0 and 7 */
|
||||||
|
|
||||||
carry = 0;
|
carry = 0;
|
||||||
for (i = 0; i < 63; ++i) {
|
for (i = 0; i < 63; ++i) {
|
||||||
e[i] += carry;
|
e[i] += carry;
|
||||||
carry = e[i] + 8;
|
carry = e[i] + 8;
|
||||||
carry >>= 4;
|
carry >>= 4;
|
||||||
e[i] -= carry << 4;
|
e[i] -= carry << 4;
|
||||||
}
|
}
|
||||||
e[63] += carry;
|
e[63] += carry;
|
||||||
/* each e[i] is between -8 and 8 */
|
/* each e[i] is between -8 and 8 */
|
||||||
|
|
||||||
ge_p3_0(h);
|
ge_p3_0(h);
|
||||||
for (i = 1; i < 64; i += 2) {
|
for (i = 1; i < 64; i += 2) {
|
||||||
table_select(&t, i / 2, e[i]);
|
table_select(&t, i / 2, e[i]);
|
||||||
ge_madd(&r, h, &t);
|
ge_madd(&r, h, &t);
|
||||||
|
ge_p1p1_to_p3(h, &r);
|
||||||
|
}
|
||||||
|
|
||||||
|
ge_p3_dbl(&r, h);
|
||||||
|
ge_p1p1_to_p2(&s, &r);
|
||||||
|
ge_p2_dbl(&r, &s);
|
||||||
|
ge_p1p1_to_p2(&s, &r);
|
||||||
|
ge_p2_dbl(&r, &s);
|
||||||
|
ge_p1p1_to_p2(&s, &r);
|
||||||
|
ge_p2_dbl(&r, &s);
|
||||||
ge_p1p1_to_p3(h, &r);
|
ge_p1p1_to_p3(h, &r);
|
||||||
}
|
|
||||||
|
|
||||||
ge_p3_dbl(&r, h);
|
for (i = 0; i < 64; i += 2) {
|
||||||
ge_p1p1_to_p2(&s, &r);
|
table_select(&t, i / 2, e[i]);
|
||||||
ge_p2_dbl(&r, &s);
|
ge_madd(&r, h, &t);
|
||||||
ge_p1p1_to_p2(&s, &r);
|
ge_p1p1_to_p3(h, &r);
|
||||||
ge_p2_dbl(&r, &s);
|
}
|
||||||
ge_p1p1_to_p2(&s, &r);
|
|
||||||
ge_p2_dbl(&r, &s);
|
|
||||||
ge_p1p1_to_p3(h, &r);
|
|
||||||
|
|
||||||
for (i = 0; i < 64; i += 2) {
|
OPENSSL_cleanse(e, sizeof(e));
|
||||||
table_select(&t, i / 2, e[i]);
|
|
||||||
ge_madd(&r, h, &t);
|
|
||||||
ge_p1p1_to_p3(h, &r);
|
|
||||||
}
|
|
||||||
|
|
||||||
OPENSSL_cleanse(e, sizeof(e));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BASE_2_51_IMPLEMENTED)
|
#if !defined(BASE_2_51_IMPLEMENTED)
|
||||||
/* Replace (f,g) with (g,f) if b == 1;
|
/*
|
||||||
|
* Replace (f,g) with (g,f) if b == 1;
|
||||||
* replace (f,g) with (f,g) if b == 0.
|
* replace (f,g) with (f,g) if b == 0.
|
||||||
*
|
*
|
||||||
* Preconditions: b in {0,1}. */
|
* Preconditions: b in {0,1}.
|
||||||
static void fe_cswap(fe f, fe g, unsigned int b) {
|
*/
|
||||||
size_t i;
|
static void fe_cswap(fe f, fe g, unsigned int b)
|
||||||
b = 0-b;
|
{
|
||||||
for (i = 0; i < 10; i++) {
|
size_t i;
|
||||||
int32_t x = f[i] ^ g[i];
|
|
||||||
x &= b;
|
b = 0-b;
|
||||||
f[i] ^= x;
|
for (i = 0; i < 10; i++) {
|
||||||
g[i] ^= x;
|
int32_t x = f[i] ^ g[i];
|
||||||
}
|
x &= b;
|
||||||
|
f[i] ^= x;
|
||||||
|
g[i] ^= x;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* h = f * 121666
|
/*
|
||||||
|
* h = f * 121666
|
||||||
|
*
|
||||||
* Can overlap h with f.
|
* Can overlap h with f.
|
||||||
*
|
*
|
||||||
* Preconditions:
|
* Preconditions:
|
||||||
* |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
* |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||||
*
|
*
|
||||||
* Postconditions:
|
* Postconditions:
|
||||||
* |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */
|
* |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||||
static void fe_mul121666(fe h, fe f) {
|
*/
|
||||||
int32_t f0 = f[0];
|
static void fe_mul121666(fe h, fe f)
|
||||||
int32_t f1 = f[1];
|
{
|
||||||
int32_t f2 = f[2];
|
int32_t f0 = f[0];
|
||||||
int32_t f3 = f[3];
|
int32_t f1 = f[1];
|
||||||
int32_t f4 = f[4];
|
int32_t f2 = f[2];
|
||||||
int32_t f5 = f[5];
|
int32_t f3 = f[3];
|
||||||
int32_t f6 = f[6];
|
int32_t f4 = f[4];
|
||||||
int32_t f7 = f[7];
|
int32_t f5 = f[5];
|
||||||
int32_t f8 = f[8];
|
int32_t f6 = f[6];
|
||||||
int32_t f9 = f[9];
|
int32_t f7 = f[7];
|
||||||
int64_t h0 = f0 * (int64_t) 121666;
|
int32_t f8 = f[8];
|
||||||
int64_t h1 = f1 * (int64_t) 121666;
|
int32_t f9 = f[9];
|
||||||
int64_t h2 = f2 * (int64_t) 121666;
|
int64_t h0 = f0 * (int64_t) 121666;
|
||||||
int64_t h3 = f3 * (int64_t) 121666;
|
int64_t h1 = f1 * (int64_t) 121666;
|
||||||
int64_t h4 = f4 * (int64_t) 121666;
|
int64_t h2 = f2 * (int64_t) 121666;
|
||||||
int64_t h5 = f5 * (int64_t) 121666;
|
int64_t h3 = f3 * (int64_t) 121666;
|
||||||
int64_t h6 = f6 * (int64_t) 121666;
|
int64_t h4 = f4 * (int64_t) 121666;
|
||||||
int64_t h7 = f7 * (int64_t) 121666;
|
int64_t h5 = f5 * (int64_t) 121666;
|
||||||
int64_t h8 = f8 * (int64_t) 121666;
|
int64_t h6 = f6 * (int64_t) 121666;
|
||||||
int64_t h9 = f9 * (int64_t) 121666;
|
int64_t h7 = f7 * (int64_t) 121666;
|
||||||
int64_t carry0;
|
int64_t h8 = f8 * (int64_t) 121666;
|
||||||
int64_t carry1;
|
int64_t h9 = f9 * (int64_t) 121666;
|
||||||
int64_t carry2;
|
int64_t carry0;
|
||||||
int64_t carry3;
|
int64_t carry1;
|
||||||
int64_t carry4;
|
int64_t carry2;
|
||||||
int64_t carry5;
|
int64_t carry3;
|
||||||
int64_t carry6;
|
int64_t carry4;
|
||||||
int64_t carry7;
|
int64_t carry5;
|
||||||
int64_t carry8;
|
int64_t carry6;
|
||||||
int64_t carry9;
|
int64_t carry7;
|
||||||
|
int64_t carry8;
|
||||||
|
int64_t carry9;
|
||||||
|
|
||||||
carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
|
carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
|
||||||
carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
|
carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
|
||||||
carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
|
carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
|
||||||
carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
|
carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
|
||||||
carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
|
carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
|
||||||
|
|
||||||
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
||||||
carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
|
carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
|
||||||
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
|
||||||
carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
|
carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
|
||||||
carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
|
carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
|
||||||
|
|
||||||
h[0] = (int32_t)h0;
|
h[0] = (int32_t)h0;
|
||||||
h[1] = (int32_t)h1;
|
h[1] = (int32_t)h1;
|
||||||
h[2] = (int32_t)h2;
|
h[2] = (int32_t)h2;
|
||||||
h[3] = (int32_t)h3;
|
h[3] = (int32_t)h3;
|
||||||
h[4] = (int32_t)h4;
|
h[4] = (int32_t)h4;
|
||||||
h[5] = (int32_t)h5;
|
h[5] = (int32_t)h5;
|
||||||
h[6] = (int32_t)h6;
|
h[6] = (int32_t)h6;
|
||||||
h[7] = (int32_t)h7;
|
h[7] = (int32_t)h7;
|
||||||
h[8] = (int32_t)h8;
|
h[8] = (int32_t)h8;
|
||||||
h[9] = (int32_t)h9;
|
h[9] = (int32_t)h9;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x25519_scalar_mult_generic(uint8_t out[32],
|
static void x25519_scalar_mult_generic(uint8_t out[32],
|
||||||
const uint8_t scalar[32],
|
const uint8_t scalar[32],
|
||||||
const uint8_t point[32]) {
|
const uint8_t point[32]) {
|
||||||
fe x1, x2, z2, x3, z3, tmp0, tmp1;
|
fe x1, x2, z2, x3, z3, tmp0, tmp1;
|
||||||
uint8_t e[32];
|
uint8_t e[32];
|
||||||
unsigned swap = 0;
|
unsigned swap = 0;
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
memcpy(e, scalar, 32);
|
memcpy(e, scalar, 32);
|
||||||
e[0] &= 248;
|
e[0] &= 248;
|
||||||
e[31] &= 127;
|
e[31] &= 127;
|
||||||
e[31] |= 64;
|
e[31] |= 64;
|
||||||
fe_frombytes(x1, point);
|
fe_frombytes(x1, point);
|
||||||
fe_1(x2);
|
fe_1(x2);
|
||||||
fe_0(z2);
|
fe_0(z2);
|
||||||
fe_copy(x3, x1);
|
fe_copy(x3, x1);
|
||||||
fe_1(z3);
|
fe_1(z3);
|
||||||
|
|
||||||
for (pos = 254; pos >= 0; --pos) {
|
for (pos = 254; pos >= 0; --pos) {
|
||||||
unsigned b = 1 & (e[pos / 8] >> (pos & 7));
|
unsigned b = 1 & (e[pos / 8] >> (pos & 7));
|
||||||
swap ^= b;
|
swap ^= b;
|
||||||
fe_cswap(x2, x3, swap);
|
fe_cswap(x2, x3, swap);
|
||||||
fe_cswap(z2, z3, swap);
|
fe_cswap(z2, z3, swap);
|
||||||
swap = b;
|
swap = b;
|
||||||
fe_sub(tmp0, x3, z3);
|
fe_sub(tmp0, x3, z3);
|
||||||
fe_sub(tmp1, x2, z2);
|
fe_sub(tmp1, x2, z2);
|
||||||
fe_add(x2, x2, z2);
|
fe_add(x2, x2, z2);
|
||||||
fe_add(z2, x3, z3);
|
fe_add(z2, x3, z3);
|
||||||
fe_mul(z3, tmp0, x2);
|
fe_mul(z3, tmp0, x2);
|
||||||
fe_mul(z2, z2, tmp1);
|
fe_mul(z2, z2, tmp1);
|
||||||
fe_sq(tmp0, tmp1);
|
fe_sq(tmp0, tmp1);
|
||||||
fe_sq(tmp1, x2);
|
fe_sq(tmp1, x2);
|
||||||
fe_add(x3, z3, z2);
|
fe_add(x3, z3, z2);
|
||||||
fe_sub(z2, z3, z2);
|
fe_sub(z2, z3, z2);
|
||||||
fe_mul(x2, tmp1, tmp0);
|
fe_mul(x2, tmp1, tmp0);
|
||||||
fe_sub(tmp1, tmp1, tmp0);
|
fe_sub(tmp1, tmp1, tmp0);
|
||||||
fe_sq(z2, z2);
|
fe_sq(z2, z2);
|
||||||
fe_mul121666(z3, tmp1);
|
fe_mul121666(z3, tmp1);
|
||||||
fe_sq(x3, x3);
|
fe_sq(x3, x3);
|
||||||
fe_add(tmp0, tmp0, z3);
|
fe_add(tmp0, tmp0, z3);
|
||||||
fe_mul(z3, x1, z2);
|
fe_mul(z3, x1, z2);
|
||||||
fe_mul(z2, tmp1, tmp0);
|
fe_mul(z2, tmp1, tmp0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fe_invert(z2, z2);
|
fe_invert(z2, z2);
|
||||||
fe_mul(x2, x2, z2);
|
fe_mul(x2, x2, z2);
|
||||||
fe_tobytes(out, x2);
|
fe_tobytes(out, x2);
|
||||||
|
|
||||||
OPENSSL_cleanse(e, sizeof(e));
|
OPENSSL_cleanse(e, sizeof(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32],
|
static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32],
|
||||||
const uint8_t point[32]) {
|
const uint8_t point[32]) {
|
||||||
x25519_scalar_mult_generic(out, scalar, point);
|
x25519_scalar_mult_generic(out, scalar, point);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void slide(signed char *r, const uint8_t *a) {
|
static void slide(signed char *r, const uint8_t *a)
|
||||||
int i;
|
{
|
||||||
int b;
|
int i;
|
||||||
int k;
|
int b;
|
||||||
|
int k;
|
||||||
|
|
||||||
for (i = 0; i < 256; ++i) {
|
for (i = 0; i < 256; ++i) {
|
||||||
r[i] = 1 & (a[i >> 3] >> (i & 7));
|
r[i] = 1 & (a[i >> 3] >> (i & 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 256; ++i) {
|
for (i = 0; i < 256; ++i) {
|
||||||
if (r[i]) {
|
if (r[i]) {
|
||||||
for (b = 1; b <= 6 && i + b < 256; ++b) {
|
for (b = 1; b <= 6 && i + b < 256; ++b) {
|
||||||
if (r[i + b]) {
|
if (r[i + b]) {
|
||||||
if (r[i] + (r[i + b] << b) <= 15) {
|
if (r[i] + (r[i + b] << b) <= 15) {
|
||||||
r[i] += r[i + b] << b;
|
r[i] += r[i + b] << b;
|
||||||
r[i + b] = 0;
|
r[i + b] = 0;
|
||||||
} else if (r[i] - (r[i + b] << b) >= -15) {
|
} else if (r[i] - (r[i + b] << b) >= -15) {
|
||||||
r[i] -= r[i + b] << b;
|
r[i] -= r[i + b] << b;
|
||||||
for (k = i + b; k < 256; ++k) {
|
for (k = i + b; k < 256; ++k) {
|
||||||
if (!r[k]) {
|
if (!r[k]) {
|
||||||
r[k] = 1;
|
r[k] = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
r[k] = 0;
|
r[k] = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ge_precomp Bi[8] = {
|
static const ge_precomp Bi[8] = {
|
||||||
@@ -4425,1066 +4522,1075 @@ static const ge_precomp Bi[8] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* r = a * A + b * B
|
/*
|
||||||
|
* r = a * A + b * B
|
||||||
|
*
|
||||||
* where a = a[0]+256*a[1]+...+256^31 a[31].
|
* where a = a[0]+256*a[1]+...+256^31 a[31].
|
||||||
* and b = b[0]+256*b[1]+...+256^31 b[31].
|
* and b = b[0]+256*b[1]+...+256^31 b[31].
|
||||||
* B is the Ed25519 base point (x,4/5) with x positive. */
|
* B is the Ed25519 base point (x,4/5) with x positive.
|
||||||
|
*/
|
||||||
static void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a,
|
static void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a,
|
||||||
const ge_p3 *A, const uint8_t *b) {
|
const ge_p3 *A, const uint8_t *b)
|
||||||
signed char aslide[256];
|
{
|
||||||
signed char bslide[256];
|
signed char aslide[256];
|
||||||
ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
|
signed char bslide[256];
|
||||||
ge_p1p1 t;
|
ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
|
||||||
ge_p3 u;
|
ge_p1p1 t;
|
||||||
ge_p3 A2;
|
ge_p3 u;
|
||||||
int i;
|
ge_p3 A2;
|
||||||
|
int i;
|
||||||
|
|
||||||
slide(aslide, a);
|
slide(aslide, a);
|
||||||
slide(bslide, b);
|
slide(bslide, b);
|
||||||
|
|
||||||
ge_p3_to_cached(&Ai[0], A);
|
ge_p3_to_cached(&Ai[0], A);
|
||||||
ge_p3_dbl(&t, A);
|
ge_p3_dbl(&t, A);
|
||||||
ge_p1p1_to_p3(&A2, &t);
|
ge_p1p1_to_p3(&A2, &t);
|
||||||
ge_add(&t, &A2, &Ai[0]);
|
ge_add(&t, &A2, &Ai[0]);
|
||||||
ge_p1p1_to_p3(&u, &t);
|
ge_p1p1_to_p3(&u, &t);
|
||||||
ge_p3_to_cached(&Ai[1], &u);
|
ge_p3_to_cached(&Ai[1], &u);
|
||||||
ge_add(&t, &A2, &Ai[1]);
|
ge_add(&t, &A2, &Ai[1]);
|
||||||
ge_p1p1_to_p3(&u, &t);
|
ge_p1p1_to_p3(&u, &t);
|
||||||
ge_p3_to_cached(&Ai[2], &u);
|
ge_p3_to_cached(&Ai[2], &u);
|
||||||
ge_add(&t, &A2, &Ai[2]);
|
ge_add(&t, &A2, &Ai[2]);
|
||||||
ge_p1p1_to_p3(&u, &t);
|
ge_p1p1_to_p3(&u, &t);
|
||||||
ge_p3_to_cached(&Ai[3], &u);
|
ge_p3_to_cached(&Ai[3], &u);
|
||||||
ge_add(&t, &A2, &Ai[3]);
|
ge_add(&t, &A2, &Ai[3]);
|
||||||
ge_p1p1_to_p3(&u, &t);
|
ge_p1p1_to_p3(&u, &t);
|
||||||
ge_p3_to_cached(&Ai[4], &u);
|
ge_p3_to_cached(&Ai[4], &u);
|
||||||
ge_add(&t, &A2, &Ai[4]);
|
ge_add(&t, &A2, &Ai[4]);
|
||||||
ge_p1p1_to_p3(&u, &t);
|
ge_p1p1_to_p3(&u, &t);
|
||||||
ge_p3_to_cached(&Ai[5], &u);
|
ge_p3_to_cached(&Ai[5], &u);
|
||||||
ge_add(&t, &A2, &Ai[5]);
|
ge_add(&t, &A2, &Ai[5]);
|
||||||
ge_p1p1_to_p3(&u, &t);
|
ge_p1p1_to_p3(&u, &t);
|
||||||
ge_p3_to_cached(&Ai[6], &u);
|
ge_p3_to_cached(&Ai[6], &u);
|
||||||
ge_add(&t, &A2, &Ai[6]);
|
ge_add(&t, &A2, &Ai[6]);
|
||||||
ge_p1p1_to_p3(&u, &t);
|
ge_p1p1_to_p3(&u, &t);
|
||||||
ge_p3_to_cached(&Ai[7], &u);
|
ge_p3_to_cached(&Ai[7], &u);
|
||||||
|
|
||||||
ge_p2_0(r);
|
ge_p2_0(r);
|
||||||
|
|
||||||
for (i = 255; i >= 0; --i) {
|
for (i = 255; i >= 0; --i) {
|
||||||
if (aslide[i] || bslide[i]) {
|
if (aslide[i] || bslide[i]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (; i >= 0; --i) {
|
|
||||||
ge_p2_dbl(&t, r);
|
|
||||||
|
|
||||||
if (aslide[i] > 0) {
|
|
||||||
ge_p1p1_to_p3(&u, &t);
|
|
||||||
ge_add(&t, &u, &Ai[aslide[i] / 2]);
|
|
||||||
} else if (aslide[i] < 0) {
|
|
||||||
ge_p1p1_to_p3(&u, &t);
|
|
||||||
ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bslide[i] > 0) {
|
for (; i >= 0; --i) {
|
||||||
ge_p1p1_to_p3(&u, &t);
|
ge_p2_dbl(&t, r);
|
||||||
ge_madd(&t, &u, &Bi[bslide[i] / 2]);
|
|
||||||
} else if (bslide[i] < 0) {
|
|
||||||
ge_p1p1_to_p3(&u, &t);
|
|
||||||
ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ge_p1p1_to_p2(r, &t);
|
if (aslide[i] > 0) {
|
||||||
}
|
ge_p1p1_to_p3(&u, &t);
|
||||||
|
ge_add(&t, &u, &Ai[aslide[i] / 2]);
|
||||||
|
} else if (aslide[i] < 0) {
|
||||||
|
ge_p1p1_to_p3(&u, &t);
|
||||||
|
ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bslide[i] > 0) {
|
||||||
|
ge_p1p1_to_p3(&u, &t);
|
||||||
|
ge_madd(&t, &u, &Bi[bslide[i] / 2]);
|
||||||
|
} else if (bslide[i] < 0) {
|
||||||
|
ge_p1p1_to_p3(&u, &t);
|
||||||
|
ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ge_p1p1_to_p2(r, &t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The set of scalars is \Z/l
|
/*
|
||||||
* where l = 2^252 + 27742317777372353535851937790883648493. */
|
* The set of scalars is \Z/l
|
||||||
|
* where l = 2^252 + 27742317777372353535851937790883648493.
|
||||||
/* Input:
|
*
|
||||||
|
* Input:
|
||||||
* s[0]+256*s[1]+...+256^63*s[63] = s
|
* s[0]+256*s[1]+...+256^63*s[63] = s
|
||||||
*
|
*
|
||||||
* Output:
|
* Output:
|
||||||
* s[0]+256*s[1]+...+256^31*s[31] = s mod l
|
* s[0]+256*s[1]+...+256^31*s[31] = s mod l
|
||||||
* where l = 2^252 + 27742317777372353535851937790883648493.
|
* where l = 2^252 + 27742317777372353535851937790883648493.
|
||||||
* Overwrites s in place. */
|
* Overwrites s in place.
|
||||||
static void x25519_sc_reduce(uint8_t *s) {
|
*/
|
||||||
int64_t s0 = 2097151 & load_3(s);
|
static void x25519_sc_reduce(uint8_t *s)
|
||||||
int64_t s1 = 2097151 & (load_4(s + 2) >> 5);
|
{
|
||||||
int64_t s2 = 2097151 & (load_3(s + 5) >> 2);
|
int64_t s0 = kBottom21Bits & load_3(s);
|
||||||
int64_t s3 = 2097151 & (load_4(s + 7) >> 7);
|
int64_t s1 = kBottom21Bits & (load_4(s + 2) >> 5);
|
||||||
int64_t s4 = 2097151 & (load_4(s + 10) >> 4);
|
int64_t s2 = kBottom21Bits & (load_3(s + 5) >> 2);
|
||||||
int64_t s5 = 2097151 & (load_3(s + 13) >> 1);
|
int64_t s3 = kBottom21Bits & (load_4(s + 7) >> 7);
|
||||||
int64_t s6 = 2097151 & (load_4(s + 15) >> 6);
|
int64_t s4 = kBottom21Bits & (load_4(s + 10) >> 4);
|
||||||
int64_t s7 = 2097151 & (load_3(s + 18) >> 3);
|
int64_t s5 = kBottom21Bits & (load_3(s + 13) >> 1);
|
||||||
int64_t s8 = 2097151 & load_3(s + 21);
|
int64_t s6 = kBottom21Bits & (load_4(s + 15) >> 6);
|
||||||
int64_t s9 = 2097151 & (load_4(s + 23) >> 5);
|
int64_t s7 = kBottom21Bits & (load_3(s + 18) >> 3);
|
||||||
int64_t s10 = 2097151 & (load_3(s + 26) >> 2);
|
int64_t s8 = kBottom21Bits & load_3(s + 21);
|
||||||
int64_t s11 = 2097151 & (load_4(s + 28) >> 7);
|
int64_t s9 = kBottom21Bits & (load_4(s + 23) >> 5);
|
||||||
int64_t s12 = 2097151 & (load_4(s + 31) >> 4);
|
int64_t s10 = kBottom21Bits & (load_3(s + 26) >> 2);
|
||||||
int64_t s13 = 2097151 & (load_3(s + 34) >> 1);
|
int64_t s11 = kBottom21Bits & (load_4(s + 28) >> 7);
|
||||||
int64_t s14 = 2097151 & (load_4(s + 36) >> 6);
|
int64_t s12 = kBottom21Bits & (load_4(s + 31) >> 4);
|
||||||
int64_t s15 = 2097151 & (load_3(s + 39) >> 3);
|
int64_t s13 = kBottom21Bits & (load_3(s + 34) >> 1);
|
||||||
int64_t s16 = 2097151 & load_3(s + 42);
|
int64_t s14 = kBottom21Bits & (load_4(s + 36) >> 6);
|
||||||
int64_t s17 = 2097151 & (load_4(s + 44) >> 5);
|
int64_t s15 = kBottom21Bits & (load_3(s + 39) >> 3);
|
||||||
int64_t s18 = 2097151 & (load_3(s + 47) >> 2);
|
int64_t s16 = kBottom21Bits & load_3(s + 42);
|
||||||
int64_t s19 = 2097151 & (load_4(s + 49) >> 7);
|
int64_t s17 = kBottom21Bits & (load_4(s + 44) >> 5);
|
||||||
int64_t s20 = 2097151 & (load_4(s + 52) >> 4);
|
int64_t s18 = kBottom21Bits & (load_3(s + 47) >> 2);
|
||||||
int64_t s21 = 2097151 & (load_3(s + 55) >> 1);
|
int64_t s19 = kBottom21Bits & (load_4(s + 49) >> 7);
|
||||||
int64_t s22 = 2097151 & (load_4(s + 57) >> 6);
|
int64_t s20 = kBottom21Bits & (load_4(s + 52) >> 4);
|
||||||
int64_t s23 = (load_4(s + 60) >> 3);
|
int64_t s21 = kBottom21Bits & (load_3(s + 55) >> 1);
|
||||||
int64_t carry0;
|
int64_t s22 = kBottom21Bits & (load_4(s + 57) >> 6);
|
||||||
int64_t carry1;
|
int64_t s23 = (load_4(s + 60) >> 3);
|
||||||
int64_t carry2;
|
int64_t carry0;
|
||||||
int64_t carry3;
|
int64_t carry1;
|
||||||
int64_t carry4;
|
int64_t carry2;
|
||||||
int64_t carry5;
|
int64_t carry3;
|
||||||
int64_t carry6;
|
int64_t carry4;
|
||||||
int64_t carry7;
|
int64_t carry5;
|
||||||
int64_t carry8;
|
int64_t carry6;
|
||||||
int64_t carry9;
|
int64_t carry7;
|
||||||
int64_t carry10;
|
int64_t carry8;
|
||||||
int64_t carry11;
|
int64_t carry9;
|
||||||
int64_t carry12;
|
int64_t carry10;
|
||||||
int64_t carry13;
|
int64_t carry11;
|
||||||
int64_t carry14;
|
int64_t carry12;
|
||||||
int64_t carry15;
|
int64_t carry13;
|
||||||
int64_t carry16;
|
int64_t carry14;
|
||||||
|
int64_t carry15;
|
||||||
|
int64_t carry16;
|
||||||
|
|
||||||
s11 += s23 * 666643;
|
s11 += s23 * 666643;
|
||||||
s12 += s23 * 470296;
|
s12 += s23 * 470296;
|
||||||
s13 += s23 * 654183;
|
s13 += s23 * 654183;
|
||||||
s14 -= s23 * 997805;
|
s14 -= s23 * 997805;
|
||||||
s15 += s23 * 136657;
|
s15 += s23 * 136657;
|
||||||
s16 -= s23 * 683901;
|
s16 -= s23 * 683901;
|
||||||
s23 = 0;
|
s23 = 0;
|
||||||
|
|
||||||
s10 += s22 * 666643;
|
s10 += s22 * 666643;
|
||||||
s11 += s22 * 470296;
|
s11 += s22 * 470296;
|
||||||
s12 += s22 * 654183;
|
s12 += s22 * 654183;
|
||||||
s13 -= s22 * 997805;
|
s13 -= s22 * 997805;
|
||||||
s14 += s22 * 136657;
|
s14 += s22 * 136657;
|
||||||
s15 -= s22 * 683901;
|
s15 -= s22 * 683901;
|
||||||
s22 = 0;
|
s22 = 0;
|
||||||
|
|
||||||
s9 += s21 * 666643;
|
s9 += s21 * 666643;
|
||||||
s10 += s21 * 470296;
|
s10 += s21 * 470296;
|
||||||
s11 += s21 * 654183;
|
s11 += s21 * 654183;
|
||||||
s12 -= s21 * 997805;
|
s12 -= s21 * 997805;
|
||||||
s13 += s21 * 136657;
|
s13 += s21 * 136657;
|
||||||
s14 -= s21 * 683901;
|
s14 -= s21 * 683901;
|
||||||
s21 = 0;
|
s21 = 0;
|
||||||
|
|
||||||
s8 += s20 * 666643;
|
s8 += s20 * 666643;
|
||||||
s9 += s20 * 470296;
|
s9 += s20 * 470296;
|
||||||
s10 += s20 * 654183;
|
s10 += s20 * 654183;
|
||||||
s11 -= s20 * 997805;
|
s11 -= s20 * 997805;
|
||||||
s12 += s20 * 136657;
|
s12 += s20 * 136657;
|
||||||
s13 -= s20 * 683901;
|
s13 -= s20 * 683901;
|
||||||
s20 = 0;
|
s20 = 0;
|
||||||
|
|
||||||
s7 += s19 * 666643;
|
s7 += s19 * 666643;
|
||||||
s8 += s19 * 470296;
|
s8 += s19 * 470296;
|
||||||
s9 += s19 * 654183;
|
s9 += s19 * 654183;
|
||||||
s10 -= s19 * 997805;
|
s10 -= s19 * 997805;
|
||||||
s11 += s19 * 136657;
|
s11 += s19 * 136657;
|
||||||
s12 -= s19 * 683901;
|
s12 -= s19 * 683901;
|
||||||
s19 = 0;
|
s19 = 0;
|
||||||
|
|
||||||
s6 += s18 * 666643;
|
s6 += s18 * 666643;
|
||||||
s7 += s18 * 470296;
|
s7 += s18 * 470296;
|
||||||
s8 += s18 * 654183;
|
s8 += s18 * 654183;
|
||||||
s9 -= s18 * 997805;
|
s9 -= s18 * 997805;
|
||||||
s10 += s18 * 136657;
|
s10 += s18 * 136657;
|
||||||
s11 -= s18 * 683901;
|
s11 -= s18 * 683901;
|
||||||
s18 = 0;
|
s18 = 0;
|
||||||
|
|
||||||
carry6 = (s6 + (1 << 20)) >> 21;
|
carry6 = (s6 + (1 << 20)) >> 21;
|
||||||
s7 += carry6;
|
s7 += carry6;
|
||||||
s6 -= carry6 * (1 << 21);
|
s6 -= carry6 * (1 << 21);
|
||||||
carry8 = (s8 + (1 << 20)) >> 21;
|
carry8 = (s8 + (1 << 20)) >> 21;
|
||||||
s9 += carry8;
|
s9 += carry8;
|
||||||
s8 -= carry8 * (1 << 21);
|
s8 -= carry8 * (1 << 21);
|
||||||
carry10 = (s10 + (1 << 20)) >> 21;
|
carry10 = (s10 + (1 << 20)) >> 21;
|
||||||
s11 += carry10;
|
s11 += carry10;
|
||||||
s10 -= carry10 * (1 << 21);
|
s10 -= carry10 * (1 << 21);
|
||||||
carry12 = (s12 + (1 << 20)) >> 21;
|
carry12 = (s12 + (1 << 20)) >> 21;
|
||||||
s13 += carry12;
|
s13 += carry12;
|
||||||
s12 -= carry12 * (1 << 21);
|
s12 -= carry12 * (1 << 21);
|
||||||
carry14 = (s14 + (1 << 20)) >> 21;
|
carry14 = (s14 + (1 << 20)) >> 21;
|
||||||
s15 += carry14;
|
s15 += carry14;
|
||||||
s14 -= carry14 * (1 << 21);
|
s14 -= carry14 * (1 << 21);
|
||||||
carry16 = (s16 + (1 << 20)) >> 21;
|
carry16 = (s16 + (1 << 20)) >> 21;
|
||||||
s17 += carry16;
|
s17 += carry16;
|
||||||
s16 -= carry16 * (1 << 21);
|
s16 -= carry16 * (1 << 21);
|
||||||
|
|
||||||
carry7 = (s7 + (1 << 20)) >> 21;
|
carry7 = (s7 + (1 << 20)) >> 21;
|
||||||
s8 += carry7;
|
s8 += carry7;
|
||||||
s7 -= carry7 * (1 << 21);
|
s7 -= carry7 * (1 << 21);
|
||||||
carry9 = (s9 + (1 << 20)) >> 21;
|
carry9 = (s9 + (1 << 20)) >> 21;
|
||||||
s10 += carry9;
|
s10 += carry9;
|
||||||
s9 -= carry9 * (1 << 21);
|
s9 -= carry9 * (1 << 21);
|
||||||
carry11 = (s11 + (1 << 20)) >> 21;
|
carry11 = (s11 + (1 << 20)) >> 21;
|
||||||
s12 += carry11;
|
s12 += carry11;
|
||||||
s11 -= carry11 * (1 << 21);
|
s11 -= carry11 * (1 << 21);
|
||||||
carry13 = (s13 + (1 << 20)) >> 21;
|
carry13 = (s13 + (1 << 20)) >> 21;
|
||||||
s14 += carry13;
|
s14 += carry13;
|
||||||
s13 -= carry13 * (1 << 21);
|
s13 -= carry13 * (1 << 21);
|
||||||
carry15 = (s15 + (1 << 20)) >> 21;
|
carry15 = (s15 + (1 << 20)) >> 21;
|
||||||
s16 += carry15;
|
s16 += carry15;
|
||||||
s15 -= carry15 * (1 << 21);
|
s15 -= carry15 * (1 << 21);
|
||||||
|
|
||||||
s5 += s17 * 666643;
|
s5 += s17 * 666643;
|
||||||
s6 += s17 * 470296;
|
s6 += s17 * 470296;
|
||||||
s7 += s17 * 654183;
|
s7 += s17 * 654183;
|
||||||
s8 -= s17 * 997805;
|
s8 -= s17 * 997805;
|
||||||
s9 += s17 * 136657;
|
s9 += s17 * 136657;
|
||||||
s10 -= s17 * 683901;
|
s10 -= s17 * 683901;
|
||||||
s17 = 0;
|
s17 = 0;
|
||||||
|
|
||||||
s4 += s16 * 666643;
|
s4 += s16 * 666643;
|
||||||
s5 += s16 * 470296;
|
s5 += s16 * 470296;
|
||||||
s6 += s16 * 654183;
|
s6 += s16 * 654183;
|
||||||
s7 -= s16 * 997805;
|
s7 -= s16 * 997805;
|
||||||
s8 += s16 * 136657;
|
s8 += s16 * 136657;
|
||||||
s9 -= s16 * 683901;
|
s9 -= s16 * 683901;
|
||||||
s16 = 0;
|
s16 = 0;
|
||||||
|
|
||||||
s3 += s15 * 666643;
|
s3 += s15 * 666643;
|
||||||
s4 += s15 * 470296;
|
s4 += s15 * 470296;
|
||||||
s5 += s15 * 654183;
|
s5 += s15 * 654183;
|
||||||
s6 -= s15 * 997805;
|
s6 -= s15 * 997805;
|
||||||
s7 += s15 * 136657;
|
s7 += s15 * 136657;
|
||||||
s8 -= s15 * 683901;
|
s8 -= s15 * 683901;
|
||||||
s15 = 0;
|
s15 = 0;
|
||||||
|
|
||||||
s2 += s14 * 666643;
|
s2 += s14 * 666643;
|
||||||
s3 += s14 * 470296;
|
s3 += s14 * 470296;
|
||||||
s4 += s14 * 654183;
|
s4 += s14 * 654183;
|
||||||
s5 -= s14 * 997805;
|
s5 -= s14 * 997805;
|
||||||
s6 += s14 * 136657;
|
s6 += s14 * 136657;
|
||||||
s7 -= s14 * 683901;
|
s7 -= s14 * 683901;
|
||||||
s14 = 0;
|
s14 = 0;
|
||||||
|
|
||||||
s1 += s13 * 666643;
|
s1 += s13 * 666643;
|
||||||
s2 += s13 * 470296;
|
s2 += s13 * 470296;
|
||||||
s3 += s13 * 654183;
|
s3 += s13 * 654183;
|
||||||
s4 -= s13 * 997805;
|
s4 -= s13 * 997805;
|
||||||
s5 += s13 * 136657;
|
s5 += s13 * 136657;
|
||||||
s6 -= s13 * 683901;
|
s6 -= s13 * 683901;
|
||||||
s13 = 0;
|
s13 = 0;
|
||||||
|
|
||||||
s0 += s12 * 666643;
|
s0 += s12 * 666643;
|
||||||
s1 += s12 * 470296;
|
s1 += s12 * 470296;
|
||||||
s2 += s12 * 654183;
|
s2 += s12 * 654183;
|
||||||
s3 -= s12 * 997805;
|
s3 -= s12 * 997805;
|
||||||
s4 += s12 * 136657;
|
s4 += s12 * 136657;
|
||||||
s5 -= s12 * 683901;
|
s5 -= s12 * 683901;
|
||||||
s12 = 0;
|
s12 = 0;
|
||||||
|
|
||||||
carry0 = (s0 + (1 << 20)) >> 21;
|
carry0 = (s0 + (1 << 20)) >> 21;
|
||||||
s1 += carry0;
|
s1 += carry0;
|
||||||
s0 -= carry0 * (1 << 21);
|
s0 -= carry0 * (1 << 21);
|
||||||
carry2 = (s2 + (1 << 20)) >> 21;
|
carry2 = (s2 + (1 << 20)) >> 21;
|
||||||
s3 += carry2;
|
s3 += carry2;
|
||||||
s2 -= carry2 * (1 << 21);
|
s2 -= carry2 * (1 << 21);
|
||||||
carry4 = (s4 + (1 << 20)) >> 21;
|
carry4 = (s4 + (1 << 20)) >> 21;
|
||||||
s5 += carry4;
|
s5 += carry4;
|
||||||
s4 -= carry4 * (1 << 21);
|
s4 -= carry4 * (1 << 21);
|
||||||
carry6 = (s6 + (1 << 20)) >> 21;
|
carry6 = (s6 + (1 << 20)) >> 21;
|
||||||
s7 += carry6;
|
s7 += carry6;
|
||||||
s6 -= carry6 * (1 << 21);
|
s6 -= carry6 * (1 << 21);
|
||||||
carry8 = (s8 + (1 << 20)) >> 21;
|
carry8 = (s8 + (1 << 20)) >> 21;
|
||||||
s9 += carry8;
|
s9 += carry8;
|
||||||
s8 -= carry8 * (1 << 21);
|
s8 -= carry8 * (1 << 21);
|
||||||
carry10 = (s10 + (1 << 20)) >> 21;
|
carry10 = (s10 + (1 << 20)) >> 21;
|
||||||
s11 += carry10;
|
s11 += carry10;
|
||||||
s10 -= carry10 * (1 << 21);
|
s10 -= carry10 * (1 << 21);
|
||||||
|
|
||||||
carry1 = (s1 + (1 << 20)) >> 21;
|
carry1 = (s1 + (1 << 20)) >> 21;
|
||||||
s2 += carry1;
|
s2 += carry1;
|
||||||
s1 -= carry1 * (1 << 21);
|
s1 -= carry1 * (1 << 21);
|
||||||
carry3 = (s3 + (1 << 20)) >> 21;
|
carry3 = (s3 + (1 << 20)) >> 21;
|
||||||
s4 += carry3;
|
s4 += carry3;
|
||||||
s3 -= carry3 * (1 << 21);
|
s3 -= carry3 * (1 << 21);
|
||||||
carry5 = (s5 + (1 << 20)) >> 21;
|
carry5 = (s5 + (1 << 20)) >> 21;
|
||||||
s6 += carry5;
|
s6 += carry5;
|
||||||
s5 -= carry5 * (1 << 21);
|
s5 -= carry5 * (1 << 21);
|
||||||
carry7 = (s7 + (1 << 20)) >> 21;
|
carry7 = (s7 + (1 << 20)) >> 21;
|
||||||
s8 += carry7;
|
s8 += carry7;
|
||||||
s7 -= carry7 * (1 << 21);
|
s7 -= carry7 * (1 << 21);
|
||||||
carry9 = (s9 + (1 << 20)) >> 21;
|
carry9 = (s9 + (1 << 20)) >> 21;
|
||||||
s10 += carry9;
|
s10 += carry9;
|
||||||
s9 -= carry9 * (1 << 21);
|
s9 -= carry9 * (1 << 21);
|
||||||
carry11 = (s11 + (1 << 20)) >> 21;
|
carry11 = (s11 + (1 << 20)) >> 21;
|
||||||
s12 += carry11;
|
s12 += carry11;
|
||||||
s11 -= carry11 * (1 << 21);
|
s11 -= carry11 * (1 << 21);
|
||||||
|
|
||||||
s0 += s12 * 666643;
|
s0 += s12 * 666643;
|
||||||
s1 += s12 * 470296;
|
s1 += s12 * 470296;
|
||||||
s2 += s12 * 654183;
|
s2 += s12 * 654183;
|
||||||
s3 -= s12 * 997805;
|
s3 -= s12 * 997805;
|
||||||
s4 += s12 * 136657;
|
s4 += s12 * 136657;
|
||||||
s5 -= s12 * 683901;
|
s5 -= s12 * 683901;
|
||||||
s12 = 0;
|
s12 = 0;
|
||||||
|
|
||||||
carry0 = s0 >> 21;
|
carry0 = s0 >> 21;
|
||||||
s1 += carry0;
|
s1 += carry0;
|
||||||
s0 -= carry0 * (1 << 21);
|
s0 -= carry0 * (1 << 21);
|
||||||
carry1 = s1 >> 21;
|
carry1 = s1 >> 21;
|
||||||
s2 += carry1;
|
s2 += carry1;
|
||||||
s1 -= carry1 * (1 << 21);
|
s1 -= carry1 * (1 << 21);
|
||||||
carry2 = s2 >> 21;
|
carry2 = s2 >> 21;
|
||||||
s3 += carry2;
|
s3 += carry2;
|
||||||
s2 -= carry2 * (1 << 21);
|
s2 -= carry2 * (1 << 21);
|
||||||
carry3 = s3 >> 21;
|
carry3 = s3 >> 21;
|
||||||
s4 += carry3;
|
s4 += carry3;
|
||||||
s3 -= carry3 * (1 << 21);
|
s3 -= carry3 * (1 << 21);
|
||||||
carry4 = s4 >> 21;
|
carry4 = s4 >> 21;
|
||||||
s5 += carry4;
|
s5 += carry4;
|
||||||
s4 -= carry4 * (1 << 21);
|
s4 -= carry4 * (1 << 21);
|
||||||
carry5 = s5 >> 21;
|
carry5 = s5 >> 21;
|
||||||
s6 += carry5;
|
s6 += carry5;
|
||||||
s5 -= carry5 * (1 << 21);
|
s5 -= carry5 * (1 << 21);
|
||||||
carry6 = s6 >> 21;
|
carry6 = s6 >> 21;
|
||||||
s7 += carry6;
|
s7 += carry6;
|
||||||
s6 -= carry6 * (1 << 21);
|
s6 -= carry6 * (1 << 21);
|
||||||
carry7 = s7 >> 21;
|
carry7 = s7 >> 21;
|
||||||
s8 += carry7;
|
s8 += carry7;
|
||||||
s7 -= carry7 * (1 << 21);
|
s7 -= carry7 * (1 << 21);
|
||||||
carry8 = s8 >> 21;
|
carry8 = s8 >> 21;
|
||||||
s9 += carry8;
|
s9 += carry8;
|
||||||
s8 -= carry8 * (1 << 21);
|
s8 -= carry8 * (1 << 21);
|
||||||
carry9 = s9 >> 21;
|
carry9 = s9 >> 21;
|
||||||
s10 += carry9;
|
s10 += carry9;
|
||||||
s9 -= carry9 * (1 << 21);
|
s9 -= carry9 * (1 << 21);
|
||||||
carry10 = s10 >> 21;
|
carry10 = s10 >> 21;
|
||||||
s11 += carry10;
|
s11 += carry10;
|
||||||
s10 -= carry10 * (1 << 21);
|
s10 -= carry10 * (1 << 21);
|
||||||
carry11 = s11 >> 21;
|
carry11 = s11 >> 21;
|
||||||
s12 += carry11;
|
s12 += carry11;
|
||||||
s11 -= carry11 * (1 << 21);
|
s11 -= carry11 * (1 << 21);
|
||||||
|
|
||||||
s0 += s12 * 666643;
|
s0 += s12 * 666643;
|
||||||
s1 += s12 * 470296;
|
s1 += s12 * 470296;
|
||||||
s2 += s12 * 654183;
|
s2 += s12 * 654183;
|
||||||
s3 -= s12 * 997805;
|
s3 -= s12 * 997805;
|
||||||
s4 += s12 * 136657;
|
s4 += s12 * 136657;
|
||||||
s5 -= s12 * 683901;
|
s5 -= s12 * 683901;
|
||||||
s12 = 0;
|
s12 = 0;
|
||||||
|
|
||||||
carry0 = s0 >> 21;
|
carry0 = s0 >> 21;
|
||||||
s1 += carry0;
|
s1 += carry0;
|
||||||
s0 -= carry0 * (1 << 21);
|
s0 -= carry0 * (1 << 21);
|
||||||
carry1 = s1 >> 21;
|
carry1 = s1 >> 21;
|
||||||
s2 += carry1;
|
s2 += carry1;
|
||||||
s1 -= carry1 * (1 << 21);
|
s1 -= carry1 * (1 << 21);
|
||||||
carry2 = s2 >> 21;
|
carry2 = s2 >> 21;
|
||||||
s3 += carry2;
|
s3 += carry2;
|
||||||
s2 -= carry2 * (1 << 21);
|
s2 -= carry2 * (1 << 21);
|
||||||
carry3 = s3 >> 21;
|
carry3 = s3 >> 21;
|
||||||
s4 += carry3;
|
s4 += carry3;
|
||||||
s3 -= carry3 * (1 << 21);
|
s3 -= carry3 * (1 << 21);
|
||||||
carry4 = s4 >> 21;
|
carry4 = s4 >> 21;
|
||||||
s5 += carry4;
|
s5 += carry4;
|
||||||
s4 -= carry4 * (1 << 21);
|
s4 -= carry4 * (1 << 21);
|
||||||
carry5 = s5 >> 21;
|
carry5 = s5 >> 21;
|
||||||
s6 += carry5;
|
s6 += carry5;
|
||||||
s5 -= carry5 * (1 << 21);
|
s5 -= carry5 * (1 << 21);
|
||||||
carry6 = s6 >> 21;
|
carry6 = s6 >> 21;
|
||||||
s7 += carry6;
|
s7 += carry6;
|
||||||
s6 -= carry6 * (1 << 21);
|
s6 -= carry6 * (1 << 21);
|
||||||
carry7 = s7 >> 21;
|
carry7 = s7 >> 21;
|
||||||
s8 += carry7;
|
s8 += carry7;
|
||||||
s7 -= carry7 * (1 << 21);
|
s7 -= carry7 * (1 << 21);
|
||||||
carry8 = s8 >> 21;
|
carry8 = s8 >> 21;
|
||||||
s9 += carry8;
|
s9 += carry8;
|
||||||
s8 -= carry8 * (1 << 21);
|
s8 -= carry8 * (1 << 21);
|
||||||
carry9 = s9 >> 21;
|
carry9 = s9 >> 21;
|
||||||
s10 += carry9;
|
s10 += carry9;
|
||||||
s9 -= carry9 * (1 << 21);
|
s9 -= carry9 * (1 << 21);
|
||||||
carry10 = s10 >> 21;
|
carry10 = s10 >> 21;
|
||||||
s11 += carry10;
|
s11 += carry10;
|
||||||
s10 -= carry10 * (1 << 21);
|
s10 -= carry10 * (1 << 21);
|
||||||
|
|
||||||
s[0] = (uint8_t)(s0 >> 0);
|
s[ 0] = (uint8_t) (s0 >> 0);
|
||||||
s[1] = (uint8_t)(s0 >> 8);
|
s[ 1] = (uint8_t) (s0 >> 8);
|
||||||
s[2] = (uint8_t)((s0 >> 16) | (s1 << 5));
|
s[ 2] = (uint8_t)((s0 >> 16) | (s1 << 5));
|
||||||
s[3] = (uint8_t)(s1 >> 3);
|
s[ 3] = (uint8_t) (s1 >> 3);
|
||||||
s[4] = (uint8_t)(s1 >> 11);
|
s[ 4] = (uint8_t) (s1 >> 11);
|
||||||
s[5] = (uint8_t)((s1 >> 19) | (s2 << 2));
|
s[ 5] = (uint8_t)((s1 >> 19) | (s2 << 2));
|
||||||
s[6] = (uint8_t)(s2 >> 6);
|
s[ 6] = (uint8_t) (s2 >> 6);
|
||||||
s[7] = (uint8_t)((s2 >> 14) | (s3 << 7));
|
s[ 7] = (uint8_t)((s2 >> 14) | (s3 << 7));
|
||||||
s[8] = (uint8_t)(s3 >> 1);
|
s[ 8] = (uint8_t) (s3 >> 1);
|
||||||
s[9] = (uint8_t)(s3 >> 9);
|
s[ 9] = (uint8_t) (s3 >> 9);
|
||||||
s[10] = (uint8_t)((s3 >> 17) | (s4 << 4));
|
s[10] = (uint8_t)((s3 >> 17) | (s4 << 4));
|
||||||
s[11] = (uint8_t)(s4 >> 4);
|
s[11] = (uint8_t) (s4 >> 4);
|
||||||
s[12] = (uint8_t)(s4 >> 12);
|
s[12] = (uint8_t) (s4 >> 12);
|
||||||
s[13] = (uint8_t)((s4 >> 20) | (s5 << 1));
|
s[13] = (uint8_t)((s4 >> 20) | (s5 << 1));
|
||||||
s[14] = (uint8_t)(s5 >> 7);
|
s[14] = (uint8_t) (s5 >> 7);
|
||||||
s[15] = (uint8_t)((s5 >> 15) | (s6 << 6));
|
s[15] = (uint8_t)((s5 >> 15) | (s6 << 6));
|
||||||
s[16] = (uint8_t)(s6 >> 2);
|
s[16] = (uint8_t) (s6 >> 2);
|
||||||
s[17] = (uint8_t)(s6 >> 10);
|
s[17] = (uint8_t) (s6 >> 10);
|
||||||
s[18] = (uint8_t)((s6 >> 18) | (s7 << 3));
|
s[18] = (uint8_t)((s6 >> 18) | (s7 << 3));
|
||||||
s[19] = (uint8_t)(s7 >> 5);
|
s[19] = (uint8_t) (s7 >> 5);
|
||||||
s[20] = (uint8_t)(s7 >> 13);
|
s[20] = (uint8_t) (s7 >> 13);
|
||||||
s[21] = (uint8_t)(s8 >> 0);
|
s[21] = (uint8_t) (s8 >> 0);
|
||||||
s[22] = (uint8_t)(s8 >> 8);
|
s[22] = (uint8_t) (s8 >> 8);
|
||||||
s[23] = (uint8_t)((s8 >> 16) | (s9 << 5));
|
s[23] = (uint8_t)((s8 >> 16) | (s9 << 5));
|
||||||
s[24] = (uint8_t)(s9 >> 3);
|
s[24] = (uint8_t) (s9 >> 3);
|
||||||
s[25] = (uint8_t)(s9 >> 11);
|
s[25] = (uint8_t) (s9 >> 11);
|
||||||
s[26] = (uint8_t)((s9 >> 19) | (s10 << 2));
|
s[26] = (uint8_t)((s9 >> 19) | (s10 << 2));
|
||||||
s[27] = (uint8_t)(s10 >> 6);
|
s[27] = (uint8_t) (s10 >> 6);
|
||||||
s[28] = (uint8_t)((s10 >> 14) | (s11 << 7));
|
s[28] = (uint8_t)((s10 >> 14) | (s11 << 7));
|
||||||
s[29] = (uint8_t)(s11 >> 1);
|
s[29] = (uint8_t) (s11 >> 1);
|
||||||
s[30] = (uint8_t)(s11 >> 9);
|
s[30] = (uint8_t) (s11 >> 9);
|
||||||
s[31] = (uint8_t)(s11 >> 17);
|
s[31] = (uint8_t) (s11 >> 17);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Input:
|
/*
|
||||||
|
* Input:
|
||||||
* a[0]+256*a[1]+...+256^31*a[31] = a
|
* a[0]+256*a[1]+...+256^31*a[31] = a
|
||||||
* b[0]+256*b[1]+...+256^31*b[31] = b
|
* b[0]+256*b[1]+...+256^31*b[31] = b
|
||||||
* c[0]+256*c[1]+...+256^31*c[31] = c
|
* c[0]+256*c[1]+...+256^31*c[31] = c
|
||||||
*
|
*
|
||||||
* Output:
|
* Output:
|
||||||
* s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
|
* s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
|
||||||
* where l = 2^252 + 27742317777372353535851937790883648493. */
|
* where l = 2^252 + 27742317777372353535851937790883648493.
|
||||||
|
*/
|
||||||
static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
|
static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
|
||||||
const uint8_t *c) {
|
const uint8_t *c)
|
||||||
int64_t a0 = 2097151 & load_3(a);
|
{
|
||||||
int64_t a1 = 2097151 & (load_4(a + 2) >> 5);
|
int64_t a0 = kBottom21Bits & load_3(a);
|
||||||
int64_t a2 = 2097151 & (load_3(a + 5) >> 2);
|
int64_t a1 = kBottom21Bits & (load_4(a + 2) >> 5);
|
||||||
int64_t a3 = 2097151 & (load_4(a + 7) >> 7);
|
int64_t a2 = kBottom21Bits & (load_3(a + 5) >> 2);
|
||||||
int64_t a4 = 2097151 & (load_4(a + 10) >> 4);
|
int64_t a3 = kBottom21Bits & (load_4(a + 7) >> 7);
|
||||||
int64_t a5 = 2097151 & (load_3(a + 13) >> 1);
|
int64_t a4 = kBottom21Bits & (load_4(a + 10) >> 4);
|
||||||
int64_t a6 = 2097151 & (load_4(a + 15) >> 6);
|
int64_t a5 = kBottom21Bits & (load_3(a + 13) >> 1);
|
||||||
int64_t a7 = 2097151 & (load_3(a + 18) >> 3);
|
int64_t a6 = kBottom21Bits & (load_4(a + 15) >> 6);
|
||||||
int64_t a8 = 2097151 & load_3(a + 21);
|
int64_t a7 = kBottom21Bits & (load_3(a + 18) >> 3);
|
||||||
int64_t a9 = 2097151 & (load_4(a + 23) >> 5);
|
int64_t a8 = kBottom21Bits & load_3(a + 21);
|
||||||
int64_t a10 = 2097151 & (load_3(a + 26) >> 2);
|
int64_t a9 = kBottom21Bits & (load_4(a + 23) >> 5);
|
||||||
int64_t a11 = (load_4(a + 28) >> 7);
|
int64_t a10 = kBottom21Bits & (load_3(a + 26) >> 2);
|
||||||
int64_t b0 = 2097151 & load_3(b);
|
int64_t a11 = (load_4(a + 28) >> 7);
|
||||||
int64_t b1 = 2097151 & (load_4(b + 2) >> 5);
|
int64_t b0 = kBottom21Bits & load_3(b);
|
||||||
int64_t b2 = 2097151 & (load_3(b + 5) >> 2);
|
int64_t b1 = kBottom21Bits & (load_4(b + 2) >> 5);
|
||||||
int64_t b3 = 2097151 & (load_4(b + 7) >> 7);
|
int64_t b2 = kBottom21Bits & (load_3(b + 5) >> 2);
|
||||||
int64_t b4 = 2097151 & (load_4(b + 10) >> 4);
|
int64_t b3 = kBottom21Bits & (load_4(b + 7) >> 7);
|
||||||
int64_t b5 = 2097151 & (load_3(b + 13) >> 1);
|
int64_t b4 = kBottom21Bits & (load_4(b + 10) >> 4);
|
||||||
int64_t b6 = 2097151 & (load_4(b + 15) >> 6);
|
int64_t b5 = kBottom21Bits & (load_3(b + 13) >> 1);
|
||||||
int64_t b7 = 2097151 & (load_3(b + 18) >> 3);
|
int64_t b6 = kBottom21Bits & (load_4(b + 15) >> 6);
|
||||||
int64_t b8 = 2097151 & load_3(b + 21);
|
int64_t b7 = kBottom21Bits & (load_3(b + 18) >> 3);
|
||||||
int64_t b9 = 2097151 & (load_4(b + 23) >> 5);
|
int64_t b8 = kBottom21Bits & load_3(b + 21);
|
||||||
int64_t b10 = 2097151 & (load_3(b + 26) >> 2);
|
int64_t b9 = kBottom21Bits & (load_4(b + 23) >> 5);
|
||||||
int64_t b11 = (load_4(b + 28) >> 7);
|
int64_t b10 = kBottom21Bits & (load_3(b + 26) >> 2);
|
||||||
int64_t c0 = 2097151 & load_3(c);
|
int64_t b11 = (load_4(b + 28) >> 7);
|
||||||
int64_t c1 = 2097151 & (load_4(c + 2) >> 5);
|
int64_t c0 = kBottom21Bits & load_3(c);
|
||||||
int64_t c2 = 2097151 & (load_3(c + 5) >> 2);
|
int64_t c1 = kBottom21Bits & (load_4(c + 2) >> 5);
|
||||||
int64_t c3 = 2097151 & (load_4(c + 7) >> 7);
|
int64_t c2 = kBottom21Bits & (load_3(c + 5) >> 2);
|
||||||
int64_t c4 = 2097151 & (load_4(c + 10) >> 4);
|
int64_t c3 = kBottom21Bits & (load_4(c + 7) >> 7);
|
||||||
int64_t c5 = 2097151 & (load_3(c + 13) >> 1);
|
int64_t c4 = kBottom21Bits & (load_4(c + 10) >> 4);
|
||||||
int64_t c6 = 2097151 & (load_4(c + 15) >> 6);
|
int64_t c5 = kBottom21Bits & (load_3(c + 13) >> 1);
|
||||||
int64_t c7 = 2097151 & (load_3(c + 18) >> 3);
|
int64_t c6 = kBottom21Bits & (load_4(c + 15) >> 6);
|
||||||
int64_t c8 = 2097151 & load_3(c + 21);
|
int64_t c7 = kBottom21Bits & (load_3(c + 18) >> 3);
|
||||||
int64_t c9 = 2097151 & (load_4(c + 23) >> 5);
|
int64_t c8 = kBottom21Bits & load_3(c + 21);
|
||||||
int64_t c10 = 2097151 & (load_3(c + 26) >> 2);
|
int64_t c9 = kBottom21Bits & (load_4(c + 23) >> 5);
|
||||||
int64_t c11 = (load_4(c + 28) >> 7);
|
int64_t c10 = kBottom21Bits & (load_3(c + 26) >> 2);
|
||||||
int64_t s0;
|
int64_t c11 = (load_4(c + 28) >> 7);
|
||||||
int64_t s1;
|
int64_t s0;
|
||||||
int64_t s2;
|
int64_t s1;
|
||||||
int64_t s3;
|
int64_t s2;
|
||||||
int64_t s4;
|
int64_t s3;
|
||||||
int64_t s5;
|
int64_t s4;
|
||||||
int64_t s6;
|
int64_t s5;
|
||||||
int64_t s7;
|
int64_t s6;
|
||||||
int64_t s8;
|
int64_t s7;
|
||||||
int64_t s9;
|
int64_t s8;
|
||||||
int64_t s10;
|
int64_t s9;
|
||||||
int64_t s11;
|
int64_t s10;
|
||||||
int64_t s12;
|
int64_t s11;
|
||||||
int64_t s13;
|
int64_t s12;
|
||||||
int64_t s14;
|
int64_t s13;
|
||||||
int64_t s15;
|
int64_t s14;
|
||||||
int64_t s16;
|
int64_t s15;
|
||||||
int64_t s17;
|
int64_t s16;
|
||||||
int64_t s18;
|
int64_t s17;
|
||||||
int64_t s19;
|
int64_t s18;
|
||||||
int64_t s20;
|
int64_t s19;
|
||||||
int64_t s21;
|
int64_t s20;
|
||||||
int64_t s22;
|
int64_t s21;
|
||||||
int64_t s23;
|
int64_t s22;
|
||||||
int64_t carry0;
|
int64_t s23;
|
||||||
int64_t carry1;
|
int64_t carry0;
|
||||||
int64_t carry2;
|
int64_t carry1;
|
||||||
int64_t carry3;
|
int64_t carry2;
|
||||||
int64_t carry4;
|
int64_t carry3;
|
||||||
int64_t carry5;
|
int64_t carry4;
|
||||||
int64_t carry6;
|
int64_t carry5;
|
||||||
int64_t carry7;
|
int64_t carry6;
|
||||||
int64_t carry8;
|
int64_t carry7;
|
||||||
int64_t carry9;
|
int64_t carry8;
|
||||||
int64_t carry10;
|
int64_t carry9;
|
||||||
int64_t carry11;
|
int64_t carry10;
|
||||||
int64_t carry12;
|
int64_t carry11;
|
||||||
int64_t carry13;
|
int64_t carry12;
|
||||||
int64_t carry14;
|
int64_t carry13;
|
||||||
int64_t carry15;
|
int64_t carry14;
|
||||||
int64_t carry16;
|
int64_t carry15;
|
||||||
int64_t carry17;
|
int64_t carry16;
|
||||||
int64_t carry18;
|
int64_t carry17;
|
||||||
int64_t carry19;
|
int64_t carry18;
|
||||||
int64_t carry20;
|
int64_t carry19;
|
||||||
int64_t carry21;
|
int64_t carry20;
|
||||||
int64_t carry22;
|
int64_t carry21;
|
||||||
|
int64_t carry22;
|
||||||
|
|
||||||
s0 = c0 + a0 * b0;
|
s0 = c0 + a0 * b0;
|
||||||
s1 = c1 + a0 * b1 + a1 * b0;
|
s1 = c1 + a0 * b1 + a1 * b0;
|
||||||
s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0;
|
s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0;
|
||||||
s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
|
s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
|
||||||
s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0;
|
s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0;
|
||||||
s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0;
|
s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0;
|
||||||
s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0;
|
s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0;
|
||||||
s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 +
|
s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0;
|
||||||
a6 * b1 + a7 * b0;
|
s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0;
|
||||||
s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 +
|
s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0;
|
||||||
a6 * b2 + a7 * b1 + a8 * b0;
|
s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0;
|
||||||
s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 +
|
s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0;
|
||||||
a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0;
|
s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1;
|
||||||
s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 +
|
s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2;
|
||||||
a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0;
|
s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3;
|
||||||
s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 +
|
s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4;
|
||||||
a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0;
|
s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5;
|
||||||
s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 +
|
s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6;
|
||||||
a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1;
|
s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7;
|
||||||
s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 +
|
s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8;
|
||||||
a9 * b4 + a10 * b3 + a11 * b2;
|
s20 = a9 * b11 + a10 * b10 + a11 * b9;
|
||||||
s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 +
|
s21 = a10 * b11 + a11 * b10;
|
||||||
a10 * b4 + a11 * b3;
|
s22 = a11 * b11;
|
||||||
s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 +
|
s23 = 0;
|
||||||
a11 * b4;
|
|
||||||
s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5;
|
|
||||||
s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6;
|
|
||||||
s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7;
|
|
||||||
s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8;
|
|
||||||
s20 = a9 * b11 + a10 * b10 + a11 * b9;
|
|
||||||
s21 = a10 * b11 + a11 * b10;
|
|
||||||
s22 = a11 * b11;
|
|
||||||
s23 = 0;
|
|
||||||
|
|
||||||
carry0 = (s0 + (1 << 20)) >> 21;
|
carry0 = (s0 + (1 << 20)) >> 21;
|
||||||
s1 += carry0;
|
s1 += carry0;
|
||||||
s0 -= carry0 * (1 << 21);
|
s0 -= carry0 * (1 << 21);
|
||||||
carry2 = (s2 + (1 << 20)) >> 21;
|
carry2 = (s2 + (1 << 20)) >> 21;
|
||||||
s3 += carry2;
|
s3 += carry2;
|
||||||
s2 -= carry2 * (1 << 21);
|
s2 -= carry2 * (1 << 21);
|
||||||
carry4 = (s4 + (1 << 20)) >> 21;
|
carry4 = (s4 + (1 << 20)) >> 21;
|
||||||
s5 += carry4;
|
s5 += carry4;
|
||||||
s4 -= carry4 * (1 << 21);
|
s4 -= carry4 * (1 << 21);
|
||||||
carry6 = (s6 + (1 << 20)) >> 21;
|
carry6 = (s6 + (1 << 20)) >> 21;
|
||||||
s7 += carry6;
|
s7 += carry6;
|
||||||
s6 -= carry6 * (1 << 21);
|
s6 -= carry6 * (1 << 21);
|
||||||
carry8 = (s8 + (1 << 20)) >> 21;
|
carry8 = (s8 + (1 << 20)) >> 21;
|
||||||
s9 += carry8;
|
s9 += carry8;
|
||||||
s8 -= carry8 * (1 << 21);
|
s8 -= carry8 * (1 << 21);
|
||||||
carry10 = (s10 + (1 << 20)) >> 21;
|
carry10 = (s10 + (1 << 20)) >> 21;
|
||||||
s11 += carry10;
|
s11 += carry10;
|
||||||
s10 -= carry10 * (1 << 21);
|
s10 -= carry10 * (1 << 21);
|
||||||
carry12 = (s12 + (1 << 20)) >> 21;
|
carry12 = (s12 + (1 << 20)) >> 21;
|
||||||
s13 += carry12;
|
s13 += carry12;
|
||||||
s12 -= carry12 * (1 << 21);
|
s12 -= carry12 * (1 << 21);
|
||||||
carry14 = (s14 + (1 << 20)) >> 21;
|
carry14 = (s14 + (1 << 20)) >> 21;
|
||||||
s15 += carry14;
|
s15 += carry14;
|
||||||
s14 -= carry14 * (1 << 21);
|
s14 -= carry14 * (1 << 21);
|
||||||
carry16 = (s16 + (1 << 20)) >> 21;
|
carry16 = (s16 + (1 << 20)) >> 21;
|
||||||
s17 += carry16;
|
s17 += carry16;
|
||||||
s16 -= carry16 * (1 << 21);
|
s16 -= carry16 * (1 << 21);
|
||||||
carry18 = (s18 + (1 << 20)) >> 21;
|
carry18 = (s18 + (1 << 20)) >> 21;
|
||||||
s19 += carry18;
|
s19 += carry18;
|
||||||
s18 -= carry18 * (1 << 21);
|
s18 -= carry18 * (1 << 21);
|
||||||
carry20 = (s20 + (1 << 20)) >> 21;
|
carry20 = (s20 + (1 << 20)) >> 21;
|
||||||
s21 += carry20;
|
s21 += carry20;
|
||||||
s20 -= carry20 * (1 << 21);
|
s20 -= carry20 * (1 << 21);
|
||||||
carry22 = (s22 + (1 << 20)) >> 21;
|
carry22 = (s22 + (1 << 20)) >> 21;
|
||||||
s23 += carry22;
|
s23 += carry22;
|
||||||
s22 -= carry22 * (1 << 21);
|
s22 -= carry22 * (1 << 21);
|
||||||
|
|
||||||
carry1 = (s1 + (1 << 20)) >> 21;
|
carry1 = (s1 + (1 << 20)) >> 21;
|
||||||
s2 += carry1;
|
s2 += carry1;
|
||||||
s1 -= carry1 * (1 << 21);
|
s1 -= carry1 * (1 << 21);
|
||||||
carry3 = (s3 + (1 << 20)) >> 21;
|
carry3 = (s3 + (1 << 20)) >> 21;
|
||||||
s4 += carry3;
|
s4 += carry3;
|
||||||
s3 -= carry3 * (1 << 21);
|
s3 -= carry3 * (1 << 21);
|
||||||
carry5 = (s5 + (1 << 20)) >> 21;
|
carry5 = (s5 + (1 << 20)) >> 21;
|
||||||
s6 += carry5;
|
s6 += carry5;
|
||||||
s5 -= carry5 * (1 << 21);
|
s5 -= carry5 * (1 << 21);
|
||||||
carry7 = (s7 + (1 << 20)) >> 21;
|
carry7 = (s7 + (1 << 20)) >> 21;
|
||||||
s8 += carry7;
|
s8 += carry7;
|
||||||
s7 -= carry7 * (1 << 21);
|
s7 -= carry7 * (1 << 21);
|
||||||
carry9 = (s9 + (1 << 20)) >> 21;
|
carry9 = (s9 + (1 << 20)) >> 21;
|
||||||
s10 += carry9;
|
s10 += carry9;
|
||||||
s9 -= carry9 * (1 << 21);
|
s9 -= carry9 * (1 << 21);
|
||||||
carry11 = (s11 + (1 << 20)) >> 21;
|
carry11 = (s11 + (1 << 20)) >> 21;
|
||||||
s12 += carry11;
|
s12 += carry11;
|
||||||
s11 -= carry11 * (1 << 21);
|
s11 -= carry11 * (1 << 21);
|
||||||
carry13 = (s13 + (1 << 20)) >> 21;
|
carry13 = (s13 + (1 << 20)) >> 21;
|
||||||
s14 += carry13;
|
s14 += carry13;
|
||||||
s13 -= carry13 * (1 << 21);
|
s13 -= carry13 * (1 << 21);
|
||||||
carry15 = (s15 + (1 << 20)) >> 21;
|
carry15 = (s15 + (1 << 20)) >> 21;
|
||||||
s16 += carry15;
|
s16 += carry15;
|
||||||
s15 -= carry15 * (1 << 21);
|
s15 -= carry15 * (1 << 21);
|
||||||
carry17 = (s17 + (1 << 20)) >> 21;
|
carry17 = (s17 + (1 << 20)) >> 21;
|
||||||
s18 += carry17;
|
s18 += carry17;
|
||||||
s17 -= carry17 * (1 << 21);
|
s17 -= carry17 * (1 << 21);
|
||||||
carry19 = (s19 + (1 << 20)) >> 21;
|
carry19 = (s19 + (1 << 20)) >> 21;
|
||||||
s20 += carry19;
|
s20 += carry19;
|
||||||
s19 -= carry19 * (1 << 21);
|
s19 -= carry19 * (1 << 21);
|
||||||
carry21 = (s21 + (1 << 20)) >> 21;
|
carry21 = (s21 + (1 << 20)) >> 21;
|
||||||
s22 += carry21;
|
s22 += carry21;
|
||||||
s21 -= carry21 * (1 << 21);
|
s21 -= carry21 * (1 << 21);
|
||||||
|
|
||||||
s11 += s23 * 666643;
|
s11 += s23 * 666643;
|
||||||
s12 += s23 * 470296;
|
s12 += s23 * 470296;
|
||||||
s13 += s23 * 654183;
|
s13 += s23 * 654183;
|
||||||
s14 -= s23 * 997805;
|
s14 -= s23 * 997805;
|
||||||
s15 += s23 * 136657;
|
s15 += s23 * 136657;
|
||||||
s16 -= s23 * 683901;
|
s16 -= s23 * 683901;
|
||||||
s23 = 0;
|
s23 = 0;
|
||||||
|
|
||||||
s10 += s22 * 666643;
|
s10 += s22 * 666643;
|
||||||
s11 += s22 * 470296;
|
s11 += s22 * 470296;
|
||||||
s12 += s22 * 654183;
|
s12 += s22 * 654183;
|
||||||
s13 -= s22 * 997805;
|
s13 -= s22 * 997805;
|
||||||
s14 += s22 * 136657;
|
s14 += s22 * 136657;
|
||||||
s15 -= s22 * 683901;
|
s15 -= s22 * 683901;
|
||||||
s22 = 0;
|
s22 = 0;
|
||||||
|
|
||||||
s9 += s21 * 666643;
|
s9 += s21 * 666643;
|
||||||
s10 += s21 * 470296;
|
s10 += s21 * 470296;
|
||||||
s11 += s21 * 654183;
|
s11 += s21 * 654183;
|
||||||
s12 -= s21 * 997805;
|
s12 -= s21 * 997805;
|
||||||
s13 += s21 * 136657;
|
s13 += s21 * 136657;
|
||||||
s14 -= s21 * 683901;
|
s14 -= s21 * 683901;
|
||||||
s21 = 0;
|
s21 = 0;
|
||||||
|
|
||||||
s8 += s20 * 666643;
|
s8 += s20 * 666643;
|
||||||
s9 += s20 * 470296;
|
s9 += s20 * 470296;
|
||||||
s10 += s20 * 654183;
|
s10 += s20 * 654183;
|
||||||
s11 -= s20 * 997805;
|
s11 -= s20 * 997805;
|
||||||
s12 += s20 * 136657;
|
s12 += s20 * 136657;
|
||||||
s13 -= s20 * 683901;
|
s13 -= s20 * 683901;
|
||||||
s20 = 0;
|
s20 = 0;
|
||||||
|
|
||||||
s7 += s19 * 666643;
|
s7 += s19 * 666643;
|
||||||
s8 += s19 * 470296;
|
s8 += s19 * 470296;
|
||||||
s9 += s19 * 654183;
|
s9 += s19 * 654183;
|
||||||
s10 -= s19 * 997805;
|
s10 -= s19 * 997805;
|
||||||
s11 += s19 * 136657;
|
s11 += s19 * 136657;
|
||||||
s12 -= s19 * 683901;
|
s12 -= s19 * 683901;
|
||||||
s19 = 0;
|
s19 = 0;
|
||||||
|
|
||||||
s6 += s18 * 666643;
|
s6 += s18 * 666643;
|
||||||
s7 += s18 * 470296;
|
s7 += s18 * 470296;
|
||||||
s8 += s18 * 654183;
|
s8 += s18 * 654183;
|
||||||
s9 -= s18 * 997805;
|
s9 -= s18 * 997805;
|
||||||
s10 += s18 * 136657;
|
s10 += s18 * 136657;
|
||||||
s11 -= s18 * 683901;
|
s11 -= s18 * 683901;
|
||||||
s18 = 0;
|
s18 = 0;
|
||||||
|
|
||||||
carry6 = (s6 + (1 << 20)) >> 21;
|
carry6 = (s6 + (1 << 20)) >> 21;
|
||||||
s7 += carry6;
|
s7 += carry6;
|
||||||
s6 -= carry6 * (1 << 21);
|
s6 -= carry6 * (1 << 21);
|
||||||
carry8 = (s8 + (1 << 20)) >> 21;
|
carry8 = (s8 + (1 << 20)) >> 21;
|
||||||
s9 += carry8;
|
s9 += carry8;
|
||||||
s8 -= carry8 * (1 << 21);
|
s8 -= carry8 * (1 << 21);
|
||||||
carry10 = (s10 + (1 << 20)) >> 21;
|
carry10 = (s10 + (1 << 20)) >> 21;
|
||||||
s11 += carry10;
|
s11 += carry10;
|
||||||
s10 -= carry10 * (1 << 21);
|
s10 -= carry10 * (1 << 21);
|
||||||
carry12 = (s12 + (1 << 20)) >> 21;
|
carry12 = (s12 + (1 << 20)) >> 21;
|
||||||
s13 += carry12;
|
s13 += carry12;
|
||||||
s12 -= carry12 * (1 << 21);
|
s12 -= carry12 * (1 << 21);
|
||||||
carry14 = (s14 + (1 << 20)) >> 21;
|
carry14 = (s14 + (1 << 20)) >> 21;
|
||||||
s15 += carry14;
|
s15 += carry14;
|
||||||
s14 -= carry14 * (1 << 21);
|
s14 -= carry14 * (1 << 21);
|
||||||
carry16 = (s16 + (1 << 20)) >> 21;
|
carry16 = (s16 + (1 << 20)) >> 21;
|
||||||
s17 += carry16;
|
s17 += carry16;
|
||||||
s16 -= carry16 * (1 << 21);
|
s16 -= carry16 * (1 << 21);
|
||||||
|
|
||||||
carry7 = (s7 + (1 << 20)) >> 21;
|
carry7 = (s7 + (1 << 20)) >> 21;
|
||||||
s8 += carry7;
|
s8 += carry7;
|
||||||
s7 -= carry7 * (1 << 21);
|
s7 -= carry7 * (1 << 21);
|
||||||
carry9 = (s9 + (1 << 20)) >> 21;
|
carry9 = (s9 + (1 << 20)) >> 21;
|
||||||
s10 += carry9;
|
s10 += carry9;
|
||||||
s9 -= carry9 * (1 << 21);
|
s9 -= carry9 * (1 << 21);
|
||||||
carry11 = (s11 + (1 << 20)) >> 21;
|
carry11 = (s11 + (1 << 20)) >> 21;
|
||||||
s12 += carry11;
|
s12 += carry11;
|
||||||
s11 -= carry11 * (1 << 21);
|
s11 -= carry11 * (1 << 21);
|
||||||
carry13 = (s13 + (1 << 20)) >> 21;
|
carry13 = (s13 + (1 << 20)) >> 21;
|
||||||
s14 += carry13;
|
s14 += carry13;
|
||||||
s13 -= carry13 * (1 << 21);
|
s13 -= carry13 * (1 << 21);
|
||||||
carry15 = (s15 + (1 << 20)) >> 21;
|
carry15 = (s15 + (1 << 20)) >> 21;
|
||||||
s16 += carry15;
|
s16 += carry15;
|
||||||
s15 -= carry15 * (1 << 21);
|
s15 -= carry15 * (1 << 21);
|
||||||
|
|
||||||
s5 += s17 * 666643;
|
s5 += s17 * 666643;
|
||||||
s6 += s17 * 470296;
|
s6 += s17 * 470296;
|
||||||
s7 += s17 * 654183;
|
s7 += s17 * 654183;
|
||||||
s8 -= s17 * 997805;
|
s8 -= s17 * 997805;
|
||||||
s9 += s17 * 136657;
|
s9 += s17 * 136657;
|
||||||
s10 -= s17 * 683901;
|
s10 -= s17 * 683901;
|
||||||
s17 = 0;
|
s17 = 0;
|
||||||
|
|
||||||
s4 += s16 * 666643;
|
s4 += s16 * 666643;
|
||||||
s5 += s16 * 470296;
|
s5 += s16 * 470296;
|
||||||
s6 += s16 * 654183;
|
s6 += s16 * 654183;
|
||||||
s7 -= s16 * 997805;
|
s7 -= s16 * 997805;
|
||||||
s8 += s16 * 136657;
|
s8 += s16 * 136657;
|
||||||
s9 -= s16 * 683901;
|
s9 -= s16 * 683901;
|
||||||
s16 = 0;
|
s16 = 0;
|
||||||
|
|
||||||
s3 += s15 * 666643;
|
s3 += s15 * 666643;
|
||||||
s4 += s15 * 470296;
|
s4 += s15 * 470296;
|
||||||
s5 += s15 * 654183;
|
s5 += s15 * 654183;
|
||||||
s6 -= s15 * 997805;
|
s6 -= s15 * 997805;
|
||||||
s7 += s15 * 136657;
|
s7 += s15 * 136657;
|
||||||
s8 -= s15 * 683901;
|
s8 -= s15 * 683901;
|
||||||
s15 = 0;
|
s15 = 0;
|
||||||
|
|
||||||
s2 += s14 * 666643;
|
s2 += s14 * 666643;
|
||||||
s3 += s14 * 470296;
|
s3 += s14 * 470296;
|
||||||
s4 += s14 * 654183;
|
s4 += s14 * 654183;
|
||||||
s5 -= s14 * 997805;
|
s5 -= s14 * 997805;
|
||||||
s6 += s14 * 136657;
|
s6 += s14 * 136657;
|
||||||
s7 -= s14 * 683901;
|
s7 -= s14 * 683901;
|
||||||
s14 = 0;
|
s14 = 0;
|
||||||
|
|
||||||
s1 += s13 * 666643;
|
s1 += s13 * 666643;
|
||||||
s2 += s13 * 470296;
|
s2 += s13 * 470296;
|
||||||
s3 += s13 * 654183;
|
s3 += s13 * 654183;
|
||||||
s4 -= s13 * 997805;
|
s4 -= s13 * 997805;
|
||||||
s5 += s13 * 136657;
|
s5 += s13 * 136657;
|
||||||
s6 -= s13 * 683901;
|
s6 -= s13 * 683901;
|
||||||
s13 = 0;
|
s13 = 0;
|
||||||
|
|
||||||
s0 += s12 * 666643;
|
s0 += s12 * 666643;
|
||||||
s1 += s12 * 470296;
|
s1 += s12 * 470296;
|
||||||
s2 += s12 * 654183;
|
s2 += s12 * 654183;
|
||||||
s3 -= s12 * 997805;
|
s3 -= s12 * 997805;
|
||||||
s4 += s12 * 136657;
|
s4 += s12 * 136657;
|
||||||
s5 -= s12 * 683901;
|
s5 -= s12 * 683901;
|
||||||
s12 = 0;
|
s12 = 0;
|
||||||
|
|
||||||
carry0 = (s0 + (1 << 20)) >> 21;
|
carry0 = (s0 + (1 << 20)) >> 21;
|
||||||
s1 += carry0;
|
s1 += carry0;
|
||||||
s0 -= carry0 * (1 << 21);
|
s0 -= carry0 * (1 << 21);
|
||||||
carry2 = (s2 + (1 << 20)) >> 21;
|
carry2 = (s2 + (1 << 20)) >> 21;
|
||||||
s3 += carry2;
|
s3 += carry2;
|
||||||
s2 -= carry2 * (1 << 21);
|
s2 -= carry2 * (1 << 21);
|
||||||
carry4 = (s4 + (1 << 20)) >> 21;
|
carry4 = (s4 + (1 << 20)) >> 21;
|
||||||
s5 += carry4;
|
s5 += carry4;
|
||||||
s4 -= carry4 * (1 << 21);
|
s4 -= carry4 * (1 << 21);
|
||||||
carry6 = (s6 + (1 << 20)) >> 21;
|
carry6 = (s6 + (1 << 20)) >> 21;
|
||||||
s7 += carry6;
|
s7 += carry6;
|
||||||
s6 -= carry6 * (1 << 21);
|
s6 -= carry6 * (1 << 21);
|
||||||
carry8 = (s8 + (1 << 20)) >> 21;
|
carry8 = (s8 + (1 << 20)) >> 21;
|
||||||
s9 += carry8;
|
s9 += carry8;
|
||||||
s8 -= carry8 * (1 << 21);
|
s8 -= carry8 * (1 << 21);
|
||||||
carry10 = (s10 + (1 << 20)) >> 21;
|
carry10 = (s10 + (1 << 20)) >> 21;
|
||||||
s11 += carry10;
|
s11 += carry10;
|
||||||
s10 -= carry10 * (1 << 21);
|
s10 -= carry10 * (1 << 21);
|
||||||
|
|
||||||
carry1 = (s1 + (1 << 20)) >> 21;
|
carry1 = (s1 + (1 << 20)) >> 21;
|
||||||
s2 += carry1;
|
s2 += carry1;
|
||||||
s1 -= carry1 * (1 << 21);
|
s1 -= carry1 * (1 << 21);
|
||||||
carry3 = (s3 + (1 << 20)) >> 21;
|
carry3 = (s3 + (1 << 20)) >> 21;
|
||||||
s4 += carry3;
|
s4 += carry3;
|
||||||
s3 -= carry3 * (1 << 21);
|
s3 -= carry3 * (1 << 21);
|
||||||
carry5 = (s5 + (1 << 20)) >> 21;
|
carry5 = (s5 + (1 << 20)) >> 21;
|
||||||
s6 += carry5;
|
s6 += carry5;
|
||||||
s5 -= carry5 * (1 << 21);
|
s5 -= carry5 * (1 << 21);
|
||||||
carry7 = (s7 + (1 << 20)) >> 21;
|
carry7 = (s7 + (1 << 20)) >> 21;
|
||||||
s8 += carry7;
|
s8 += carry7;
|
||||||
s7 -= carry7 * (1 << 21);
|
s7 -= carry7 * (1 << 21);
|
||||||
carry9 = (s9 + (1 << 20)) >> 21;
|
carry9 = (s9 + (1 << 20)) >> 21;
|
||||||
s10 += carry9;
|
s10 += carry9;
|
||||||
s9 -= carry9 * (1 << 21);
|
s9 -= carry9 * (1 << 21);
|
||||||
carry11 = (s11 + (1 << 20)) >> 21;
|
carry11 = (s11 + (1 << 20)) >> 21;
|
||||||
s12 += carry11;
|
s12 += carry11;
|
||||||
s11 -= carry11 * (1 << 21);
|
s11 -= carry11 * (1 << 21);
|
||||||
|
|
||||||
s0 += s12 * 666643;
|
s0 += s12 * 666643;
|
||||||
s1 += s12 * 470296;
|
s1 += s12 * 470296;
|
||||||
s2 += s12 * 654183;
|
s2 += s12 * 654183;
|
||||||
s3 -= s12 * 997805;
|
s3 -= s12 * 997805;
|
||||||
s4 += s12 * 136657;
|
s4 += s12 * 136657;
|
||||||
s5 -= s12 * 683901;
|
s5 -= s12 * 683901;
|
||||||
s12 = 0;
|
s12 = 0;
|
||||||
|
|
||||||
carry0 = s0 >> 21;
|
carry0 = s0 >> 21;
|
||||||
s1 += carry0;
|
s1 += carry0;
|
||||||
s0 -= carry0 * (1 << 21);
|
s0 -= carry0 * (1 << 21);
|
||||||
carry1 = s1 >> 21;
|
carry1 = s1 >> 21;
|
||||||
s2 += carry1;
|
s2 += carry1;
|
||||||
s1 -= carry1 * (1 << 21);
|
s1 -= carry1 * (1 << 21);
|
||||||
carry2 = s2 >> 21;
|
carry2 = s2 >> 21;
|
||||||
s3 += carry2;
|
s3 += carry2;
|
||||||
s2 -= carry2 * (1 << 21);
|
s2 -= carry2 * (1 << 21);
|
||||||
carry3 = s3 >> 21;
|
carry3 = s3 >> 21;
|
||||||
s4 += carry3;
|
s4 += carry3;
|
||||||
s3 -= carry3 * (1 << 21);
|
s3 -= carry3 * (1 << 21);
|
||||||
carry4 = s4 >> 21;
|
carry4 = s4 >> 21;
|
||||||
s5 += carry4;
|
s5 += carry4;
|
||||||
s4 -= carry4 * (1 << 21);
|
s4 -= carry4 * (1 << 21);
|
||||||
carry5 = s5 >> 21;
|
carry5 = s5 >> 21;
|
||||||
s6 += carry5;
|
s6 += carry5;
|
||||||
s5 -= carry5 * (1 << 21);
|
s5 -= carry5 * (1 << 21);
|
||||||
carry6 = s6 >> 21;
|
carry6 = s6 >> 21;
|
||||||
s7 += carry6;
|
s7 += carry6;
|
||||||
s6 -= carry6 * (1 << 21);
|
s6 -= carry6 * (1 << 21);
|
||||||
carry7 = s7 >> 21;
|
carry7 = s7 >> 21;
|
||||||
s8 += carry7;
|
s8 += carry7;
|
||||||
s7 -= carry7 * (1 << 21);
|
s7 -= carry7 * (1 << 21);
|
||||||
carry8 = s8 >> 21;
|
carry8 = s8 >> 21;
|
||||||
s9 += carry8;
|
s9 += carry8;
|
||||||
s8 -= carry8 * (1 << 21);
|
s8 -= carry8 * (1 << 21);
|
||||||
carry9 = s9 >> 21;
|
carry9 = s9 >> 21;
|
||||||
s10 += carry9;
|
s10 += carry9;
|
||||||
s9 -= carry9 * (1 << 21);
|
s9 -= carry9 * (1 << 21);
|
||||||
carry10 = s10 >> 21;
|
carry10 = s10 >> 21;
|
||||||
s11 += carry10;
|
s11 += carry10;
|
||||||
s10 -= carry10 * (1 << 21);
|
s10 -= carry10 * (1 << 21);
|
||||||
carry11 = s11 >> 21;
|
carry11 = s11 >> 21;
|
||||||
s12 += carry11;
|
s12 += carry11;
|
||||||
s11 -= carry11 * (1 << 21);
|
s11 -= carry11 * (1 << 21);
|
||||||
|
|
||||||
s0 += s12 * 666643;
|
s0 += s12 * 666643;
|
||||||
s1 += s12 * 470296;
|
s1 += s12 * 470296;
|
||||||
s2 += s12 * 654183;
|
s2 += s12 * 654183;
|
||||||
s3 -= s12 * 997805;
|
s3 -= s12 * 997805;
|
||||||
s4 += s12 * 136657;
|
s4 += s12 * 136657;
|
||||||
s5 -= s12 * 683901;
|
s5 -= s12 * 683901;
|
||||||
s12 = 0;
|
s12 = 0;
|
||||||
|
|
||||||
carry0 = s0 >> 21;
|
carry0 = s0 >> 21;
|
||||||
s1 += carry0;
|
s1 += carry0;
|
||||||
s0 -= carry0 * (1 << 21);
|
s0 -= carry0 * (1 << 21);
|
||||||
carry1 = s1 >> 21;
|
carry1 = s1 >> 21;
|
||||||
s2 += carry1;
|
s2 += carry1;
|
||||||
s1 -= carry1 * (1 << 21);
|
s1 -= carry1 * (1 << 21);
|
||||||
carry2 = s2 >> 21;
|
carry2 = s2 >> 21;
|
||||||
s3 += carry2;
|
s3 += carry2;
|
||||||
s2 -= carry2 * (1 << 21);
|
s2 -= carry2 * (1 << 21);
|
||||||
carry3 = s3 >> 21;
|
carry3 = s3 >> 21;
|
||||||
s4 += carry3;
|
s4 += carry3;
|
||||||
s3 -= carry3 * (1 << 21);
|
s3 -= carry3 * (1 << 21);
|
||||||
carry4 = s4 >> 21;
|
carry4 = s4 >> 21;
|
||||||
s5 += carry4;
|
s5 += carry4;
|
||||||
s4 -= carry4 * (1 << 21);
|
s4 -= carry4 * (1 << 21);
|
||||||
carry5 = s5 >> 21;
|
carry5 = s5 >> 21;
|
||||||
s6 += carry5;
|
s6 += carry5;
|
||||||
s5 -= carry5 * (1 << 21);
|
s5 -= carry5 * (1 << 21);
|
||||||
carry6 = s6 >> 21;
|
carry6 = s6 >> 21;
|
||||||
s7 += carry6;
|
s7 += carry6;
|
||||||
s6 -= carry6 * (1 << 21);
|
s6 -= carry6 * (1 << 21);
|
||||||
carry7 = s7 >> 21;
|
carry7 = s7 >> 21;
|
||||||
s8 += carry7;
|
s8 += carry7;
|
||||||
s7 -= carry7 * (1 << 21);
|
s7 -= carry7 * (1 << 21);
|
||||||
carry8 = s8 >> 21;
|
carry8 = s8 >> 21;
|
||||||
s9 += carry8;
|
s9 += carry8;
|
||||||
s8 -= carry8 * (1 << 21);
|
s8 -= carry8 * (1 << 21);
|
||||||
carry9 = s9 >> 21;
|
carry9 = s9 >> 21;
|
||||||
s10 += carry9;
|
s10 += carry9;
|
||||||
s9 -= carry9 * (1 << 21);
|
s9 -= carry9 * (1 << 21);
|
||||||
carry10 = s10 >> 21;
|
carry10 = s10 >> 21;
|
||||||
s11 += carry10;
|
s11 += carry10;
|
||||||
s10 -= carry10 * (1 << 21);
|
s10 -= carry10 * (1 << 21);
|
||||||
|
|
||||||
s[0] = (uint8_t)(s0 >> 0);
|
s[ 0] = (uint8_t) (s0 >> 0);
|
||||||
s[1] = (uint8_t)(s0 >> 8);
|
s[ 1] = (uint8_t) (s0 >> 8);
|
||||||
s[2] = (uint8_t)((s0 >> 16) | (s1 << 5));
|
s[ 2] = (uint8_t)((s0 >> 16) | (s1 << 5));
|
||||||
s[3] = (uint8_t)(s1 >> 3);
|
s[ 3] = (uint8_t) (s1 >> 3);
|
||||||
s[4] = (uint8_t)(s1 >> 11);
|
s[ 4] = (uint8_t) (s1 >> 11);
|
||||||
s[5] = (uint8_t)((s1 >> 19) | (s2 << 2));
|
s[ 5] = (uint8_t)((s1 >> 19) | (s2 << 2));
|
||||||
s[6] = (uint8_t)(s2 >> 6);
|
s[ 6] = (uint8_t) (s2 >> 6);
|
||||||
s[7] = (uint8_t)((s2 >> 14) | (s3 << 7));
|
s[ 7] = (uint8_t)((s2 >> 14) | (s3 << 7));
|
||||||
s[8] = (uint8_t)(s3 >> 1);
|
s[ 8] = (uint8_t) (s3 >> 1);
|
||||||
s[9] = (uint8_t)(s3 >> 9);
|
s[ 9] = (uint8_t) (s3 >> 9);
|
||||||
s[10] = (uint8_t)((s3 >> 17) | (s4 << 4));
|
s[10] = (uint8_t)((s3 >> 17) | (s4 << 4));
|
||||||
s[11] = (uint8_t)(s4 >> 4);
|
s[11] = (uint8_t) (s4 >> 4);
|
||||||
s[12] = (uint8_t)(s4 >> 12);
|
s[12] = (uint8_t) (s4 >> 12);
|
||||||
s[13] = (uint8_t)((s4 >> 20) | (s5 << 1));
|
s[13] = (uint8_t)((s4 >> 20) | (s5 << 1));
|
||||||
s[14] = (uint8_t)(s5 >> 7);
|
s[14] = (uint8_t) (s5 >> 7);
|
||||||
s[15] = (uint8_t)((s5 >> 15) | (s6 << 6));
|
s[15] = (uint8_t)((s5 >> 15) | (s6 << 6));
|
||||||
s[16] = (uint8_t)(s6 >> 2);
|
s[16] = (uint8_t) (s6 >> 2);
|
||||||
s[17] = (uint8_t)(s6 >> 10);
|
s[17] = (uint8_t) (s6 >> 10);
|
||||||
s[18] = (uint8_t)((s6 >> 18) | (s7 << 3));
|
s[18] = (uint8_t)((s6 >> 18) | (s7 << 3));
|
||||||
s[19] = (uint8_t)(s7 >> 5);
|
s[19] = (uint8_t) (s7 >> 5);
|
||||||
s[20] = (uint8_t)(s7 >> 13);
|
s[20] = (uint8_t) (s7 >> 13);
|
||||||
s[21] = (uint8_t)(s8 >> 0);
|
s[21] = (uint8_t) (s8 >> 0);
|
||||||
s[22] = (uint8_t)(s8 >> 8);
|
s[22] = (uint8_t) (s8 >> 8);
|
||||||
s[23] = (uint8_t)((s8 >> 16) | (s9 << 5));
|
s[23] = (uint8_t)((s8 >> 16) | (s9 << 5));
|
||||||
s[24] = (uint8_t)(s9 >> 3);
|
s[24] = (uint8_t) (s9 >> 3);
|
||||||
s[25] = (uint8_t)(s9 >> 11);
|
s[25] = (uint8_t) (s9 >> 11);
|
||||||
s[26] = (uint8_t)((s9 >> 19) | (s10 << 2));
|
s[26] = (uint8_t)((s9 >> 19) | (s10 << 2));
|
||||||
s[27] = (uint8_t)(s10 >> 6);
|
s[27] = (uint8_t) (s10 >> 6);
|
||||||
s[28] = (uint8_t)((s10 >> 14) | (s11 << 7));
|
s[28] = (uint8_t)((s10 >> 14) | (s11 << 7));
|
||||||
s[29] = (uint8_t)(s11 >> 1);
|
s[29] = (uint8_t) (s11 >> 1);
|
||||||
s[30] = (uint8_t)(s11 >> 9);
|
s[30] = (uint8_t) (s11 >> 9);
|
||||||
s[31] = (uint8_t)(s11 >> 17);
|
s[31] = (uint8_t) (s11 >> 17);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
|
int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
|
||||||
const uint8_t public_key[32], const uint8_t private_key[32]) {
|
const uint8_t public_key[32], const uint8_t private_key[32])
|
||||||
uint8_t az[SHA512_DIGEST_LENGTH];
|
{
|
||||||
uint8_t nonce[SHA512_DIGEST_LENGTH];
|
uint8_t az[SHA512_DIGEST_LENGTH];
|
||||||
ge_p3 R;
|
uint8_t nonce[SHA512_DIGEST_LENGTH];
|
||||||
uint8_t hram[SHA512_DIGEST_LENGTH];
|
ge_p3 R;
|
||||||
SHA512_CTX hash_ctx;
|
uint8_t hram[SHA512_DIGEST_LENGTH];
|
||||||
|
SHA512_CTX hash_ctx;
|
||||||
|
|
||||||
SHA512_Init(&hash_ctx);
|
SHA512_Init(&hash_ctx);
|
||||||
SHA512_Update(&hash_ctx, private_key, 32);
|
SHA512_Update(&hash_ctx, private_key, 32);
|
||||||
SHA512_Final(az, &hash_ctx);
|
SHA512_Final(az, &hash_ctx);
|
||||||
|
|
||||||
az[0] &= 248;
|
az[0] &= 248;
|
||||||
az[31] &= 63;
|
az[31] &= 63;
|
||||||
az[31] |= 64;
|
az[31] |= 64;
|
||||||
|
|
||||||
SHA512_Init(&hash_ctx);
|
SHA512_Init(&hash_ctx);
|
||||||
SHA512_Update(&hash_ctx, az + 32, 32);
|
SHA512_Update(&hash_ctx, az + 32, 32);
|
||||||
SHA512_Update(&hash_ctx, message, message_len);
|
SHA512_Update(&hash_ctx, message, message_len);
|
||||||
SHA512_Final(nonce, &hash_ctx);
|
SHA512_Final(nonce, &hash_ctx);
|
||||||
|
|
||||||
x25519_sc_reduce(nonce);
|
x25519_sc_reduce(nonce);
|
||||||
ge_scalarmult_base(&R, nonce);
|
ge_scalarmult_base(&R, nonce);
|
||||||
ge_p3_tobytes(out_sig, &R);
|
ge_p3_tobytes(out_sig, &R);
|
||||||
|
|
||||||
SHA512_Init(&hash_ctx);
|
SHA512_Init(&hash_ctx);
|
||||||
SHA512_Update(&hash_ctx, out_sig, 32);
|
SHA512_Update(&hash_ctx, out_sig, 32);
|
||||||
SHA512_Update(&hash_ctx, public_key, 32);
|
SHA512_Update(&hash_ctx, public_key, 32);
|
||||||
SHA512_Update(&hash_ctx, message, message_len);
|
SHA512_Update(&hash_ctx, message, message_len);
|
||||||
SHA512_Final(hram, &hash_ctx);
|
SHA512_Final(hram, &hash_ctx);
|
||||||
|
|
||||||
x25519_sc_reduce(hram);
|
x25519_sc_reduce(hram);
|
||||||
sc_muladd(out_sig + 32, hram, az, nonce);
|
sc_muladd(out_sig + 32, hram, az, nonce);
|
||||||
|
|
||||||
OPENSSL_cleanse(&hash_ctx, sizeof(hash_ctx));
|
OPENSSL_cleanse(&hash_ctx, sizeof(hash_ctx));
|
||||||
OPENSSL_cleanse(nonce, sizeof(nonce));
|
OPENSSL_cleanse(nonce, sizeof(nonce));
|
||||||
OPENSSL_cleanse(az, sizeof(az));
|
OPENSSL_cleanse(az, sizeof(az));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char allzeroes[15];
|
static const char allzeroes[15];
|
||||||
|
|
||||||
int ED25519_verify(const uint8_t *message, size_t message_len,
|
int ED25519_verify(const uint8_t *message, size_t message_len,
|
||||||
const uint8_t signature[64], const uint8_t public_key[32]) {
|
const uint8_t signature[64], const uint8_t public_key[32])
|
||||||
int i;
|
{
|
||||||
ge_p3 A;
|
int i;
|
||||||
const uint8_t *r, *s;
|
ge_p3 A;
|
||||||
SHA512_CTX hash_ctx;
|
const uint8_t *r, *s;
|
||||||
ge_p2 R;
|
SHA512_CTX hash_ctx;
|
||||||
uint8_t rcheck[32];
|
ge_p2 R;
|
||||||
uint8_t h[SHA512_DIGEST_LENGTH];
|
uint8_t rcheck[32];
|
||||||
/* 27742317777372353535851937790883648493 in little endian format */
|
uint8_t h[SHA512_DIGEST_LENGTH];
|
||||||
const uint8_t l_low[16] = {
|
/* 27742317777372353535851937790883648493 in little endian format */
|
||||||
0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2,
|
const uint8_t l_low[16] = {
|
||||||
0xDE, 0xF9, 0xDE, 0x14
|
0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2,
|
||||||
};
|
0xDE, 0xF9, 0xDE, 0x14
|
||||||
|
};
|
||||||
|
|
||||||
r = signature;
|
r = signature;
|
||||||
s = signature + 32;
|
s = signature + 32;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check 0 <= s < L where L = 2^252 + 27742317777372353535851937790883648493
|
* Check 0 <= s < L where L = 2^252 + 27742317777372353535851937790883648493
|
||||||
*
|
*
|
||||||
* If not the signature is publicly invalid. Since it's public we can do the
|
* If not the signature is publicly invalid. Since it's public we can do the
|
||||||
* check in variable time.
|
* check in variable time.
|
||||||
*
|
*
|
||||||
* First check the most significant byte
|
* First check the most significant byte
|
||||||
*/
|
*/
|
||||||
if (s[31] > 0x10)
|
if (s[31] > 0x10)
|
||||||
return 0;
|
|
||||||
if (s[31] == 0x10) {
|
|
||||||
/*
|
|
||||||
* Most significant byte indicates a value close to 2^252 so check the
|
|
||||||
* rest
|
|
||||||
*/
|
|
||||||
if (memcmp(s + 16, allzeroes, sizeof(allzeroes)) != 0)
|
|
||||||
return 0;
|
return 0;
|
||||||
for (i = 15; i >= 0; i--) {
|
if (s[31] == 0x10) {
|
||||||
if (s[i] < l_low[i])
|
/*
|
||||||
break;
|
* Most significant byte indicates a value close to 2^252 so check the
|
||||||
if (s[i] > l_low[i])
|
* rest
|
||||||
|
*/
|
||||||
|
if (memcmp(s + 16, allzeroes, sizeof(allzeroes)) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
for (i = 15; i >= 0; i--) {
|
||||||
if (i < 0)
|
if (s[i] < l_low[i])
|
||||||
|
break;
|
||||||
|
if (s[i] > l_low[i])
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (i < 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ge_frombytes_vartime(&A, public_key) != 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ge_frombytes_vartime(&A, public_key) != 0) {
|
fe_neg(A.X, A.X);
|
||||||
return 0;
|
fe_neg(A.T, A.T);
|
||||||
}
|
|
||||||
|
|
||||||
fe_neg(A.X, A.X);
|
SHA512_Init(&hash_ctx);
|
||||||
fe_neg(A.T, A.T);
|
SHA512_Update(&hash_ctx, r, 32);
|
||||||
|
SHA512_Update(&hash_ctx, public_key, 32);
|
||||||
|
SHA512_Update(&hash_ctx, message, message_len);
|
||||||
|
SHA512_Final(h, &hash_ctx);
|
||||||
|
|
||||||
SHA512_Init(&hash_ctx);
|
x25519_sc_reduce(h);
|
||||||
SHA512_Update(&hash_ctx, r, 32);
|
|
||||||
SHA512_Update(&hash_ctx, public_key, 32);
|
|
||||||
SHA512_Update(&hash_ctx, message, message_len);
|
|
||||||
SHA512_Final(h, &hash_ctx);
|
|
||||||
|
|
||||||
x25519_sc_reduce(h);
|
ge_double_scalarmult_vartime(&R, h, &A, s);
|
||||||
|
|
||||||
ge_double_scalarmult_vartime(&R, h, &A, s);
|
ge_tobytes(rcheck, &R);
|
||||||
|
|
||||||
ge_tobytes(rcheck, &R);
|
return CRYPTO_memcmp(rcheck, r, sizeof(rcheck)) == 0;
|
||||||
|
|
||||||
return CRYPTO_memcmp(rcheck, r, sizeof(rcheck)) == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED25519_public_from_private(uint8_t out_public_key[32],
|
void ED25519_public_from_private(uint8_t out_public_key[32],
|
||||||
const uint8_t private_key[32]) {
|
const uint8_t private_key[32])
|
||||||
uint8_t az[SHA512_DIGEST_LENGTH];
|
{
|
||||||
ge_p3 A;
|
uint8_t az[SHA512_DIGEST_LENGTH];
|
||||||
|
ge_p3 A;
|
||||||
|
|
||||||
SHA512(private_key, 32, az);
|
SHA512(private_key, 32, az);
|
||||||
|
|
||||||
az[0] &= 248;
|
az[0] &= 248;
|
||||||
az[31] &= 63;
|
az[31] &= 63;
|
||||||
az[31] |= 64;
|
az[31] |= 64;
|
||||||
|
|
||||||
ge_scalarmult_base(&A, az);
|
ge_scalarmult_base(&A, az);
|
||||||
ge_p3_tobytes(out_public_key, &A);
|
ge_p3_tobytes(out_public_key, &A);
|
||||||
|
|
||||||
OPENSSL_cleanse(az, sizeof(az));
|
OPENSSL_cleanse(az, sizeof(az));
|
||||||
}
|
}
|
||||||
|
|
||||||
int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
|
int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
|
||||||
const uint8_t peer_public_value[32]) {
|
const uint8_t peer_public_value[32])
|
||||||
static const uint8_t kZeros[32] = {0};
|
{
|
||||||
x25519_scalar_mult(out_shared_key, private_key, peer_public_value);
|
static const uint8_t kZeros[32] = {0};
|
||||||
/* The all-zero output results when the input is a point of small order. */
|
x25519_scalar_mult(out_shared_key, private_key, peer_public_value);
|
||||||
return CRYPTO_memcmp(kZeros, out_shared_key, 32) != 0;
|
/* The all-zero output results when the input is a point of small order. */
|
||||||
|
return CRYPTO_memcmp(kZeros, out_shared_key, 32) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void X25519_public_from_private(uint8_t out_public_value[32],
|
void X25519_public_from_private(uint8_t out_public_value[32],
|
||||||
const uint8_t private_key[32]) {
|
const uint8_t private_key[32])
|
||||||
uint8_t e[32];
|
{
|
||||||
ge_p3 A;
|
uint8_t e[32];
|
||||||
fe zplusy, zminusy, zminusy_inv;
|
ge_p3 A;
|
||||||
|
fe zplusy, zminusy, zminusy_inv;
|
||||||
|
|
||||||
memcpy(e, private_key, 32);
|
memcpy(e, private_key, 32);
|
||||||
e[0] &= 248;
|
e[0] &= 248;
|
||||||
e[31] &= 127;
|
e[31] &= 127;
|
||||||
e[31] |= 64;
|
e[31] |= 64;
|
||||||
|
|
||||||
ge_scalarmult_base(&A, e);
|
ge_scalarmult_base(&A, e);
|
||||||
|
|
||||||
/* We only need the u-coordinate of the curve25519 point. The map is
|
/*
|
||||||
* u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). */
|
* We only need the u-coordinate of the curve25519 point.
|
||||||
fe_add(zplusy, A.Z, A.Y);
|
* The map is u=(y+1)/(1-y). Since y=Y/Z, this gives
|
||||||
fe_sub(zminusy, A.Z, A.Y);
|
* u=(Z+Y)/(Z-Y).
|
||||||
fe_invert(zminusy_inv, zminusy);
|
*/
|
||||||
fe_mul(zplusy, zplusy, zminusy_inv);
|
fe_add(zplusy, A.Z, A.Y);
|
||||||
fe_tobytes(out_public_value, zplusy);
|
fe_sub(zminusy, A.Z, A.Y);
|
||||||
|
fe_invert(zminusy_inv, zminusy);
|
||||||
|
fe_mul(zplusy, zplusy, zminusy_inv);
|
||||||
|
fe_tobytes(out_public_value, zplusy);
|
||||||
|
|
||||||
OPENSSL_cleanse(e, sizeof(e));
|
OPENSSL_cleanse(e, sizeof(e));
|
||||||
}
|
}
|
||||||
@@ -246,10 +246,36 @@ c448_error_t c448_ed448_verify(
|
|||||||
uint8_t context_len)
|
uint8_t context_len)
|
||||||
{
|
{
|
||||||
curve448_point_t pk_point, r_point;
|
curve448_point_t pk_point, r_point;
|
||||||
c448_error_t error =
|
c448_error_t error;
|
||||||
curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point, pubkey);
|
|
||||||
curve448_scalar_t challenge_scalar;
|
curve448_scalar_t challenge_scalar;
|
||||||
curve448_scalar_t response_scalar;
|
curve448_scalar_t response_scalar;
|
||||||
|
/* Order in little endian format */
|
||||||
|
static const uint8_t order[] = {
|
||||||
|
0xF3, 0x44, 0x58, 0xAB, 0x92, 0xC2, 0x78, 0x23, 0x55, 0x8F, 0xC5, 0x8D,
|
||||||
|
0x72, 0xC2, 0x6C, 0x21, 0x90, 0x36, 0xD6, 0xAE, 0x49, 0xDB, 0x4E, 0xC4,
|
||||||
|
0xE9, 0x23, 0xCA, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that s (second 57 bytes of the sig) is less than the order. Both
|
||||||
|
* s and the order are in little-endian format. This can be done in
|
||||||
|
* variable time, since if this is not the case the signature if publicly
|
||||||
|
* invalid.
|
||||||
|
*/
|
||||||
|
for (i = EDDSA_448_PUBLIC_BYTES - 1; i >= 0; i--) {
|
||||||
|
if (signature[i + EDDSA_448_PUBLIC_BYTES] > order[i])
|
||||||
|
return C448_FAILURE;
|
||||||
|
if (signature[i + EDDSA_448_PUBLIC_BYTES] < order[i])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i < 0)
|
||||||
|
return C448_FAILURE;
|
||||||
|
|
||||||
|
error =
|
||||||
|
curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point, pubkey);
|
||||||
|
|
||||||
if (C448_SUCCESS != error)
|
if (C448_SUCCESS != error)
|
||||||
return error;
|
return error;
|
||||||
|
|||||||
+611
-68
@@ -16,6 +16,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <openssl/conf.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
@@ -34,6 +35,34 @@
|
|||||||
* saner... why re-open /dev/crypto for every session?
|
* saner... why re-open /dev/crypto for every session?
|
||||||
*/
|
*/
|
||||||
static int cfd;
|
static int cfd;
|
||||||
|
#define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */
|
||||||
|
#define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */
|
||||||
|
#define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */
|
||||||
|
|
||||||
|
#define DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS DEVCRYPTO_REJECT_SOFTWARE
|
||||||
|
static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cipher/digest status & acceleration definitions
|
||||||
|
* Make sure the defaults are set to 0
|
||||||
|
*/
|
||||||
|
struct driver_info_st {
|
||||||
|
enum devcrypto_status_t {
|
||||||
|
DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */
|
||||||
|
DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */
|
||||||
|
DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */
|
||||||
|
DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
|
||||||
|
DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
|
||||||
|
} status;
|
||||||
|
|
||||||
|
enum devcrypto_accelerated_t {
|
||||||
|
DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
|
||||||
|
DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
|
||||||
|
DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
|
||||||
|
} accelerated;
|
||||||
|
|
||||||
|
char *driver_name;
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
@@ -47,10 +76,12 @@ static int cfd;
|
|||||||
|
|
||||||
struct cipher_ctx {
|
struct cipher_ctx {
|
||||||
struct session_op sess;
|
struct session_op sess;
|
||||||
|
|
||||||
/* to pass from init to do_cipher */
|
|
||||||
const unsigned char *iv;
|
|
||||||
int op; /* COP_ENCRYPT or COP_DECRYPT */
|
int op; /* COP_ENCRYPT or COP_DECRYPT */
|
||||||
|
unsigned long mode; /* EVP_CIPH_*_MODE */
|
||||||
|
|
||||||
|
/* to handle ctr mode being a stream cipher */
|
||||||
|
unsigned char partial[EVP_MAX_BLOCK_LENGTH];
|
||||||
|
unsigned int blocksize, num;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct cipher_data_st {
|
static const struct cipher_data_st {
|
||||||
@@ -87,9 +118,9 @@ static const struct cipher_data_st {
|
|||||||
{ NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
|
{ NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
|
||||||
#endif
|
#endif
|
||||||
#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB)
|
#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB)
|
||||||
{ NID_aes_128_ecb, 16, 128 / 8, 16, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
|
{ NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
|
||||||
{ NID_aes_192_ecb, 16, 192 / 8, 16, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
|
{ NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
|
||||||
{ NID_aes_256_ecb, 16, 256 / 8, 16, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
|
{ NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
|
||||||
#endif
|
#endif
|
||||||
#if 0 /* Not yet supported */
|
#if 0 /* Not yet supported */
|
||||||
{ NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
|
{ NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
|
||||||
@@ -106,13 +137,22 @@ static const struct cipher_data_st {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static size_t get_cipher_data_index(int nid)
|
static size_t find_cipher_data_index(int nid)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < OSSL_NELEM(cipher_data); i++)
|
for (i = 0; i < OSSL_NELEM(cipher_data); i++)
|
||||||
if (nid == cipher_data[i].nid)
|
if (nid == cipher_data[i].nid)
|
||||||
return i;
|
return i;
|
||||||
|
return (size_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t get_cipher_data_index(int nid)
|
||||||
|
{
|
||||||
|
size_t i = find_cipher_data_index(nid);
|
||||||
|
|
||||||
|
if (i != (size_t)-1)
|
||||||
|
return i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code further down must make sure that only NIDs in the table above
|
* Code further down must make sure that only NIDs in the table above
|
||||||
@@ -146,6 +186,8 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
|||||||
cipher_ctx->sess.keylen = cipher_d->keylen;
|
cipher_ctx->sess.keylen = cipher_d->keylen;
|
||||||
cipher_ctx->sess.key = (void *)key;
|
cipher_ctx->sess.key = (void *)key;
|
||||||
cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT;
|
cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT;
|
||||||
|
cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE;
|
||||||
|
cipher_ctx->blocksize = cipher_d->blocksize;
|
||||||
if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
|
if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
|
||||||
SYSerr(SYS_F_IOCTL, errno);
|
SYSerr(SYS_F_IOCTL, errno);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -160,8 +202,11 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
|||||||
struct cipher_ctx *cipher_ctx =
|
struct cipher_ctx *cipher_ctx =
|
||||||
(struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
|
(struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
|
||||||
struct crypt_op cryp;
|
struct crypt_op cryp;
|
||||||
|
unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
|
||||||
#if !defined(COP_FLAG_WRITE_IV)
|
#if !defined(COP_FLAG_WRITE_IV)
|
||||||
unsigned char saved_iv[EVP_MAX_IV_LENGTH];
|
unsigned char saved_iv[EVP_MAX_IV_LENGTH];
|
||||||
|
const unsigned char *ivptr;
|
||||||
|
size_t nblocks, ivlen;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memset(&cryp, 0, sizeof(cryp));
|
memset(&cryp, 0, sizeof(cryp));
|
||||||
@@ -169,19 +214,28 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
|||||||
cryp.len = inl;
|
cryp.len = inl;
|
||||||
cryp.src = (void *)in;
|
cryp.src = (void *)in;
|
||||||
cryp.dst = (void *)out;
|
cryp.dst = (void *)out;
|
||||||
cryp.iv = (void *)EVP_CIPHER_CTX_iv_noconst(ctx);
|
cryp.iv = (void *)iv;
|
||||||
cryp.op = cipher_ctx->op;
|
cryp.op = cipher_ctx->op;
|
||||||
#if !defined(COP_FLAG_WRITE_IV)
|
#if !defined(COP_FLAG_WRITE_IV)
|
||||||
cryp.flags = 0;
|
cryp.flags = 0;
|
||||||
|
|
||||||
if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
|
ivlen = EVP_CIPHER_CTX_iv_length(ctx);
|
||||||
assert(inl >= EVP_CIPHER_CTX_iv_length(ctx));
|
if (ivlen > 0)
|
||||||
if (!EVP_CIPHER_CTX_encrypting(ctx)) {
|
switch (cipher_ctx->mode) {
|
||||||
unsigned char *ivptr = in + inl - EVP_CIPHER_CTX_iv_length(ctx);
|
case EVP_CIPH_CBC_MODE:
|
||||||
|
assert(inl >= ivlen);
|
||||||
|
if (!EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||||
|
ivptr = in + inl - ivlen;
|
||||||
|
memcpy(saved_iv, ivptr, ivlen);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
memcpy(saved_iv, ivptr, EVP_CIPHER_CTX_iv_length(ctx));
|
case EVP_CIPH_CTR_MODE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* should not happen */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
cryp.flags = COP_FLAG_WRITE_IV;
|
cryp.flags = COP_FLAG_WRITE_IV;
|
||||||
#endif
|
#endif
|
||||||
@@ -192,21 +246,94 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(COP_FLAG_WRITE_IV)
|
#if !defined(COP_FLAG_WRITE_IV)
|
||||||
if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
|
if (ivlen > 0)
|
||||||
unsigned char *ivptr = saved_iv;
|
switch (cipher_ctx->mode) {
|
||||||
|
case EVP_CIPH_CBC_MODE:
|
||||||
|
assert(inl >= ivlen);
|
||||||
|
if (EVP_CIPHER_CTX_encrypting(ctx))
|
||||||
|
ivptr = out + inl - ivlen;
|
||||||
|
else
|
||||||
|
ivptr = saved_iv;
|
||||||
|
|
||||||
assert(inl >= EVP_CIPHER_CTX_iv_length(ctx));
|
memcpy(iv, ivptr, ivlen);
|
||||||
if (!EVP_CIPHER_CTX_encrypting(ctx))
|
break;
|
||||||
ivptr = out + inl - EVP_CIPHER_CTX_iv_length(ctx);
|
|
||||||
|
|
||||||
memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), ivptr,
|
case EVP_CIPH_CTR_MODE:
|
||||||
EVP_CIPHER_CTX_iv_length(ctx));
|
nblocks = (inl + cipher_ctx->blocksize - 1)
|
||||||
}
|
/ cipher_ctx->blocksize;
|
||||||
|
do {
|
||||||
|
ivlen--;
|
||||||
|
nblocks += iv[ivlen];
|
||||||
|
iv[ivlen] = (uint8_t) nblocks;
|
||||||
|
nblocks >>= 8;
|
||||||
|
} while (ivlen);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* should not happen */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||||
|
const unsigned char *in, size_t inl)
|
||||||
|
{
|
||||||
|
struct cipher_ctx *cipher_ctx =
|
||||||
|
(struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
|
||||||
|
size_t nblocks, len;
|
||||||
|
|
||||||
|
/* initial partial block */
|
||||||
|
while (cipher_ctx->num && inl) {
|
||||||
|
(*out++) = *(in++) ^ cipher_ctx->partial[cipher_ctx->num];
|
||||||
|
--inl;
|
||||||
|
cipher_ctx->num = (cipher_ctx->num + 1) % cipher_ctx->blocksize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* full blocks */
|
||||||
|
if (inl > (unsigned int) cipher_ctx->blocksize) {
|
||||||
|
nblocks = inl/cipher_ctx->blocksize;
|
||||||
|
len = nblocks * cipher_ctx->blocksize;
|
||||||
|
if (cipher_do_cipher(ctx, out, in, len) < 1)
|
||||||
|
return 0;
|
||||||
|
inl -= len;
|
||||||
|
out += len;
|
||||||
|
in += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* final partial block */
|
||||||
|
if (inl) {
|
||||||
|
memset(cipher_ctx->partial, 0, cipher_ctx->blocksize);
|
||||||
|
if (cipher_do_cipher(ctx, cipher_ctx->partial, cipher_ctx->partial,
|
||||||
|
cipher_ctx->blocksize) < 1)
|
||||||
|
return 0;
|
||||||
|
while (inl--) {
|
||||||
|
out[cipher_ctx->num] = in[cipher_ctx->num]
|
||||||
|
^ cipher_ctx->partial[cipher_ctx->num];
|
||||||
|
cipher_ctx->num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2)
|
||||||
|
{
|
||||||
|
EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2;
|
||||||
|
struct cipher_ctx *cipher_ctx;
|
||||||
|
|
||||||
|
if (type == EVP_CTRL_COPY) {
|
||||||
|
/* when copying the context, a new session needs to be initialized */
|
||||||
|
cipher_ctx = (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
|
||||||
|
return (cipher_ctx == NULL)
|
||||||
|
|| cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx),
|
||||||
|
(cipher_ctx->op == COP_ENCRYPT));
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
|
static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
|
||||||
{
|
{
|
||||||
struct cipher_ctx *cipher_ctx =
|
struct cipher_ctx *cipher_ctx =
|
||||||
@@ -221,18 +348,40 @@ static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep a table of known nids and associated methods.
|
* Keep tables of known nids, associated methods, selected ciphers, and driver
|
||||||
|
* info.
|
||||||
* Note that known_cipher_nids[] isn't necessarily indexed the same way as
|
* Note that known_cipher_nids[] isn't necessarily indexed the same way as
|
||||||
* cipher_data[] above, which known_cipher_methods[] is.
|
* cipher_data[] above, which the other tables are.
|
||||||
*/
|
*/
|
||||||
static int known_cipher_nids[OSSL_NELEM(cipher_data)];
|
static int known_cipher_nids[OSSL_NELEM(cipher_data)];
|
||||||
static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */
|
static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */
|
||||||
static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, };
|
static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, };
|
||||||
|
static int selected_ciphers[OSSL_NELEM(cipher_data)];
|
||||||
|
static struct driver_info_st cipher_driver_info[OSSL_NELEM(cipher_data)];
|
||||||
|
|
||||||
|
|
||||||
|
static int devcrypto_test_cipher(size_t cipher_data_index)
|
||||||
|
{
|
||||||
|
return (cipher_driver_info[cipher_data_index].status == DEVCRYPTO_STATUS_USABLE
|
||||||
|
&& selected_ciphers[cipher_data_index] == 1
|
||||||
|
&& (cipher_driver_info[cipher_data_index].accelerated
|
||||||
|
== DEVCRYPTO_ACCELERATED
|
||||||
|
|| use_softdrivers == DEVCRYPTO_USE_SOFTWARE
|
||||||
|
|| (cipher_driver_info[cipher_data_index].accelerated
|
||||||
|
!= DEVCRYPTO_NOT_ACCELERATED
|
||||||
|
&& use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
|
||||||
|
}
|
||||||
|
|
||||||
static void prepare_cipher_methods(void)
|
static void prepare_cipher_methods(void)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
struct session_op sess;
|
struct session_op sess;
|
||||||
|
unsigned long cipher_mode;
|
||||||
|
#ifdef CIOCGSESSINFO
|
||||||
|
struct session_info_op siop;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
memset(&cipher_driver_info, 0, sizeof(cipher_driver_info));
|
||||||
|
|
||||||
memset(&sess, 0, sizeof(sess));
|
memset(&sess, 0, sizeof(sess));
|
||||||
sess.key = (void *)"01234567890123456789012345678901234567890123456789";
|
sess.key = (void *)"01234567890123456789012345678901234567890123456789";
|
||||||
@@ -240,41 +389,80 @@ static void prepare_cipher_methods(void)
|
|||||||
for (i = 0, known_cipher_nids_amount = 0;
|
for (i = 0, known_cipher_nids_amount = 0;
|
||||||
i < OSSL_NELEM(cipher_data); i++) {
|
i < OSSL_NELEM(cipher_data); i++) {
|
||||||
|
|
||||||
|
selected_ciphers[i] = 1;
|
||||||
/*
|
/*
|
||||||
* Check that the algo is really availably by trying to open and close
|
* Check that the cipher is usable
|
||||||
* a session.
|
|
||||||
*/
|
*/
|
||||||
sess.cipher = cipher_data[i].devcryptoid;
|
sess.cipher = cipher_data[i].devcryptoid;
|
||||||
sess.keylen = cipher_data[i].keylen;
|
sess.keylen = cipher_data[i].keylen;
|
||||||
if (ioctl(cfd, CIOCGSESSION, &sess) < 0
|
if (ioctl(cfd, CIOCGSESSION, &sess) < 0) {
|
||||||
|| ioctl(cfd, CIOCFSESSION, &sess.ses) < 0)
|
cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE;
|
||||||
|
|
||||||
if ((known_cipher_methods[i] =
|
if ((known_cipher_methods[i] =
|
||||||
EVP_CIPHER_meth_new(cipher_data[i].nid,
|
EVP_CIPHER_meth_new(cipher_data[i].nid,
|
||||||
cipher_data[i].blocksize,
|
cipher_mode == EVP_CIPH_CTR_MODE ? 1 :
|
||||||
|
cipher_data[i].blocksize,
|
||||||
cipher_data[i].keylen)) == NULL
|
cipher_data[i].keylen)) == NULL
|
||||||
|| !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i],
|
|| !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i],
|
||||||
cipher_data[i].ivlen)
|
cipher_data[i].ivlen)
|
||||||
|| !EVP_CIPHER_meth_set_flags(known_cipher_methods[i],
|
|| !EVP_CIPHER_meth_set_flags(known_cipher_methods[i],
|
||||||
cipher_data[i].flags
|
cipher_data[i].flags
|
||||||
|
| EVP_CIPH_CUSTOM_COPY
|
||||||
| EVP_CIPH_FLAG_DEFAULT_ASN1)
|
| EVP_CIPH_FLAG_DEFAULT_ASN1)
|
||||||
|| !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init)
|
|| !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init)
|
||||||
|| !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i],
|
|| !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i],
|
||||||
|
cipher_mode == EVP_CIPH_CTR_MODE ?
|
||||||
|
ctr_do_cipher :
|
||||||
cipher_do_cipher)
|
cipher_do_cipher)
|
||||||
|
|| !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl)
|
||||||
|| !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i],
|
|| !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i],
|
||||||
cipher_cleanup)
|
cipher_cleanup)
|
||||||
|| !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
|
|| !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
|
||||||
sizeof(struct cipher_ctx))) {
|
sizeof(struct cipher_ctx))) {
|
||||||
|
cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
|
||||||
EVP_CIPHER_meth_free(known_cipher_methods[i]);
|
EVP_CIPHER_meth_free(known_cipher_methods[i]);
|
||||||
known_cipher_methods[i] = NULL;
|
known_cipher_methods[i] = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
|
||||||
|
#ifdef CIOCGSESSINFO
|
||||||
|
siop.ses = sess.ses;
|
||||||
|
if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
|
||||||
|
cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
|
||||||
|
} else {
|
||||||
|
cipher_driver_info[i].driver_name =
|
||||||
|
OPENSSL_strndup(siop.cipher_info.cra_driver_name,
|
||||||
|
CRYPTODEV_MAX_ALG_NAME);
|
||||||
|
if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
|
||||||
|
cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
|
||||||
|
else
|
||||||
|
cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
|
||||||
|
}
|
||||||
|
#endif /* CIOCGSESSINFO */
|
||||||
|
}
|
||||||
|
ioctl(cfd, CIOCFSESSION, &sess.ses);
|
||||||
|
if (devcrypto_test_cipher(i)) {
|
||||||
known_cipher_nids[known_cipher_nids_amount++] =
|
known_cipher_nids[known_cipher_nids_amount++] =
|
||||||
cipher_data[i].nid;
|
cipher_data[i].nid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rebuild_known_cipher_nids(ENGINE *e)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0, known_cipher_nids_amount = 0; i < OSSL_NELEM(cipher_data); i++) {
|
||||||
|
if (devcrypto_test_cipher(i))
|
||||||
|
known_cipher_nids[known_cipher_nids_amount++] = cipher_data[i].nid;
|
||||||
|
}
|
||||||
|
ENGINE_unregister_ciphers(e);
|
||||||
|
ENGINE_register_ciphers(e);
|
||||||
|
}
|
||||||
|
|
||||||
static const EVP_CIPHER *get_cipher_method(int nid)
|
static const EVP_CIPHER *get_cipher_method(int nid)
|
||||||
{
|
{
|
||||||
size_t i = get_cipher_data_index(nid);
|
size_t i = get_cipher_data_index(nid);
|
||||||
@@ -302,8 +490,11 @@ static void destroy_all_cipher_methods(void)
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < OSSL_NELEM(cipher_data); i++)
|
for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
|
||||||
destroy_cipher_method(cipher_data[i].nid);
|
destroy_cipher_method(cipher_data[i].nid);
|
||||||
|
OPENSSL_free(cipher_driver_info[i].driver_name);
|
||||||
|
cipher_driver_info[i].driver_name = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
||||||
@@ -317,6 +508,70 @@ static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
|||||||
return *cipher != NULL;
|
return *cipher != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void devcrypto_select_all_ciphers(int *cipher_list)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < OSSL_NELEM(cipher_data); i++)
|
||||||
|
cipher_list[i] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cryptodev_select_cipher_cb(const char *str, int len, void *usr)
|
||||||
|
{
|
||||||
|
int *cipher_list = (int *)usr;
|
||||||
|
char *name;
|
||||||
|
const EVP_CIPHER *EVP;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
return 1;
|
||||||
|
if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
|
||||||
|
return 0;
|
||||||
|
EVP = EVP_get_cipherbyname(name);
|
||||||
|
if (EVP == NULL)
|
||||||
|
fprintf(stderr, "devcrypto: unknown cipher %s\n", name);
|
||||||
|
else if ((i = find_cipher_data_index(EVP_CIPHER_nid(EVP))) != (size_t)-1)
|
||||||
|
cipher_list[i] = 1;
|
||||||
|
else
|
||||||
|
fprintf(stderr, "devcrypto: cipher %s not available\n", name);
|
||||||
|
OPENSSL_free(name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_cipher_info(void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
fprintf (stderr, "Information about ciphers supported by the /dev/crypto"
|
||||||
|
" engine:\n");
|
||||||
|
#ifndef CIOCGSESSINFO
|
||||||
|
fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
|
||||||
|
#endif
|
||||||
|
for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
|
||||||
|
name = OBJ_nid2sn(cipher_data[i].nid);
|
||||||
|
fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ",
|
||||||
|
name ? name : "unknown", cipher_data[i].nid,
|
||||||
|
cipher_data[i].devcryptoid);
|
||||||
|
if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION ) {
|
||||||
|
fprintf (stderr, "CIOCGSESSION (session open call) failed\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ?
|
||||||
|
cipher_driver_info[i].driver_name : "unknown");
|
||||||
|
if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
|
||||||
|
fprintf(stderr, "(hw accelerated)");
|
||||||
|
else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
|
||||||
|
fprintf(stderr, "(software)");
|
||||||
|
else
|
||||||
|
fprintf(stderr, "(acceleration status unknown)");
|
||||||
|
if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
|
||||||
|
fprintf (stderr, ". Cipher setup failed");
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We only support digests if the cryptodev implementation supports multiple
|
* We only support digests if the cryptodev implementation supports multiple
|
||||||
* data updates and session copying. Otherwise, we would be forced to maintain
|
* data updates and session copying. Otherwise, we would be forced to maintain
|
||||||
@@ -338,7 +593,9 @@ static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
|||||||
|
|
||||||
struct digest_ctx {
|
struct digest_ctx {
|
||||||
struct session_op sess;
|
struct session_op sess;
|
||||||
int init;
|
/* This signals that the init function was called, not that it succeeded. */
|
||||||
|
int init_called;
|
||||||
|
unsigned char digest_res[HASH_MAX_LEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct digest_data_st {
|
static const struct digest_data_st {
|
||||||
@@ -369,13 +626,22 @@ static const struct digest_data_st {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static size_t get_digest_data_index(int nid)
|
static size_t find_digest_data_index(int nid)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < OSSL_NELEM(digest_data); i++)
|
for (i = 0; i < OSSL_NELEM(digest_data); i++)
|
||||||
if (nid == digest_data[i].nid)
|
if (nid == digest_data[i].nid)
|
||||||
return i;
|
return i;
|
||||||
|
return (size_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t get_digest_data_index(int nid)
|
||||||
|
{
|
||||||
|
size_t i = find_digest_data_index(nid);
|
||||||
|
|
||||||
|
if (i != (size_t)-1)
|
||||||
|
return i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code further down must make sure that only NIDs in the table above
|
* Code further down must make sure that only NIDs in the table above
|
||||||
@@ -392,8 +658,8 @@ static const struct digest_data_st *get_digest_data(int nid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Following are the four necessary functions to map OpenSSL functionality
|
* Following are the five necessary functions to map OpenSSL functionality
|
||||||
* with cryptodev.
|
* with cryptodev: init, update, final, cleanup, and copy.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int digest_init(EVP_MD_CTX *ctx)
|
static int digest_init(EVP_MD_CTX *ctx)
|
||||||
@@ -403,7 +669,7 @@ static int digest_init(EVP_MD_CTX *ctx)
|
|||||||
const struct digest_data_st *digest_d =
|
const struct digest_data_st *digest_d =
|
||||||
get_digest_data(EVP_MD_CTX_type(ctx));
|
get_digest_data(EVP_MD_CTX_type(ctx));
|
||||||
|
|
||||||
digest_ctx->init = 1;
|
digest_ctx->init_called = 1;
|
||||||
|
|
||||||
memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess));
|
memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess));
|
||||||
digest_ctx->sess.mac = digest_d->devcryptoid;
|
digest_ctx->sess.mac = digest_d->devcryptoid;
|
||||||
@@ -438,12 +704,18 @@ static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
|||||||
if (count == 0)
|
if (count == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) < 0) {
|
if (digest_ctx == NULL)
|
||||||
SYSerr(SYS_F_IOCTL, errno);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
|
||||||
|
if (digest_op(digest_ctx, data, count, digest_ctx->digest_res, 0) >= 0)
|
||||||
|
return 1;
|
||||||
|
} else if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) >= 0) {
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
SYSerr(SYS_F_IOCTL, errno);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
|
static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||||
@@ -451,11 +723,12 @@ static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
|
|||||||
struct digest_ctx *digest_ctx =
|
struct digest_ctx *digest_ctx =
|
||||||
(struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
|
(struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
|
||||||
|
|
||||||
if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) {
|
if (md == NULL || digest_ctx == NULL)
|
||||||
SYSerr(SYS_F_IOCTL, errno);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
if (ioctl(cfd, CIOCFSESSION, &digest_ctx->sess.ses) < 0) {
|
if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
|
||||||
|
memcpy(md, digest_ctx->digest_res, EVP_MD_CTX_size(ctx));
|
||||||
|
} else if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) {
|
||||||
SYSerr(SYS_F_IOCTL, errno);
|
SYSerr(SYS_F_IOCTL, errno);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -471,14 +744,9 @@ static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
|
|||||||
(struct digest_ctx *)EVP_MD_CTX_md_data(to);
|
(struct digest_ctx *)EVP_MD_CTX_md_data(to);
|
||||||
struct cphash_op cphash;
|
struct cphash_op cphash;
|
||||||
|
|
||||||
if (digest_from == NULL)
|
if (digest_from == NULL || digest_from->init_called != 1)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (digest_from->init != 1) {
|
|
||||||
SYSerr(SYS_F_IOCTL, EINVAL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!digest_init(to)) {
|
if (!digest_init(to)) {
|
||||||
SYSerr(SYS_F_IOCTL, errno);
|
SYSerr(SYS_F_IOCTL, errno);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -495,37 +763,111 @@ static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
|
|||||||
|
|
||||||
static int digest_cleanup(EVP_MD_CTX *ctx)
|
static int digest_cleanup(EVP_MD_CTX *ctx)
|
||||||
{
|
{
|
||||||
|
struct digest_ctx *digest_ctx =
|
||||||
|
(struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
|
||||||
|
|
||||||
|
if (digest_ctx == NULL)
|
||||||
|
return 1;
|
||||||
|
if (ioctl(cfd, CIOCFSESSION, &digest_ctx->sess.ses) < 0) {
|
||||||
|
SYSerr(SYS_F_IOCTL, errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep a table of known nids and associated methods.
|
* Keep tables of known nids, associated methods, selected digests, and
|
||||||
|
* driver info.
|
||||||
* Note that known_digest_nids[] isn't necessarily indexed the same way as
|
* Note that known_digest_nids[] isn't necessarily indexed the same way as
|
||||||
* digest_data[] above, which known_digest_methods[] is.
|
* digest_data[] above, which the other tables are.
|
||||||
*/
|
*/
|
||||||
static int known_digest_nids[OSSL_NELEM(digest_data)];
|
static int known_digest_nids[OSSL_NELEM(digest_data)];
|
||||||
static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */
|
static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */
|
||||||
static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, };
|
static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, };
|
||||||
|
static int selected_digests[OSSL_NELEM(digest_data)];
|
||||||
|
static struct driver_info_st digest_driver_info[OSSL_NELEM(digest_data)];
|
||||||
|
|
||||||
|
static int devcrypto_test_digest(size_t digest_data_index)
|
||||||
|
{
|
||||||
|
return (digest_driver_info[digest_data_index].status == DEVCRYPTO_STATUS_USABLE
|
||||||
|
&& selected_digests[digest_data_index] == 1
|
||||||
|
&& (digest_driver_info[digest_data_index].accelerated
|
||||||
|
== DEVCRYPTO_ACCELERATED
|
||||||
|
|| use_softdrivers == DEVCRYPTO_USE_SOFTWARE
|
||||||
|
|| (digest_driver_info[digest_data_index].accelerated
|
||||||
|
!= DEVCRYPTO_NOT_ACCELERATED
|
||||||
|
&& use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rebuild_known_digest_nids(ENGINE *e)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); i++) {
|
||||||
|
if (devcrypto_test_digest(i))
|
||||||
|
known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
|
||||||
|
}
|
||||||
|
ENGINE_unregister_digests(e);
|
||||||
|
ENGINE_register_digests(e);
|
||||||
|
}
|
||||||
|
|
||||||
static void prepare_digest_methods(void)
|
static void prepare_digest_methods(void)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
struct session_op sess;
|
struct session_op sess1, sess2;
|
||||||
|
#ifdef CIOCGSESSINFO
|
||||||
|
struct session_info_op siop;
|
||||||
|
#endif
|
||||||
|
struct cphash_op cphash;
|
||||||
|
|
||||||
memset(&sess, 0, sizeof(sess));
|
memset(&digest_driver_info, 0, sizeof(digest_driver_info));
|
||||||
|
|
||||||
|
memset(&sess1, 0, sizeof(sess1));
|
||||||
|
memset(&sess2, 0, sizeof(sess2));
|
||||||
|
|
||||||
for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data);
|
for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data);
|
||||||
i++) {
|
i++) {
|
||||||
|
|
||||||
/*
|
selected_digests[i] = 1;
|
||||||
* Check that the algo is really availably by trying to open and close
|
|
||||||
* a session.
|
|
||||||
*/
|
|
||||||
sess.mac = digest_data[i].devcryptoid;
|
|
||||||
if (ioctl(cfd, CIOCGSESSION, &sess) < 0
|
|
||||||
|| ioctl(cfd, CIOCFSESSION, &sess.ses) < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that the digest is usable
|
||||||
|
*/
|
||||||
|
sess1.mac = digest_data[i].devcryptoid;
|
||||||
|
sess2.ses = 0;
|
||||||
|
if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) {
|
||||||
|
digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CIOCGSESSINFO
|
||||||
|
/* gather hardware acceleration info from the driver */
|
||||||
|
siop.ses = sess1.ses;
|
||||||
|
if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
|
||||||
|
digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
|
||||||
|
} else {
|
||||||
|
digest_driver_info[i].driver_name =
|
||||||
|
OPENSSL_strndup(siop.hash_info.cra_driver_name,
|
||||||
|
CRYPTODEV_MAX_ALG_NAME);
|
||||||
|
if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
|
||||||
|
digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
|
||||||
|
else
|
||||||
|
digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* digest must be capable of hash state copy */
|
||||||
|
sess2.mac = sess1.mac;
|
||||||
|
if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) {
|
||||||
|
digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
cphash.src_ses = sess1.ses;
|
||||||
|
cphash.dst_ses = sess2.ses;
|
||||||
|
if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
|
||||||
|
digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid,
|
if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid,
|
||||||
NID_undef)) == NULL
|
NID_undef)) == NULL
|
||||||
|| !EVP_MD_meth_set_result_size(known_digest_methods[i],
|
|| !EVP_MD_meth_set_result_size(known_digest_methods[i],
|
||||||
@@ -537,11 +879,18 @@ static void prepare_digest_methods(void)
|
|||||||
|| !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
|
|| !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
|
||||||
|| !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
|
|| !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
|
||||||
sizeof(struct digest_ctx))) {
|
sizeof(struct digest_ctx))) {
|
||||||
|
digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
|
||||||
EVP_MD_meth_free(known_digest_methods[i]);
|
EVP_MD_meth_free(known_digest_methods[i]);
|
||||||
known_digest_methods[i] = NULL;
|
known_digest_methods[i] = NULL;
|
||||||
} else {
|
goto finish;
|
||||||
known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
|
|
||||||
}
|
}
|
||||||
|
digest_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
|
||||||
|
finish:
|
||||||
|
ioctl(cfd, CIOCFSESSION, &sess1.ses);
|
||||||
|
if (sess2.ses != 0)
|
||||||
|
ioctl(cfd, CIOCFSESSION, &sess2.ses);
|
||||||
|
if (devcrypto_test_digest(i))
|
||||||
|
known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,8 +921,11 @@ static void destroy_all_digest_methods(void)
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < OSSL_NELEM(digest_data); i++)
|
for (i = 0; i < OSSL_NELEM(digest_data); i++) {
|
||||||
destroy_digest_method(digest_data[i].nid);
|
destroy_digest_method(digest_data[i].nid);
|
||||||
|
OPENSSL_free(digest_driver_info[i].driver_name);
|
||||||
|
digest_driver_info[i].driver_name = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
|
static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
|
||||||
@@ -587,8 +939,197 @@ static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
|
|||||||
return *digest != NULL;
|
return *digest != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void devcrypto_select_all_digests(int *digest_list)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < OSSL_NELEM(digest_data); i++)
|
||||||
|
digest_list[i] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cryptodev_select_digest_cb(const char *str, int len, void *usr)
|
||||||
|
{
|
||||||
|
int *digest_list = (int *)usr;
|
||||||
|
char *name;
|
||||||
|
const EVP_MD *EVP;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
return 1;
|
||||||
|
if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
|
||||||
|
return 0;
|
||||||
|
EVP = EVP_get_digestbyname(name);
|
||||||
|
if (EVP == NULL)
|
||||||
|
fprintf(stderr, "devcrypto: unknown digest %s\n", name);
|
||||||
|
else if ((i = find_digest_data_index(EVP_MD_type(EVP))) != (size_t)-1)
|
||||||
|
digest_list[i] = 1;
|
||||||
|
else
|
||||||
|
fprintf(stderr, "devcrypto: digest %s not available\n", name);
|
||||||
|
OPENSSL_free(name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_digest_info(void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
fprintf (stderr, "Information about digests supported by the /dev/crypto"
|
||||||
|
" engine:\n");
|
||||||
|
#ifndef CIOCGSESSINFO
|
||||||
|
fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < OSSL_NELEM(digest_data); i++) {
|
||||||
|
name = OBJ_nid2sn(digest_data[i].nid);
|
||||||
|
fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s",
|
||||||
|
name ? name : "unknown", digest_data[i].nid,
|
||||||
|
digest_data[i].devcryptoid,
|
||||||
|
digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown");
|
||||||
|
if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) {
|
||||||
|
fprintf (stderr, ". CIOCGSESSION (session open) failed\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
|
||||||
|
fprintf(stderr, " (hw accelerated)");
|
||||||
|
else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
|
||||||
|
fprintf(stderr, " (software)");
|
||||||
|
else
|
||||||
|
fprintf(stderr, " (acceleration status unknown)");
|
||||||
|
if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
|
||||||
|
fprintf (stderr, ". Cipher setup failed\n");
|
||||||
|
else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH)
|
||||||
|
fprintf(stderr, ", CIOCCPHASH failed\n");
|
||||||
|
else
|
||||||
|
fprintf(stderr, ", CIOCCPHASH capable\n");
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* CONTROL COMMANDS
|
||||||
|
*
|
||||||
|
*****/
|
||||||
|
|
||||||
|
#define DEVCRYPTO_CMD_USE_SOFTDRIVERS ENGINE_CMD_BASE
|
||||||
|
#define DEVCRYPTO_CMD_CIPHERS (ENGINE_CMD_BASE + 1)
|
||||||
|
#define DEVCRYPTO_CMD_DIGESTS (ENGINE_CMD_BASE + 2)
|
||||||
|
#define DEVCRYPTO_CMD_DUMP_INFO (ENGINE_CMD_BASE + 3)
|
||||||
|
|
||||||
|
static const ENGINE_CMD_DEFN devcrypto_cmds[] = {
|
||||||
|
#ifdef CIOCGSESSINFO
|
||||||
|
{DEVCRYPTO_CMD_USE_SOFTDRIVERS,
|
||||||
|
"USE_SOFTDRIVERS",
|
||||||
|
"specifies whether to use software (not accelerated) drivers ("
|
||||||
|
OPENSSL_MSTR(DEVCRYPTO_REQUIRE_ACCELERATED) "=use only accelerated drivers, "
|
||||||
|
OPENSSL_MSTR(DEVCRYPTO_USE_SOFTWARE) "=allow all drivers, "
|
||||||
|
OPENSSL_MSTR(DEVCRYPTO_REJECT_SOFTWARE)
|
||||||
|
"=use if acceleration can't be determined) [default="
|
||||||
|
OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS) "]",
|
||||||
|
ENGINE_CMD_FLAG_NUMERIC},
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{DEVCRYPTO_CMD_CIPHERS,
|
||||||
|
"CIPHERS",
|
||||||
|
"either ALL, NONE, or a comma-separated list of ciphers to enable [default=ALL]",
|
||||||
|
ENGINE_CMD_FLAG_STRING},
|
||||||
|
|
||||||
|
#ifdef IMPLEMENT_DIGEST
|
||||||
|
{DEVCRYPTO_CMD_DIGESTS,
|
||||||
|
"DIGESTS",
|
||||||
|
"either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]",
|
||||||
|
ENGINE_CMD_FLAG_STRING},
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{DEVCRYPTO_CMD_DUMP_INFO,
|
||||||
|
"DUMP_INFO",
|
||||||
|
"dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'",
|
||||||
|
ENGINE_CMD_FLAG_NO_INPUT},
|
||||||
|
|
||||||
|
{0, NULL, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
|
||||||
|
{
|
||||||
|
int *new_list;
|
||||||
|
switch (cmd) {
|
||||||
|
#ifdef CIOCGSESSINFO
|
||||||
|
case DEVCRYPTO_CMD_USE_SOFTDRIVERS:
|
||||||
|
switch (i) {
|
||||||
|
case DEVCRYPTO_REQUIRE_ACCELERATED:
|
||||||
|
case DEVCRYPTO_USE_SOFTWARE:
|
||||||
|
case DEVCRYPTO_REJECT_SOFTWARE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "devcrypto: invalid value (%ld) for USE_SOFTDRIVERS\n", i);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (use_softdrivers == i)
|
||||||
|
return 1;
|
||||||
|
use_softdrivers = i;
|
||||||
|
#ifdef IMPLEMENT_DIGEST
|
||||||
|
rebuild_known_digest_nids(e);
|
||||||
|
#endif
|
||||||
|
rebuild_known_cipher_nids(e);
|
||||||
|
return 1;
|
||||||
|
#endif /* CIOCGSESSINFO */
|
||||||
|
|
||||||
|
case DEVCRYPTO_CMD_CIPHERS:
|
||||||
|
if (p == NULL)
|
||||||
|
return 1;
|
||||||
|
if (strcasecmp((const char *)p, "ALL") == 0) {
|
||||||
|
devcrypto_select_all_ciphers(selected_ciphers);
|
||||||
|
} else if (strcasecmp((const char*)p, "NONE") == 0) {
|
||||||
|
memset(selected_ciphers, 0, sizeof(selected_ciphers));
|
||||||
|
} else {
|
||||||
|
new_list=OPENSSL_zalloc(sizeof(selected_ciphers));
|
||||||
|
if (!CONF_parse_list(p, ',', 1, cryptodev_select_cipher_cb, new_list)) {
|
||||||
|
OPENSSL_free(new_list);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(selected_ciphers, new_list, sizeof(selected_ciphers));
|
||||||
|
OPENSSL_free(new_list);
|
||||||
|
}
|
||||||
|
rebuild_known_cipher_nids(e);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
#ifdef IMPLEMENT_DIGEST
|
||||||
|
case DEVCRYPTO_CMD_DIGESTS:
|
||||||
|
if (p == NULL)
|
||||||
|
return 1;
|
||||||
|
if (strcasecmp((const char *)p, "ALL") == 0) {
|
||||||
|
devcrypto_select_all_digests(selected_digests);
|
||||||
|
} else if (strcasecmp((const char*)p, "NONE") == 0) {
|
||||||
|
memset(selected_digests, 0, sizeof(selected_digests));
|
||||||
|
} else {
|
||||||
|
new_list=OPENSSL_zalloc(sizeof(selected_digests));
|
||||||
|
if (!CONF_parse_list(p, ',', 1, cryptodev_select_digest_cb, new_list)) {
|
||||||
|
OPENSSL_free(new_list);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(selected_digests, new_list, sizeof(selected_digests));
|
||||||
|
OPENSSL_free(new_list);
|
||||||
|
}
|
||||||
|
rebuild_known_digest_nids(e);
|
||||||
|
return 1;
|
||||||
|
#endif /* IMPLEMENT_DIGEST */
|
||||||
|
|
||||||
|
case DEVCRYPTO_CMD_DUMP_INFO:
|
||||||
|
dump_cipher_info();
|
||||||
|
#ifdef IMPLEMENT_DIGEST
|
||||||
|
dump_digest_info();
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* LOAD / UNLOAD
|
* LOAD / UNLOAD
|
||||||
@@ -619,11 +1160,6 @@ void engine_load_devcrypto_int()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare_cipher_methods();
|
|
||||||
#ifdef IMPLEMENT_DIGEST
|
|
||||||
prepare_digest_methods();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((e = ENGINE_new()) == NULL
|
if ((e = ENGINE_new()) == NULL
|
||||||
|| !ENGINE_set_destroy_function(e, devcrypto_unload)) {
|
|| !ENGINE_set_destroy_function(e, devcrypto_unload)) {
|
||||||
ENGINE_free(e);
|
ENGINE_free(e);
|
||||||
@@ -636,8 +1172,15 @@ void engine_load_devcrypto_int()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prepare_cipher_methods();
|
||||||
|
#ifdef IMPLEMENT_DIGEST
|
||||||
|
prepare_digest_methods();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!ENGINE_set_id(e, "devcrypto")
|
if (!ENGINE_set_id(e, "devcrypto")
|
||||||
|| !ENGINE_set_name(e, "/dev/crypto engine")
|
|| !ENGINE_set_name(e, "/dev/crypto engine")
|
||||||
|
|| !ENGINE_set_cmd_defns(e, devcrypto_cmds)
|
||||||
|
|| !ENGINE_set_ctrl_function(e, devcrypto_ctrl)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD
|
* Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD
|
||||||
|
|||||||
+25
-2
@@ -21,6 +21,7 @@
|
|||||||
#include "internal/thread_once.h"
|
#include "internal/thread_once.h"
|
||||||
#include "internal/ctype.h"
|
#include "internal/ctype.h"
|
||||||
#include "internal/constant_time_locl.h"
|
#include "internal/constant_time_locl.h"
|
||||||
|
#include "e_os.h"
|
||||||
|
|
||||||
static int err_load_strings(const ERR_STRING_DATA *str);
|
static int err_load_strings(const ERR_STRING_DATA *str);
|
||||||
|
|
||||||
@@ -206,6 +207,7 @@ static void build_SYS_str_reasons(void)
|
|||||||
size_t cnt = 0;
|
size_t cnt = 0;
|
||||||
static int init = 1;
|
static int init = 1;
|
||||||
int i;
|
int i;
|
||||||
|
int saveerrno = get_last_sys_error();
|
||||||
|
|
||||||
CRYPTO_THREAD_write_lock(err_string_lock);
|
CRYPTO_THREAD_write_lock(err_string_lock);
|
||||||
if (!init) {
|
if (!init) {
|
||||||
@@ -251,6 +253,8 @@ static void build_SYS_str_reasons(void)
|
|||||||
init = 0;
|
init = 0;
|
||||||
|
|
||||||
CRYPTO_THREAD_unlock(err_string_lock);
|
CRYPTO_THREAD_unlock(err_string_lock);
|
||||||
|
/* openssl_strerror_r could change errno, but we want to preserve it */
|
||||||
|
set_sys_error(saveerrno);
|
||||||
err_load_strings(SYS_str_reasons);
|
err_load_strings(SYS_str_reasons);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -880,6 +884,25 @@ int ERR_clear_last_mark(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef UINTPTR_T
|
||||||
|
# undef UINTPTR_T
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* uintptr_t is the answer, but unfortunately C89, current "least common
|
||||||
|
* denominator" doesn't define it. Most legacy platforms typedef it anyway,
|
||||||
|
* so that attempt to fill the gaps means that one would have to identify
|
||||||
|
* that track these gaps, which would be undesirable. Macro it is...
|
||||||
|
*/
|
||||||
|
#if defined(__VMS) && __INITIAL_POINTER_SIZE==64
|
||||||
|
/*
|
||||||
|
* But we can't use size_t on VMS, because it adheres to sizeof(size_t)==4
|
||||||
|
* even in 64-bit builds, which means that it won't work as mask.
|
||||||
|
*/
|
||||||
|
# define UINTPTR_T unsigned long long
|
||||||
|
#else
|
||||||
|
# define UINTPTR_T size_t
|
||||||
|
#endif
|
||||||
|
|
||||||
void err_clear_last_constant_time(int clear)
|
void err_clear_last_constant_time(int clear)
|
||||||
{
|
{
|
||||||
ERR_STATE *es;
|
ERR_STATE *es;
|
||||||
@@ -893,8 +916,8 @@ void err_clear_last_constant_time(int clear)
|
|||||||
|
|
||||||
es->err_flags[top] &= ~(0 - clear);
|
es->err_flags[top] &= ~(0 - clear);
|
||||||
es->err_buffer[top] &= ~(0UL - clear);
|
es->err_buffer[top] &= ~(0UL - clear);
|
||||||
es->err_file[top] = (const char *)((uintptr_t)es->err_file[top] &
|
es->err_file[top] = (const char *)((UINTPTR_T)es->err_file[top] &
|
||||||
~((uintptr_t)0 - clear));
|
~((UINTPTR_T)0 - clear));
|
||||||
es->err_line[top] |= 0 - clear;
|
es->err_line[top] |= 0 - clear;
|
||||||
|
|
||||||
es->top = (top + ERR_NUM_ERRORS - clear) % ERR_NUM_ERRORS;
|
es->top = (top + ERR_NUM_ERRORS - clear) % ERR_NUM_ERRORS;
|
||||||
|
|||||||
@@ -738,6 +738,7 @@ EVP_F_EVP_DECRYPTFINAL_EX:101:EVP_DecryptFinal_ex
|
|||||||
EVP_F_EVP_DECRYPTUPDATE:166:EVP_DecryptUpdate
|
EVP_F_EVP_DECRYPTUPDATE:166:EVP_DecryptUpdate
|
||||||
EVP_F_EVP_DIGESTFINALXOF:174:EVP_DigestFinalXOF
|
EVP_F_EVP_DIGESTFINALXOF:174:EVP_DigestFinalXOF
|
||||||
EVP_F_EVP_DIGESTINIT_EX:128:EVP_DigestInit_ex
|
EVP_F_EVP_DIGESTINIT_EX:128:EVP_DigestInit_ex
|
||||||
|
EVP_F_EVP_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_MAC_CTRL:209:EVP_MAC_ctrl
|
EVP_F_EVP_MAC_CTRL:209:EVP_MAC_ctrl
|
||||||
|
|||||||
+5
-1
@@ -190,7 +190,11 @@ void openssl_add_all_ciphers_int(void)
|
|||||||
EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
|
EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
|
||||||
EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256());
|
EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256());
|
||||||
EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256());
|
EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256());
|
||||||
|
#ifndef OPENSSL_NO_SIV
|
||||||
|
EVP_add_cipher(EVP_aes_128_siv());
|
||||||
|
EVP_add_cipher(EVP_aes_192_siv());
|
||||||
|
EVP_add_cipher(EVP_aes_256_siv());
|
||||||
|
#endif
|
||||||
#ifndef OPENSSL_NO_ARIA
|
#ifndef OPENSSL_NO_ARIA
|
||||||
EVP_add_cipher(EVP_aria_128_ecb());
|
EVP_add_cipher(EVP_aria_128_ecb());
|
||||||
EVP_add_cipher(EVP_aria_128_cbc());
|
EVP_add_cipher(EVP_aria_128_cbc());
|
||||||
|
|||||||
+130
-5
@@ -17,6 +17,7 @@
|
|||||||
#include "internal/evp_int.h"
|
#include "internal/evp_int.h"
|
||||||
#include "modes_lcl.h"
|
#include "modes_lcl.h"
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/cmac.h>
|
||||||
#include "evp_locl.h"
|
#include "evp_locl.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -540,7 +541,8 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
|||||||
# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
|
# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
|
||||||
static const EVP_CIPHER aesni_##keylen##_##mode = { \
|
static const EVP_CIPHER aesni_##keylen##_##mode = { \
|
||||||
nid##_##keylen##_##mode,blocksize, \
|
nid##_##keylen##_##mode,blocksize, \
|
||||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
|
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \
|
||||||
|
ivlen, \
|
||||||
flags|EVP_CIPH_##MODE##_MODE, \
|
flags|EVP_CIPH_##MODE##_MODE, \
|
||||||
aesni_##mode##_init_key, \
|
aesni_##mode##_init_key, \
|
||||||
aesni_##mode##_cipher, \
|
aesni_##mode##_cipher, \
|
||||||
@@ -549,7 +551,8 @@ static const EVP_CIPHER aesni_##keylen##_##mode = { \
|
|||||||
NULL,NULL,aes_##mode##_ctrl,NULL }; \
|
NULL,NULL,aes_##mode##_ctrl,NULL }; \
|
||||||
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||||
nid##_##keylen##_##mode,blocksize, \
|
nid##_##keylen##_##mode,blocksize, \
|
||||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
|
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \
|
||||||
|
ivlen, \
|
||||||
flags|EVP_CIPH_##MODE##_MODE, \
|
flags|EVP_CIPH_##MODE##_MODE, \
|
||||||
aes_##mode##_init_key, \
|
aes_##mode##_init_key, \
|
||||||
aes_##mode##_cipher, \
|
aes_##mode##_cipher, \
|
||||||
@@ -948,7 +951,8 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
|||||||
# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
|
# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
|
||||||
static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
|
static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
|
||||||
nid##_##keylen##_##mode,blocksize, \
|
nid##_##keylen##_##mode,blocksize, \
|
||||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
|
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \
|
||||||
|
ivlen, \
|
||||||
flags|EVP_CIPH_##MODE##_MODE, \
|
flags|EVP_CIPH_##MODE##_MODE, \
|
||||||
aes_t4_##mode##_init_key, \
|
aes_t4_##mode##_init_key, \
|
||||||
aes_t4_##mode##_cipher, \
|
aes_t4_##mode##_cipher, \
|
||||||
@@ -957,7 +961,8 @@ static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
|
|||||||
NULL,NULL,aes_##mode##_ctrl,NULL }; \
|
NULL,NULL,aes_##mode##_ctrl,NULL }; \
|
||||||
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||||
nid##_##keylen##_##mode,blocksize, \
|
nid##_##keylen##_##mode,blocksize, \
|
||||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
|
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \
|
||||||
|
ivlen, \
|
||||||
flags|EVP_CIPH_##MODE##_MODE, \
|
flags|EVP_CIPH_##MODE##_MODE, \
|
||||||
aes_##mode##_init_key, \
|
aes_##mode##_init_key, \
|
||||||
aes_##mode##_cipher, \
|
aes_##mode##_cipher, \
|
||||||
@@ -2512,7 +2517,8 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
|||||||
# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
|
# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
|
||||||
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||||
nid##_##keylen##_##mode,blocksize, \
|
nid##_##keylen##_##mode,blocksize, \
|
||||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
|
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE?2:1)*keylen/8, \
|
||||||
|
ivlen, \
|
||||||
flags|EVP_CIPH_##MODE##_MODE, \
|
flags|EVP_CIPH_##MODE##_MODE, \
|
||||||
aes_##mode##_init_key, \
|
aes_##mode##_init_key, \
|
||||||
aes_##mode##_cipher, \
|
aes_##mode##_cipher, \
|
||||||
@@ -2866,6 +2872,14 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
|||||||
memcpy(ptr, c->buf, arg);
|
memcpy(ptr, c->buf, arg);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
case EVP_CTRL_GET_IV:
|
||||||
|
if (gctx->iv_gen != 1)
|
||||||
|
return 0;
|
||||||
|
if (gctx->ivlen != arg)
|
||||||
|
return 0;
|
||||||
|
memcpy(ptr, gctx->iv, arg);
|
||||||
|
return 1;
|
||||||
|
|
||||||
case EVP_CTRL_GCM_SET_IV_FIXED:
|
case EVP_CTRL_GCM_SET_IV_FIXED:
|
||||||
/* Special case: -1 length restores whole IV */
|
/* Special case: -1 length restores whole IV */
|
||||||
if (arg == -1) {
|
if (arg == -1) {
|
||||||
@@ -4255,3 +4269,114 @@ BLOCK_CIPHER_custom(NID_aes, 192, 16, 12, ocb, OCB,
|
|||||||
BLOCK_CIPHER_custom(NID_aes, 256, 16, 12, ocb, OCB,
|
BLOCK_CIPHER_custom(NID_aes, 256, 16, 12, ocb, OCB,
|
||||||
EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
|
EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
|
||||||
#endif /* OPENSSL_NO_OCB */
|
#endif /* OPENSSL_NO_OCB */
|
||||||
|
|
||||||
|
/* AES-SIV mode */
|
||||||
|
#ifndef OPENSSL_NO_SIV
|
||||||
|
|
||||||
|
typedef SIV128_CONTEXT EVP_AES_SIV_CTX;
|
||||||
|
|
||||||
|
#define aesni_siv_init_key aes_siv_init_key
|
||||||
|
static int aes_siv_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||||
|
const unsigned char *iv, int enc)
|
||||||
|
{
|
||||||
|
const EVP_CIPHER *ctr;
|
||||||
|
const EVP_CIPHER *cbc;
|
||||||
|
SIV128_CONTEXT *sctx = EVP_C_DATA(SIV128_CONTEXT, ctx);
|
||||||
|
int klen = EVP_CIPHER_CTX_key_length(ctx) / 2;
|
||||||
|
|
||||||
|
if (key == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
switch (klen) {
|
||||||
|
case 16:
|
||||||
|
cbc = EVP_aes_128_cbc();
|
||||||
|
ctr = EVP_aes_128_ctr();
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
cbc = EVP_aes_192_cbc();
|
||||||
|
ctr = EVP_aes_192_ctr();
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
cbc = EVP_aes_256_cbc();
|
||||||
|
ctr = EVP_aes_256_ctr();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* klen is the length of the underlying cipher, not the input key,
|
||||||
|
which should be twice as long */
|
||||||
|
return CRYPTO_siv128_init(sctx, key, klen, cbc, ctr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define aesni_siv_cipher aes_siv_cipher
|
||||||
|
static int aes_siv_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||||
|
const unsigned char *in, size_t len)
|
||||||
|
{
|
||||||
|
SIV128_CONTEXT *sctx = EVP_C_DATA(SIV128_CONTEXT, ctx);
|
||||||
|
|
||||||
|
/* EncryptFinal or DecryptFinal */
|
||||||
|
if (in == NULL)
|
||||||
|
return CRYPTO_siv128_finish(sctx);
|
||||||
|
|
||||||
|
/* Deal with associated data */
|
||||||
|
if (out == NULL)
|
||||||
|
return CRYPTO_siv128_aad(sctx, in, len);
|
||||||
|
|
||||||
|
if (EVP_CIPHER_CTX_encrypting(ctx))
|
||||||
|
return CRYPTO_siv128_encrypt(sctx, in, out, len);
|
||||||
|
|
||||||
|
return CRYPTO_siv128_decrypt(sctx, in, out, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define aesni_siv_cleanup aes_siv_cleanup
|
||||||
|
static int aes_siv_cleanup(EVP_CIPHER_CTX *c)
|
||||||
|
{
|
||||||
|
SIV128_CONTEXT *sctx = EVP_C_DATA(SIV128_CONTEXT, c);
|
||||||
|
|
||||||
|
return CRYPTO_siv128_cleanup(sctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define aesni_siv_ctrl aes_siv_ctrl
|
||||||
|
static int aes_siv_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||||
|
{
|
||||||
|
SIV128_CONTEXT *sctx = EVP_C_DATA(SIV128_CONTEXT, c);
|
||||||
|
SIV128_CONTEXT *sctx_out;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case EVP_CTRL_INIT:
|
||||||
|
return CRYPTO_siv128_cleanup(sctx);
|
||||||
|
|
||||||
|
case EVP_CTRL_SET_SPEED:
|
||||||
|
return CRYPTO_siv128_speed(sctx, arg);
|
||||||
|
|
||||||
|
case EVP_CTRL_AEAD_SET_TAG:
|
||||||
|
if (!EVP_CIPHER_CTX_encrypting(c))
|
||||||
|
return CRYPTO_siv128_set_tag(sctx, ptr, arg);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case EVP_CTRL_AEAD_GET_TAG:
|
||||||
|
if (!EVP_CIPHER_CTX_encrypting(c))
|
||||||
|
return 0;
|
||||||
|
return CRYPTO_siv128_get_tag(sctx, ptr, arg);
|
||||||
|
|
||||||
|
case EVP_CTRL_COPY:
|
||||||
|
sctx_out = EVP_C_DATA(SIV128_CONTEXT, (EVP_CIPHER_CTX*)ptr);
|
||||||
|
return CRYPTO_siv128_copy_ctx(sctx_out, sctx);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SIV_FLAGS (EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_DEFAULT_ASN1 \
|
||||||
|
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
|
||||||
|
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_COPY \
|
||||||
|
| EVP_CIPH_CTRL_INIT)
|
||||||
|
|
||||||
|
BLOCK_CIPHER_custom(NID_aes, 128, 1, 0, siv, SIV, SIV_FLAGS)
|
||||||
|
BLOCK_CIPHER_custom(NID_aes, 192, 1, 0, siv, SIV, SIV_FLAGS)
|
||||||
|
BLOCK_CIPHER_custom(NID_aes, 256, 1, 0, siv, SIV, SIV_FLAGS)
|
||||||
|
#endif
|
||||||
+39
-6
@@ -294,8 +294,9 @@ int is_partially_overlapping(const void *ptr1, const void *ptr2, int len)
|
|||||||
return overlapped;
|
return overlapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
|
||||||
const unsigned char *in, int inl)
|
unsigned char *out, int *outl,
|
||||||
|
const unsigned char *in, int inl)
|
||||||
{
|
{
|
||||||
int i, j, bl, cmpl = inl;
|
int i, j, bl, cmpl = inl;
|
||||||
|
|
||||||
@@ -307,7 +308,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
|||||||
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
||||||
/* If block size > 1 then the cipher will have to do this check */
|
/* If block size > 1 then the cipher will have to do this check */
|
||||||
if (bl == 1 && is_partially_overlapping(out, in, cmpl)) {
|
if (bl == 1 && is_partially_overlapping(out, in, cmpl)) {
|
||||||
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
|
EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,7 +325,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
|||||||
return inl == 0;
|
return inl == 0;
|
||||||
}
|
}
|
||||||
if (is_partially_overlapping(out + ctx->buf_len, in, cmpl)) {
|
if (is_partially_overlapping(out + ctx->buf_len, in, cmpl)) {
|
||||||
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
|
EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,6 +372,19 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||||
|
const unsigned char *in, int inl)
|
||||||
|
{
|
||||||
|
/* Prevent accidental use of decryption context when encrypting */
|
||||||
|
if (!ctx->encrypt) {
|
||||||
|
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_INVALID_OPERATION);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl);
|
||||||
|
}
|
||||||
|
|
||||||
int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -383,6 +397,12 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
|||||||
int n, ret;
|
int n, ret;
|
||||||
unsigned int i, b, bl;
|
unsigned int i, b, bl;
|
||||||
|
|
||||||
|
/* Prevent accidental use of decryption context when encrypting */
|
||||||
|
if (!ctx->encrypt) {
|
||||||
|
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_INVALID_OPERATION);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
||||||
ret = ctx->cipher->do_cipher(ctx, out, NULL, 0);
|
ret = ctx->cipher->do_cipher(ctx, out, NULL, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -426,6 +446,12 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
|||||||
int fix_len, cmpl = inl;
|
int fix_len, cmpl = inl;
|
||||||
unsigned int b;
|
unsigned int b;
|
||||||
|
|
||||||
|
/* Prevent accidental use of encryption context when decrypting */
|
||||||
|
if (ctx->encrypt) {
|
||||||
|
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_INVALID_OPERATION);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
b = ctx->cipher->block_size;
|
b = ctx->cipher->block_size;
|
||||||
|
|
||||||
if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
|
if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
|
||||||
@@ -452,7 +478,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->flags & EVP_CIPH_NO_PADDING)
|
if (ctx->flags & EVP_CIPH_NO_PADDING)
|
||||||
return EVP_EncryptUpdate(ctx, out, outl, in, inl);
|
return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl);
|
||||||
|
|
||||||
OPENSSL_assert(b <= sizeof(ctx->final));
|
OPENSSL_assert(b <= sizeof(ctx->final));
|
||||||
|
|
||||||
@@ -469,7 +495,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
|||||||
} else
|
} else
|
||||||
fix_len = 0;
|
fix_len = 0;
|
||||||
|
|
||||||
if (!EVP_EncryptUpdate(ctx, out, outl, in, inl))
|
if (!evp_EncryptDecryptUpdate(ctx, out, outl, in, inl))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -500,6 +526,13 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
|||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
unsigned int b;
|
unsigned int b;
|
||||||
|
|
||||||
|
/* Prevent accidental use of encryption context when decrypting */
|
||||||
|
if (ctx->encrypt) {
|
||||||
|
EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_INVALID_OPERATION);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
*outl = 0;
|
*outl = 0;
|
||||||
|
|
||||||
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
|
|||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTUPDATE, 0), "EVP_DecryptUpdate"},
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTUPDATE, 0), "EVP_DecryptUpdate"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTFINALXOF, 0), "EVP_DigestFinalXOF"},
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTFINALXOF, 0), "EVP_DigestFinalXOF"},
|
||||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTINIT_EX, 0), "EVP_DigestInit_ex"},
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTINIT_EX, 0), "EVP_DigestInit_ex"},
|
||||||
|
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTDECRYPTUPDATE, 0),
|
||||||
|
"evp_EncryptDecryptUpdate"},
|
||||||
{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"},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
* Licensed under the 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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
* Licensed under the 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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
* Licensed under the 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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Licensed under the OpenSSL licenses, (the "License");
|
* Licensed under the Apache License 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Copyright 2017 Ribose Inc. All Rights Reserved.
|
* Copyright 2017 Ribose Inc. All Rights Reserved.
|
||||||
* Ported from Ribose contributions from Botan.
|
* Ported from Ribose contributions from Botan.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* 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-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
* Copyright 2017 Ribose Inc. All Rights Reserved.
|
* Copyright 2017 Ribose Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
* Copyright 2017 Ribose Inc. All Rights Reserved.
|
* Copyright 2017 Ribose Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
* Licensed under the 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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
+4
-4
@@ -19,28 +19,28 @@
|
|||||||
* KMAC128(K, X, L, S)
|
* KMAC128(K, X, L, S)
|
||||||
* {
|
* {
|
||||||
* newX = bytepad(encode_string(K), 168) || X || right_encode(L).
|
* newX = bytepad(encode_string(K), 168) || X || right_encode(L).
|
||||||
* T = bytepad(encode_string(“KMAC”) || encode_string(S), 168).
|
* T = bytepad(encode_string("KMAC") || encode_string(S), 168).
|
||||||
* return KECCAK[256](T || newX || 00, L).
|
* return KECCAK[256](T || newX || 00, L).
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* KMAC256(K, X, L, S)
|
* KMAC256(K, X, L, S)
|
||||||
* {
|
* {
|
||||||
* newX = bytepad(encode_string(K), 136) || X || right_encode(L).
|
* newX = bytepad(encode_string(K), 136) || X || right_encode(L).
|
||||||
* T = bytepad(encode_string(“KMAC”) || encode_string(S), 136).
|
* T = bytepad(encode_string("KMAC") || encode_string(S), 136).
|
||||||
* return KECCAK[512](T || newX || 00, L).
|
* return KECCAK[512](T || newX || 00, L).
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* KMAC128XOF(K, X, L, S)
|
* KMAC128XOF(K, X, L, S)
|
||||||
* {
|
* {
|
||||||
* newX = bytepad(encode_string(K), 168) || X || right_encode(0).
|
* newX = bytepad(encode_string(K), 168) || X || right_encode(0).
|
||||||
* T = bytepad(encode_string(“KMAC”) || encode_string(S), 168).
|
* T = bytepad(encode_string("KMAC") || encode_string(S), 168).
|
||||||
* return KECCAK[256](T || newX || 00, L).
|
* return KECCAK[256](T || newX || 00, L).
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* KMAC256XOF(K, X, L, S)
|
* KMAC256XOF(K, X, L, S)
|
||||||
* {
|
* {
|
||||||
* newX = bytepad(encode_string(K), 136) || X || right_encode(0).
|
* newX = bytepad(encode_string(K), 136) || X || right_encode(0).
|
||||||
* T = bytepad(encode_string(“KMAC”) || encode_string(S), 136).
|
* T = bytepad(encode_string("KMAC") || encode_string(S), 136).
|
||||||
* return KECCAK[512](T || newX || 00, L).
|
* return KECCAK[512](T || newX || 00, L).
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
LIBS=../../libcrypto
|
LIBS=../../libcrypto
|
||||||
SOURCE[../../libcrypto]=\
|
SOURCE[../../libcrypto]=\
|
||||||
cbc128.c ctr128.c cts128.c cfb128.c ofb128.c gcm128.c \
|
cbc128.c ctr128.c cts128.c cfb128.c ofb128.c gcm128.c \
|
||||||
ccm128.c xts128.c wrap128.c ocb128.c \
|
ccm128.c xts128.c wrap128.c ocb128.c siv128.c \
|
||||||
{- $target{modes_asm_src} -}
|
{- $target{modes_asm_src} -}
|
||||||
|
|
||||||
INCLUDE[gcm128.o]=..
|
INCLUDE[gcm128.o]=..
|
||||||
|
|||||||
@@ -188,3 +188,28 @@ struct ocb128_context {
|
|||||||
} sess;
|
} sess;
|
||||||
};
|
};
|
||||||
#endif /* OPENSSL_NO_OCB */
|
#endif /* OPENSSL_NO_OCB */
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_SIV
|
||||||
|
|
||||||
|
#include <openssl/cmac.h>
|
||||||
|
|
||||||
|
#define SIV_LEN 16
|
||||||
|
|
||||||
|
typedef union siv_block_u {
|
||||||
|
uint64_t word[SIV_LEN/sizeof(uint64_t)];
|
||||||
|
unsigned char byte[SIV_LEN];
|
||||||
|
} SIV_BLOCK;
|
||||||
|
|
||||||
|
struct siv128_context {
|
||||||
|
/* d stores intermediate results of S2V; it corresponds to D from the
|
||||||
|
pseudocode in section 2.4 of RFC 5297. */
|
||||||
|
SIV_BLOCK d;
|
||||||
|
SIV_BLOCK tag;
|
||||||
|
EVP_CIPHER_CTX *cipher_ctx;
|
||||||
|
CMAC_CTX *cmac_ctx_init;
|
||||||
|
CMAC_CTX *cmac_ctx;
|
||||||
|
int final_ret;
|
||||||
|
int crypto_ok;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* OPENSSL_NO_SIV */
|
||||||
@@ -0,0 +1,349 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||||
|
* this file except in compliance with the License. You can obtain a copy
|
||||||
|
* in the file LICENSE in the source distribution or at
|
||||||
|
* https://www.openssl.org/source/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
#include <openssl/cmac.h>
|
||||||
|
#include "modes_lcl.h"
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_SIV
|
||||||
|
|
||||||
|
__owur static ossl_inline uint32_t rotl8(uint32_t x)
|
||||||
|
{
|
||||||
|
return (x << 8) | (x >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
__owur static ossl_inline uint32_t rotr8(uint32_t x)
|
||||||
|
{
|
||||||
|
return (x >> 8) | (x << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
__owur static ossl_inline uint64_t byteswap8(uint64_t x)
|
||||||
|
{
|
||||||
|
uint32_t high = (uint32_t)(x >> 32);
|
||||||
|
uint32_t low = (uint32_t)x;
|
||||||
|
|
||||||
|
high = (rotl8(high) & 0x00ff00ff) | (rotr8(high) & 0xff00ff00);
|
||||||
|
low = (rotl8(low) & 0x00ff00ff) | (rotr8(low) & 0xff00ff00);
|
||||||
|
return ((uint64_t)low) << 32 | (uint64_t)high;
|
||||||
|
}
|
||||||
|
|
||||||
|
__owur static ossl_inline uint64_t siv128_getword(SIV_BLOCK const *b, size_t i)
|
||||||
|
{
|
||||||
|
const union {
|
||||||
|
long one;
|
||||||
|
char little;
|
||||||
|
} is_endian = { 1 };
|
||||||
|
|
||||||
|
if (is_endian.little)
|
||||||
|
return byteswap8(b->word[i]);
|
||||||
|
return b->word[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
static ossl_inline void siv128_putword(SIV_BLOCK *b, size_t i, uint64_t x)
|
||||||
|
{
|
||||||
|
const union {
|
||||||
|
long one;
|
||||||
|
char little;
|
||||||
|
} is_endian = { 1 };
|
||||||
|
|
||||||
|
if (is_endian.little)
|
||||||
|
b->word[i] = byteswap8(x);
|
||||||
|
else
|
||||||
|
b->word[i] = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ossl_inline void siv128_xorblock(SIV_BLOCK *x,
|
||||||
|
SIV_BLOCK const *y)
|
||||||
|
{
|
||||||
|
x->word[0] ^= y->word[0];
|
||||||
|
x->word[1] ^= y->word[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Doubles |b|, which is 16 bytes representing an element
|
||||||
|
* of GF(2**128) modulo the irreducible polynomial
|
||||||
|
* x**128 + x**7 + x**2 + x + 1.
|
||||||
|
* Assumes two's-complement arithmetic
|
||||||
|
*/
|
||||||
|
static ossl_inline void siv128_dbl(SIV_BLOCK *b)
|
||||||
|
{
|
||||||
|
uint64_t high = siv128_getword(b, 0);
|
||||||
|
uint64_t low = siv128_getword(b, 1);
|
||||||
|
uint64_t high_carry = high & (((uint64_t)1) << 63);
|
||||||
|
uint64_t low_carry = low & (((uint64_t)1) << 63);
|
||||||
|
int64_t low_mask = -((int64_t)(high_carry >> 63)) & 0x87;
|
||||||
|
uint64_t high_mask = low_carry >> 63;
|
||||||
|
|
||||||
|
high = (high << 1) | high_mask;
|
||||||
|
low = (low << 1) ^ (uint64_t)low_mask;
|
||||||
|
siv128_putword(b, 0, high);
|
||||||
|
siv128_putword(b, 1, low);
|
||||||
|
}
|
||||||
|
|
||||||
|
__owur static ossl_inline int siv128_do_s2v_p(SIV128_CONTEXT *ctx, SIV_BLOCK *out,
|
||||||
|
unsigned char const* in, size_t len)
|
||||||
|
{
|
||||||
|
SIV_BLOCK t;
|
||||||
|
size_t out_len = sizeof(out->byte);
|
||||||
|
|
||||||
|
if (!CMAC_CTX_copy(ctx->cmac_ctx, ctx->cmac_ctx_init))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (len >= SIV_LEN) {
|
||||||
|
if (!CMAC_Update(ctx->cmac_ctx, in, len - SIV_LEN))
|
||||||
|
return 0;
|
||||||
|
memcpy(&t, in + (len-SIV_LEN), SIV_LEN);
|
||||||
|
siv128_xorblock(&t, &ctx->d);
|
||||||
|
if (!CMAC_Update(ctx->cmac_ctx, t.byte, SIV_LEN))
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
memset(&t, 0, sizeof(t));
|
||||||
|
memcpy(&t, in, len);
|
||||||
|
t.byte[len] = 0x80;
|
||||||
|
siv128_dbl(&ctx->d);
|
||||||
|
siv128_xorblock(&t, &ctx->d);
|
||||||
|
if (!CMAC_Update(ctx->cmac_ctx, t.byte, SIV_LEN))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!CMAC_Final(ctx->cmac_ctx, out->byte, &out_len)
|
||||||
|
|| out_len != SIV_LEN)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__owur static ossl_inline int siv128_do_encrypt(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||||
|
unsigned char const *in, size_t len,
|
||||||
|
SIV_BLOCK *icv)
|
||||||
|
{
|
||||||
|
int out_len = (int)len;
|
||||||
|
|
||||||
|
if (!EVP_CipherInit_ex(ctx, NULL, NULL, NULL, icv->byte, 1))
|
||||||
|
return 0;
|
||||||
|
return EVP_EncryptUpdate(ctx, out, &out_len, in, out_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a new SIV128_CONTEXT
|
||||||
|
*/
|
||||||
|
SIV128_CONTEXT *CRYPTO_siv128_new(const unsigned char *key, int klen, EVP_CIPHER* cbc, EVP_CIPHER* ctr)
|
||||||
|
{
|
||||||
|
SIV128_CONTEXT *ctx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if ((ctx = OPENSSL_malloc(sizeof(*ctx))) != NULL) {
|
||||||
|
ret = CRYPTO_siv128_init(ctx, key, klen, cbc, ctr);
|
||||||
|
if (ret)
|
||||||
|
return ctx;
|
||||||
|
OPENSSL_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise an existing SIV128_CONTEXT
|
||||||
|
*/
|
||||||
|
int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen,
|
||||||
|
const EVP_CIPHER* cbc, const EVP_CIPHER* ctr)
|
||||||
|
{
|
||||||
|
static const unsigned char zero[SIV_LEN] = { 0 };
|
||||||
|
size_t out_len = SIV_LEN;
|
||||||
|
|
||||||
|
memset(&ctx->d, 0, sizeof(ctx->d));
|
||||||
|
ctx->cipher_ctx = NULL;
|
||||||
|
ctx->cmac_ctx = NULL;
|
||||||
|
ctx->cmac_ctx_init = NULL;
|
||||||
|
|
||||||
|
if (key == NULL || cbc == NULL || ctr == NULL
|
||||||
|
|| (ctx->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL
|
||||||
|
|| (ctx->cmac_ctx_init = CMAC_CTX_new()) == NULL
|
||||||
|
|| (ctx->cmac_ctx = CMAC_CTX_new()) == NULL
|
||||||
|
|| !CMAC_Init(ctx->cmac_ctx_init, key, klen, cbc, NULL)
|
||||||
|
|| !EVP_EncryptInit_ex(ctx->cipher_ctx, ctr, NULL, key + klen, NULL)
|
||||||
|
|| !CMAC_CTX_copy(ctx->cmac_ctx, ctx->cmac_ctx_init)
|
||||||
|
|| !CMAC_Update(ctx->cmac_ctx, zero, sizeof(zero))
|
||||||
|
|| !CMAC_Final(ctx->cmac_ctx, ctx->d.byte, &out_len)) {
|
||||||
|
EVP_CIPHER_CTX_free(ctx->cipher_ctx);
|
||||||
|
CMAC_CTX_free(ctx->cmac_ctx_init);
|
||||||
|
CMAC_CTX_free(ctx->cmac_ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->final_ret = -1;
|
||||||
|
ctx->crypto_ok = 1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy an SIV128_CONTEXT object
|
||||||
|
*/
|
||||||
|
int CRYPTO_siv128_copy_ctx(SIV128_CONTEXT *dest, SIV128_CONTEXT *src)
|
||||||
|
{
|
||||||
|
memcpy(&dest->d, &src->d, sizeof(src->d));
|
||||||
|
if (!EVP_CIPHER_CTX_copy(dest->cipher_ctx, src->cipher_ctx))
|
||||||
|
return 0;
|
||||||
|
if (!CMAC_CTX_copy(dest->cmac_ctx_init, src->cmac_ctx_init))
|
||||||
|
return 0;
|
||||||
|
/* no need to copy cmac_ctx since it's temp storage */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Provide any AAD. This can be called multiple times.
|
||||||
|
* Per RFC5297, the last piece of associated data
|
||||||
|
* is the nonce, but it's not treated special
|
||||||
|
*/
|
||||||
|
int CRYPTO_siv128_aad(SIV128_CONTEXT *ctx, const unsigned char *aad,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
SIV_BLOCK cmac_out;
|
||||||
|
size_t out_len = SIV_LEN;
|
||||||
|
|
||||||
|
siv128_dbl(&ctx->d);
|
||||||
|
|
||||||
|
if (!CMAC_CTX_copy(ctx->cmac_ctx, ctx->cmac_ctx_init)
|
||||||
|
|| !CMAC_Update(ctx->cmac_ctx, aad, len)
|
||||||
|
|| !CMAC_Final(ctx->cmac_ctx, cmac_out.byte, &out_len)
|
||||||
|
|| out_len != SIV_LEN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
siv128_xorblock(&ctx->d, &cmac_out);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Provide any data to be encrypted. This can be called once.
|
||||||
|
*/
|
||||||
|
int CRYPTO_siv128_encrypt(SIV128_CONTEXT *ctx,
|
||||||
|
const unsigned char *in, unsigned char *out,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
SIV_BLOCK q;
|
||||||
|
|
||||||
|
/* can only do one crypto operation */
|
||||||
|
if (ctx->crypto_ok == 0)
|
||||||
|
return 0;
|
||||||
|
ctx->crypto_ok--;
|
||||||
|
|
||||||
|
if (!siv128_do_s2v_p(ctx, &q, in, len))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memcpy(ctx->tag.byte, &q, SIV_LEN);
|
||||||
|
q.byte[8] &= 0x7f;
|
||||||
|
q.byte[12] &= 0x7f;
|
||||||
|
|
||||||
|
if (!siv128_do_encrypt(ctx->cipher_ctx, out, in, len, &q))
|
||||||
|
return 0;
|
||||||
|
ctx->final_ret = 0;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Provide any data to be decrypted. This can be called once.
|
||||||
|
*/
|
||||||
|
int CRYPTO_siv128_decrypt(SIV128_CONTEXT *ctx,
|
||||||
|
const unsigned char *in, unsigned char *out,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
unsigned char* p;
|
||||||
|
SIV_BLOCK t, q;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* can only do one crypto operation */
|
||||||
|
if (ctx->crypto_ok == 0)
|
||||||
|
return 0;
|
||||||
|
ctx->crypto_ok--;
|
||||||
|
|
||||||
|
memcpy(&q, ctx->tag.byte, SIV_LEN);
|
||||||
|
q.byte[8] &= 0x7f;
|
||||||
|
q.byte[12] &= 0x7f;
|
||||||
|
|
||||||
|
if (!siv128_do_encrypt(ctx->cipher_ctx, out, in, len, &q)
|
||||||
|
|| !siv128_do_s2v_p(ctx, &t, out, len))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
p = ctx->tag.byte;
|
||||||
|
for (i = 0; i < SIV_LEN; i++)
|
||||||
|
t.byte[i] ^= p[i];
|
||||||
|
|
||||||
|
if ((t.word[0] | t.word[1]) != 0) {
|
||||||
|
OPENSSL_cleanse(out, len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ctx->final_ret = 0;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the already calculated final result.
|
||||||
|
*/
|
||||||
|
int CRYPTO_siv128_finish(SIV128_CONTEXT *ctx)
|
||||||
|
{
|
||||||
|
return ctx->final_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the tag
|
||||||
|
*/
|
||||||
|
int CRYPTO_siv128_set_tag(SIV128_CONTEXT *ctx, const unsigned char *tag, size_t len)
|
||||||
|
{
|
||||||
|
if (len != SIV_LEN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Copy the tag from the supplied buffer */
|
||||||
|
memcpy(ctx->tag.byte, tag, len);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve the calculated tag
|
||||||
|
*/
|
||||||
|
int CRYPTO_siv128_get_tag(SIV128_CONTEXT *ctx, unsigned char *tag, size_t len)
|
||||||
|
{
|
||||||
|
if (len != SIV_LEN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Copy the tag into the supplied buffer */
|
||||||
|
memcpy(tag, ctx->tag.byte, len);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Release all resources
|
||||||
|
*/
|
||||||
|
int CRYPTO_siv128_cleanup(SIV128_CONTEXT *ctx)
|
||||||
|
{
|
||||||
|
if (ctx != NULL) {
|
||||||
|
EVP_CIPHER_CTX_free(ctx->cipher_ctx);
|
||||||
|
ctx->cipher_ctx = NULL;
|
||||||
|
CMAC_CTX_free(ctx->cmac_ctx_init);
|
||||||
|
ctx->cmac_ctx_init = NULL;
|
||||||
|
CMAC_CTX_free(ctx->cmac_ctx);
|
||||||
|
ctx->cmac_ctx = NULL;
|
||||||
|
OPENSSL_cleanse(&ctx->d, sizeof(ctx->d));
|
||||||
|
OPENSSL_cleanse(&ctx->tag, sizeof(ctx->tag));
|
||||||
|
ctx->final_ret = -1;
|
||||||
|
ctx->crypto_ok = 1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CRYPTO_siv128_speed(SIV128_CONTEXT *ctx, int arg)
|
||||||
|
{
|
||||||
|
ctx->crypto_ok = (arg == 1) ? -1 : 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* OPENSSL_NO_SIV */
|
||||||
@@ -1079,7 +1079,7 @@ static const unsigned char so[7767] = {
|
|||||||
0x28,0xCC,0x45,0x03,0x04, /* [ 7761] OBJ_gmac */
|
0x28,0xCC,0x45,0x03,0x04, /* [ 7761] OBJ_gmac */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_NID 1199
|
#define NUM_NID 1202
|
||||||
static const ASN1_OBJECT nid_objs[NUM_NID] = {
|
static const ASN1_OBJECT nid_objs[NUM_NID] = {
|
||||||
{"UNDEF", "undefined", NID_undef},
|
{"UNDEF", "undefined", NID_undef},
|
||||||
{"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
|
{"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
|
||||||
@@ -2279,10 +2279,13 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
|
|||||||
{"GMAC", "gmac", NID_gmac, 5, &so[7761]},
|
{"GMAC", "gmac", NID_gmac, 5, &so[7761]},
|
||||||
{"KMAC128", "kmac128", NID_kmac128},
|
{"KMAC128", "kmac128", NID_kmac128},
|
||||||
{"KMAC256", "kmac256", NID_kmac256},
|
{"KMAC256", "kmac256", NID_kmac256},
|
||||||
|
{"AES-128-SIV", "aes-128-siv", NID_aes_128_siv},
|
||||||
|
{"AES-192-SIV", "aes-192-siv", NID_aes_192_siv},
|
||||||
|
{"AES-256-SIV", "aes-256-siv", NID_aes_256_siv},
|
||||||
{"ChaCha20-Poly1305-D", "chacha20-poly1305-draft", NID_chacha20_poly1305_draft },
|
{"ChaCha20-Poly1305-D", "chacha20-poly1305-draft", NID_chacha20_poly1305_draft },
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_SN 1190
|
#define NUM_SN 1193
|
||||||
static const unsigned int sn_objs[NUM_SN] = {
|
static const unsigned int sn_objs[NUM_SN] = {
|
||||||
364, /* "AD_DVCS" */
|
364, /* "AD_DVCS" */
|
||||||
419, /* "AES-128-CBC" */
|
419, /* "AES-128-CBC" */
|
||||||
@@ -2295,6 +2298,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
|||||||
418, /* "AES-128-ECB" */
|
418, /* "AES-128-ECB" */
|
||||||
958, /* "AES-128-OCB" */
|
958, /* "AES-128-OCB" */
|
||||||
420, /* "AES-128-OFB" */
|
420, /* "AES-128-OFB" */
|
||||||
|
1198, /* "AES-128-SIV" */
|
||||||
913, /* "AES-128-XTS" */
|
913, /* "AES-128-XTS" */
|
||||||
423, /* "AES-192-CBC" */
|
423, /* "AES-192-CBC" */
|
||||||
917, /* "AES-192-CBC-HMAC-SHA1" */
|
917, /* "AES-192-CBC-HMAC-SHA1" */
|
||||||
@@ -2306,6 +2310,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
|||||||
422, /* "AES-192-ECB" */
|
422, /* "AES-192-ECB" */
|
||||||
959, /* "AES-192-OCB" */
|
959, /* "AES-192-OCB" */
|
||||||
424, /* "AES-192-OFB" */
|
424, /* "AES-192-OFB" */
|
||||||
|
1199, /* "AES-192-SIV" */
|
||||||
427, /* "AES-256-CBC" */
|
427, /* "AES-256-CBC" */
|
||||||
918, /* "AES-256-CBC-HMAC-SHA1" */
|
918, /* "AES-256-CBC-HMAC-SHA1" */
|
||||||
950, /* "AES-256-CBC-HMAC-SHA256" */
|
950, /* "AES-256-CBC-HMAC-SHA256" */
|
||||||
@@ -2316,6 +2321,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
|||||||
426, /* "AES-256-ECB" */
|
426, /* "AES-256-ECB" */
|
||||||
960, /* "AES-256-OCB" */
|
960, /* "AES-256-OCB" */
|
||||||
428, /* "AES-256-OFB" */
|
428, /* "AES-256-OFB" */
|
||||||
|
1200, /* "AES-256-SIV" */
|
||||||
914, /* "AES-256-XTS" */
|
914, /* "AES-256-XTS" */
|
||||||
1066, /* "ARIA-128-CBC" */
|
1066, /* "ARIA-128-CBC" */
|
||||||
1120, /* "ARIA-128-CCM" */
|
1120, /* "ARIA-128-CCM" */
|
||||||
@@ -2400,7 +2406,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
|||||||
417, /* "CSPName" */
|
417, /* "CSPName" */
|
||||||
1019, /* "ChaCha20" */
|
1019, /* "ChaCha20" */
|
||||||
1018, /* "ChaCha20-Poly1305" */
|
1018, /* "ChaCha20-Poly1305" */
|
||||||
1198, /* "chacha20-poly1305-draft" */
|
1201, /* "chacha20-poly1305-draft" */
|
||||||
367, /* "CrlID" */
|
367, /* "CrlID" */
|
||||||
391, /* "DC" */
|
391, /* "DC" */
|
||||||
31, /* "DES-CBC" */
|
31, /* "DES-CBC" */
|
||||||
@@ -3476,7 +3482,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
|||||||
1093, /* "x509ExtAdmission" */
|
1093, /* "x509ExtAdmission" */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_LN 1190
|
#define NUM_LN 1193
|
||||||
static const unsigned int ln_objs[NUM_LN] = {
|
static const unsigned int ln_objs[NUM_LN] = {
|
||||||
363, /* "AD Time Stamping" */
|
363, /* "AD Time Stamping" */
|
||||||
405, /* "ANSI X9.62" */
|
405, /* "ANSI X9.62" */
|
||||||
@@ -3703,6 +3709,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
|||||||
895, /* "aes-128-gcm" */
|
895, /* "aes-128-gcm" */
|
||||||
958, /* "aes-128-ocb" */
|
958, /* "aes-128-ocb" */
|
||||||
420, /* "aes-128-ofb" */
|
420, /* "aes-128-ofb" */
|
||||||
|
1198, /* "aes-128-siv" */
|
||||||
913, /* "aes-128-xts" */
|
913, /* "aes-128-xts" */
|
||||||
423, /* "aes-192-cbc" */
|
423, /* "aes-192-cbc" */
|
||||||
917, /* "aes-192-cbc-hmac-sha1" */
|
917, /* "aes-192-cbc-hmac-sha1" */
|
||||||
@@ -3716,6 +3723,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
|||||||
898, /* "aes-192-gcm" */
|
898, /* "aes-192-gcm" */
|
||||||
959, /* "aes-192-ocb" */
|
959, /* "aes-192-ocb" */
|
||||||
424, /* "aes-192-ofb" */
|
424, /* "aes-192-ofb" */
|
||||||
|
1199, /* "aes-192-siv" */
|
||||||
427, /* "aes-256-cbc" */
|
427, /* "aes-256-cbc" */
|
||||||
918, /* "aes-256-cbc-hmac-sha1" */
|
918, /* "aes-256-cbc-hmac-sha1" */
|
||||||
950, /* "aes-256-cbc-hmac-sha256" */
|
950, /* "aes-256-cbc-hmac-sha256" */
|
||||||
@@ -3728,6 +3736,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
|||||||
901, /* "aes-256-gcm" */
|
901, /* "aes-256-gcm" */
|
||||||
960, /* "aes-256-ocb" */
|
960, /* "aes-256-ocb" */
|
||||||
428, /* "aes-256-ofb" */
|
428, /* "aes-256-ofb" */
|
||||||
|
1200, /* "aes-256-siv" */
|
||||||
914, /* "aes-256-xts" */
|
914, /* "aes-256-xts" */
|
||||||
376, /* "algorithm" */
|
376, /* "algorithm" */
|
||||||
1066, /* "aria-128-cbc" */
|
1066, /* "aria-128-cbc" */
|
||||||
@@ -3855,7 +3864,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
|||||||
883, /* "certificateRevocationList" */
|
883, /* "certificateRevocationList" */
|
||||||
1019, /* "chacha20" */
|
1019, /* "chacha20" */
|
||||||
1018, /* "chacha20-poly1305" */
|
1018, /* "chacha20-poly1305" */
|
||||||
1198, /* "ChaCha20-Poly1305-D" */
|
1201, /* "ChaCha20-Poly1305-D" */
|
||||||
54, /* "challengePassword" */
|
54, /* "challengePassword" */
|
||||||
407, /* "characteristic-two-field" */
|
407, /* "characteristic-two-field" */
|
||||||
395, /* "clearance" */
|
395, /* "clearance" */
|
||||||
|
|||||||
@@ -1195,4 +1195,7 @@ hmacWithSHA512_256 1194
|
|||||||
gmac 1195
|
gmac 1195
|
||||||
kmac128 1196
|
kmac128 1196
|
||||||
kmac256 1197
|
kmac256 1197
|
||||||
chacha20_poly1305_draft 1198
|
aes_128_siv 1198
|
||||||
|
aes_192_siv 1199
|
||||||
|
aes_256_siv 1200
|
||||||
|
chacha20_poly1305_draft 1201
|
||||||
@@ -1646,7 +1646,6 @@ id-pkinit 5 : pkInitKDC : Signing KDC Response
|
|||||||
: Poly1305 : poly1305
|
: Poly1305 : poly1305
|
||||||
# NID for SipHash
|
# NID for SipHash
|
||||||
: SipHash : siphash
|
: SipHash : siphash
|
||||||
|
|
||||||
# NIDs for RFC7919 DH parameters
|
# NIDs for RFC7919 DH parameters
|
||||||
: ffdhe2048
|
: ffdhe2048
|
||||||
: ffdhe3072
|
: ffdhe3072
|
||||||
@@ -1683,3 +1682,7 @@ dstu4145le 2 6 : uacurve6 : DSTU curve 6
|
|||||||
dstu4145le 2 7 : uacurve7 : DSTU curve 7
|
dstu4145le 2 7 : uacurve7 : DSTU curve 7
|
||||||
dstu4145le 2 8 : uacurve8 : DSTU curve 8
|
dstu4145le 2 8 : uacurve8 : DSTU curve 8
|
||||||
dstu4145le 2 9 : uacurve9 : DSTU curve 9
|
dstu4145le 2 9 : uacurve9 : DSTU curve 9
|
||||||
|
# NID for AES-SIV
|
||||||
|
: AES-128-SIV : aes-128-siv
|
||||||
|
: AES-192-SIV : aes-192-siv
|
||||||
|
: AES-256-SIV : aes-256-siv
|
||||||
@@ -98,6 +98,7 @@ B<openssl> B<s_server>
|
|||||||
[B<-no_comp>]
|
[B<-no_comp>]
|
||||||
[B<-comp>]
|
[B<-comp>]
|
||||||
[B<-no_ticket>]
|
[B<-no_ticket>]
|
||||||
|
[B<-num_tickets>]
|
||||||
[B<-serverpref>]
|
[B<-serverpref>]
|
||||||
[B<-legacy_renegotiation>]
|
[B<-legacy_renegotiation>]
|
||||||
[B<-no_renegotiation>]
|
[B<-no_renegotiation>]
|
||||||
@@ -558,7 +559,14 @@ OpenSSL 1.1.0.
|
|||||||
|
|
||||||
=item B<-no_ticket>
|
=item B<-no_ticket>
|
||||||
|
|
||||||
Disable RFC4507bis session ticket support.
|
Disable RFC4507bis session ticket support. This option has no effect if TLSv1.3
|
||||||
|
is negotiated. See B<-num_tickets>.
|
||||||
|
|
||||||
|
=item B<-num_tickets>
|
||||||
|
|
||||||
|
Control the number of tickets that will be sent to the client after a full
|
||||||
|
handshake in TLSv1.3. The default number of tickets is 2. This option does not
|
||||||
|
affect the number of tickets sent after a resumption handshake.
|
||||||
|
|
||||||
=item B<-serverpref>
|
=item B<-serverpref>
|
||||||
|
|
||||||
|
|||||||
+13
-1
@@ -5,7 +5,7 @@
|
|||||||
BIO_ctrl, BIO_callback_ctrl, BIO_ptr_ctrl, BIO_int_ctrl, BIO_reset,
|
BIO_ctrl, BIO_callback_ctrl, BIO_ptr_ctrl, BIO_int_ctrl, BIO_reset,
|
||||||
BIO_seek, BIO_tell, BIO_flush, BIO_eof, BIO_set_close, BIO_get_close,
|
BIO_seek, BIO_tell, BIO_flush, BIO_eof, BIO_set_close, BIO_get_close,
|
||||||
BIO_pending, BIO_wpending, BIO_ctrl_pending, BIO_ctrl_wpending,
|
BIO_pending, BIO_wpending, BIO_ctrl_pending, BIO_ctrl_wpending,
|
||||||
BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb
|
BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb, BIO_get_ktls_send
|
||||||
- BIO control operations
|
- BIO control operations
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
@@ -34,6 +34,8 @@ BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb
|
|||||||
int BIO_get_info_callback(BIO *b, BIO_info_cb **cbp);
|
int BIO_get_info_callback(BIO *b, BIO_info_cb **cbp);
|
||||||
int BIO_set_info_callback(BIO *b, BIO_info_cb *cb);
|
int BIO_set_info_callback(BIO *b, BIO_info_cb *cb);
|
||||||
|
|
||||||
|
int BIO_get_ktls_send(BIO *b);
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
BIO_ctrl(), BIO_callback_ctrl(), BIO_ptr_ctrl() and BIO_int_ctrl()
|
BIO_ctrl(), BIO_callback_ctrl(), BIO_ptr_ctrl() and BIO_int_ctrl()
|
||||||
@@ -72,6 +74,9 @@ Not all BIOs support these calls. BIO_ctrl_pending() and BIO_ctrl_wpending()
|
|||||||
return a size_t type and are functions, BIO_pending() and BIO_wpending() are
|
return a size_t type and are functions, BIO_pending() and BIO_wpending() are
|
||||||
macros which call BIO_ctrl().
|
macros which call BIO_ctrl().
|
||||||
|
|
||||||
|
BIO_get_ktls_send() return 1 if the BIO is using the Kernel TLS data-path for
|
||||||
|
sending. Otherwise, it returns zero.
|
||||||
|
|
||||||
=head1 RETURN VALUES
|
=head1 RETURN VALUES
|
||||||
|
|
||||||
BIO_reset() normally returns 1 for success and 0 or -1 for failure. File
|
BIO_reset() normally returns 1 for success and 0 or -1 for failure. File
|
||||||
@@ -92,6 +97,9 @@ BIO_get_close() returns the close flag value: BIO_CLOSE or BIO_NOCLOSE.
|
|||||||
BIO_pending(), BIO_ctrl_pending(), BIO_wpending() and BIO_ctrl_wpending()
|
BIO_pending(), BIO_ctrl_pending(), BIO_wpending() and BIO_ctrl_wpending()
|
||||||
return the amount of pending data.
|
return the amount of pending data.
|
||||||
|
|
||||||
|
BIO_get_ktls_send() return 1 if the BIO is using the Kernel TLS data-path for
|
||||||
|
sending. Otherwise, it returns zero.
|
||||||
|
|
||||||
=head1 NOTES
|
=head1 NOTES
|
||||||
|
|
||||||
BIO_flush(), because it can write data may return 0 or -1 indicating
|
BIO_flush(), because it can write data may return 0 or -1 indicating
|
||||||
@@ -124,6 +132,10 @@ particular a return value of 0 can be returned if an operation is not
|
|||||||
supported, if an error occurred, if EOF has not been reached and in
|
supported, if an error occurred, if EOF has not been reached and in
|
||||||
the case of BIO_seek() on a file BIO for a successful operation.
|
the case of BIO_seek() on a file BIO for a successful operation.
|
||||||
|
|
||||||
|
=head1 HISTORY
|
||||||
|
|
||||||
|
The BIO_get_ktls_send() function was added in OpenSSL 3.0.0.
|
||||||
|
|
||||||
=head1 COPYRIGHT
|
=head1 COPYRIGHT
|
||||||
|
|
||||||
Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
|
Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ The available flags are:
|
|||||||
=item EVP_CIPH_STREAM_CIPHER, EVP_CIPH_ECB_MODE EVP_CIPH_CBC_MODE,
|
=item EVP_CIPH_STREAM_CIPHER, EVP_CIPH_ECB_MODE EVP_CIPH_CBC_MODE,
|
||||||
EVP_CIPH_CFB_MODE, EVP_CIPH_OFB_MODE, EVP_CIPH_CTR_MODE, EVP_CIPH_GCM_MODE,
|
EVP_CIPH_CFB_MODE, EVP_CIPH_OFB_MODE, EVP_CIPH_CTR_MODE, EVP_CIPH_GCM_MODE,
|
||||||
EVP_CIPH_CCM_MODE, EVP_CIPH_XTS_MODE, EVP_CIPH_WRAP_MODE,
|
EVP_CIPH_CCM_MODE, EVP_CIPH_XTS_MODE, EVP_CIPH_WRAP_MODE,
|
||||||
EVP_CIPH_OCB_MODE
|
EVP_CIPH_OCB_MODE, EVP_CIPH_SIV_MODE
|
||||||
|
|
||||||
The cipher mode.
|
The cipher mode.
|
||||||
|
|
||||||
|
|||||||
@@ -426,6 +426,49 @@ AES.
|
|||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
|
=head2 SIV Mode
|
||||||
|
|
||||||
|
For SIV mode ciphers the behaviour of the EVP interface is subtly
|
||||||
|
altered and several additional ctrl operations are supported.
|
||||||
|
|
||||||
|
To specify any additional authenticated data (AAD) and/or a Nonce, a call to
|
||||||
|
EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should be made
|
||||||
|
with the output parameter B<out> set to B<NULL>.
|
||||||
|
|
||||||
|
RFC5297 states that the Nonce is the last piece of AAD before the actual
|
||||||
|
encrypt/decrypt takes place. The API does not differentiate the Nonce from
|
||||||
|
other AAD.
|
||||||
|
|
||||||
|
When decrypting the return value of EVP_DecryptFinal() or EVP_CipherFinal()
|
||||||
|
indicates if the operation was successful. If it does not indicate success
|
||||||
|
the authentication operation has failed and any output data B<MUST NOT>
|
||||||
|
be used as it is corrupted.
|
||||||
|
|
||||||
|
The following ctrls are supported in both SIV modes.
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen, tag);
|
||||||
|
|
||||||
|
Writes B<taglen> bytes of the tag value to the buffer indicated by B<tag>.
|
||||||
|
This call can only be made when encrypting data and B<after> all data has been
|
||||||
|
processed (e.g. after an EVP_EncryptFinal() call). For SIV mode the taglen must
|
||||||
|
be 16.
|
||||||
|
|
||||||
|
=item EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, taglen, tag);
|
||||||
|
|
||||||
|
Sets the expected tag to B<taglen> bytes from B<tag>. This call is only legal
|
||||||
|
when decrypting data and must be made B<before> any data is processed (e.g.
|
||||||
|
before any EVP_DecryptUpdate() call). For SIV mode the taglen must be 16.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
SIV mode makes two passes over the input data, thus, only one call to
|
||||||
|
EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should be made
|
||||||
|
with B<out> set to a non-B<NULL> value. A call to EVP_Decrypt_Final() or
|
||||||
|
EVP_CipherFinal() is not required, but will indicate if the update
|
||||||
|
operation succeeded.
|
||||||
|
|
||||||
=head2 ChaCha20-Poly1305
|
=head2 ChaCha20-Poly1305
|
||||||
|
|
||||||
The following I<ctrl>s are supported for the ChaCha20-Poly1305 AEAD algorithm.
|
The following I<ctrl>s are supported for the ChaCha20-Poly1305 AEAD algorithm.
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ with the exception of the L</BACKWARD COMPATIBILITY> ones.
|
|||||||
|
|
||||||
Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
|
|
||||||
Licensed under the OpenSSL license (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
|
||||||
in the file LICENSE in the source distribution or at
|
in the file LICENSE in the source distribution or at
|
||||||
L<https://www.openssl.org/source/license.html>.
|
L<https://www.openssl.org/source/license.html>.
|
||||||
|
|||||||
@@ -105,6 +105,22 @@ Enable asynchronous processing. TLS I/O operations may indicate a retry with
|
|||||||
SSL_ERROR_WANT_ASYNC with this mode set if an asynchronous capable engine is
|
SSL_ERROR_WANT_ASYNC with this mode set if an asynchronous capable engine is
|
||||||
used to perform cryptographic operations. See L<SSL_get_error(3)>.
|
used to perform cryptographic operations. See L<SSL_get_error(3)>.
|
||||||
|
|
||||||
|
=item SSL_MODE_NO_KTLS_TX
|
||||||
|
|
||||||
|
Disable the use of the kernel TLS egress data-path.
|
||||||
|
By default kernel TLS is enabled if it is supported by the negotiated ciphersuites
|
||||||
|
and extensions and OpenSSL has been compiled with support for it.
|
||||||
|
The kernel TLS data-path implements the record layer,
|
||||||
|
and the crypto algorithm. The kernel will utilize the best hardware
|
||||||
|
available for crypto. Using the kernel data-path should reduce the memory
|
||||||
|
footprint of OpenSSL because no buffering is required. Also, the throughput
|
||||||
|
should improve because data copy is avoided when user data is encrypted into
|
||||||
|
kernel memory instead of the usual encrypt than copy to kernel.
|
||||||
|
|
||||||
|
Kernel TLS might not support all the features of OpenSSL. For instance,
|
||||||
|
renegotiation, and setting the maximum fragment size is not possible as of
|
||||||
|
Linux 4.20.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
All modes are off by default except for SSL_MODE_AUTO_RETRY which is on by
|
All modes are off by default except for SSL_MODE_AUTO_RETRY which is on by
|
||||||
@@ -125,6 +141,7 @@ L<SSL_write(3)>, L<SSL_get_error(3)>
|
|||||||
=head1 HISTORY
|
=head1 HISTORY
|
||||||
|
|
||||||
SSL_MODE_ASYNC was first added to OpenSSL 1.1.0.
|
SSL_MODE_ASYNC was first added to OpenSSL 1.1.0.
|
||||||
|
SSL_MODE_NO_KTLS_TX was first added to OpenSSL 3.0.0.
|
||||||
|
|
||||||
=head1 COPYRIGHT
|
=head1 COPYRIGHT
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ SSL_CTX_get_num_tickets
|
|||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
SSL_CTX_set_num_tickets() and SSL_set_num_tickets() can be called for a server
|
SSL_CTX_set_num_tickets() and SSL_set_num_tickets() can be called for a server
|
||||||
application and set the number of session tickets that will be sent to the
|
application and set the number of TLSv1.3 session tickets that will be sent to
|
||||||
client after a full handshake. Set the desired value (which could be 0) in the
|
the client after a full handshake. Set the desired value (which could be 0) in
|
||||||
B<num_tickets> argument. Typically these functions should be called before the
|
the B<num_tickets> argument. Typically these functions should be called before
|
||||||
start of the handshake.
|
the start of the handshake.
|
||||||
|
|
||||||
The default number of tickets is 2; the default number of tickets sent following
|
The default number of tickets is 2; the default number of tickets sent following
|
||||||
a resumption handshake is 1 but this cannot be changed using these functions.
|
a resumption handshake is 1 but this cannot be changed using these functions.
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ ticket information or it starts a full TLS handshake to create a new session
|
|||||||
ticket.
|
ticket.
|
||||||
|
|
||||||
Before the callback function is started I<ctx> and I<hctx> have been
|
Before the callback function is started I<ctx> and I<hctx> have been
|
||||||
initialised with EVP_CIPHER_CTX_init and HMAC_CTX_init respectively.
|
initialised with L<EVP_CIPHER_CTX_reset(3)> and L<HMAC_CTX_reset(3)> respectively.
|
||||||
|
|
||||||
For new sessions tickets, when the client doesn't present a session ticket, or
|
For new sessions tickets, when the client doesn't present a session ticket, or
|
||||||
an attempted retrieval of the ticket failed, or a renew option was indicated,
|
an attempted retrieval of the ticket failed, or a renew option was indicated,
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
|
|
||||||
# define get_last_sys_error() errno
|
# define get_last_sys_error() errno
|
||||||
# define clear_sys_error() errno=0
|
# define clear_sys_error() errno=0
|
||||||
|
# define set_sys_error(e) errno=(e)
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
The Microsoft section
|
The Microsoft section
|
||||||
@@ -66,8 +67,10 @@
|
|||||||
# ifdef WIN32
|
# ifdef WIN32
|
||||||
# undef get_last_sys_error
|
# undef get_last_sys_error
|
||||||
# undef clear_sys_error
|
# undef clear_sys_error
|
||||||
|
# undef set_sys_error
|
||||||
# define get_last_sys_error() GetLastError()
|
# define get_last_sys_error() GetLastError()
|
||||||
# define clear_sys_error() SetLastError(0)
|
# define clear_sys_error() SetLastError(0)
|
||||||
|
# define set_sys_error(e) SetLastError(e)
|
||||||
# if !defined(WINNT)
|
# if !defined(WINNT)
|
||||||
# define WIN_CONSOLE_BUG
|
# define WIN_CONSOLE_BUG
|
||||||
# endif
|
# endif
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
+37
-1
@@ -1,12 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef HEADER_INTERNAL_BIO_H
|
||||||
|
# define HEADER_INTERNAL_BIO_H
|
||||||
|
|
||||||
#include <openssl/bio.h>
|
#include <openssl/bio.h>
|
||||||
|
|
||||||
struct bio_method_st {
|
struct bio_method_st {
|
||||||
@@ -31,3 +34,36 @@ void bio_cleanup(void);
|
|||||||
/* Old style to new style BIO_METHOD conversion functions */
|
/* Old style to new style BIO_METHOD conversion functions */
|
||||||
int bwrite_conv(BIO *bio, const char *data, size_t datal, size_t *written);
|
int bwrite_conv(BIO *bio, const char *data, size_t datal, size_t *written);
|
||||||
int bread_conv(BIO *bio, char *data, size_t datal, size_t *read);
|
int bread_conv(BIO *bio, char *data, size_t datal, size_t *read);
|
||||||
|
|
||||||
|
# define BIO_CTRL_SET_KTLS_SEND 72
|
||||||
|
# define BIO_CTRL_SET_KTLS_SEND_CTRL_MSG 74
|
||||||
|
# define BIO_CTRL_CLEAR_KTLS_CTRL_MSG 75
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is used with socket BIOs:
|
||||||
|
* BIO_FLAGS_KTLS means we are using ktls with this BIO.
|
||||||
|
* BIO_FLAGS_KTLS_CTRL_MSG means we are about to send a ctrl message next.
|
||||||
|
*/
|
||||||
|
# define BIO_FLAGS_KTLS 0x800
|
||||||
|
# define BIO_FLAGS_KTLS_CTRL_MSG 0x1000
|
||||||
|
|
||||||
|
/* KTLS related controls and flags */
|
||||||
|
# define BIO_set_ktls_flag(b) \
|
||||||
|
BIO_set_flags(b, BIO_FLAGS_KTLS)
|
||||||
|
# define BIO_should_ktls_flag(b) \
|
||||||
|
BIO_test_flags(b, BIO_FLAGS_KTLS)
|
||||||
|
# define BIO_set_ktls_ctrl_msg_flag(b) \
|
||||||
|
BIO_set_flags(b, BIO_FLAGS_KTLS_CTRL_MSG)
|
||||||
|
# define BIO_should_ktls_ctrl_msg_flag(b) \
|
||||||
|
BIO_test_flags(b, (BIO_FLAGS_KTLS_CTRL_MSG))
|
||||||
|
# define BIO_clear_ktls_ctrl_msg_flag(b) \
|
||||||
|
BIO_clear_flags(b, (BIO_FLAGS_KTLS_CTRL_MSG))
|
||||||
|
|
||||||
|
# define BIO_set_ktls(b, keyblob, is_tx) \
|
||||||
|
BIO_ctrl(b, BIO_CTRL_SET_KTLS_SEND, is_tx, keyblob)
|
||||||
|
# define BIO_set_ktls_ctrl_msg(b, record_type) \
|
||||||
|
BIO_ctrl(b, BIO_CTRL_SET_KTLS_SEND_CTRL_MSG, record_type, NULL)
|
||||||
|
# define BIO_clear_ktls_ctrl_msg(b) \
|
||||||
|
BIO_ctrl(b, BIO_CTRL_CLEAR_KTLS_CTRL_MSG, 0, NULL)
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
* Licensed under the 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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* 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-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_KTLS
|
||||||
|
# ifndef HEADER_INTERNAL_KTLS
|
||||||
|
# define HEADER_INTERNAL_KTLS
|
||||||
|
|
||||||
|
# if defined(OPENSSL_SYS_LINUX)
|
||||||
|
# include <linux/version.h>
|
||||||
|
|
||||||
|
# define K_MAJ 4
|
||||||
|
# define K_MIN1 13
|
||||||
|
# define K_MIN2 0
|
||||||
|
# if LINUX_VERSION_CODE < KERNEL_VERSION(K_MAJ, K_MIN1, K_MIN2)
|
||||||
|
|
||||||
|
# ifndef PEDANTIC
|
||||||
|
# warning "KTLS requires Kernel Headers >= 4.13.0"
|
||||||
|
# warning "Skipping Compilation of KTLS data path"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define TLS_TX 1
|
||||||
|
|
||||||
|
# define TLS_CIPHER_AES_GCM_128 51
|
||||||
|
# define TLS_CIPHER_AES_GCM_128_IV_SIZE 8
|
||||||
|
# define TLS_CIPHER_AES_GCM_128_KEY_SIZE 16
|
||||||
|
# define TLS_CIPHER_AES_GCM_128_SALT_SIZE 4
|
||||||
|
# define TLS_CIPHER_AES_GCM_128_TAG_SIZE 16
|
||||||
|
# define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE 8
|
||||||
|
|
||||||
|
# define TLS_SET_RECORD_TYPE 1
|
||||||
|
|
||||||
|
struct tls_crypto_info {
|
||||||
|
unsigned short version;
|
||||||
|
unsigned short cipher_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tls12_crypto_info_aes_gcm_128 {
|
||||||
|
struct tls_crypto_info info;
|
||||||
|
unsigned char iv[TLS_CIPHER_AES_GCM_128_IV_SIZE];
|
||||||
|
unsigned char key[TLS_CIPHER_AES_GCM_128_KEY_SIZE];
|
||||||
|
unsigned char salt[TLS_CIPHER_AES_GCM_128_SALT_SIZE];
|
||||||
|
unsigned char rec_seq[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Dummy functions here */
|
||||||
|
static ossl_inline int ktls_enable(int fd)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ossl_inline int ktls_start(int fd,
|
||||||
|
struct tls12_crypto_info_aes_gcm_128
|
||||||
|
*crypto_info, size_t len, int is_tx)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type,
|
||||||
|
const void *data, size_t length)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# else /* KERNEL_VERSION */
|
||||||
|
|
||||||
|
# include <netinet/tcp.h>
|
||||||
|
# include <linux/tls.h>
|
||||||
|
# include <linux/socket.h>
|
||||||
|
|
||||||
|
# ifndef SOL_TLS
|
||||||
|
# define SOL_TLS 282
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef TCP_ULP
|
||||||
|
# define TCP_ULP 31
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When successful, this socket option doesn't change the behaviour of the
|
||||||
|
* TCP socket, except changing the TCP setsockopt handler to enable the
|
||||||
|
* processing of SOL_TLS socket options. All other functionality remains the
|
||||||
|
* same.
|
||||||
|
*/
|
||||||
|
static ossl_inline int ktls_enable(int fd)
|
||||||
|
{
|
||||||
|
return setsockopt(fd, SOL_TCP, TCP_ULP, "tls", sizeof("tls")) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The TLS_TX socket option changes the send/sendmsg handlers of the TCP socket.
|
||||||
|
* If successful, then data sent using this socket will be encrypted and
|
||||||
|
* encapsulated in TLS records using the crypto_info provided here.
|
||||||
|
*/
|
||||||
|
static ossl_inline int ktls_start(int fd,
|
||||||
|
struct tls12_crypto_info_aes_gcm_128
|
||||||
|
*crypto_info, size_t len, int is_tx)
|
||||||
|
{
|
||||||
|
if (is_tx)
|
||||||
|
return setsockopt(fd, SOL_TLS, TLS_TX, crypto_info,
|
||||||
|
sizeof(*crypto_info)) ? 0 : 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send a TLS record using the crypto_info provided in ktls_start and use
|
||||||
|
* record_type instead of the default SSL3_RT_APPLICATION_DATA.
|
||||||
|
* When the socket is non-blocking, then this call either returns EAGAIN or
|
||||||
|
* the entire record is pushed to TCP. It is impossible to send a partial
|
||||||
|
* record using this control message.
|
||||||
|
*/
|
||||||
|
static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type,
|
||||||
|
const void *data, size_t length)
|
||||||
|
{
|
||||||
|
struct msghdr msg = { 0 };
|
||||||
|
int cmsg_len = sizeof(record_type);
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
char buf[CMSG_SPACE(cmsg_len)];
|
||||||
|
struct iovec msg_iov; /* Vector of data to send/receive into */
|
||||||
|
|
||||||
|
msg.msg_control = buf;
|
||||||
|
msg.msg_controllen = sizeof(buf);
|
||||||
|
cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
|
cmsg->cmsg_level = SOL_TLS;
|
||||||
|
cmsg->cmsg_type = TLS_SET_RECORD_TYPE;
|
||||||
|
cmsg->cmsg_len = CMSG_LEN(cmsg_len);
|
||||||
|
*((unsigned char *)CMSG_DATA(cmsg)) = record_type;
|
||||||
|
msg.msg_controllen = cmsg->cmsg_len;
|
||||||
|
|
||||||
|
msg_iov.iov_base = (void *)data;
|
||||||
|
msg_iov.iov_len = length;
|
||||||
|
msg.msg_iov = &msg_iov;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
|
||||||
|
return sendmsg(fd, &msg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
# endif /* KERNEL_VERSION */
|
||||||
|
# endif /* OPENSSL_SYS_LINUX */
|
||||||
|
# endif /* HEADER_INTERNAL_KTLS */
|
||||||
|
#endif /* OPENSSL_NO_KTLS */
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2003-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
* Licensed under the 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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* 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-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
* Licensed under the 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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* 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-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
|
|||||||
+11
-1
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
* Licensed under the 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
|
||||||
* in the file LICENSE in the source distribution or at
|
* in the file LICENSE in the source distribution or at
|
||||||
* https://www.openssl.org/source/license.html
|
* https://www.openssl.org/source/license.html
|
||||||
@@ -145,6 +145,16 @@ extern "C" {
|
|||||||
|
|
||||||
# define BIO_CTRL_DGRAM_SET_PEEK_MODE 71
|
# define BIO_CTRL_DGRAM_SET_PEEK_MODE 71
|
||||||
|
|
||||||
|
/* internal BIO see include/internal/bio.h:
|
||||||
|
* # define BIO_CTRL_SET_KTLS_SEND 72
|
||||||
|
* # define BIO_CTRL_SET_KTLS_SEND_CTRL_MSG 74
|
||||||
|
* # define BIO_CTRL_CLEAR_KTLS_CTRL_MSG 75
|
||||||
|
*/
|
||||||
|
|
||||||
|
# define BIO_CTRL_GET_KTLS_SEND 73
|
||||||
|
# define BIO_get_ktls_send(b) \
|
||||||
|
BIO_ctrl(b, BIO_CTRL_GET_KTLS_SEND, 0, NULL)
|
||||||
|
|
||||||
/* modifiers */
|
/* modifiers */
|
||||||
# define BIO_FP_READ 0x02
|
# define BIO_FP_READ 0x02
|
||||||
# define BIO_FP_WRITE 0x04
|
# define BIO_FP_WRITE 0x04
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user