Latest update
This commit is contained in:
@@ -9,6 +9,9 @@
|
||||
|
||||
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.
|
||||
[Richard Levitte]
|
||||
|
||||
@@ -33,6 +36,9 @@
|
||||
and retain API/ABI compatibility.
|
||||
[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
|
||||
'dist' target has fallen out of use, and it shouldn't be
|
||||
necessary to configure just to create a source distribution.
|
||||
@@ -84,6 +90,11 @@
|
||||
list of built in objects, i.e. OIDs with names.
|
||||
[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]
|
||||
|
||||
*) 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)
|
||||
[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.
|
||||
[Steve Henson]
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
our $osslprefix = 'OSSL$';
|
||||
(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 $sourcedir = $config{sourcedir};
|
||||
@@ -104,7 +104,7 @@ BLDDIR={- $config{builddir} -}
|
||||
# to testing.
|
||||
VERBOSE=$(V)
|
||||
|
||||
VERSION={- "$config{major}.$config{minor}.$config{patch}$config{prerelease}$config{build_metadata}" -}
|
||||
VERSION={- "$config{full_version}" -}
|
||||
MAJOR={- $config{major} -}
|
||||
MINOR={- $config{minor} -}
|
||||
SHLIB_VERSION_NUMBER={- $config{shlib_version} -}
|
||||
@@ -639,7 +639,7 @@ vmsconfig.pm : configdata.pm
|
||||
WRITE CONFIG "our %config = ("
|
||||
WRITE CONFIG " target => '","{- $config{target} -}","',"
|
||||
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_minor => '","{- $config{shlib_minor} -}","',"
|
||||
WRITE CONFIG " no_shared => '","{- $disabled{shared} -}","',"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
# libcrypto.a and use libcrypto_a.a as static one.
|
||||
sub sharedaix { !$disabled{shared} && $config{target} =~ /^aix/ }
|
||||
|
||||
our $sover_dirname = $config{shlib_version_number};
|
||||
our $sover_dirname = $config{shlib_version};
|
||||
$sover_dirname =~ s|\.|_|g
|
||||
if $config{target} =~ /^mingw/;
|
||||
|
||||
@@ -88,7 +88,7 @@ CONFIGURE_ARGS=({- join(", ",quotify_l(@{$config{perlargv}})) -})
|
||||
SRCDIR={- $config{sourcedir} -}
|
||||
BLDDIR={- $config{builddir} -}
|
||||
|
||||
VERSION={- "$config{major}.$config{minor}.$config{patch}$config{prerelease}$config{build_metadata}" -}
|
||||
VERSION={- "$config{full_version}" -}
|
||||
MAJOR={- $config{major} -}
|
||||
MINOR={- $config{minor} -}
|
||||
SHLIB_VERSION_NUMBER={- $config{shlib_version} -}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
our $shlibextimport = $target{shared_import_extension} || ".lib";
|
||||
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 $install_flavour = $build_scheme->[$#$build_scheme]; # last element
|
||||
@@ -71,7 +71,7 @@ PLATFORM={- $config{target} -}
|
||||
SRCDIR={- $config{sourcedir} -}
|
||||
BLDDIR={- $config{builddir} -}
|
||||
|
||||
VERSION={- "$config{major}.$config{minor}.$config{patch}$config{prerelease}$config{build_metadata}" -}
|
||||
VERSION={- "$config{full_version}" -}
|
||||
MAJOR={- $config{major} -}
|
||||
MINOR={- $config{minor} -}
|
||||
|
||||
|
||||
@@ -276,6 +276,9 @@ die "erroneous version information in opensslv.h: ",
|
||||
|| $config{patch} 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
|
||||
|
||||
my $pattern = catfile(dirname($0), "Configurations", "*.conf");
|
||||
@@ -318,6 +321,7 @@ my @dtls = qw(dtls1 dtls1_2);
|
||||
# For developers: keep it sorted alphabetically
|
||||
|
||||
my @disablables = (
|
||||
"ktls",
|
||||
"afalgeng",
|
||||
"aria",
|
||||
"asan",
|
||||
@@ -387,6 +391,7 @@ my @disablables = (
|
||||
"seed",
|
||||
"shared",
|
||||
"siphash",
|
||||
"siv",
|
||||
"sm2",
|
||||
"sm3",
|
||||
"sm4",
|
||||
@@ -448,6 +453,7 @@ our %disabled = ( # "what" => "comment"
|
||||
"weak-ssl-ciphers" => "default",
|
||||
"zlib" => "default",
|
||||
"zlib-dynamic" => "default",
|
||||
"ktls" => "default",
|
||||
);
|
||||
|
||||
# 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{"msan"} } => [ "asm" ],
|
||||
|
||||
sub { $disabled{cmac}; } => [ "siv" ],
|
||||
);
|
||||
|
||||
# Avoid protocol support holes. Also disable all versions below N, if version
|
||||
@@ -997,8 +1005,8 @@ if ($target eq "HASH") {
|
||||
exit 0;
|
||||
}
|
||||
|
||||
print "Configuring OpenSSL version $config{version} ($config{version_num}) ";
|
||||
print "for $target\n";
|
||||
print "Configuring OpenSSL version $config{full_version} ";
|
||||
print "for target $target\n";
|
||||
|
||||
if (scalar(@seed_sources) == 0) {
|
||||
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});
|
||||
|
||||
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
|
||||
# apart from "make variables"
|
||||
foreach (keys %useradd) {
|
||||
|
||||
@@ -250,6 +250,15 @@
|
||||
Don't build the AFALG engine. This option will be forced if
|
||||
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
|
||||
Build with the Address sanitiser. This is a developer option
|
||||
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
|
||||
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
|
||||
Don't build support for loading Dynamic Shared Objects.
|
||||
|
||||
@@ -542,9 +556,9 @@
|
||||
Build without support for the specified algorithm, where
|
||||
<alg> is one of: aria, bf, blake2, camellia, cast, chacha,
|
||||
cmac, des, dh, dsa, ecdh, ecdsa, idea, md4, mdc2, ocb,
|
||||
poly1305, rc2, rc4, rmd160, scrypt, seed, siphash, sm2, sm3,
|
||||
sm4 or whirlpool. The "ripemd" algorithm is deprecated and
|
||||
if used is synonymous with rmd160.
|
||||
poly1305, rc2, rc4, rmd160, scrypt, seed, siphash, siv, sm2,
|
||||
sm3, sm4 or whirlpool. The "ripemd" algorithm is deprecated
|
||||
and if used is synonymous with rmd160.
|
||||
|
||||
-Dxxx, -Ixxx, -Wp, -lxxx, -Lxxx, -Wl, -rpath, -R, -framework, -static
|
||||
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",
|
||||
expansion ? SSL_COMP_get_name(expansion) : "NONE");
|
||||
#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
|
||||
{
|
||||
|
||||
@@ -2911,6 +2911,10 @@ static void print_connection_info(SSL *con)
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -2657,6 +2657,10 @@ int speed_main(int argc, char **argv)
|
||||
EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
|
||||
loopargs[k].key, NULL, -1);
|
||||
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);
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ sub create_curl {
|
||||
$curl->setopt(CURLOPT_VERBOSE, 1) if $options{d};
|
||||
$curl->setopt(CURLOPT_FAILONERROR, 1);
|
||||
$curl->setopt(CURLOPT_USERAGENT,
|
||||
"OpenTSA tsget.pl/openssl-{- $config{version} -}");
|
||||
"OpenTSA tsget.pl/openssl-{- $config{full_version} -}");
|
||||
|
||||
# Options for POST method.
|
||||
$curl->setopt(CURLOPT_UPLOAD, 1);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
/* This is the primary function used to parse ASN1_UTCTIME */
|
||||
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)
|
||||
return 0;
|
||||
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, };
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
|
||||
if (app_methods == NULL)
|
||||
@@ -216,18 +232,6 @@ EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
|
||||
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) {
|
||||
ameth->pem_str = OPENSSL_strdup(pem_str);
|
||||
if (!ameth->pem_str)
|
||||
|
||||
+45
-1
@@ -11,6 +11,7 @@
|
||||
#include <errno.h>
|
||||
#include "bio_lcl.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/ktls.h"
|
||||
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
|
||||
@@ -64,6 +65,17 @@ BIO *BIO_new_socket(int fd, int close_flag)
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -108,9 +120,19 @@ static int sock_read(BIO *b, char *out, int outl)
|
||||
|
||||
static int sock_write(BIO *b, const char *in, int inl)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
clear_socket_error();
|
||||
# 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);
|
||||
if (ret <= 0) {
|
||||
@@ -124,6 +146,9 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
{
|
||||
long ret = 1;
|
||||
int *ip;
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
struct tls12_crypto_info_aes_gcm_128 *crypto_info;
|
||||
# endif
|
||||
|
||||
switch (cmd) {
|
||||
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:
|
||||
ret = 1;
|
||||
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:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#endif
|
||||
|
||||
#include "dso_locl.h"
|
||||
#include "e_os.h"
|
||||
|
||||
#ifdef DSO_DLFCN
|
||||
|
||||
@@ -99,6 +100,7 @@ static int dlfcn_load(DSO *dso)
|
||||
/* See applicable comments in dso_dl.c */
|
||||
char *filename = DSO_convert_filename(dso, NULL);
|
||||
int flags = DLOPEN_FLAG;
|
||||
int saveerrno = get_last_sys_error();
|
||||
|
||||
if (filename == NULL) {
|
||||
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());
|
||||
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)) {
|
||||
DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR);
|
||||
goto err;
|
||||
|
||||
+287
-181
@@ -744,43 +744,50 @@ static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32],
|
||||
|
||||
/*
|
||||
* Reference base 2^25.5 implementation.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* This code is mostly taken from the ref10 version of Ed25519 in SUPERCOP
|
||||
* 20141124 (http://bench.cr.yp.to/supercop.html).
|
||||
*
|
||||
* 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
|
||||
* 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];
|
||||
|
||||
static const int64_t kBottom21Bits = 0x1fffffLL;
|
||||
static const int64_t kBottom25Bits = 0x1ffffffLL;
|
||||
static const int64_t kBottom26Bits = 0x3ffffffLL;
|
||||
static const int64_t kTop39Bits = 0xfffffffffe000000LL;
|
||||
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];
|
||||
|
||||
result = ((uint64_t)in[0]);
|
||||
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];
|
||||
|
||||
result = ((uint64_t)in[0]);
|
||||
result |= ((uint64_t)in[1]) << 8;
|
||||
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);
|
||||
int64_t h1 = load_3(s + 4) << 6;
|
||||
@@ -791,7 +798,7 @@ static void fe_frombytes(fe h, const uint8_t *s) {
|
||||
int64_t h6 = load_3(s + 20) << 7;
|
||||
int64_t h7 = load_3(s + 23) << 5;
|
||||
int64_t h8 = load_3(s + 26) << 4;
|
||||
int64_t h9 = (load_3(s + 29) & 8388607) << 2;
|
||||
int64_t h9 = (load_3(s + 29) & 0x7fffff) << 2;
|
||||
int64_t carry0;
|
||||
int64_t carry1;
|
||||
int64_t carry2;
|
||||
@@ -827,7 +834,8 @@ static void fe_frombytes(fe h, const uint8_t *s) {
|
||||
h[9] = (int32_t)h9;
|
||||
}
|
||||
|
||||
/* Preconditions:
|
||||
/*
|
||||
* 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).
|
||||
@@ -848,8 +856,10 @@ 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.
|
||||
*
|
||||
* 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. */
|
||||
static void fe_tobytes(uint8_t *s, const fe h) {
|
||||
* 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];
|
||||
int32_t h1 = h[1];
|
||||
int32_t h2 = h[2];
|
||||
@@ -890,11 +900,12 @@ static void fe_tobytes(uint8_t *s, const fe h) {
|
||||
h9 &= kBottom25Bits;
|
||||
/* h10 = carry9 */
|
||||
|
||||
/* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
|
||||
/*
|
||||
* 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;
|
||||
* evidently 2^255 h10-2^255 q = 0.
|
||||
* Goal: Output h0+...+2^230 h9. */
|
||||
|
||||
* Goal: Output h0+...+2^230 h9.
|
||||
*/
|
||||
s[ 0] = (uint8_t) (h0 >> 0);
|
||||
s[ 1] = (uint8_t) (h0 >> 8);
|
||||
s[ 2] = (uint8_t) (h0 >> 16);
|
||||
@@ -930,20 +941,27 @@ static void fe_tobytes(uint8_t *s, const fe h) {
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
static void fe_1(fe h) {
|
||||
static void fe_1(fe h)
|
||||
{
|
||||
memset(h, 0, sizeof(int32_t) * 10);
|
||||
h[0] = 1;
|
||||
}
|
||||
|
||||
/* h = f + g
|
||||
/*
|
||||
* h = f + g
|
||||
*
|
||||
* Can overlap h with f or g.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Postconditions:
|
||||
* |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) {
|
||||
* |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;
|
||||
|
||||
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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Postconditions:
|
||||
* |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) {
|
||||
* |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;
|
||||
|
||||
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.
|
||||
*
|
||||
* Preconditions:
|
||||
@@ -1001,8 +1029,10 @@ static void fe_sub(fe h, const fe f, const fe g) {
|
||||
* 10 of them are 2-way parallelizable and vectorizable.
|
||||
* Can get away with 11 carries, but then data flow is much deeper.
|
||||
*
|
||||
* With tighter constraints on inputs can squeeze carries into int32. */
|
||||
static void fe_mul(fe h, const fe f, const fe g) {
|
||||
* 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];
|
||||
int32_t f1 = f[1];
|
||||
int32_t f2 = f[2];
|
||||
@@ -1218,7 +1248,9 @@ static void fe_mul(fe h, const fe f, const fe g) {
|
||||
h[9] = (int32_t)h9;
|
||||
}
|
||||
|
||||
/* h = f * f
|
||||
/*
|
||||
* h = f * f
|
||||
*
|
||||
* Can overlap h with f.
|
||||
*
|
||||
* Preconditions:
|
||||
@@ -1227,8 +1259,10 @@ static void fe_mul(fe h, const fe f, const fe g) {
|
||||
* Postconditions:
|
||||
* |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. */
|
||||
static void fe_sq(fe h, const fe f) {
|
||||
* See fe_mul.c for discussion of implementation strategy.
|
||||
*/
|
||||
static void fe_sq(fe h, const fe f)
|
||||
{
|
||||
int32_t f0 = f[0];
|
||||
int32_t f1 = f[1];
|
||||
int32_t f2 = f[2];
|
||||
@@ -1359,7 +1393,8 @@ static void fe_sq(fe h, const fe f) {
|
||||
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 t2;
|
||||
@@ -1454,26 +1489,34 @@ static void fe_invert(fe out, const fe z) {
|
||||
fe_mul(out, t1, t0);
|
||||
}
|
||||
|
||||
/* h = -f
|
||||
/*
|
||||
* h = -f
|
||||
*
|
||||
* Preconditions:
|
||||
* |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
*
|
||||
* Postconditions:
|
||||
* |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) {
|
||||
* |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;
|
||||
|
||||
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.
|
||||
*
|
||||
* Preconditions: b in {0,1}. */
|
||||
static void fe_cmov(fe f, const fe g, unsigned b) {
|
||||
* Preconditions: b in {0,1}.
|
||||
*/
|
||||
static void fe_cmov(fe f, const fe g, unsigned b)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
b = 0-b;
|
||||
for (i = 0; i < 10; i++) {
|
||||
int32_t x = f[i] ^ g[i];
|
||||
@@ -1482,31 +1525,41 @@ static void fe_cmov(fe f, const fe g, unsigned b) {
|
||||
}
|
||||
}
|
||||
|
||||
/* return 0 if f == 0
|
||||
/*
|
||||
* return 0 if f == 0
|
||||
* return 1 if f != 0
|
||||
*
|
||||
* Preconditions:
|
||||
* |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) {
|
||||
* |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 const uint8_t zero[32] = {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}
|
||||
*
|
||||
* Preconditions:
|
||||
* |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) {
|
||||
* |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];
|
||||
|
||||
fe_tobytes(s, f);
|
||||
return s[0] & 1;
|
||||
}
|
||||
|
||||
/* h = 2 * f * f
|
||||
/*
|
||||
* h = 2 * f * f
|
||||
*
|
||||
* Can overlap h with f.
|
||||
*
|
||||
* Preconditions:
|
||||
@@ -1515,8 +1568,10 @@ static int fe_isnegative(const fe f) {
|
||||
* Postconditions:
|
||||
* |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. */
|
||||
static void fe_sq2(fe h, const fe f) {
|
||||
* See fe_mul.c for discussion of implementation strategy.
|
||||
*/
|
||||
static void fe_sq2(fe h, const fe f)
|
||||
{
|
||||
int32_t f0 = f[0];
|
||||
int32_t f1 = f[1];
|
||||
int32_t f2 = f[2];
|
||||
@@ -1658,7 +1713,8 @@ static void fe_sq2(fe h, const fe f) {
|
||||
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 t2;
|
||||
@@ -1715,8 +1771,9 @@ static void fe_pow22523(fe out, const fe z) {
|
||||
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)
|
||||
* satisfying -x^2 + y^2 = 1 + d x^2y^2
|
||||
* where d = -121665/121666.
|
||||
@@ -1725,8 +1782,8 @@ static void fe_pow22523(fe out, const fe 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_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 {
|
||||
fe X;
|
||||
fe Y;
|
||||
@@ -1760,7 +1817,8 @@ typedef struct {
|
||||
fe T2d;
|
||||
} 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 y;
|
||||
@@ -1772,7 +1830,8 @@ static void ge_tobytes(uint8_t *s, const ge_p2 *h) {
|
||||
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 y;
|
||||
@@ -1784,13 +1843,18 @@ static void ge_p3_tobytes(uint8_t *s, const ge_p3 *h) {
|
||||
s[31] ^= fe_isnegative(x) << 7;
|
||||
}
|
||||
|
||||
static const fe d = {-10913610, 13857413, -15372611, 6949391, 114729,
|
||||
-8787816, -6275908, -3247719, -18696448, -12055116};
|
||||
static const fe d = {
|
||||
-10913610, 13857413, -15372611, 6949391, 114729,
|
||||
-8787816, -6275908, -3247719, -18696448, -12055116
|
||||
};
|
||||
|
||||
static const fe sqrtm1 = {-32595792, -7943725, 9377950, 3500415, 12389472,
|
||||
-272473, -25146209, -2005654, 326686, 11406482};
|
||||
static const fe sqrtm1 = {
|
||||
-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 v3;
|
||||
@@ -1833,37 +1897,44 @@ static int ge_frombytes_vartime(ge_p3 *h, const uint8_t *s) {
|
||||
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_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_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_0(h->xy2d);
|
||||
}
|
||||
|
||||
/* 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->Z, p->Z);
|
||||
}
|
||||
|
||||
static const fe d2 = {-21827239, -5839606, -30745221, 13898782, 229458,
|
||||
15978800, -12551817, -6495438, 29715968, 9444199};
|
||||
static const fe d2 = {
|
||||
-21827239, -5839606, -30745221, 13898782, 229458,
|
||||
15978800, -12551817, -6495438, 29715968, 9444199
|
||||
};
|
||||
|
||||
/* 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_copy(r->Z, p->Z);
|
||||
@@ -1871,14 +1942,16 @@ static void ge_p3_to_cached(ge_cached *r, const ge_p3 *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->Z, p->Z, p->T);
|
||||
}
|
||||
|
||||
/* 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->Z, p->Z, p->T);
|
||||
@@ -1886,7 +1959,8 @@ static void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *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_sq(r->X, p->X);
|
||||
@@ -1901,14 +1975,16 @@ static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *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_dbl(r, &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_add(r->X, p->Y, p->X);
|
||||
@@ -1924,7 +2000,8 @@ static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *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_add(r->X, p->Y, p->X);
|
||||
@@ -1940,7 +2017,8 @@ static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *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_add(r->X, p->Y, p->X);
|
||||
@@ -1957,7 +2035,8 @@ static void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *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_add(r->X, p->Y, p->X);
|
||||
@@ -1973,7 +2052,8 @@ static void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
|
||||
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 x = ub ^ uc; /* 0: yes; 1..255: no */
|
||||
@@ -1983,7 +2063,8 @@ static uint8_t equal(signed char b, signed char c) {
|
||||
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->xy2d, u->xy2d, b);
|
||||
@@ -4105,13 +4186,16 @@ 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 */
|
||||
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);
|
||||
uint8_t babs = b - ((uint8_t)((-bnegative) & b) << 1);
|
||||
@@ -4131,13 +4215,17 @@ static void table_select(ge_precomp *t, int pos, signed char b) {
|
||||
cmov(t, &minust, bnegative);
|
||||
}
|
||||
|
||||
/* h = a * B
|
||||
/*
|
||||
* h = a * B
|
||||
*
|
||||
* where a = a[0]+256*a[1]+...+256^31 a[31]
|
||||
* B is the Ed25519 base point (x,4/5) with x positive.
|
||||
*
|
||||
* Preconditions:
|
||||
* a[31] <= 127 */
|
||||
static void ge_scalarmult_base(ge_p3 *h, const uint8_t *a) {
|
||||
* a[31] <= 127
|
||||
*/
|
||||
static void ge_scalarmult_base(ge_p3 *h, const uint8_t *a)
|
||||
{
|
||||
signed char e[64];
|
||||
signed char carry;
|
||||
ge_p1p1 r;
|
||||
@@ -4188,12 +4276,16 @@ static void ge_scalarmult_base(ge_p3 *h, const uint8_t *a) {
|
||||
}
|
||||
|
||||
#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.
|
||||
*
|
||||
* Preconditions: b in {0,1}. */
|
||||
static void fe_cswap(fe f, fe g, unsigned int b) {
|
||||
* Preconditions: b in {0,1}.
|
||||
*/
|
||||
static void fe_cswap(fe f, fe g, unsigned int b)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
b = 0-b;
|
||||
for (i = 0; i < 10; i++) {
|
||||
int32_t x = f[i] ^ g[i];
|
||||
@@ -4203,15 +4295,19 @@ static void fe_cswap(fe f, fe g, unsigned int b) {
|
||||
}
|
||||
}
|
||||
|
||||
/* h = f * 121666
|
||||
/*
|
||||
* h = f * 121666
|
||||
*
|
||||
* Can overlap h with f.
|
||||
*
|
||||
* Preconditions:
|
||||
* |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
*
|
||||
* Postconditions:
|
||||
* |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) {
|
||||
* |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];
|
||||
int32_t f1 = f[1];
|
||||
int32_t f2 = f[2];
|
||||
@@ -4324,7 +4420,8 @@ static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32],
|
||||
}
|
||||
#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 k;
|
||||
@@ -4425,12 +4522,16 @@ 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].
|
||||
* 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,
|
||||
const ge_p3 *A, const uint8_t *b) {
|
||||
const ge_p3 *A, const uint8_t *b)
|
||||
{
|
||||
signed char aslide[256];
|
||||
signed char bslide[256];
|
||||
ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
|
||||
@@ -4498,40 +4599,43 @@ static void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a,
|
||||
}
|
||||
}
|
||||
|
||||
/* The set of scalars is \Z/l
|
||||
* where l = 2^252 + 27742317777372353535851937790883648493. */
|
||||
|
||||
/* Input:
|
||||
/*
|
||||
* The set of scalars is \Z/l
|
||||
* where l = 2^252 + 27742317777372353535851937790883648493.
|
||||
*
|
||||
* Input:
|
||||
* s[0]+256*s[1]+...+256^63*s[63] = s
|
||||
*
|
||||
* Output:
|
||||
* s[0]+256*s[1]+...+256^31*s[31] = s mod l
|
||||
* where l = 2^252 + 27742317777372353535851937790883648493.
|
||||
* Overwrites s in place. */
|
||||
static void x25519_sc_reduce(uint8_t *s) {
|
||||
int64_t s0 = 2097151 & load_3(s);
|
||||
int64_t s1 = 2097151 & (load_4(s + 2) >> 5);
|
||||
int64_t s2 = 2097151 & (load_3(s + 5) >> 2);
|
||||
int64_t s3 = 2097151 & (load_4(s + 7) >> 7);
|
||||
int64_t s4 = 2097151 & (load_4(s + 10) >> 4);
|
||||
int64_t s5 = 2097151 & (load_3(s + 13) >> 1);
|
||||
int64_t s6 = 2097151 & (load_4(s + 15) >> 6);
|
||||
int64_t s7 = 2097151 & (load_3(s + 18) >> 3);
|
||||
int64_t s8 = 2097151 & load_3(s + 21);
|
||||
int64_t s9 = 2097151 & (load_4(s + 23) >> 5);
|
||||
int64_t s10 = 2097151 & (load_3(s + 26) >> 2);
|
||||
int64_t s11 = 2097151 & (load_4(s + 28) >> 7);
|
||||
int64_t s12 = 2097151 & (load_4(s + 31) >> 4);
|
||||
int64_t s13 = 2097151 & (load_3(s + 34) >> 1);
|
||||
int64_t s14 = 2097151 & (load_4(s + 36) >> 6);
|
||||
int64_t s15 = 2097151 & (load_3(s + 39) >> 3);
|
||||
int64_t s16 = 2097151 & load_3(s + 42);
|
||||
int64_t s17 = 2097151 & (load_4(s + 44) >> 5);
|
||||
int64_t s18 = 2097151 & (load_3(s + 47) >> 2);
|
||||
int64_t s19 = 2097151 & (load_4(s + 49) >> 7);
|
||||
int64_t s20 = 2097151 & (load_4(s + 52) >> 4);
|
||||
int64_t s21 = 2097151 & (load_3(s + 55) >> 1);
|
||||
int64_t s22 = 2097151 & (load_4(s + 57) >> 6);
|
||||
* Overwrites s in place.
|
||||
*/
|
||||
static void x25519_sc_reduce(uint8_t *s)
|
||||
{
|
||||
int64_t s0 = kBottom21Bits & load_3(s);
|
||||
int64_t s1 = kBottom21Bits & (load_4(s + 2) >> 5);
|
||||
int64_t s2 = kBottom21Bits & (load_3(s + 5) >> 2);
|
||||
int64_t s3 = kBottom21Bits & (load_4(s + 7) >> 7);
|
||||
int64_t s4 = kBottom21Bits & (load_4(s + 10) >> 4);
|
||||
int64_t s5 = kBottom21Bits & (load_3(s + 13) >> 1);
|
||||
int64_t s6 = kBottom21Bits & (load_4(s + 15) >> 6);
|
||||
int64_t s7 = kBottom21Bits & (load_3(s + 18) >> 3);
|
||||
int64_t s8 = kBottom21Bits & load_3(s + 21);
|
||||
int64_t s9 = kBottom21Bits & (load_4(s + 23) >> 5);
|
||||
int64_t s10 = kBottom21Bits & (load_3(s + 26) >> 2);
|
||||
int64_t s11 = kBottom21Bits & (load_4(s + 28) >> 7);
|
||||
int64_t s12 = kBottom21Bits & (load_4(s + 31) >> 4);
|
||||
int64_t s13 = kBottom21Bits & (load_3(s + 34) >> 1);
|
||||
int64_t s14 = kBottom21Bits & (load_4(s + 36) >> 6);
|
||||
int64_t s15 = kBottom21Bits & (load_3(s + 39) >> 3);
|
||||
int64_t s16 = kBottom21Bits & load_3(s + 42);
|
||||
int64_t s17 = kBottom21Bits & (load_4(s + 44) >> 5);
|
||||
int64_t s18 = kBottom21Bits & (load_3(s + 47) >> 2);
|
||||
int64_t s19 = kBottom21Bits & (load_4(s + 49) >> 7);
|
||||
int64_t s20 = kBottom21Bits & (load_4(s + 52) >> 4);
|
||||
int64_t s21 = kBottom21Bits & (load_3(s + 55) >> 1);
|
||||
int64_t s22 = kBottom21Bits & (load_4(s + 57) >> 6);
|
||||
int64_t s23 = (load_4(s + 60) >> 3);
|
||||
int64_t carry0;
|
||||
int64_t carry1;
|
||||
@@ -4841,51 +4945,54 @@ static void x25519_sc_reduce(uint8_t *s) {
|
||||
s[31] = (uint8_t) (s11 >> 17);
|
||||
}
|
||||
|
||||
/* Input:
|
||||
/*
|
||||
* Input:
|
||||
* a[0]+256*a[1]+...+256^31*a[31] = a
|
||||
* b[0]+256*b[1]+...+256^31*b[31] = b
|
||||
* c[0]+256*c[1]+...+256^31*c[31] = c
|
||||
*
|
||||
* Output:
|
||||
* 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,
|
||||
const uint8_t *c) {
|
||||
int64_t a0 = 2097151 & load_3(a);
|
||||
int64_t a1 = 2097151 & (load_4(a + 2) >> 5);
|
||||
int64_t a2 = 2097151 & (load_3(a + 5) >> 2);
|
||||
int64_t a3 = 2097151 & (load_4(a + 7) >> 7);
|
||||
int64_t a4 = 2097151 & (load_4(a + 10) >> 4);
|
||||
int64_t a5 = 2097151 & (load_3(a + 13) >> 1);
|
||||
int64_t a6 = 2097151 & (load_4(a + 15) >> 6);
|
||||
int64_t a7 = 2097151 & (load_3(a + 18) >> 3);
|
||||
int64_t a8 = 2097151 & load_3(a + 21);
|
||||
int64_t a9 = 2097151 & (load_4(a + 23) >> 5);
|
||||
int64_t a10 = 2097151 & (load_3(a + 26) >> 2);
|
||||
const uint8_t *c)
|
||||
{
|
||||
int64_t a0 = kBottom21Bits & load_3(a);
|
||||
int64_t a1 = kBottom21Bits & (load_4(a + 2) >> 5);
|
||||
int64_t a2 = kBottom21Bits & (load_3(a + 5) >> 2);
|
||||
int64_t a3 = kBottom21Bits & (load_4(a + 7) >> 7);
|
||||
int64_t a4 = kBottom21Bits & (load_4(a + 10) >> 4);
|
||||
int64_t a5 = kBottom21Bits & (load_3(a + 13) >> 1);
|
||||
int64_t a6 = kBottom21Bits & (load_4(a + 15) >> 6);
|
||||
int64_t a7 = kBottom21Bits & (load_3(a + 18) >> 3);
|
||||
int64_t a8 = kBottom21Bits & load_3(a + 21);
|
||||
int64_t a9 = kBottom21Bits & (load_4(a + 23) >> 5);
|
||||
int64_t a10 = kBottom21Bits & (load_3(a + 26) >> 2);
|
||||
int64_t a11 = (load_4(a + 28) >> 7);
|
||||
int64_t b0 = 2097151 & load_3(b);
|
||||
int64_t b1 = 2097151 & (load_4(b + 2) >> 5);
|
||||
int64_t b2 = 2097151 & (load_3(b + 5) >> 2);
|
||||
int64_t b3 = 2097151 & (load_4(b + 7) >> 7);
|
||||
int64_t b4 = 2097151 & (load_4(b + 10) >> 4);
|
||||
int64_t b5 = 2097151 & (load_3(b + 13) >> 1);
|
||||
int64_t b6 = 2097151 & (load_4(b + 15) >> 6);
|
||||
int64_t b7 = 2097151 & (load_3(b + 18) >> 3);
|
||||
int64_t b8 = 2097151 & load_3(b + 21);
|
||||
int64_t b9 = 2097151 & (load_4(b + 23) >> 5);
|
||||
int64_t b10 = 2097151 & (load_3(b + 26) >> 2);
|
||||
int64_t b0 = kBottom21Bits & load_3(b);
|
||||
int64_t b1 = kBottom21Bits & (load_4(b + 2) >> 5);
|
||||
int64_t b2 = kBottom21Bits & (load_3(b + 5) >> 2);
|
||||
int64_t b3 = kBottom21Bits & (load_4(b + 7) >> 7);
|
||||
int64_t b4 = kBottom21Bits & (load_4(b + 10) >> 4);
|
||||
int64_t b5 = kBottom21Bits & (load_3(b + 13) >> 1);
|
||||
int64_t b6 = kBottom21Bits & (load_4(b + 15) >> 6);
|
||||
int64_t b7 = kBottom21Bits & (load_3(b + 18) >> 3);
|
||||
int64_t b8 = kBottom21Bits & load_3(b + 21);
|
||||
int64_t b9 = kBottom21Bits & (load_4(b + 23) >> 5);
|
||||
int64_t b10 = kBottom21Bits & (load_3(b + 26) >> 2);
|
||||
int64_t b11 = (load_4(b + 28) >> 7);
|
||||
int64_t c0 = 2097151 & load_3(c);
|
||||
int64_t c1 = 2097151 & (load_4(c + 2) >> 5);
|
||||
int64_t c2 = 2097151 & (load_3(c + 5) >> 2);
|
||||
int64_t c3 = 2097151 & (load_4(c + 7) >> 7);
|
||||
int64_t c4 = 2097151 & (load_4(c + 10) >> 4);
|
||||
int64_t c5 = 2097151 & (load_3(c + 13) >> 1);
|
||||
int64_t c6 = 2097151 & (load_4(c + 15) >> 6);
|
||||
int64_t c7 = 2097151 & (load_3(c + 18) >> 3);
|
||||
int64_t c8 = 2097151 & load_3(c + 21);
|
||||
int64_t c9 = 2097151 & (load_4(c + 23) >> 5);
|
||||
int64_t c10 = 2097151 & (load_3(c + 26) >> 2);
|
||||
int64_t c0 = kBottom21Bits & load_3(c);
|
||||
int64_t c1 = kBottom21Bits & (load_4(c + 2) >> 5);
|
||||
int64_t c2 = kBottom21Bits & (load_3(c + 5) >> 2);
|
||||
int64_t c3 = kBottom21Bits & (load_4(c + 7) >> 7);
|
||||
int64_t c4 = kBottom21Bits & (load_4(c + 10) >> 4);
|
||||
int64_t c5 = kBottom21Bits & (load_3(c + 13) >> 1);
|
||||
int64_t c6 = kBottom21Bits & (load_4(c + 15) >> 6);
|
||||
int64_t c7 = kBottom21Bits & (load_3(c + 18) >> 3);
|
||||
int64_t c8 = kBottom21Bits & load_3(c + 21);
|
||||
int64_t c9 = kBottom21Bits & (load_4(c + 23) >> 5);
|
||||
int64_t c10 = kBottom21Bits & (load_3(c + 26) >> 2);
|
||||
int64_t c11 = (load_4(c + 28) >> 7);
|
||||
int64_t s0;
|
||||
int64_t s1;
|
||||
@@ -4942,24 +5049,15 @@ static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
|
||||
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;
|
||||
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 +
|
||||
a6 * b1 + a7 * b0;
|
||||
s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 +
|
||||
a6 * b2 + a7 * b1 + a8 * b0;
|
||||
s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 +
|
||||
a6 * b3 + a7 * b2 + a8 * b1 + a9 * 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;
|
||||
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;
|
||||
s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 +
|
||||
a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1;
|
||||
s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 +
|
||||
a9 * b4 + a10 * b3 + a11 * b2;
|
||||
s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 +
|
||||
a10 * b4 + a11 * b3;
|
||||
s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 +
|
||||
a11 * b4;
|
||||
s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0;
|
||||
s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0;
|
||||
s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * 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;
|
||||
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;
|
||||
s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1;
|
||||
s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2;
|
||||
s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3;
|
||||
s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + 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;
|
||||
@@ -5331,7 +5429,8 @@ static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
|
||||
}
|
||||
|
||||
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];
|
||||
ge_p3 R;
|
||||
@@ -5374,7 +5473,8 @@ int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
|
||||
static const char allzeroes[15];
|
||||
|
||||
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;
|
||||
const uint8_t *r, *s;
|
||||
@@ -5441,7 +5541,8 @@ int ED25519_verify(const uint8_t *message, size_t message_len,
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -5458,7 +5559,8 @@ void ED25519_public_from_private(uint8_t out_public_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);
|
||||
/* The all-zero output results when the input is a point of small order. */
|
||||
@@ -5466,7 +5568,8 @@ int X25519(uint8_t out_shared_key[32], const uint8_t private_key[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;
|
||||
fe zplusy, zminusy, zminusy_inv;
|
||||
@@ -5478,8 +5581,11 @@ void X25519_public_from_private(uint8_t out_public_value[32],
|
||||
|
||||
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.
|
||||
* The map is u=(y+1)/(1-y). Since y=Y/Z, this gives
|
||||
* u=(Z+Y)/(Z-Y).
|
||||
*/
|
||||
fe_add(zplusy, A.Z, A.Y);
|
||||
fe_sub(zminusy, A.Z, A.Y);
|
||||
fe_invert(zminusy_inv, zminusy);
|
||||
|
||||
@@ -246,10 +246,36 @@ c448_error_t c448_ed448_verify(
|
||||
uint8_t context_len)
|
||||
{
|
||||
curve448_point_t pk_point, r_point;
|
||||
c448_error_t error =
|
||||
curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point, pubkey);
|
||||
c448_error_t error;
|
||||
curve448_scalar_t challenge_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)
|
||||
return error;
|
||||
|
||||
+608
-65
@@ -16,6 +16,7 @@
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/engine.h>
|
||||
@@ -34,6 +35,34 @@
|
||||
* saner... why re-open /dev/crypto for every session?
|
||||
*/
|
||||
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 session_op sess;
|
||||
|
||||
/* to pass from init to do_cipher */
|
||||
const unsigned char *iv;
|
||||
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 {
|
||||
@@ -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 },
|
||||
#endif
|
||||
#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_192_ecb, 16, 192 / 8, 16, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
|
||||
{ NID_aes_256_ecb, 16, 256 / 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, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
|
||||
{ NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
|
||||
#endif
|
||||
#if 0 /* Not yet supported */
|
||||
{ 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
|
||||
};
|
||||
|
||||
static size_t get_cipher_data_index(int nid)
|
||||
static size_t find_cipher_data_index(int nid)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(cipher_data); i++)
|
||||
if (nid == cipher_data[i].nid)
|
||||
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
|
||||
@@ -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.key = (void *)key;
|
||||
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) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
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 *)EVP_CIPHER_CTX_get_cipher_data(ctx);
|
||||
struct crypt_op cryp;
|
||||
unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
|
||||
#if !defined(COP_FLAG_WRITE_IV)
|
||||
unsigned char saved_iv[EVP_MAX_IV_LENGTH];
|
||||
const unsigned char *ivptr;
|
||||
size_t nblocks, ivlen;
|
||||
#endif
|
||||
|
||||
memset(&cryp, 0, sizeof(cryp));
|
||||
@@ -169,18 +214,27 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
cryp.len = inl;
|
||||
cryp.src = (void *)in;
|
||||
cryp.dst = (void *)out;
|
||||
cryp.iv = (void *)EVP_CIPHER_CTX_iv_noconst(ctx);
|
||||
cryp.iv = (void *)iv;
|
||||
cryp.op = cipher_ctx->op;
|
||||
#if !defined(COP_FLAG_WRITE_IV)
|
||||
cryp.flags = 0;
|
||||
|
||||
if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
|
||||
assert(inl >= EVP_CIPHER_CTX_iv_length(ctx));
|
||||
ivlen = EVP_CIPHER_CTX_iv_length(ctx);
|
||||
if (ivlen > 0)
|
||||
switch (cipher_ctx->mode) {
|
||||
case EVP_CIPH_CBC_MODE:
|
||||
assert(inl >= ivlen);
|
||||
if (!EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
unsigned char *ivptr = in + inl - EVP_CIPHER_CTX_iv_length(ctx);
|
||||
|
||||
memcpy(saved_iv, ivptr, EVP_CIPHER_CTX_iv_length(ctx));
|
||||
ivptr = in + inl - ivlen;
|
||||
memcpy(saved_iv, ivptr, ivlen);
|
||||
}
|
||||
break;
|
||||
|
||||
case EVP_CIPH_CTR_MODE:
|
||||
break;
|
||||
|
||||
default: /* should not happen */
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
cryp.flags = COP_FLAG_WRITE_IV;
|
||||
@@ -192,21 +246,94 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
}
|
||||
|
||||
#if !defined(COP_FLAG_WRITE_IV)
|
||||
if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
|
||||
unsigned char *ivptr = saved_iv;
|
||||
if (ivlen > 0)
|
||||
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));
|
||||
if (!EVP_CIPHER_CTX_encrypting(ctx))
|
||||
ivptr = out + inl - EVP_CIPHER_CTX_iv_length(ctx);
|
||||
memcpy(iv, ivptr, ivlen);
|
||||
break;
|
||||
|
||||
memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), ivptr,
|
||||
EVP_CIPHER_CTX_iv_length(ctx));
|
||||
case EVP_CIPH_CTR_MODE:
|
||||
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
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
* 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_amount = -1; /* -1 indicates not yet initialised */
|
||||
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)
|
||||
{
|
||||
size_t i;
|
||||
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));
|
||||
sess.key = (void *)"01234567890123456789012345678901234567890123456789";
|
||||
@@ -240,41 +389,80 @@ static void prepare_cipher_methods(void)
|
||||
for (i = 0, known_cipher_nids_amount = 0;
|
||||
i < OSSL_NELEM(cipher_data); i++) {
|
||||
|
||||
selected_ciphers[i] = 1;
|
||||
/*
|
||||
* Check that the algo is really availably by trying to open and close
|
||||
* a session.
|
||||
* Check that the cipher is usable
|
||||
*/
|
||||
sess.cipher = cipher_data[i].devcryptoid;
|
||||
sess.keylen = cipher_data[i].keylen;
|
||||
if (ioctl(cfd, CIOCGSESSION, &sess) < 0
|
||||
|| ioctl(cfd, CIOCFSESSION, &sess.ses) < 0)
|
||||
if (ioctl(cfd, CIOCGSESSION, &sess) < 0) {
|
||||
cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
|
||||
continue;
|
||||
}
|
||||
|
||||
cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE;
|
||||
|
||||
if ((known_cipher_methods[i] =
|
||||
EVP_CIPHER_meth_new(cipher_data[i].nid,
|
||||
cipher_mode == EVP_CIPH_CTR_MODE ? 1 :
|
||||
cipher_data[i].blocksize,
|
||||
cipher_data[i].keylen)) == NULL
|
||||
|| !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i],
|
||||
cipher_data[i].ivlen)
|
||||
|| !EVP_CIPHER_meth_set_flags(known_cipher_methods[i],
|
||||
cipher_data[i].flags
|
||||
| EVP_CIPH_CUSTOM_COPY
|
||||
| EVP_CIPH_FLAG_DEFAULT_ASN1)
|
||||
|| !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init)
|
||||
|| !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i],
|
||||
cipher_mode == EVP_CIPH_CTR_MODE ?
|
||||
ctr_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],
|
||||
cipher_cleanup)
|
||||
|| !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
|
||||
sizeof(struct cipher_ctx))) {
|
||||
cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
|
||||
EVP_CIPHER_meth_free(known_cipher_methods[i]);
|
||||
known_cipher_methods[i] = NULL;
|
||||
} 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++] =
|
||||
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)
|
||||
{
|
||||
size_t i = get_cipher_data_index(nid);
|
||||
@@ -302,8 +490,11 @@ static void destroy_all_cipher_methods(void)
|
||||
{
|
||||
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);
|
||||
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,
|
||||
@@ -317,6 +508,70 @@ static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
||||
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
|
||||
* 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 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 {
|
||||
@@ -369,13 +626,22 @@ static const struct digest_data_st {
|
||||
#endif
|
||||
};
|
||||
|
||||
static size_t get_digest_data_index(int nid)
|
||||
static size_t find_digest_data_index(int nid)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(digest_data); i++)
|
||||
if (nid == digest_data[i].nid)
|
||||
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
|
||||
@@ -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
|
||||
* with cryptodev.
|
||||
* Following are the five necessary functions to map OpenSSL functionality
|
||||
* with cryptodev: init, update, final, cleanup, and copy.
|
||||
*/
|
||||
|
||||
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 =
|
||||
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));
|
||||
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)
|
||||
return 1;
|
||||
|
||||
if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
if (digest_ctx == NULL)
|
||||
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)
|
||||
@@ -451,11 +723,12 @@ static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
struct digest_ctx *digest_ctx =
|
||||
(struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
if (md == NULL || digest_ctx == NULL)
|
||||
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);
|
||||
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 cphash_op cphash;
|
||||
|
||||
if (digest_from == NULL)
|
||||
if (digest_from == NULL || digest_from->init_called != 1)
|
||||
return 1;
|
||||
|
||||
if (digest_from->init != 1) {
|
||||
SYSerr(SYS_F_IOCTL, EINVAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!digest_init(to)) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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_amount = -1; /* -1 indicates not yet initialised */
|
||||
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)
|
||||
{
|
||||
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);
|
||||
i++) {
|
||||
|
||||
/*
|
||||
* 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;
|
||||
selected_digests[i] = 1;
|
||||
|
||||
/*
|
||||
* 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,
|
||||
NID_undef)) == NULL
|
||||
|| !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_app_datasize(known_digest_methods[i],
|
||||
sizeof(struct digest_ctx))) {
|
||||
digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
|
||||
EVP_MD_meth_free(known_digest_methods[i]);
|
||||
known_digest_methods[i] = NULL;
|
||||
} else {
|
||||
known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
|
||||
goto finish;
|
||||
}
|
||||
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;
|
||||
|
||||
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);
|
||||
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,
|
||||
@@ -587,8 +939,197 @@ static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
|
||||
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
|
||||
|
||||
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
|
||||
@@ -619,11 +1160,6 @@ void engine_load_devcrypto_int()
|
||||
return;
|
||||
}
|
||||
|
||||
prepare_cipher_methods();
|
||||
#ifdef IMPLEMENT_DIGEST
|
||||
prepare_digest_methods();
|
||||
#endif
|
||||
|
||||
if ((e = ENGINE_new()) == NULL
|
||||
|| !ENGINE_set_destroy_function(e, devcrypto_unload)) {
|
||||
ENGINE_free(e);
|
||||
@@ -636,8 +1172,15 @@ void engine_load_devcrypto_int()
|
||||
return;
|
||||
}
|
||||
|
||||
prepare_cipher_methods();
|
||||
#ifdef IMPLEMENT_DIGEST
|
||||
prepare_digest_methods();
|
||||
#endif
|
||||
|
||||
if (!ENGINE_set_id(e, "devcrypto")
|
||||
|| !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
|
||||
|
||||
+25
-2
@@ -21,6 +21,7 @@
|
||||
#include "internal/thread_once.h"
|
||||
#include "internal/ctype.h"
|
||||
#include "internal/constant_time_locl.h"
|
||||
#include "e_os.h"
|
||||
|
||||
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;
|
||||
static int init = 1;
|
||||
int i;
|
||||
int saveerrno = get_last_sys_error();
|
||||
|
||||
CRYPTO_THREAD_write_lock(err_string_lock);
|
||||
if (!init) {
|
||||
@@ -251,6 +253,8 @@ static void build_SYS_str_reasons(void)
|
||||
init = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
@@ -880,6 +884,25 @@ int ERR_clear_last_mark(void)
|
||||
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)
|
||||
{
|
||||
ERR_STATE *es;
|
||||
@@ -893,8 +916,8 @@ void err_clear_last_constant_time(int clear)
|
||||
|
||||
es->err_flags[top] &= ~(0 - clear);
|
||||
es->err_buffer[top] &= ~(0UL - clear);
|
||||
es->err_file[top] = (const char *)((uintptr_t)es->err_file[top] &
|
||||
~((uintptr_t)0 - clear));
|
||||
es->err_file[top] = (const char *)((UINTPTR_T)es->err_file[top] &
|
||||
~((UINTPTR_T)0 - clear));
|
||||
es->err_line[top] |= 0 - clear;
|
||||
|
||||
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_DIGESTFINALXOF:174:EVP_DigestFinalXOF
|
||||
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_ENCRYPTUPDATE:167:EVP_EncryptUpdate
|
||||
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_128_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
|
||||
EVP_add_cipher(EVP_aria_128_ecb());
|
||||
EVP_add_cipher(EVP_aria_128_cbc());
|
||||
|
||||
+130
-5
@@ -17,6 +17,7 @@
|
||||
#include "internal/evp_int.h"
|
||||
#include "modes_lcl.h"
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/cmac.h>
|
||||
#include "evp_locl.h"
|
||||
|
||||
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) \
|
||||
static const EVP_CIPHER aesni_##keylen##_##mode = { \
|
||||
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, \
|
||||
aesni_##mode##_init_key, \
|
||||
aesni_##mode##_cipher, \
|
||||
@@ -549,7 +551,8 @@ static const EVP_CIPHER aesni_##keylen##_##mode = { \
|
||||
NULL,NULL,aes_##mode##_ctrl,NULL }; \
|
||||
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||
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, \
|
||||
aes_##mode##_init_key, \
|
||||
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) \
|
||||
static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
|
||||
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, \
|
||||
aes_t4_##mode##_init_key, \
|
||||
aes_t4_##mode##_cipher, \
|
||||
@@ -957,7 +961,8 @@ static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
|
||||
NULL,NULL,aes_##mode##_ctrl,NULL }; \
|
||||
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||
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, \
|
||||
aes_##mode##_init_key, \
|
||||
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) \
|
||||
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||
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, \
|
||||
aes_##mode##_init_key, \
|
||||
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);
|
||||
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:
|
||||
/* Special case: -1 length restores whole IV */
|
||||
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,
|
||||
EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
|
||||
#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
|
||||
+38
-5
@@ -294,7 +294,8 @@ int is_partially_overlapping(const void *ptr1, const void *ptr2, int len)
|
||||
return overlapped;
|
||||
}
|
||||
|
||||
int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
static int evp_EncryptDecryptUpdate(EVP_CIPHER_CTX *ctx,
|
||||
unsigned char *out, int *outl,
|
||||
const unsigned char *in, int 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 block size > 1 then the cipher will have to do this check */
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -324,7 +325,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
return inl == 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -371,6 +372,19 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
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 ret;
|
||||
@@ -383,6 +397,12 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
||||
int n, ret;
|
||||
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) {
|
||||
ret = ctx->cipher->do_cipher(ctx, out, NULL, 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;
|
||||
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;
|
||||
|
||||
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)
|
||||
return EVP_EncryptUpdate(ctx, out, outl, in, inl);
|
||||
return evp_EncryptDecryptUpdate(ctx, out, outl, in, inl);
|
||||
|
||||
OPENSSL_assert(b <= sizeof(ctx->final));
|
||||
|
||||
@@ -469,7 +495,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
} else
|
||||
fix_len = 0;
|
||||
|
||||
if (!EVP_EncryptUpdate(ctx, out, outl, in, inl))
|
||||
if (!evp_EncryptDecryptUpdate(ctx, out, outl, in, inl))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@@ -500,6 +526,13 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
||||
{
|
||||
int i, n;
|
||||
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;
|
||||
|
||||
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_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_ENCRYPTDECRYPTUPDATE, 0),
|
||||
"evp_EncryptDecryptUpdate"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0),
|
||||
"EVP_EncryptFinal_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTUPDATE, 0), "EVP_EncryptUpdate"},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright 2006-2018 The OpenSSL Project Authors. 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* 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 obtain a copy of the License at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright 2018 The OpenSSL Project Authors. 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright 2017 Ribose Inc. All Rights Reserved.
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright 2017 The OpenSSL Project Authors. 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright 2017 The OpenSSL Project Authors. 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
+4
-4
@@ -19,28 +19,28 @@
|
||||
* KMAC128(K, X, L, S)
|
||||
* {
|
||||
* 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).
|
||||
* }
|
||||
*
|
||||
* KMAC256(K, X, L, S)
|
||||
* {
|
||||
* 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).
|
||||
* }
|
||||
*
|
||||
* KMAC128XOF(K, X, L, S)
|
||||
* {
|
||||
* 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).
|
||||
* }
|
||||
*
|
||||
* KMAC256XOF(K, X, L, S)
|
||||
* {
|
||||
* 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).
|
||||
* }
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
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} -}
|
||||
|
||||
INCLUDE[gcm128.o]=..
|
||||
|
||||
@@ -188,3 +188,28 @@ struct ocb128_context {
|
||||
} sess;
|
||||
};
|
||||
#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 */
|
||||
};
|
||||
|
||||
#define NUM_NID 1199
|
||||
#define NUM_NID 1202
|
||||
static const ASN1_OBJECT nid_objs[NUM_NID] = {
|
||||
{"UNDEF", "undefined", NID_undef},
|
||||
{"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]},
|
||||
{"KMAC128", "kmac128", NID_kmac128},
|
||||
{"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 },
|
||||
};
|
||||
|
||||
#define NUM_SN 1190
|
||||
#define NUM_SN 1193
|
||||
static const unsigned int sn_objs[NUM_SN] = {
|
||||
364, /* "AD_DVCS" */
|
||||
419, /* "AES-128-CBC" */
|
||||
@@ -2295,6 +2298,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
418, /* "AES-128-ECB" */
|
||||
958, /* "AES-128-OCB" */
|
||||
420, /* "AES-128-OFB" */
|
||||
1198, /* "AES-128-SIV" */
|
||||
913, /* "AES-128-XTS" */
|
||||
423, /* "AES-192-CBC" */
|
||||
917, /* "AES-192-CBC-HMAC-SHA1" */
|
||||
@@ -2306,6 +2310,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
422, /* "AES-192-ECB" */
|
||||
959, /* "AES-192-OCB" */
|
||||
424, /* "AES-192-OFB" */
|
||||
1199, /* "AES-192-SIV" */
|
||||
427, /* "AES-256-CBC" */
|
||||
918, /* "AES-256-CBC-HMAC-SHA1" */
|
||||
950, /* "AES-256-CBC-HMAC-SHA256" */
|
||||
@@ -2316,6 +2321,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
426, /* "AES-256-ECB" */
|
||||
960, /* "AES-256-OCB" */
|
||||
428, /* "AES-256-OFB" */
|
||||
1200, /* "AES-256-SIV" */
|
||||
914, /* "AES-256-XTS" */
|
||||
1066, /* "ARIA-128-CBC" */
|
||||
1120, /* "ARIA-128-CCM" */
|
||||
@@ -2400,7 +2406,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
417, /* "CSPName" */
|
||||
1019, /* "ChaCha20" */
|
||||
1018, /* "ChaCha20-Poly1305" */
|
||||
1198, /* "chacha20-poly1305-draft" */
|
||||
1201, /* "chacha20-poly1305-draft" */
|
||||
367, /* "CrlID" */
|
||||
391, /* "DC" */
|
||||
31, /* "DES-CBC" */
|
||||
@@ -3476,7 +3482,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
1093, /* "x509ExtAdmission" */
|
||||
};
|
||||
|
||||
#define NUM_LN 1190
|
||||
#define NUM_LN 1193
|
||||
static const unsigned int ln_objs[NUM_LN] = {
|
||||
363, /* "AD Time Stamping" */
|
||||
405, /* "ANSI X9.62" */
|
||||
@@ -3703,6 +3709,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
895, /* "aes-128-gcm" */
|
||||
958, /* "aes-128-ocb" */
|
||||
420, /* "aes-128-ofb" */
|
||||
1198, /* "aes-128-siv" */
|
||||
913, /* "aes-128-xts" */
|
||||
423, /* "aes-192-cbc" */
|
||||
917, /* "aes-192-cbc-hmac-sha1" */
|
||||
@@ -3716,6 +3723,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
898, /* "aes-192-gcm" */
|
||||
959, /* "aes-192-ocb" */
|
||||
424, /* "aes-192-ofb" */
|
||||
1199, /* "aes-192-siv" */
|
||||
427, /* "aes-256-cbc" */
|
||||
918, /* "aes-256-cbc-hmac-sha1" */
|
||||
950, /* "aes-256-cbc-hmac-sha256" */
|
||||
@@ -3728,6 +3736,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
901, /* "aes-256-gcm" */
|
||||
960, /* "aes-256-ocb" */
|
||||
428, /* "aes-256-ofb" */
|
||||
1200, /* "aes-256-siv" */
|
||||
914, /* "aes-256-xts" */
|
||||
376, /* "algorithm" */
|
||||
1066, /* "aria-128-cbc" */
|
||||
@@ -3855,7 +3864,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
883, /* "certificateRevocationList" */
|
||||
1019, /* "chacha20" */
|
||||
1018, /* "chacha20-poly1305" */
|
||||
1198, /* "ChaCha20-Poly1305-D" */
|
||||
1201, /* "ChaCha20-Poly1305-D" */
|
||||
54, /* "challengePassword" */
|
||||
407, /* "characteristic-two-field" */
|
||||
395, /* "clearance" */
|
||||
|
||||
@@ -1195,4 +1195,7 @@ hmacWithSHA512_256 1194
|
||||
gmac 1195
|
||||
kmac128 1196
|
||||
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
|
||||
# NID for SipHash
|
||||
: SipHash : siphash
|
||||
|
||||
# NIDs for RFC7919 DH parameters
|
||||
: ffdhe2048
|
||||
: ffdhe3072
|
||||
@@ -1683,3 +1682,7 @@ dstu4145le 2 6 : uacurve6 : DSTU curve 6
|
||||
dstu4145le 2 7 : uacurve7 : DSTU curve 7
|
||||
dstu4145le 2 8 : uacurve8 : DSTU curve 8
|
||||
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<-comp>]
|
||||
[B<-no_ticket>]
|
||||
[B<-num_tickets>]
|
||||
[B<-serverpref>]
|
||||
[B<-legacy_renegotiation>]
|
||||
[B<-no_renegotiation>]
|
||||
@@ -558,7 +559,14 @@ OpenSSL 1.1.0.
|
||||
|
||||
=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>
|
||||
|
||||
|
||||
+13
-1
@@ -5,7 +5,7 @@
|
||||
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_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
|
||||
|
||||
=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_set_info_callback(BIO *b, BIO_info_cb *cb);
|
||||
|
||||
int BIO_get_ktls_send(BIO *b);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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()
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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,
|
||||
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_OCB_MODE
|
||||
EVP_CIPH_OCB_MODE, EVP_CIPH_SIV_MODE
|
||||
|
||||
The cipher mode.
|
||||
|
||||
|
||||
@@ -426,6 +426,49 @@ AES.
|
||||
|
||||
=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
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
in the file LICENSE in the source distribution or at
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -20,10 +20,10 @@ SSL_CTX_get_num_tickets
|
||||
=head1 DESCRIPTION
|
||||
|
||||
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
|
||||
client after a full handshake. Set the desired value (which could be 0) in the
|
||||
B<num_tickets> argument. Typically these functions should be called before the
|
||||
start of the handshake.
|
||||
application and set the number of TLSv1.3 session tickets that will be sent to
|
||||
the client after a full handshake. Set the desired value (which could be 0) in
|
||||
the B<num_tickets> argument. Typically these functions should be called before
|
||||
the start of the handshake.
|
||||
|
||||
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.
|
||||
|
||||
@@ -38,7 +38,7 @@ ticket information or it starts a full TLS handshake to create a new session
|
||||
ticket.
|
||||
|
||||
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
|
||||
an attempted retrieval of the ticket failed, or a renew option was indicated,
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
|
||||
# define get_last_sys_error() errno
|
||||
# define clear_sys_error() errno=0
|
||||
# define set_sys_error(e) errno=(e)
|
||||
|
||||
/********************************************************************
|
||||
The Microsoft section
|
||||
@@ -66,8 +67,10 @@
|
||||
# ifdef WIN32
|
||||
# undef get_last_sys_error
|
||||
# undef clear_sys_error
|
||||
# undef set_sys_error
|
||||
# define get_last_sys_error() GetLastError()
|
||||
# define clear_sys_error() SetLastError(0)
|
||||
# define set_sys_error(e) SetLastError(e)
|
||||
# if !defined(WINNT)
|
||||
# define WIN_CONSOLE_BUG
|
||||
# endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
+37
-1
@@ -1,12 +1,15 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#ifndef HEADER_INTERNAL_BIO_H
|
||||
# define HEADER_INTERNAL_BIO_H
|
||||
|
||||
#include <openssl/bio.h>
|
||||
|
||||
struct bio_method_st {
|
||||
@@ -31,3 +34,36 @@ void bio_cleanup(void);
|
||||
/* Old style to new style BIO_METHOD conversion functions */
|
||||
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);
|
||||
|
||||
# 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.
|
||||
*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
+11
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
@@ -145,6 +145,16 @@ extern "C" {
|
||||
|
||||
# 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 */
|
||||
# define BIO_FP_READ 0x02
|
||||
# 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