Latest update

This commit is contained in:
2018-12-12 13:00:30 +09:00
parent 3aaee0f8f9
commit 7cd0ce9c1d
228 changed files with 10180 additions and 7774 deletions
+12 -1
View File
@@ -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]
+3 -3
View File
@@ -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} -}","',"
+2 -2
View File
@@ -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} -}
+2 -2
View File
@@ -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} -}
+31 -2
View File
@@ -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) {
+17 -3
View File
@@ -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
+4
View File
@@ -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
{
+4
View File
@@ -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);
}
+4
View File
@@ -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
View File
@@ -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);
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+7
View File
@@ -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;
+394 -288
View File
@@ -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,60 +900,68 @@ 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. */
s[0] = (uint8_t)(h0 >> 0);
s[1] = (uint8_t)(h0 >> 8);
s[2] = (uint8_t)(h0 >> 16);
s[3] = (uint8_t)((h0 >> 24) | ((uint32_t)(h1) << 2));
s[4] = (uint8_t)(h1 >> 6);
s[5] = (uint8_t)(h1 >> 14);
s[6] = (uint8_t)((h1 >> 22) | ((uint32_t)(h2) << 3));
s[7] = (uint8_t)(h2 >> 5);
s[8] = (uint8_t)(h2 >> 13);
s[9] = (uint8_t)((h2 >> 21) | ((uint32_t)(h3) << 5));
s[10] = (uint8_t)(h3 >> 3);
s[11] = (uint8_t)(h3 >> 11);
* Goal: Output h0+...+2^230 h9.
*/
s[ 0] = (uint8_t) (h0 >> 0);
s[ 1] = (uint8_t) (h0 >> 8);
s[ 2] = (uint8_t) (h0 >> 16);
s[ 3] = (uint8_t)((h0 >> 24) | ((uint32_t)(h1) << 2));
s[ 4] = (uint8_t) (h1 >> 6);
s[ 5] = (uint8_t) (h1 >> 14);
s[ 6] = (uint8_t)((h1 >> 22) | ((uint32_t)(h2) << 3));
s[ 7] = (uint8_t) (h2 >> 5);
s[ 8] = (uint8_t) (h2 >> 13);
s[ 9] = (uint8_t)((h2 >> 21) | ((uint32_t)(h3) << 5));
s[10] = (uint8_t) (h3 >> 3);
s[11] = (uint8_t) (h3 >> 11);
s[12] = (uint8_t)((h3 >> 19) | ((uint32_t)(h4) << 6));
s[13] = (uint8_t)(h4 >> 2);
s[14] = (uint8_t)(h4 >> 10);
s[15] = (uint8_t)(h4 >> 18);
s[16] = (uint8_t)(h5 >> 0);
s[17] = (uint8_t)(h5 >> 8);
s[18] = (uint8_t)(h5 >> 16);
s[13] = (uint8_t) (h4 >> 2);
s[14] = (uint8_t) (h4 >> 10);
s[15] = (uint8_t) (h4 >> 18);
s[16] = (uint8_t) (h5 >> 0);
s[17] = (uint8_t) (h5 >> 8);
s[18] = (uint8_t) (h5 >> 16);
s[19] = (uint8_t)((h5 >> 24) | ((uint32_t)(h6) << 1));
s[20] = (uint8_t)(h6 >> 7);
s[21] = (uint8_t)(h6 >> 15);
s[20] = (uint8_t) (h6 >> 7);
s[21] = (uint8_t) (h6 >> 15);
s[22] = (uint8_t)((h6 >> 23) | ((uint32_t)(h7) << 3));
s[23] = (uint8_t)(h7 >> 5);
s[24] = (uint8_t)(h7 >> 13);
s[23] = (uint8_t) (h7 >> 5);
s[24] = (uint8_t) (h7 >> 13);
s[25] = (uint8_t)((h7 >> 21) | ((uint32_t)(h8) << 4));
s[26] = (uint8_t)(h8 >> 4);
s[27] = (uint8_t)(h8 >> 12);
s[26] = (uint8_t) (h8 >> 4);
s[27] = (uint8_t) (h8 >> 12);
s[28] = (uint8_t)((h8 >> 20) | ((uint32_t)(h9) << 6));
s[29] = (uint8_t)(h9 >> 2);
s[30] = (uint8_t)(h9 >> 10);
s[31] = (uint8_t)(h9 >> 18);
s[29] = (uint8_t) (h9 >> 2);
s[30] = (uint8_t) (h9 >> 10);
s[31] = (uint8_t) (h9 >> 18);
}
/* 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];
@@ -1137,16 +1167,16 @@ static void fe_mul(fe h, const fe f, const fe g) {
int64_t f9g7_38 = f9_2 * (int64_t) g7_19;
int64_t f9g8_19 = f9 * (int64_t) g8_19;
int64_t f9g9_38 = f9_2 * (int64_t) g9_19;
int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38;
int64_t h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19;
int64_t h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38;
int64_t h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19;
int64_t h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38;
int64_t h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19;
int64_t h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38;
int64_t h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19;
int64_t h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38;
int64_t h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ;
int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38;
int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19;
int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38;
int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19;
int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38;
int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19;
int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38;
int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19;
int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38;
int64_t h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 ;
int64_t carry0;
int64_t carry1;
int64_t carry2;
@@ -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];
@@ -1307,16 +1341,16 @@ static void fe_sq(fe h, const fe f) {
int64_t f8f8_19 = f8 * (int64_t) f8_19;
int64_t f8f9_38 = f8 * (int64_t) f9_38;
int64_t f9f9_38 = f9 * (int64_t) f9_38;
int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
int64_t carry0;
int64_t carry1;
int64_t carry2;
@@ -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];
@@ -1595,16 +1650,16 @@ static void fe_sq2(fe h, const fe f) {
int64_t f8f8_19 = f8 * (int64_t) f8_19;
int64_t f8f9_38 = f8 * (int64_t) f9_38;
int64_t f9f9_38 = f9 * (int64_t) f9_38;
int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
int64_t carry0;
int64_t carry1;
int64_t carry2;
@@ -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;
@@ -4807,85 +4911,88 @@ static void x25519_sc_reduce(uint8_t *s) {
s11 += carry10;
s10 -= carry10 * (1 << 21);
s[0] = (uint8_t)(s0 >> 0);
s[1] = (uint8_t)(s0 >> 8);
s[2] = (uint8_t)((s0 >> 16) | (s1 << 5));
s[3] = (uint8_t)(s1 >> 3);
s[4] = (uint8_t)(s1 >> 11);
s[5] = (uint8_t)((s1 >> 19) | (s2 << 2));
s[6] = (uint8_t)(s2 >> 6);
s[7] = (uint8_t)((s2 >> 14) | (s3 << 7));
s[8] = (uint8_t)(s3 >> 1);
s[9] = (uint8_t)(s3 >> 9);
s[ 0] = (uint8_t) (s0 >> 0);
s[ 1] = (uint8_t) (s0 >> 8);
s[ 2] = (uint8_t)((s0 >> 16) | (s1 << 5));
s[ 3] = (uint8_t) (s1 >> 3);
s[ 4] = (uint8_t) (s1 >> 11);
s[ 5] = (uint8_t)((s1 >> 19) | (s2 << 2));
s[ 6] = (uint8_t) (s2 >> 6);
s[ 7] = (uint8_t)((s2 >> 14) | (s3 << 7));
s[ 8] = (uint8_t) (s3 >> 1);
s[ 9] = (uint8_t) (s3 >> 9);
s[10] = (uint8_t)((s3 >> 17) | (s4 << 4));
s[11] = (uint8_t)(s4 >> 4);
s[12] = (uint8_t)(s4 >> 12);
s[11] = (uint8_t) (s4 >> 4);
s[12] = (uint8_t) (s4 >> 12);
s[13] = (uint8_t)((s4 >> 20) | (s5 << 1));
s[14] = (uint8_t)(s5 >> 7);
s[14] = (uint8_t) (s5 >> 7);
s[15] = (uint8_t)((s5 >> 15) | (s6 << 6));
s[16] = (uint8_t)(s6 >> 2);
s[17] = (uint8_t)(s6 >> 10);
s[16] = (uint8_t) (s6 >> 2);
s[17] = (uint8_t) (s6 >> 10);
s[18] = (uint8_t)((s6 >> 18) | (s7 << 3));
s[19] = (uint8_t)(s7 >> 5);
s[20] = (uint8_t)(s7 >> 13);
s[21] = (uint8_t)(s8 >> 0);
s[22] = (uint8_t)(s8 >> 8);
s[19] = (uint8_t) (s7 >> 5);
s[20] = (uint8_t) (s7 >> 13);
s[21] = (uint8_t) (s8 >> 0);
s[22] = (uint8_t) (s8 >> 8);
s[23] = (uint8_t)((s8 >> 16) | (s9 << 5));
s[24] = (uint8_t)(s9 >> 3);
s[25] = (uint8_t)(s9 >> 11);
s[24] = (uint8_t) (s9 >> 3);
s[25] = (uint8_t) (s9 >> 11);
s[26] = (uint8_t)((s9 >> 19) | (s10 << 2));
s[27] = (uint8_t)(s10 >> 6);
s[27] = (uint8_t) (s10 >> 6);
s[28] = (uint8_t)((s10 >> 14) | (s11 << 7));
s[29] = (uint8_t)(s11 >> 1);
s[30] = (uint8_t)(s11 >> 9);
s[31] = (uint8_t)(s11 >> 17);
s[29] = (uint8_t) (s11 >> 1);
s[30] = (uint8_t) (s11 >> 9);
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;
@@ -5296,42 +5394,43 @@ static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
s11 += carry10;
s10 -= carry10 * (1 << 21);
s[0] = (uint8_t)(s0 >> 0);
s[1] = (uint8_t)(s0 >> 8);
s[2] = (uint8_t)((s0 >> 16) | (s1 << 5));
s[3] = (uint8_t)(s1 >> 3);
s[4] = (uint8_t)(s1 >> 11);
s[5] = (uint8_t)((s1 >> 19) | (s2 << 2));
s[6] = (uint8_t)(s2 >> 6);
s[7] = (uint8_t)((s2 >> 14) | (s3 << 7));
s[8] = (uint8_t)(s3 >> 1);
s[9] = (uint8_t)(s3 >> 9);
s[ 0] = (uint8_t) (s0 >> 0);
s[ 1] = (uint8_t) (s0 >> 8);
s[ 2] = (uint8_t)((s0 >> 16) | (s1 << 5));
s[ 3] = (uint8_t) (s1 >> 3);
s[ 4] = (uint8_t) (s1 >> 11);
s[ 5] = (uint8_t)((s1 >> 19) | (s2 << 2));
s[ 6] = (uint8_t) (s2 >> 6);
s[ 7] = (uint8_t)((s2 >> 14) | (s3 << 7));
s[ 8] = (uint8_t) (s3 >> 1);
s[ 9] = (uint8_t) (s3 >> 9);
s[10] = (uint8_t)((s3 >> 17) | (s4 << 4));
s[11] = (uint8_t)(s4 >> 4);
s[12] = (uint8_t)(s4 >> 12);
s[11] = (uint8_t) (s4 >> 4);
s[12] = (uint8_t) (s4 >> 12);
s[13] = (uint8_t)((s4 >> 20) | (s5 << 1));
s[14] = (uint8_t)(s5 >> 7);
s[14] = (uint8_t) (s5 >> 7);
s[15] = (uint8_t)((s5 >> 15) | (s6 << 6));
s[16] = (uint8_t)(s6 >> 2);
s[17] = (uint8_t)(s6 >> 10);
s[16] = (uint8_t) (s6 >> 2);
s[17] = (uint8_t) (s6 >> 10);
s[18] = (uint8_t)((s6 >> 18) | (s7 << 3));
s[19] = (uint8_t)(s7 >> 5);
s[20] = (uint8_t)(s7 >> 13);
s[21] = (uint8_t)(s8 >> 0);
s[22] = (uint8_t)(s8 >> 8);
s[19] = (uint8_t) (s7 >> 5);
s[20] = (uint8_t) (s7 >> 13);
s[21] = (uint8_t) (s8 >> 0);
s[22] = (uint8_t) (s8 >> 8);
s[23] = (uint8_t)((s8 >> 16) | (s9 << 5));
s[24] = (uint8_t)(s9 >> 3);
s[25] = (uint8_t)(s9 >> 11);
s[24] = (uint8_t) (s9 >> 3);
s[25] = (uint8_t) (s9 >> 11);
s[26] = (uint8_t)((s9 >> 19) | (s10 << 2));
s[27] = (uint8_t)(s10 >> 6);
s[27] = (uint8_t) (s10 >> 6);
s[28] = (uint8_t)((s10 >> 14) | (s11 << 7));
s[29] = (uint8_t)(s11 >> 1);
s[30] = (uint8_t)(s11 >> 9);
s[31] = (uint8_t)(s11 >> 17);
s[29] = (uint8_t) (s11 >> 1);
s[30] = (uint8_t) (s11 >> 9);
s[31] = (uint8_t) (s11 >> 17);
}
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);
+28 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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) {
+2
View File
@@ -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
+1 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
+1 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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]=..
+25
View File
@@ -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 */
+349
View File
@@ -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 */
+14 -5
View File
@@ -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" */
+4 -1
View File
@@ -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
+4 -1
View File
@@ -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
+9 -1
View File
@@ -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
View File
@@ -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.
+1 -1
View File
@@ -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.
+43
View File
@@ -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.
+1 -1
View File
@@ -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>.
+17
View File
@@ -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
+4 -4
View File
@@ -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,
+3
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
+1 -1
View File
@@ -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 -1
View File
@@ -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
+147
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
+1 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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