Latest update
This commit is contained in:
@@ -9,6 +9,19 @@
|
||||
|
||||
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
|
||||
|
||||
*) Added newline escaping functionality to a filename when using openssl dgst.
|
||||
This output format is to replicate the output format found in the '*sum'
|
||||
checksum programs. This aims to preserve backward compatibility.
|
||||
[Matt Eaton, Richard Levitte, and Paul Dale]
|
||||
|
||||
*) Removed the heartbeat message in DTLS feature, as it has very
|
||||
little usage and doesn't seem to fulfill a valuable purpose.
|
||||
[Richard Levitte]
|
||||
|
||||
*) Changed the output of 'openssl {digestname} < file' to display the
|
||||
digest name in its output.
|
||||
[Richard Levitte]
|
||||
|
||||
*) Added a new generic trace API which provides support for enabling
|
||||
instrumentation through trace output. This feature is mainly intended
|
||||
as an aid for developers and is disabled by default. To utilize it,
|
||||
@@ -31,6 +44,12 @@
|
||||
'enable-buildtest-c++'.
|
||||
[Richard Levitte]
|
||||
|
||||
*) Add Single Step KDF (EVP_KDF_SS) to EVP_KDF.
|
||||
[Shane Lontis]
|
||||
|
||||
*) Add KMAC to EVP_MAC.
|
||||
[Shane Lontis]
|
||||
|
||||
*) Added property based algorithm implementation selection framework to
|
||||
the core.
|
||||
[Paul Dale]
|
||||
|
||||
@@ -241,6 +241,8 @@ my %targets=(
|
||||
aes_asm_src => "aes_core.c aes_cbc.c aes-ia64.s",
|
||||
sha1_asm_src => "sha1-ia64.s sha256-ia64.s sha512-ia64.s",
|
||||
modes_asm_src => "ghash-ia64.s",
|
||||
chacha_asm_src => "chacha-ia64.S",
|
||||
poly1305_asm_src=> "asm/poly1305-ia64.S",
|
||||
perlasm_scheme => "void"
|
||||
},
|
||||
sparcv9_asm => {
|
||||
|
||||
@@ -846,9 +846,15 @@ EOF
|
||||
}
|
||||
|
||||
sub src2obj {
|
||||
my $asmext = platform->asmext();
|
||||
my %args = @_;
|
||||
my @srcs = map { (my $x = $_) =~ s/\.s$/.asm/; $x } ( @{$args{srcs}} );
|
||||
my @srcs =
|
||||
map { my $x = $_;
|
||||
(platform->isasm($x) && grep { $x eq $_ } @generated)
|
||||
? platform->asm($x) : $x }
|
||||
( @{$args{srcs}} );
|
||||
my $obj = platform->obj($args{obj});
|
||||
my $dep = platform->dep($args{obj});
|
||||
my $deps = join(", -\n\t\t", @srcs, @{$args{deps}});
|
||||
|
||||
# Because VMS C isn't very good at combining a /INCLUDE path with
|
||||
@@ -860,26 +866,14 @@ EOF
|
||||
my $forward = dirname($args{srcs}->[0]);
|
||||
my $backward = abs2rel(rel2abs("."), rel2abs($forward));
|
||||
my $objd = abs2rel(rel2abs(dirname($obj)), rel2abs($forward));
|
||||
my $objn = basename($obj, platform->objext());
|
||||
my $objn = basename($obj);
|
||||
my $depd = abs2rel(rel2abs(dirname($dep)), rel2abs($forward));
|
||||
my $depn = basename($dep);
|
||||
my $srcs =
|
||||
join(", ", map { abs2rel(rel2abs($_), rel2abs($forward)) } @srcs);
|
||||
my $before = $unified_info{before}->{$obj} || "\@ !";
|
||||
my $after = $unified_info{after}->{$obj} || "\@ !";
|
||||
|
||||
if ($srcs[0] =~ /\.asm$/) {
|
||||
my $asflags = { shlib => ' $(LIB_ASFLAGS)',
|
||||
lib => ' $(LIB_ASFLAGS)',
|
||||
dso => ' $(DSO_ASFLAGS)',
|
||||
bin => ' $(BIN_ASFLAGS)' } -> {$args{intent}};
|
||||
return <<"EOF";
|
||||
$obj : $deps
|
||||
${before}
|
||||
SET DEFAULT $forward
|
||||
\$(AS) $asflags \$(ASOUTFLAG)${objd}${objn}.OBJ $srcs
|
||||
SET DEFAULT $backward
|
||||
EOF
|
||||
}
|
||||
|
||||
my $cflags;
|
||||
if ($args{attrs}->{noinst}) {
|
||||
$cflags = { shlib => '$(NO_INST_LIB_CFLAGS)',
|
||||
@@ -914,37 +908,37 @@ EOF
|
||||
my $incs_on = join("\n\t\@ ", @{$incs_cmds[0]}) || '!';
|
||||
my $incs_off = join("\n\t\@ ", @{$incs_cmds[1]}) || '!';
|
||||
|
||||
if ($srcs[0] =~ /\.asm$/) {
|
||||
if ($srcs[0] =~ /\Q${asmext}\E$/) {
|
||||
return <<"EOF";
|
||||
$obj.OBJ : $deps
|
||||
$obj : $deps
|
||||
${before}
|
||||
SET DEFAULT $forward
|
||||
\$(AS) $asflags \$(ASOUTFLAG)${objd}${objn}.OBJ $srcs
|
||||
\$(AS) $asflags \$(ASOUTFLAG)${objd}${objn} $srcs
|
||||
SET DEFAULT $backward
|
||||
${after}
|
||||
- PURGE $obj.OBJ
|
||||
- PURGE $obj
|
||||
EOF
|
||||
} elsif ($srcs[0] =~ /.S$/) {
|
||||
return <<"EOF";
|
||||
$obj.OBJ : $deps
|
||||
$obj : $deps
|
||||
${before}
|
||||
SET DEFAULT $forward
|
||||
\@ $incs_on
|
||||
\@ extradefines = "$defs"
|
||||
PIPE \$(CPP) ${cflags} $srcs | -
|
||||
\$(PERL) -ne "/^#(\\s*line)?\\s*[0-9]+\\s+""/ or print" -
|
||||
> ${objd}${objn}.asm
|
||||
> ${objd}${objn}-asm
|
||||
\@ DELETE/SYMBOL/LOCAL extradefines
|
||||
\@ $incs_off
|
||||
SET DEFAULT $backward
|
||||
${after}
|
||||
\$(AS) $asflags \$(ASOUTFLAG)$obj.OBJ $obj.asm
|
||||
- PURGE $obj.OBJ
|
||||
\$(AS) $asflags \$(ASOUTFLAG)$obj $obj-asm
|
||||
- PURGE $obj
|
||||
EOF
|
||||
}
|
||||
|
||||
my $depbuild = $disabled{makedepend} ? ""
|
||||
: " /MMS=(FILE=${objd}${objn}.D,TARGET=$obj)";
|
||||
: " /MMS=(FILE=${depd}${depn},TARGET=$obj)";
|
||||
|
||||
return <<"EOF";
|
||||
$obj : $deps
|
||||
@@ -952,7 +946,7 @@ $obj : $deps
|
||||
SET DEFAULT $forward
|
||||
\@ $incs_on
|
||||
\@ extradefines = "$defs"
|
||||
\$(CC) ${cflags}${depbuild} /OBJECT=${objd}${objn}.OBJ /REPOSITORY=$backward $srcs
|
||||
\$(CC) ${cflags}${depbuild} /OBJECT=${objd}${objn} /REPOSITORY=$backward $srcs
|
||||
\@ DELETE/SYMBOL/LOCAL extradefines
|
||||
\@ $incs_off
|
||||
SET DEFAULT $backward
|
||||
|
||||
@@ -601,8 +601,13 @@ EOF
|
||||
}
|
||||
|
||||
sub src2obj {
|
||||
my $asmext = platform->asmext();
|
||||
my %args = @_;
|
||||
my @srcs = map { (my $x = $_) =~ s/\.s$/.asm/; $x } ( @{$args{srcs}} );
|
||||
my @srcs =
|
||||
map { my $x = $_;
|
||||
(platform->isasm($x) && grep { $x eq $_ } @generated)
|
||||
? platform->asm($x) : $x }
|
||||
( @{$args{srcs}} );
|
||||
my $srcs = '"'.join('" "', @srcs).'"';
|
||||
my $deps = '"'.join('" "', @srcs, @{$args{deps}}).'"';
|
||||
my $incs = join("", map { ' /I "'.$_.'"' } @{$args{incs}});
|
||||
@@ -630,7 +635,7 @@ EOF
|
||||
}
|
||||
my $obj = platform->obj($args{obj});
|
||||
my $dep = platform->dep($args{obj});
|
||||
if ($srcs[0] =~ /\.asm$/) {
|
||||
if ($srcs[0] =~ /\Q${asmext}\E$/) {
|
||||
return <<"EOF";
|
||||
$obj: $deps
|
||||
\$(AS) $asflags \$(ASOUTFLAG)\$\@ $srcs
|
||||
|
||||
@@ -375,7 +375,6 @@ my @disablables = (
|
||||
"fuzz-libfuzzer",
|
||||
"fuzz-afl",
|
||||
"gost",
|
||||
"heartbeats",
|
||||
"idea",
|
||||
"makedepend",
|
||||
"md2",
|
||||
@@ -456,7 +455,6 @@ our %disabled = ( # "what" => "comment"
|
||||
"external-tests" => "default",
|
||||
"fuzz-libfuzzer" => "default",
|
||||
"fuzz-afl" => "default",
|
||||
"heartbeats" => "default",
|
||||
"md2" => "default",
|
||||
"msan" => "default",
|
||||
"rc5" => "default",
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
3.0.0
|
||||
o Added EVP_MAC, an EVP layer MAC API, and a generic EVP_PKEY to EVP_MAC
|
||||
bridge.
|
||||
o Removed the heartbeat message in DTLS feature.
|
||||
|
||||
Major changes between OpenSSL 1.1.1 and OpenSSL 1.1.1a [20 Nov 2018]
|
||||
|
||||
|
||||
+8
-3
@@ -1623,8 +1623,10 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
|
||||
if (n == NULL)
|
||||
return NULL;
|
||||
work = OPENSSL_strdup(cp);
|
||||
if (work == NULL)
|
||||
if (work == NULL) {
|
||||
BIO_printf(bio_err, "%s: Error copying name input\n", opt_getprog());
|
||||
goto err;
|
||||
}
|
||||
|
||||
while (*cp) {
|
||||
char *bp = work;
|
||||
@@ -1639,7 +1641,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
|
||||
*bp++ = *cp++;
|
||||
if (*cp == '\0') {
|
||||
BIO_printf(bio_err,
|
||||
"%s: Hit end of string before finding the equals.\n",
|
||||
"%s: Hit end of string before finding the '='\n",
|
||||
opt_getprog());
|
||||
goto err;
|
||||
}
|
||||
@@ -1681,9 +1683,12 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
|
||||
}
|
||||
if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
|
||||
valstr, strlen((char *)valstr),
|
||||
-1, ismulti ? -1 : 0))
|
||||
-1, ismulti ? -1 : 0)) {
|
||||
BIO_printf(bio_err, "%s: Error adding name attribute \"/%s=%s\"\n",
|
||||
opt_getprog(), typestr ,valstr);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
OPENSSL_free(work);
|
||||
return n;
|
||||
|
||||
+52
-5
@@ -86,6 +86,7 @@ int dgst_main(int argc, char **argv)
|
||||
const EVP_MD *md = NULL, *m;
|
||||
const char *outfile = NULL, *keyfile = NULL, *prog = NULL;
|
||||
const char *sigfile = NULL;
|
||||
const char *md_name = NULL;
|
||||
OPTION_CHOICE o;
|
||||
int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0;
|
||||
int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0;
|
||||
@@ -365,13 +366,15 @@ int dgst_main(int argc, char **argv)
|
||||
BIO_get_md_ctx(bmd, &tctx);
|
||||
md = EVP_MD_CTX_md(tctx);
|
||||
}
|
||||
if (md != NULL)
|
||||
md_name = EVP_MD_name(md);
|
||||
|
||||
if (argc == 0) {
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
|
||||
siglen, NULL, NULL, "stdin");
|
||||
siglen, NULL, md_name, "stdin");
|
||||
} else {
|
||||
const char *md_name = NULL, *sig_name = NULL;
|
||||
const char *sig_name = NULL;
|
||||
if (!out_bin) {
|
||||
if (sigkey != NULL) {
|
||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||
@@ -380,8 +383,6 @@ int dgst_main(int argc, char **argv)
|
||||
EVP_PKEY_asn1_get0_info(NULL, NULL,
|
||||
NULL, NULL, &sig_name, ameth);
|
||||
}
|
||||
if (md != NULL)
|
||||
md_name = EVP_MD_name(md);
|
||||
}
|
||||
ret = 0;
|
||||
for (i = 0; i < argc; i++) {
|
||||
@@ -413,13 +414,52 @@ int dgst_main(int argc, char **argv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The newline_escape_filename function performs newline escaping for any
|
||||
* filename that contains a newline. This function also takes a pointer
|
||||
* to backslash. The backslash pointer is a flag to indicating whether a newline
|
||||
* is present in the filename. If a newline is present, the backslash flag is
|
||||
* set and the output format will contain a backslash at the beginning of the
|
||||
* digest output. This output format is to replicate the output format found
|
||||
* in the '*sum' checksum programs. This aims to preserve backward
|
||||
* compatibility.
|
||||
*/
|
||||
static const char *newline_escape_filename(const char *file, int * backslash)
|
||||
{
|
||||
size_t i, e = 0, length = strlen(file), newline_count = 0, mem_len = 0;
|
||||
char *file_cpy = NULL;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
if (file[i] == '\n')
|
||||
newline_count++;
|
||||
|
||||
mem_len = length + newline_count + 1;
|
||||
file_cpy = app_malloc(mem_len, file);
|
||||
i = 0;
|
||||
|
||||
while(e < length) {
|
||||
const char c = file[e];
|
||||
if (c == '\n') {
|
||||
file_cpy[i++] = '\\';
|
||||
file_cpy[i++] = 'n';
|
||||
*backslash = 1;
|
||||
} else {
|
||||
file_cpy[i++] = c;
|
||||
}
|
||||
e++;
|
||||
}
|
||||
file_cpy[i] = '\0';
|
||||
return (const char*)file_cpy;
|
||||
}
|
||||
|
||||
|
||||
int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
|
||||
EVP_PKEY *key, unsigned char *sigin, int siglen,
|
||||
const char *sig_name, const char *md_name,
|
||||
const char *file)
|
||||
{
|
||||
size_t len;
|
||||
int i;
|
||||
int i, backslash = 0;
|
||||
|
||||
for (;;) {
|
||||
i = BIO_read(bp, (char *)buf, BUFSIZE);
|
||||
@@ -467,9 +507,16 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
|
||||
if (binout) {
|
||||
BIO_write(out, buf, len);
|
||||
} else if (sep == 2) {
|
||||
file = newline_escape_filename(file, &backslash);
|
||||
|
||||
if (backslash == 1)
|
||||
BIO_puts(out, "\\");
|
||||
|
||||
for (i = 0; i < (int)len; i++)
|
||||
BIO_printf(out, "%02x", buf[i]);
|
||||
|
||||
BIO_printf(out, " *%s\n", file);
|
||||
OPENSSL_free((char *)file);
|
||||
} else {
|
||||
if (sig_name != NULL) {
|
||||
BIO_puts(out, sig_name);
|
||||
|
||||
+1
-2
@@ -76,8 +76,7 @@ int mac_main(int argc, char **argv)
|
||||
buf = app_malloc(BUFSIZE, "I/O buffer");
|
||||
while ((o = opt_next()) != OPT_EOF) {
|
||||
switch (o) {
|
||||
case OPT_EOF:
|
||||
case OPT_ERR:
|
||||
default:
|
||||
opthelp:
|
||||
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
|
||||
goto err;
|
||||
|
||||
+8
-3
@@ -641,8 +641,10 @@ redo_accept:
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (req != NULL && add_nonce)
|
||||
OCSP_request_add1_nonce(req, NULL, -1);
|
||||
if (req != NULL && add_nonce) {
|
||||
if (!OCSP_request_add1_nonce(req, NULL, -1))
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (signfile != NULL) {
|
||||
if (keyfile == NULL)
|
||||
@@ -1245,7 +1247,10 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
OCSP_basic_sign_ctx(bs, rcert, mctx, rother, flags);
|
||||
if (!OCSP_basic_sign_ctx(bs, rcert, mctx, rother, flags)) {
|
||||
*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, bs);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (badsig) {
|
||||
const ASN1_OCTET_STRING *sig = OCSP_resp_get0_signature(bs);
|
||||
|
||||
+41
-22
@@ -118,6 +118,8 @@ static char *make_config_name(void)
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
#ifndef OPENSSL_NO_TRACE
|
||||
typedef struct tracedata_st {
|
||||
BIO *bio;
|
||||
unsigned int ingroup:1;
|
||||
@@ -183,6 +185,33 @@ static void cleanup_trace(void)
|
||||
sk_tracedata_pop_free(trace_data_stack, tracedata_free);
|
||||
}
|
||||
|
||||
static void setup_trace_category(int category)
|
||||
{
|
||||
BIO *channel;
|
||||
tracedata *trace_data;
|
||||
|
||||
if (OSSL_trace_enabled(category))
|
||||
return;
|
||||
|
||||
channel = BIO_push(BIO_new(apps_bf_prefix()),
|
||||
dup_bio_err(FORMAT_TEXT));
|
||||
trace_data = OPENSSL_zalloc(sizeof(*trace_data));
|
||||
|
||||
if (trace_data == NULL
|
||||
|| (trace_data->bio = channel) == NULL
|
||||
|| OSSL_trace_set_callback(category, internal_trace_cb,
|
||||
trace_data) == 0
|
||||
|| sk_tracedata_push(trace_data_stack, trace_data) == 0) {
|
||||
|
||||
fprintf(stderr,
|
||||
"warning: unable to setup trace callback for category '%s'.\n",
|
||||
OSSL_trace_get_category_name(category));
|
||||
|
||||
OSSL_trace_set_callback(category, NULL, NULL);
|
||||
BIO_free_all(channel);
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_trace(const char *str)
|
||||
{
|
||||
char *val;
|
||||
@@ -197,26 +226,15 @@ static void setup_trace(const char *str)
|
||||
for (valp = val; (item = strtok(valp, ",")) != NULL; valp = NULL) {
|
||||
int category = OSSL_trace_get_category_num(item);
|
||||
|
||||
if (category >= 0) {
|
||||
BIO *channel = BIO_push(BIO_new(apps_bf_prefix()),
|
||||
dup_bio_err(FORMAT_TEXT));
|
||||
tracedata *trace_data = OPENSSL_zalloc(sizeof(*trace_data));
|
||||
|
||||
if (trace_data == NULL
|
||||
|| (trace_data->bio = channel) == NULL
|
||||
|| OSSL_trace_set_callback(category, internal_trace_cb,
|
||||
trace_data) == 0
|
||||
|| sk_tracedata_push(trace_data_stack, trace_data) == 0) {
|
||||
OSSL_trace_set_callback(category, NULL, NULL);
|
||||
BIO_free_all(channel);
|
||||
fprintf(stderr,
|
||||
"warning: unable to setup trace callback for category '%s'.\n",
|
||||
item);
|
||||
}
|
||||
if (category == OSSL_TRACE_CATEGORY_ALL) {
|
||||
while (++category < OSSL_TRACE_CATEGORY_NUM)
|
||||
setup_trace_category(category);
|
||||
break;
|
||||
} else if (category > 0) {
|
||||
setup_trace_category(category);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"warning: unknown trace category: '%s'.\n",
|
||||
item);
|
||||
"warning: unknown trace category: '%s'.\n", item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,6 +242,7 @@ static void setup_trace(const char *str)
|
||||
OPENSSL_free(val);
|
||||
atexit(cleanup_trace);
|
||||
}
|
||||
#endif /* OPENSSL_NO_TRACE */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -260,7 +279,9 @@ int main(int argc, char *argv[])
|
||||
*/
|
||||
atexit(destroy_prefix_method);
|
||||
|
||||
#ifndef OPENSSL_NO_TRACE
|
||||
setup_trace(getenv("OPENSSL_TRACE"));
|
||||
#endif
|
||||
|
||||
p = getenv("OPENSSL_DEBUG_MEMORY");
|
||||
if (p != NULL && strcmp(p, "on") == 0)
|
||||
@@ -715,8 +736,9 @@ static void list_type(FUNC_TYPE ft, int one)
|
||||
{
|
||||
FUNCTION *fp;
|
||||
int i = 0;
|
||||
DISPLAY_COLUMNS dc = {0};
|
||||
DISPLAY_COLUMNS dc;
|
||||
|
||||
memset(&dc, 0, sizeof(dc));
|
||||
if (!one)
|
||||
calculate_columns(&dc);
|
||||
|
||||
@@ -922,9 +944,6 @@ static void list_disabled(void)
|
||||
#ifdef OPENSSL_NO_GOST
|
||||
BIO_puts(bio_out, "GOST\n");
|
||||
#endif
|
||||
#ifdef OPENSSL_NO_HEARTBEATS
|
||||
BIO_puts(bio_out, "HEARTBEATS\n");
|
||||
#endif
|
||||
#ifdef OPENSSL_NO_IDEA
|
||||
BIO_puts(bio_out, "IDEA\n");
|
||||
#endif
|
||||
|
||||
+2
-7
@@ -13,9 +13,7 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/evp.h>
|
||||
#ifndef OPENSSL_NO_POSIX_IO
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define KEY_NONE 0
|
||||
#define KEY_PRIVKEY 1
|
||||
@@ -348,15 +346,12 @@ int pkeyutl_main(int argc, char **argv)
|
||||
|
||||
if (pkey_op != EVP_PKEY_OP_DERIVE) {
|
||||
in = bio_open_default(infile, 'r', FORMAT_BINARY);
|
||||
#ifndef OPENSSL_NO_POSIX_IO
|
||||
if (infile != NULL)
|
||||
{
|
||||
if (infile != NULL) {
|
||||
struct stat st;
|
||||
|
||||
if (stat(infile, &st) == 0 && st.st_size <= INT_MAX)
|
||||
filesize = (int)st.st_size;
|
||||
}
|
||||
#endif
|
||||
if (in == NULL)
|
||||
goto end;
|
||||
}
|
||||
|
||||
+81
-42
@@ -600,22 +600,6 @@ void msg_cb(int write_p, int version, int content_type, const void *buf,
|
||||
case 23:
|
||||
str_content_type = ", ApplicationData";
|
||||
break;
|
||||
#ifndef OPENSSL_NO_HEARTBEATS
|
||||
case 24:
|
||||
str_details1 = ", Heartbeat";
|
||||
|
||||
if (len > 0) {
|
||||
switch (bp[0]) {
|
||||
case 1:
|
||||
str_details1 = ", HeartbeatRequest";
|
||||
break;
|
||||
case 2:
|
||||
str_details1 = ", HeartbeatResponse";
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,7 +640,6 @@ static STRINT_PAIR tlsext_types[] = {
|
||||
{"SRP", TLSEXT_TYPE_srp},
|
||||
{"signature algorithms", TLSEXT_TYPE_signature_algorithms},
|
||||
{"use SRTP", TLSEXT_TYPE_use_srtp},
|
||||
{"heartbeat", TLSEXT_TYPE_heartbeat},
|
||||
{"session ticket", TLSEXT_TYPE_session_ticket},
|
||||
{"renegotiation info", TLSEXT_TYPE_renegotiate},
|
||||
{"signed certificate timestamps", TLSEXT_TYPE_signed_certificate_timestamp},
|
||||
@@ -683,6 +666,53 @@ static STRINT_PAIR tlsext_types[] = {
|
||||
{NULL}
|
||||
};
|
||||
|
||||
/* from rfc8446 4.2.3. + gost (https://tools.ietf.org/id/draft-smyshlyaev-tls12-gost-suites-04.html) */
|
||||
static STRINT_PAIR signature_tls13_scheme_list[] = {
|
||||
{"rsa_pkcs1_sha1", 0x0201 /* TLSEXT_SIGALG_rsa_pkcs1_sha1 */},
|
||||
{"ecdsa_sha1", 0x0203 /* TLSEXT_SIGALG_ecdsa_sha1 */},
|
||||
/* {"rsa_pkcs1_sha224", 0x0301 TLSEXT_SIGALG_rsa_pkcs1_sha224}, not in rfc8446 */
|
||||
/* {"ecdsa_sha224", 0x0303 TLSEXT_SIGALG_ecdsa_sha224} not in rfc8446 */
|
||||
{"rsa_pkcs1_sha256", 0x0401 /* TLSEXT_SIGALG_rsa_pkcs1_sha256 */},
|
||||
{"ecdsa_secp256r1_sha256", 0x0403 /* TLSEXT_SIGALG_ecdsa_secp256r1_sha256 */},
|
||||
{"rsa_pkcs1_sha384", 0x0501 /* TLSEXT_SIGALG_rsa_pkcs1_sha384 */},
|
||||
{"ecdsa_secp384r1_sha384", 0x0503 /* TLSEXT_SIGALG_ecdsa_secp384r1_sha384 */},
|
||||
{"rsa_pkcs1_sha512", 0x0601 /* TLSEXT_SIGALG_rsa_pkcs1_sha512 */},
|
||||
{"ecdsa_secp521r1_sha512", 0x0603 /* TLSEXT_SIGALG_ecdsa_secp521r1_sha512 */},
|
||||
{"rsa_pss_rsae_sha256", 0x0804 /* TLSEXT_SIGALG_rsa_pss_rsae_sha256 */},
|
||||
{"rsa_pss_rsae_sha384", 0x0805 /* TLSEXT_SIGALG_rsa_pss_rsae_sha384 */},
|
||||
{"rsa_pss_rsae_sha512", 0x0806 /* TLSEXT_SIGALG_rsa_pss_rsae_sha512 */},
|
||||
{"ed25519", 0x0807 /* TLSEXT_SIGALG_ed25519 */},
|
||||
{"ed448", 0x0808 /* TLSEXT_SIGALG_ed448 */},
|
||||
{"rsa_pss_pss_sha256", 0x0809 /* TLSEXT_SIGALG_rsa_pss_pss_sha256 */},
|
||||
{"rsa_pss_pss_sha384", 0x080a /* TLSEXT_SIGALG_rsa_pss_pss_sha384 */},
|
||||
{"rsa_pss_pss_sha512", 0x080b /* TLSEXT_SIGALG_rsa_pss_pss_sha512 */},
|
||||
{"gostr34102001", 0xeded /* TLSEXT_SIGALG_gostr34102001_gostr3411 */},
|
||||
{"gostr34102012_256", 0xeeee /* TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256 */},
|
||||
{"gostr34102012_512", 0xefef /* TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512 */},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
/* from rfc5246 7.4.1.4.1. */
|
||||
static STRINT_PAIR signature_tls12_alg_list[] = {
|
||||
{"anonymous", TLSEXT_signature_anonymous /* 0 */},
|
||||
{"RSA", TLSEXT_signature_rsa /* 1 */},
|
||||
{"DSA", TLSEXT_signature_dsa /* 2 */},
|
||||
{"ECDSA", TLSEXT_signature_ecdsa /* 3 */},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
/* from rfc5246 7.4.1.4.1. */
|
||||
static STRINT_PAIR signature_tls12_hash_list[] = {
|
||||
{"none", TLSEXT_hash_none /* 0 */},
|
||||
{"MD5", TLSEXT_hash_md5 /* 1 */},
|
||||
{"SHA1", TLSEXT_hash_sha1 /* 2 */},
|
||||
{"SHA224", TLSEXT_hash_sha224 /* 3 */},
|
||||
{"SHA256", TLSEXT_hash_sha256 /* 4 */},
|
||||
{"SHA384", TLSEXT_hash_sha384 /* 5 */},
|
||||
{"SHA512", TLSEXT_hash_sha512 /* 6 */},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
void tlsext_cb(SSL *s, int client_server, int type,
|
||||
const unsigned char *data, int len, void *arg)
|
||||
{
|
||||
@@ -1282,9 +1312,9 @@ static STRINT_PAIR callback_types[] = {
|
||||
{"Supported Curve", SSL_SECOP_CURVE_SUPPORTED},
|
||||
{"Shared Curve", SSL_SECOP_CURVE_SHARED},
|
||||
{"Check Curve", SSL_SECOP_CURVE_CHECK},
|
||||
{"Supported Signature Algorithm digest", SSL_SECOP_SIGALG_SUPPORTED},
|
||||
{"Shared Signature Algorithm digest", SSL_SECOP_SIGALG_SHARED},
|
||||
{"Check Signature Algorithm digest", SSL_SECOP_SIGALG_CHECK},
|
||||
{"Supported Signature Algorithm", SSL_SECOP_SIGALG_SUPPORTED},
|
||||
{"Shared Signature Algorithm", SSL_SECOP_SIGALG_SHARED},
|
||||
{"Check Signature Algorithm", SSL_SECOP_SIGALG_CHECK},
|
||||
{"Signature Algorithm mask", SSL_SECOP_SIGALG_MASK},
|
||||
{"Certificate chain EE key", SSL_SECOP_EE_KEY},
|
||||
{"Certificate chain CA key", SSL_SECOP_CA_KEY},
|
||||
@@ -1304,29 +1334,37 @@ static int security_callback_debug(const SSL *s, const SSL_CTX *ctx,
|
||||
security_debug_ex *sdb = ex;
|
||||
int rv, show_bits = 1, cert_md = 0;
|
||||
const char *nm;
|
||||
int show_nm;
|
||||
rv = sdb->old_cb(s, ctx, op, bits, nid, other, ex);
|
||||
if (rv == 1 && sdb->verbose < 2)
|
||||
return 1;
|
||||
BIO_puts(sdb->out, "Security callback: ");
|
||||
|
||||
nm = lookup(op, callback_types, NULL);
|
||||
show_nm = nm != NULL;
|
||||
switch (op) {
|
||||
case SSL_SECOP_TICKET:
|
||||
case SSL_SECOP_COMPRESSION:
|
||||
show_bits = 0;
|
||||
nm = NULL;
|
||||
show_nm = 0;
|
||||
break;
|
||||
case SSL_SECOP_VERSION:
|
||||
BIO_printf(sdb->out, "Version=%s", lookup(nid, ssl_versions, "???"));
|
||||
show_bits = 0;
|
||||
nm = NULL;
|
||||
show_nm = 0;
|
||||
break;
|
||||
case SSL_SECOP_CA_MD:
|
||||
case SSL_SECOP_PEER_CA_MD:
|
||||
cert_md = 1;
|
||||
break;
|
||||
case SSL_SECOP_SIGALG_SUPPORTED:
|
||||
case SSL_SECOP_SIGALG_SHARED:
|
||||
case SSL_SECOP_SIGALG_CHECK:
|
||||
case SSL_SECOP_SIGALG_MASK:
|
||||
show_nm = 0;
|
||||
break;
|
||||
}
|
||||
if (nm != NULL)
|
||||
if (show_nm)
|
||||
BIO_printf(sdb->out, "%s=", nm);
|
||||
|
||||
switch (op & SSL_SECOP_OTHER_TYPE) {
|
||||
@@ -1373,27 +1411,28 @@ static int security_callback_debug(const SSL *s, const SSL_CTX *ctx,
|
||||
{
|
||||
const unsigned char *salg = other;
|
||||
const char *sname = NULL;
|
||||
switch (salg[1]) {
|
||||
case TLSEXT_signature_anonymous:
|
||||
sname = "anonymous";
|
||||
break;
|
||||
case TLSEXT_signature_rsa:
|
||||
sname = "RSA";
|
||||
break;
|
||||
case TLSEXT_signature_dsa:
|
||||
sname = "DSA";
|
||||
break;
|
||||
case TLSEXT_signature_ecdsa:
|
||||
sname = "ECDSA";
|
||||
break;
|
||||
}
|
||||
int raw_sig_code = (salg[0] << 8) + salg[1]; /* always big endian (msb, lsb) */
|
||||
/* raw_sig_code: signature_scheme from tls1.3, or signature_and_hash from tls1.2 */
|
||||
|
||||
BIO_puts(sdb->out, OBJ_nid2sn(nid));
|
||||
if (sname)
|
||||
BIO_printf(sdb->out, ", algorithm=%s", sname);
|
||||
if (nm != NULL)
|
||||
BIO_printf(sdb->out, "%s", nm);
|
||||
else
|
||||
BIO_printf(sdb->out, ", algid=%d", salg[1]);
|
||||
break;
|
||||
BIO_printf(sdb->out, "s_cb.c:security_callback_debug op=0x%x", op);
|
||||
|
||||
sname = lookup(raw_sig_code, signature_tls13_scheme_list, NULL);
|
||||
if (sname != NULL) {
|
||||
BIO_printf(sdb->out, " scheme=%s", sname);
|
||||
} else {
|
||||
int alg_code = salg[1];
|
||||
int hash_code = salg[0];
|
||||
const char *alg_str = lookup(alg_code, signature_tls12_alg_list, NULL);
|
||||
const char *hash_str = lookup(hash_code, signature_tls12_hash_list, NULL);
|
||||
|
||||
if (alg_str != NULL && hash_str != NULL)
|
||||
BIO_printf(sdb->out, " digest=%s, algorithm=%s", hash_str, alg_str);
|
||||
else
|
||||
BIO_printf(sdb->out, " scheme=unknown(0x%04x)", raw_sig_code);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-9
@@ -3111,15 +3111,7 @@ int s_client_main(int argc, char **argv)
|
||||
cbuf[0] == 'K' ? SSL_KEY_UPDATE_REQUESTED
|
||||
: SSL_KEY_UPDATE_NOT_REQUESTED);
|
||||
cbuf_len = 0;
|
||||
}
|
||||
#ifndef OPENSSL_NO_HEARTBEATS
|
||||
else if ((!c_ign_eof) && (cbuf[0] == 'B' && cmdletters)) {
|
||||
BIO_printf(bio_err, "HEARTBEATING\n");
|
||||
SSL_heartbeat(con);
|
||||
cbuf_len = 0;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
} else {
|
||||
cbuf_len = i;
|
||||
cbuf_off = 0;
|
||||
#ifdef CHARSET_EBCDIC
|
||||
|
||||
@@ -2507,14 +2507,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context)
|
||||
*/
|
||||
goto err;
|
||||
}
|
||||
#ifndef OPENSSL_NO_HEARTBEATS
|
||||
if ((buf[0] == 'B') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
|
||||
BIO_printf(bio_err, "HEARTBEATING\n");
|
||||
SSL_heartbeat(con);
|
||||
i = 0;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if ((buf[0] == 'r') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
|
||||
SSL_renegotiate(con);
|
||||
i = SSL_do_handshake(con);
|
||||
|
||||
+39
-24
@@ -492,30 +492,35 @@ static const OPT_PAIR rsa_choices[] = {
|
||||
static double rsa_results[RSA_NUM][2]; /* 2 ops: sign then verify */
|
||||
#endif /* OPENSSL_NO_RSA */
|
||||
|
||||
#define R_EC_P160 0
|
||||
#define R_EC_P192 1
|
||||
#define R_EC_P224 2
|
||||
#define R_EC_P256 3
|
||||
#define R_EC_P384 4
|
||||
#define R_EC_P521 5
|
||||
#define R_EC_K163 6
|
||||
#define R_EC_K233 7
|
||||
#define R_EC_K283 8
|
||||
#define R_EC_K409 9
|
||||
#define R_EC_K571 10
|
||||
#define R_EC_B163 11
|
||||
#define R_EC_B233 12
|
||||
#define R_EC_B283 13
|
||||
#define R_EC_B409 14
|
||||
#define R_EC_B571 15
|
||||
#define R_EC_BRP256R1 16
|
||||
#define R_EC_BRP256T1 17
|
||||
#define R_EC_BRP384R1 18
|
||||
#define R_EC_BRP384T1 19
|
||||
#define R_EC_BRP512R1 20
|
||||
#define R_EC_BRP512T1 21
|
||||
#define R_EC_X25519 22
|
||||
#define R_EC_X448 23
|
||||
enum {
|
||||
R_EC_P160,
|
||||
R_EC_P192,
|
||||
R_EC_P224,
|
||||
R_EC_P256,
|
||||
R_EC_P384,
|
||||
R_EC_P521,
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
R_EC_K163,
|
||||
R_EC_K233,
|
||||
R_EC_K283,
|
||||
R_EC_K409,
|
||||
R_EC_K571,
|
||||
R_EC_B163,
|
||||
R_EC_B233,
|
||||
R_EC_B283,
|
||||
R_EC_B409,
|
||||
R_EC_B571,
|
||||
#endif
|
||||
R_EC_BRP256R1,
|
||||
R_EC_BRP256T1,
|
||||
R_EC_BRP384R1,
|
||||
R_EC_BRP384T1,
|
||||
R_EC_BRP512R1,
|
||||
R_EC_BRP512T1,
|
||||
R_EC_X25519,
|
||||
R_EC_X448
|
||||
};
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
static OPT_PAIR ecdsa_choices[] = {
|
||||
{"ecdsap160", R_EC_P160},
|
||||
@@ -524,6 +529,7 @@ static OPT_PAIR ecdsa_choices[] = {
|
||||
{"ecdsap256", R_EC_P256},
|
||||
{"ecdsap384", R_EC_P384},
|
||||
{"ecdsap521", R_EC_P521},
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
{"ecdsak163", R_EC_K163},
|
||||
{"ecdsak233", R_EC_K233},
|
||||
{"ecdsak283", R_EC_K283},
|
||||
@@ -534,6 +540,7 @@ static OPT_PAIR ecdsa_choices[] = {
|
||||
{"ecdsab283", R_EC_B283},
|
||||
{"ecdsab409", R_EC_B409},
|
||||
{"ecdsab571", R_EC_B571},
|
||||
# endif
|
||||
{"ecdsabrp256r1", R_EC_BRP256R1},
|
||||
{"ecdsabrp256t1", R_EC_BRP256T1},
|
||||
{"ecdsabrp384r1", R_EC_BRP384R1},
|
||||
@@ -552,6 +559,7 @@ static const OPT_PAIR ecdh_choices[] = {
|
||||
{"ecdhp256", R_EC_P256},
|
||||
{"ecdhp384", R_EC_P384},
|
||||
{"ecdhp521", R_EC_P521},
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
{"ecdhk163", R_EC_K163},
|
||||
{"ecdhk233", R_EC_K233},
|
||||
{"ecdhk283", R_EC_K283},
|
||||
@@ -562,6 +570,7 @@ static const OPT_PAIR ecdh_choices[] = {
|
||||
{"ecdhb283", R_EC_B283},
|
||||
{"ecdhb409", R_EC_B409},
|
||||
{"ecdhb571", R_EC_B571},
|
||||
# endif
|
||||
{"ecdhbrp256r1", R_EC_BRP256R1},
|
||||
{"ecdhbrp256t1", R_EC_BRP256T1},
|
||||
{"ecdhbrp384r1", R_EC_BRP384R1},
|
||||
@@ -1524,6 +1533,7 @@ int speed_main(int argc, char **argv)
|
||||
{"nistp256", NID_X9_62_prime256v1, 256},
|
||||
{"nistp384", NID_secp384r1, 384},
|
||||
{"nistp521", NID_secp521r1, 521},
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
/* Binary Curves */
|
||||
{"nistk163", NID_sect163k1, 163},
|
||||
{"nistk233", NID_sect233k1, 233},
|
||||
@@ -1535,6 +1545,7 @@ int speed_main(int argc, char **argv)
|
||||
{"nistb283", NID_sect283r1, 283},
|
||||
{"nistb409", NID_sect409r1, 409},
|
||||
{"nistb571", NID_sect571r1, 571},
|
||||
# endif
|
||||
{"brainpoolP256r1", NID_brainpoolP256r1, 256},
|
||||
{"brainpoolP256t1", NID_brainpoolP256t1, 256},
|
||||
{"brainpoolP384r1", NID_brainpoolP384r1, 384},
|
||||
@@ -2063,6 +2074,7 @@ int speed_main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
}
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
ecdsa_c[R_EC_K163][0] = count / 1000;
|
||||
ecdsa_c[R_EC_K163][1] = count / 1000 / 2;
|
||||
for (i = R_EC_K233; i <= R_EC_K571; i++) {
|
||||
@@ -2091,6 +2103,7 @@ int speed_main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
ecdh_c[R_EC_P160][0] = count / 1000;
|
||||
for (i = R_EC_P192; i <= R_EC_P521; i++) {
|
||||
@@ -2103,6 +2116,7 @@ int speed_main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
}
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
ecdh_c[R_EC_K163][0] = count / 1000;
|
||||
for (i = R_EC_K233; i <= R_EC_K571; i++) {
|
||||
ecdh_c[i][0] = ecdh_c[i - 1][0] / 2;
|
||||
@@ -2125,6 +2139,7 @@ int speed_main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif
|
||||
/* repeated code good to factorize */
|
||||
ecdh_c[R_EC_BRP256R1][0] = count / 1000;
|
||||
for (i = R_EC_BRP384R1; i <= R_EC_BRP512R1; i += 2) {
|
||||
|
||||
@@ -80,6 +80,7 @@ int verify_main(int argc, char **argv)
|
||||
OPTION_CHOICE o;
|
||||
unsigned char *sm2_id = NULL;
|
||||
size_t sm2_idlen = 0;
|
||||
int sm2_free = 0;
|
||||
|
||||
if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
|
||||
goto end;
|
||||
@@ -174,6 +175,7 @@ int verify_main(int argc, char **argv)
|
||||
break;
|
||||
case OPT_SM2HEXID:
|
||||
/* try to parse the input as hex string first */
|
||||
sm2_free = 1;
|
||||
sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen);
|
||||
if (sm2_id == NULL) {
|
||||
BIO_printf(bio_err, "Invalid hex string input\n");
|
||||
@@ -216,6 +218,8 @@ int verify_main(int argc, char **argv)
|
||||
}
|
||||
|
||||
end:
|
||||
if (sm2_free)
|
||||
OPENSSL_free(sm2_id);
|
||||
X509_VERIFY_PARAM_free(vpm);
|
||||
X509_STORE_free(store);
|
||||
sk_X509_pop_free(untrusted, X509_free);
|
||||
|
||||
+56
-16
@@ -49,8 +49,8 @@ typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM,
|
||||
OPT_CAKEYFORM, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE,
|
||||
OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_SIGNKEY, OPT_CA,
|
||||
OPT_CAKEY, OPT_CASERIAL, OPT_SET_SERIAL, OPT_FORCE_PUBKEY,
|
||||
OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_SIGNKEY, OPT_CA, OPT_CAKEY,
|
||||
OPT_CASERIAL, OPT_SET_SERIAL, OPT_NEW, OPT_FORCE_PUBKEY, OPT_SUBJ,
|
||||
OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_NAMEOPT,
|
||||
OPT_C, OPT_EMAIL, OPT_OCSP_URI, OPT_SERIAL, OPT_NEXT_SERIAL,
|
||||
OPT_MODULUS, OPT_PUBKEY, OPT_X509TOREQ, OPT_TEXT, OPT_HASH,
|
||||
@@ -132,7 +132,9 @@ const OPTIONS x509_options[] = {
|
||||
{"CAform", OPT_CAFORM, 'F', "CA format - default PEM"},
|
||||
{"CAkeyform", OPT_CAKEYFORM, 'f', "CA key format - default PEM"},
|
||||
{"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
|
||||
{"new", OPT_NEW, '-', "Generate a certificate from scratch"},
|
||||
{"force_pubkey", OPT_FORCE_PUBKEY, '<', "Force the key to put inside certificate"},
|
||||
{"subj", OPT_SUBJ, 's', "Set or override certificate subject (and issuer)"},
|
||||
{"next_serial", OPT_NEXT_SERIAL, '-', "Increment current certificate serial number"},
|
||||
{"clrreject", OPT_CLRREJECT, '-',
|
||||
"Clears all the prohibited or rejected uses of the certificate"},
|
||||
@@ -158,6 +160,11 @@ int x509_main(int argc, char **argv)
|
||||
BIO *out = NULL;
|
||||
CONF *extconf = NULL;
|
||||
EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL;
|
||||
int newcert = 0;
|
||||
char *subj = NULL;
|
||||
X509_NAME *fsubj = NULL;
|
||||
const unsigned long chtype = MBSTRING_ASC;
|
||||
const int multirdn = 0;
|
||||
STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
|
||||
STACK_OF(OPENSSL_STRING) *sigopts = NULL;
|
||||
X509 *x = NULL, *xca = NULL;
|
||||
@@ -281,9 +288,15 @@ int x509_main(int argc, char **argv)
|
||||
if ((sno = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL)
|
||||
goto opthelp;
|
||||
break;
|
||||
case OPT_NEW:
|
||||
newcert = 1;
|
||||
break;
|
||||
case OPT_FORCE_PUBKEY:
|
||||
fkeyfile = opt_arg();
|
||||
break;
|
||||
case OPT_SUBJ:
|
||||
subj = opt_arg();
|
||||
break;
|
||||
case OPT_ADDTRUST:
|
||||
if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) {
|
||||
BIO_printf(bio_err,
|
||||
@@ -477,18 +490,38 @@ int x509_main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (newcert && infile != NULL) {
|
||||
BIO_printf(bio_err, "The -in option must not be used since -new is set\n");
|
||||
goto end;
|
||||
}
|
||||
if (newcert && fkeyfile == NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"The -new option requires a public key to be set using -force_pubkey\n");
|
||||
goto end;
|
||||
}
|
||||
if (fkeyfile != NULL) {
|
||||
fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key");
|
||||
if (fkey == NULL)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) {
|
||||
if (newcert && subj == NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"The -new option requires a subject to be set using -subj\n");
|
||||
goto end;
|
||||
}
|
||||
if (subj != NULL && (fsubj = parse_name(subj, chtype, multirdn)) == NULL)
|
||||
goto end;
|
||||
|
||||
if (CAkeyfile == NULL && CA_flag && CAformat == FORMAT_PEM) {
|
||||
CAkeyfile = CAfile;
|
||||
} else if ((CA_flag) && (CAkeyfile == NULL)) {
|
||||
} else if (CA_flag && CAkeyfile == NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"need to specify a CAkey if using the CA command\n");
|
||||
goto end;
|
||||
} else if (!CA_flag && CAkeyfile != NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"ignoring -CAkey option since no -CA option is given\n");
|
||||
}
|
||||
|
||||
if (extfile != NULL) {
|
||||
@@ -516,10 +549,6 @@ int x509_main(int argc, char **argv)
|
||||
EVP_PKEY *pkey;
|
||||
BIO *in;
|
||||
|
||||
if (!sign_flag && !CA_flag) {
|
||||
BIO_printf(bio_err, "We need a private key to sign with\n");
|
||||
goto end;
|
||||
}
|
||||
in = bio_open_default(infile, 'r', informat);
|
||||
if (in == NULL)
|
||||
goto end;
|
||||
@@ -537,21 +566,30 @@ int x509_main(int argc, char **argv)
|
||||
}
|
||||
i = X509_REQ_verify(req, pkey);
|
||||
if (i < 0) {
|
||||
BIO_printf(bio_err, "Signature verification error\n");
|
||||
BIO_printf(bio_err, "Request self-signature verification error\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (i == 0) {
|
||||
BIO_printf(bio_err,
|
||||
"Signature did not match the certificate request\n");
|
||||
"Request self-signature did not match the certificate request\n");
|
||||
goto end;
|
||||
} else {
|
||||
BIO_printf(bio_err, "Signature ok\n");
|
||||
BIO_printf(bio_err, "Request self-signature ok\n");
|
||||
}
|
||||
|
||||
print_name(bio_err, "subject=", X509_REQ_get_subject_name(req),
|
||||
get_nameopt());
|
||||
}
|
||||
|
||||
if (reqfile || newcert) {
|
||||
X509_NAME *n;
|
||||
|
||||
if (!sign_flag && CAkeyfile == NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"We need a private key to sign with, use -signkey or -CAkey or -CA <file> with private key\n");
|
||||
goto end;
|
||||
}
|
||||
if ((x = X509_new()) == NULL)
|
||||
goto end;
|
||||
|
||||
@@ -567,9 +605,8 @@ int x509_main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!X509_set_issuer_name(x, X509_REQ_get_subject_name(req)))
|
||||
goto end;
|
||||
if (!X509_set_subject_name(x, X509_REQ_get_subject_name(req)))
|
||||
n = req == NULL ? fsubj : X509_REQ_get_subject_name(req);
|
||||
if (!X509_set_issuer_name(x, n) || !X509_set_subject_name(x, n))
|
||||
goto end;
|
||||
if (!set_cert_times(x, NULL, NULL, days))
|
||||
goto end;
|
||||
@@ -582,6 +619,8 @@ int x509_main(int argc, char **argv)
|
||||
goto end;
|
||||
if (fkey != NULL && !X509_set_pubkey(x, fkey))
|
||||
goto end;
|
||||
if (fsubj != NULL && !X509_set_subject_name(x, fsubj))
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (CA_flag) {
|
||||
@@ -654,7 +693,7 @@ int x509_main(int argc, char **argv)
|
||||
i2a_ASN1_INTEGER(out, ser);
|
||||
ASN1_INTEGER_free(ser);
|
||||
BIO_puts(out, "\n");
|
||||
} else if ((email == i) || (ocsp_uri == i)) {
|
||||
} else if (email == i || ocsp_uri == i) {
|
||||
int j;
|
||||
STACK_OF(OPENSSL_STRING) *emlst;
|
||||
if (email == i)
|
||||
@@ -788,7 +827,7 @@ int x509_main(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* should be in the library */
|
||||
else if ((sign_flag == i) && (x509req == 0)) {
|
||||
else if (sign_flag == i && x509req == 0) {
|
||||
BIO_printf(bio_err, "Getting Private key\n");
|
||||
if (Upkey == NULL) {
|
||||
Upkey = load_key(keyfile, keyformat, 0,
|
||||
@@ -890,6 +929,7 @@ int x509_main(int argc, char **argv)
|
||||
NCONF_free(extconf);
|
||||
BIO_free_all(out);
|
||||
X509_STORE_free(ctx);
|
||||
X509_NAME_free(fsubj);
|
||||
X509_REQ_free(req);
|
||||
X509_free(x);
|
||||
X509_free(xca);
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Note that some of these directories are filtered in Configure. Look for
|
||||
# %skipdir there for further explanations.
|
||||
SUBDIRS=crypto ssl apps test util tools fuzz engines
|
||||
SUBDIRS=crypto ssl apps test util tools fuzz engines providers
|
||||
|
||||
LIBS=libcrypto libssl
|
||||
INCLUDE[libcrypto]=. crypto/include include
|
||||
|
||||
@@ -1829,7 +1829,7 @@ Lctr32_enc8x_three:
|
||||
stvx_u $out1,$x10,$out
|
||||
stvx_u $out2,$x20,$out
|
||||
addi $out,$out,0x30
|
||||
b Lcbc_dec8x_done
|
||||
b Lctr32_enc8x_done
|
||||
|
||||
.align 5
|
||||
Lctr32_enc8x_two:
|
||||
@@ -1841,7 +1841,7 @@ Lctr32_enc8x_two:
|
||||
stvx_u $out0,$x00,$out
|
||||
stvx_u $out1,$x10,$out
|
||||
addi $out,$out,0x20
|
||||
b Lcbc_dec8x_done
|
||||
b Lctr32_enc8x_done
|
||||
|
||||
.align 5
|
||||
Lctr32_enc8x_one:
|
||||
|
||||
@@ -22,6 +22,12 @@ NON_EMPTY_TRANSLATION_UNIT
|
||||
|
||||
# ifndef OPENSSL_NO_RC4
|
||||
|
||||
# define ASN1_BROKEN_SEQUENCE(tname) \
|
||||
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
|
||||
ASN1_SEQUENCE(tname)
|
||||
# define static_ASN1_BROKEN_SEQUENCE_END(stname) \
|
||||
static_ASN1_SEQUENCE_END_ref(stname, stname)
|
||||
|
||||
typedef struct netscape_pkey_st {
|
||||
int32_t version;
|
||||
X509_ALGOR *algor;
|
||||
|
||||
@@ -88,7 +88,7 @@ if ($flavour =~ /64|n32/i) {
|
||||
$SZREG=4;
|
||||
$REG_S="sw";
|
||||
$REG_L="lw";
|
||||
$code=".set mips2\n";
|
||||
$code="#if !(defined (__mips_isa_rev) && (__mips_isa_rev >= 6))\n.set mips2\n#endif\n";
|
||||
}
|
||||
|
||||
# Below is N32/64 register layout used in the original module.
|
||||
|
||||
@@ -258,6 +258,7 @@ $data=<<EOF;
|
||||
# .text section
|
||||
|
||||
.machine "any"
|
||||
.text
|
||||
|
||||
#
|
||||
# NOTE: The following label name should be changed to
|
||||
|
||||
@@ -184,6 +184,8 @@ void BN_CTX_start(BN_CTX *ctx)
|
||||
|
||||
void BN_CTX_end(BN_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
CTXDBG("ENTER BN_CTX_end()", ctx);
|
||||
if (ctx->err_stack)
|
||||
ctx->err_stack--;
|
||||
|
||||
@@ -338,6 +338,8 @@ void BN_swap(BIGNUM *a, BIGNUM *b)
|
||||
|
||||
void BN_clear(BIGNUM *a)
|
||||
{
|
||||
if (a == NULL)
|
||||
return;
|
||||
bn_check_top(a);
|
||||
if (a->d != NULL)
|
||||
OPENSSL_cleanse(a->d, sizeof(*a->d) * a->dmax);
|
||||
|
||||
@@ -170,7 +170,6 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
|
||||
found = 1;
|
||||
err:
|
||||
OPENSSL_free(mods);
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
bn_check_top(ret);
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 x509v3 conf \
|
||||
|
||||
LIBS=../libcrypto
|
||||
# The Core
|
||||
SOURCE[../libcrypto]=provider_core.c core_fetch.c
|
||||
SOURCE[../libcrypto]=provider_core.c provider_predefined.c core_fetch.c
|
||||
|
||||
# Central utilities
|
||||
SOURCE[../libcrypto]=\
|
||||
|
||||
@@ -0,0 +1,292 @@
|
||||
#!/usr/bin/env perl
|
||||
#
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov, @dot-asm, initially for use with OpenSSL.
|
||||
# ====================================================================
|
||||
#
|
||||
# ChaCha20 for Itanium.
|
||||
#
|
||||
# March 2019
|
||||
#
|
||||
# Itanium 9xxx, which has pair of shifters, manages to process one byte
|
||||
# in 9.3 cycles. This aligns perfectly with theoretical estimate.
|
||||
# On the other hand, pre-9000 CPU has single shifter and each extr/dep
|
||||
# pairs below takes additional cycle. Then final input->xor->output
|
||||
# pass runs slower than expected... Overall result is 15.6 cpb, two
|
||||
# cycles more than theoretical estimate.
|
||||
|
||||
$output = pop;
|
||||
open STDOUT, ">$output" if $output;
|
||||
|
||||
my @k = map("r$_",(16..31));
|
||||
my @x = map("r$_",(38..53));
|
||||
my @y = map("r$_",(8..11));
|
||||
my @z = map("r$_",(15,35..37));
|
||||
my ($out,$inp,$len,$key,$counter) = map("r$_",(32..36));
|
||||
|
||||
$code.=<<___;
|
||||
#if defined(_HPUX_SOURCE)
|
||||
# if !defined(_LP64)
|
||||
# define ADDP addp4
|
||||
# else
|
||||
# define ADDP add
|
||||
# endif
|
||||
#else
|
||||
# define ADDP add
|
||||
#endif
|
||||
|
||||
.text
|
||||
|
||||
.global ChaCha20_ctr32#
|
||||
.proc ChaCha20_ctr32#
|
||||
.align 32
|
||||
ChaCha20_ctr32:
|
||||
.prologue
|
||||
.save ar.pfs,r2
|
||||
{ .mmi; alloc r2=ar.pfs,5,17,0,0
|
||||
ADDP @k[11]=4,$key
|
||||
.save ar.lc,r3
|
||||
mov r3=ar.lc }
|
||||
{ .mmi; ADDP $key=0,$key
|
||||
ADDP $counter=0,$counter
|
||||
.save pr,r14
|
||||
mov r14=pr };;
|
||||
|
||||
.body
|
||||
{ .mlx; ld4 @k[4]=[$key],8
|
||||
movl @k[0]=0x61707865 }
|
||||
{ .mlx; ld4 @k[5]=[@k[11]],8
|
||||
movl @k[1]=0x3320646e };;
|
||||
{ .mlx; ld4 @k[6]=[$key],8
|
||||
movl @k[2]=0x79622d32 }
|
||||
{ .mlx; ld4 @k[7]=[@k[11]],8
|
||||
movl @k[3]=0x6b206574 };;
|
||||
{ .mmi; ld4 @k[8]=[$key],8
|
||||
ld4 @k[9]=[@k[11]],8
|
||||
add @k[15]=4,$counter };;
|
||||
{ .mmi; ld4 @k[10]=[$key]
|
||||
ld4 @k[11]=[@k[11]]
|
||||
mov @x[0]=@k[0] };;
|
||||
{ .mmi; ld4 @k[12]=[$counter],8
|
||||
ld4 @k[13]=[@k[15]],8
|
||||
mov @x[1]=@k[1] };;
|
||||
{ .mmi; ld4 @k[14]=[$counter]
|
||||
ld4 @k[15]=[@k[15]]
|
||||
mov @x[2]=@k[2] }
|
||||
{ .mmi; mov @x[3]=@k[3]
|
||||
mov @x[4]=@k[4]
|
||||
mov @x[5]=@k[5] };;
|
||||
{ .mmi; mov @x[6]=@k[6]
|
||||
mov @x[7]=@k[7]
|
||||
mov @x[8]=@k[8] }
|
||||
{ .mmi; mov @x[9]=@k[9]
|
||||
mov @x[10]=@k[10]
|
||||
mov @x[11]=@k[11] }
|
||||
{ .mmi; mov @x[12]=@k[12]
|
||||
mov @x[13]=@k[13]
|
||||
mov @x[14]=@k[14] };;
|
||||
|
||||
.Loop_outer:
|
||||
{ .mii; mov @x[15]=@k[15]
|
||||
mov ar.lc=9
|
||||
mov ar.ec=1 }
|
||||
{ .mmb; cmp.geu p6,p0=64,$len
|
||||
sub @z[1]=64,$len
|
||||
brp.loop.imp .Loop_top,.Loop_end-16 };;
|
||||
|
||||
.Loop_top:
|
||||
___
|
||||
sub ROUND {
|
||||
my ($a0,$b0,$c0,$d0)=@_;
|
||||
my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
|
||||
my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
|
||||
my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
|
||||
|
||||
$code.=<<___;
|
||||
{ .mmi; add @x[$a0]=@x[$a0],@x[$b0]
|
||||
add @x[$a1]=@x[$a1],@x[$b1]
|
||||
add @x[$a2]=@x[$a2],@x[$b2] };;
|
||||
{ .mmi; add @x[$a3]=@x[$a3],@x[$b3]
|
||||
xor @x[$d0]=@x[$d0],@x[$a0]
|
||||
xor @x[$d1]=@x[$d1],@x[$a1] };;
|
||||
{ .mmi; xor @x[$d2]=@x[$d2],@x[$a2]
|
||||
xor @x[$d3]=@x[$d3],@x[$a3]
|
||||
extr.u @y[0]=@x[$d0],16,16 };;
|
||||
{ .mii; extr.u @y[1]=@x[$d1],16,16
|
||||
dep @x[$d0]=@x[$d0],@y[0],16,16 };;
|
||||
{ .mii; add @x[$c0]=@x[$c0],@x[$d0]
|
||||
extr.u @y[2]=@x[$d2],16,16
|
||||
dep @x[$d1]=@x[$d1],@y[1],16,16 };;
|
||||
{ .mii; add @x[$c1]=@x[$c1],@x[$d1]
|
||||
xor @x[$b0]=@x[$b0],@x[$c0]
|
||||
extr.u @y[3]=@x[$d3],16,16 };;
|
||||
{ .mii; xor @x[$b1]=@x[$b1],@x[$c1]
|
||||
dep @x[$d2]=@x[$d2],@y[2],16,16
|
||||
dep @x[$d3]=@x[$d3],@y[3],16,16 };;
|
||||
{ .mmi; add @x[$c2]=@x[$c2],@x[$d2]
|
||||
add @x[$c3]=@x[$c3],@x[$d3]
|
||||
extr.u @y[0]=@x[$b0],20,12 };;
|
||||
{ .mmi; xor @x[$b2]=@x[$b2],@x[$c2]
|
||||
xor @x[$b3]=@x[$b3],@x[$c3]
|
||||
dep.z @x[$b0]=@x[$b0],12,20 };;
|
||||
{ .mii; or @x[$b0]=@x[$b0],@y[0]
|
||||
extr.u @y[1]=@x[$b1],20,12
|
||||
dep.z @x[$b1]=@x[$b1],12,20 };;
|
||||
{ .mii; add @x[$a0]=@x[$a0],@x[$b0]
|
||||
extr.u @y[2]=@x[$b2],20,12
|
||||
extr.u @y[3]=@x[$b3],20,12 }
|
||||
{ .mii; or @x[$b1]=@x[$b1],@y[1]
|
||||
dep.z @x[$b2]=@x[$b2],12,20
|
||||
dep.z @x[$b3]=@x[$b3],12,20 };;
|
||||
{ .mmi; or @x[$b2]=@x[$b2],@y[2]
|
||||
or @x[$b3]=@x[$b3],@y[3]
|
||||
add @x[$a1]=@x[$a1],@x[$b1] };;
|
||||
{ .mmi; add @x[$a2]=@x[$a2],@x[$b2]
|
||||
add @x[$a3]=@x[$a3],@x[$b3]
|
||||
xor @x[$d0]=@x[$d0],@x[$a0] };;
|
||||
{ .mii; xor @x[$d1]=@x[$d1],@x[$a1]
|
||||
extr.u @y[0]=@x[$d0],24,8
|
||||
dep.z @x[$d0]=@x[$d0],8,24 };;
|
||||
{ .mii; or @x[$d0]=@x[$d0],@y[0]
|
||||
extr.u @y[1]=@x[$d1],24,8
|
||||
dep.z @x[$d1]=@x[$d1],8,24 };;
|
||||
{ .mmi; or @x[$d1]=@x[$d1],@y[1]
|
||||
xor @x[$d2]=@x[$d2],@x[$a2]
|
||||
xor @x[$d3]=@x[$d3],@x[$a3] };;
|
||||
{ .mii; add @x[$c0]=@x[$c0],@x[$d0]
|
||||
extr.u @y[2]=@x[$d2],24,8
|
||||
dep.z @x[$d2]=@x[$d2],8,24 };;
|
||||
{ .mii; xor @x[$b0]=@x[$b0],@x[$c0]
|
||||
extr.u @y[3]=@x[$d3],24,8
|
||||
dep.z @x[$d3]=@x[$d3],8,24 };;
|
||||
{ .mmi; or @x[$d2]=@x[$d2],@y[2]
|
||||
or @x[$d3]=@x[$d3],@y[3]
|
||||
extr.u @y[0]=@x[$b0],25,7 };;
|
||||
{ .mmi; add @x[$c1]=@x[$c1],@x[$d1]
|
||||
add @x[$c2]=@x[$c2],@x[$d2]
|
||||
dep.z @x[$b0]=@x[$b0],7,25 };;
|
||||
{ .mmi; xor @x[$b1]=@x[$b1],@x[$c1]
|
||||
xor @x[$b2]=@x[$b2],@x[$c2]
|
||||
add @x[$c3]=@x[$c3],@x[$d3] };;
|
||||
{ .mii; xor @x[$b3]=@x[$b3],@x[$c3]
|
||||
extr.u @y[1]=@x[$b1],25,7
|
||||
dep.z @x[$b1]=@x[$b1],7,25 };;
|
||||
{ .mii; or @x[$b0]=@x[$b0],@y[0]
|
||||
extr.u @y[2]=@x[$b2],25,7
|
||||
dep.z @x[$b2]=@x[$b2],7,25 };;
|
||||
{ .mii; or @x[$b1]=@x[$b1],@y[1]
|
||||
extr.u @y[3]=@x[$b3],25,7
|
||||
dep.z @x[$b3]=@x[$b3],7,25 };;
|
||||
___
|
||||
$code.=<<___ if ($d0 == 12);
|
||||
{ .mmi; or @x[$b2]=@x[$b2],@y[2]
|
||||
or @x[$b3]=@x[$b3],@y[3]
|
||||
mov @z[0]=-1 };;
|
||||
___
|
||||
$code.=<<___ if ($d0 == 15);
|
||||
{ .mmb; or @x[$b2]=@x[$b2],@y[2]
|
||||
or @x[$b3]=@x[$b3],@y[3]
|
||||
br.ctop.sptk .Loop_top };;
|
||||
___
|
||||
}
|
||||
&ROUND(0, 4, 8, 12);
|
||||
&ROUND(0, 5, 10, 15);
|
||||
$code.=<<___;
|
||||
.Loop_end:
|
||||
|
||||
{ .mmi; add @x[0]=@x[0],@k[0]
|
||||
add @x[1]=@x[1],@k[1]
|
||||
(p6) shr.u @z[0]=@z[0],@z[1] }
|
||||
{ .mmb; add @x[2]=@x[2],@k[2]
|
||||
add @x[3]=@x[3],@k[3]
|
||||
clrrrb.pr };;
|
||||
{ .mmi; add @x[4]=@x[4],@k[4]
|
||||
add @x[5]=@x[5],@k[5]
|
||||
add @x[6]=@x[6],@k[6] }
|
||||
{ .mmi; add @x[7]=@x[7],@k[7]
|
||||
add @x[8]=@x[8],@k[8]
|
||||
add @x[9]=@x[9],@k[9] }
|
||||
{ .mmi; add @x[10]=@x[10],@k[10]
|
||||
add @x[11]=@x[11],@k[11]
|
||||
add @x[12]=@x[12],@k[12] }
|
||||
{ .mmi; add @x[13]=@x[13],@k[13]
|
||||
add @x[14]=@x[14],@k[14]
|
||||
add @x[15]=@x[15],@k[15] }
|
||||
{ .mmi; add @k[12]=1,@k[12] // next counter
|
||||
mov pr=@z[0],0x1ffff };;
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Each predicate bit corresponds to byte to be processed. Note
|
||||
// that p0 is wired to 1, but it works out, because there always
|
||||
// is at least one byte to process...
|
||||
{ .mmi; (p0) ld1 @z[0]=[$inp],1
|
||||
shr.u @y[1]=@x[0],8 };;
|
||||
{ .mmi; (p1) ld1 @z[1]=[$inp],1
|
||||
(p2) shr.u @y[2]=@x[0],16 };;
|
||||
{ .mmi; (p2) ld1 @z[2]=[$inp],1
|
||||
(p0) xor @z[0]=@z[0],@x[0]
|
||||
(p3) shr.u @y[3]=@x[0],24 };;
|
||||
___
|
||||
for(my $i0=0; $i0<60; $i0+=4) {
|
||||
my ($i1, $i2, $i3, $i4, $i5, $i6, $i7) = map($i0+$_,(1..7));
|
||||
my $k = $i0/4+1;
|
||||
|
||||
$code.=<<___;
|
||||
{ .mmi; (p$i3) ld1 @z[3]=[$inp],1
|
||||
(p$i0) st1 [$out]=@z[0],1
|
||||
(p$i1) xor @z[1]=@z[1],@y[1] };;
|
||||
{ .mmi; (p$i4) ld1 @z[0]=[$inp],1
|
||||
(p$i5) shr.u @y[1]=@x[$k],8 }
|
||||
{ .mmi; (p$i1) st1 [$out]=@z[1],1
|
||||
(p$i2) xor @z[2]=@z[2],@y[2]
|
||||
(p1) mov @x[$k-1]=@k[$k-1] };;
|
||||
{ .mfi; (p$i5) ld1 @z[1]=[$inp],1
|
||||
(p$i6) shr.u @y[2]=@x[$k],16 }
|
||||
{ .mfi; (p$i2) st1 [$out]=@z[2],1
|
||||
(p$i3) xor @z[3]=@z[3],@y[3] };;
|
||||
{ .mfi; (p$i6) ld1 @z[2]=[$inp],1
|
||||
(p$i7) shr.u @y[3]=@x[$k],24 }
|
||||
___
|
||||
$code.=<<___ if ($i0==0); # p1,p2 are available for reuse in first round
|
||||
{ .mmi; (p$i3) st1 [$out]=@z[3],1
|
||||
(p$i4) xor @z[0]=@z[0],@x[$k]
|
||||
cmp.ltu p1,p2=64,$len };;
|
||||
___
|
||||
$code.=<<___ if ($i0>0);
|
||||
{ .mfi; (p$i3) st1 [$out]=@z[3],1
|
||||
(p$i4) xor @z[0]=@z[0],@x[$k] };;
|
||||
___
|
||||
}
|
||||
$code.=<<___;
|
||||
{ .mmi; (p63) ld1 @z[3]=[$inp],1
|
||||
(p60) st1 [$out]=@z[0],1
|
||||
(p61) xor @z[1]=@z[1],@y[1] };;
|
||||
{ .mmi; (p61) st1 [$out]=@z[1],1
|
||||
(p62) xor @z[2]=@z[2],@y[2] };;
|
||||
{ .mmi; (p62) st1 [$out]=@z[2],1
|
||||
(p63) xor @z[3]=@z[3],@y[3]
|
||||
(p2) mov ar.lc=r3 };;
|
||||
{ .mib; (p63) st1 [$out]=@z[3],1
|
||||
(p1) add $len=-64,$len
|
||||
(p1) br.dptk.many .Loop_outer };;
|
||||
|
||||
{ .mmi; mov @k[4]=0 // wipe key material
|
||||
mov @k[5]=0
|
||||
mov @k[6]=0 }
|
||||
{ .mmi; mov @k[7]=0
|
||||
mov @k[8]=0
|
||||
mov @k[9]=0 }
|
||||
{ .mmi; mov @k[10]=0
|
||||
mov @k[11]=0
|
||||
mov @k[12]=0 }
|
||||
{ .mmi; mov @k[13]=0
|
||||
mov @k[14]=0
|
||||
mov @k[15]=0 }
|
||||
{ .mib; mov pr=r14,0x1ffff
|
||||
br.ret.sptk.many b0 };;
|
||||
.endp ChaCha20_ctr32#
|
||||
stringz "ChaCha20 for IA64, CRYPTOGAMS by \@dot-asm"
|
||||
___
|
||||
|
||||
print $code;
|
||||
close STDOUT;
|
||||
@@ -12,3 +12,4 @@ INCLUDE[chacha-armv8.o]=..
|
||||
INCLUDE[chacha-s390x.o]=..
|
||||
GENERATE[chacha-c64xplus.S]=asm/chacha-c64xplus.pl $(PERLASM_SCHEME)
|
||||
GENERATE[chacha-s390x.S]=asm/chacha-s390x.pl $(PERLASM_SCHEME)
|
||||
GENERATE[chacha-ia64.S]=asm/chacha-ia64.pl $(PERLASM_SCHEME)
|
||||
@@ -669,7 +669,7 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from)
|
||||
static BIO *process_include(char *include, OPENSSL_DIR_CTX **dirctx,
|
||||
char **dirpath)
|
||||
{
|
||||
struct stat st = { 0 };
|
||||
struct stat st;
|
||||
BIO *next;
|
||||
|
||||
if (stat(include, &st) < 0) {
|
||||
|
||||
@@ -35,6 +35,7 @@ void OPENSSL_config(const char *appname)
|
||||
memset(&settings, 0, sizeof(settings));
|
||||
if (appname != NULL)
|
||||
settings.appname = strdup(appname);
|
||||
settings.flags = DEFAULT_CONF_MFLAGS;
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, &settings);
|
||||
}
|
||||
#endif
|
||||
|
||||
+18
-10
@@ -39,25 +39,33 @@ static int ossl_method_construct_this(OSSL_PROVIDER *provider, void *cbdata)
|
||||
data->mcm_data)) == NULL)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Note regarding putting the method in stores:
|
||||
*
|
||||
* we don't need to care if it actually got in or not here.
|
||||
* If it didn't get in, it will simply not be available when
|
||||
* ossl_method_construct() tries to get it from the store.
|
||||
*
|
||||
* It is *expected* that the put function increments the refcnt
|
||||
* of the passed method.
|
||||
*/
|
||||
|
||||
if (data->force_store || !no_store) {
|
||||
/*
|
||||
* If we haven't been told not to store,
|
||||
* add to the global store
|
||||
*/
|
||||
if (!data->mcm->put(data->libctx, NULL,
|
||||
data->mcm->put(data->libctx, NULL,
|
||||
thismap->property_definition,
|
||||
method, data->mcm_data)) {
|
||||
data->mcm->destruct(method);
|
||||
continue;
|
||||
}
|
||||
method, data->mcm_data);
|
||||
}
|
||||
|
||||
if (!data->mcm->put(data->libctx, data->store,
|
||||
data->mcm->put(data->libctx, data->store,
|
||||
thismap->property_definition,
|
||||
method, data->mcm_data)) {
|
||||
data->mcm->destruct(method);
|
||||
continue;
|
||||
}
|
||||
method, data->mcm_data);
|
||||
|
||||
/* refcnt-- because we're dropping the reference */
|
||||
data->mcm->destruct(method, data->mcm_data);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -57,6 +57,11 @@ static const ERR_STRING_DATA CRYPTO_str_functs[] = {
|
||||
"pkey_poly1305_init"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PKEY_SIPHASH_INIT, 0),
|
||||
"pkey_siphash_init"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_ACTIVATE, 0),
|
||||
"provider_activate"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_NEW, 0), "provider_new"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_STORE_NEW, 0),
|
||||
"provider_store_new"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_SK_RESERVE, 0), "sk_reserve"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright Nokia 2007-2018
|
||||
* Copyright Siemens AG 2015-2018
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright Nokia 2007-2018
|
||||
* Copyright Siemens AG 2015-2018
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright Nokia 2007-2018
|
||||
* Copyright Siemens AG 2015-2018
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Copyright Nokia 2007-2018
|
||||
* Copyright Siemens AG 2015-2018
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <openssl/bn.h>
|
||||
#include "dh_locl.h"
|
||||
|
||||
# define DH_NUMBER_ITERATIONS_FOR_PRIME 64
|
||||
|
||||
/*-
|
||||
* Check that p and g are suitable enough
|
||||
*
|
||||
@@ -58,10 +60,8 @@ int DH_check_params(const DH *dh, int *ret)
|
||||
|
||||
ok = 1;
|
||||
err:
|
||||
if (ctx != NULL) {
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ int DH_check(const DH *dh, int *ret)
|
||||
if (!BN_is_one(t1))
|
||||
*ret |= DH_NOT_SUITABLE_GENERATOR;
|
||||
}
|
||||
r = BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL);
|
||||
r = BN_is_prime_ex(dh->q, DH_NUMBER_ITERATIONS_FOR_PRIME, ctx, NULL);
|
||||
if (r < 0)
|
||||
goto err;
|
||||
if (!r)
|
||||
@@ -155,7 +155,7 @@ int DH_check(const DH *dh, int *ret)
|
||||
} else
|
||||
*ret |= DH_UNABLE_TO_CHECK_GENERATOR;
|
||||
|
||||
r = BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL);
|
||||
r = BN_is_prime_ex(dh->p, DH_NUMBER_ITERATIONS_FOR_PRIME, ctx, NULL);
|
||||
if (r < 0)
|
||||
goto err;
|
||||
if (!r)
|
||||
@@ -163,7 +163,7 @@ int DH_check(const DH *dh, int *ret)
|
||||
else if (!dh->q) {
|
||||
if (!BN_rshift1(t1, dh->p))
|
||||
goto err;
|
||||
r = BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL);
|
||||
r = BN_is_prime_ex(t1, DH_NUMBER_ITERATIONS_FOR_PRIME, ctx, NULL);
|
||||
if (r < 0)
|
||||
goto err;
|
||||
if (!r)
|
||||
@@ -171,10 +171,8 @@ int DH_check(const DH *dh, int *ret)
|
||||
}
|
||||
ok = 1;
|
||||
err:
|
||||
if (ctx != NULL) {
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -225,9 +223,7 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
|
||||
|
||||
ok = 1;
|
||||
err:
|
||||
if (ctx != NULL) {
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
@@ -122,9 +122,7 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
|
||||
ok = 0;
|
||||
}
|
||||
|
||||
if (ctx != NULL) {
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
@@ -205,10 +205,8 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
|
||||
|
||||
ret = BN_bn2bin(tmp, key);
|
||||
err:
|
||||
if (ctx != NULL) {
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -458,6 +458,8 @@ static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
|
||||
DSA_SIG_free(dsa_sig);
|
||||
return rv;
|
||||
}
|
||||
if (BIO_puts(bp, "\n") <= 0)
|
||||
return 0;
|
||||
return X509_signature_dump(bp, sig, indent);
|
||||
}
|
||||
|
||||
|
||||
@@ -292,7 +292,6 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
|
||||
if (seed_out)
|
||||
memcpy(seed_out, seed, qsize);
|
||||
}
|
||||
if (ctx)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
BN_MONT_CTX_free(mont);
|
||||
@@ -607,7 +606,6 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
|
||||
OPENSSL_free(seed);
|
||||
if (seed_out != seed_tmp)
|
||||
OPENSSL_free(seed_tmp);
|
||||
if (ctx)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
BN_MONT_CTX_free(mont);
|
||||
|
||||
+107
-1
@@ -64,6 +64,7 @@ static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname);
|
||||
static char *win32_name_converter(DSO *dso, const char *filename);
|
||||
static char *win32_merger(DSO *dso, const char *filespec1,
|
||||
const char *filespec2);
|
||||
static int win32_pathbyaddr(void *addr, char *path, int sz);
|
||||
static void *win32_globallookup(const char *name);
|
||||
|
||||
static const char *openssl_strnchr(const char *string, int c, size_t len);
|
||||
@@ -78,7 +79,7 @@ static DSO_METHOD dso_meth_win32 = {
|
||||
win32_merger,
|
||||
NULL, /* init */
|
||||
NULL, /* finish */
|
||||
NULL, /* pathbyaddr */
|
||||
win32_pathbyaddr, /* pathbyaddr */
|
||||
win32_globallookup
|
||||
};
|
||||
|
||||
@@ -500,6 +501,111 @@ typedef HANDLE(WINAPI *CREATETOOLHELP32SNAPSHOT) (DWORD, DWORD);
|
||||
typedef BOOL(WINAPI *CLOSETOOLHELP32SNAPSHOT) (HANDLE);
|
||||
typedef BOOL(WINAPI *MODULE32) (HANDLE, MODULEENTRY32 *);
|
||||
|
||||
static int win32_pathbyaddr(void *addr, char *path, int sz)
|
||||
{
|
||||
HMODULE dll;
|
||||
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
|
||||
MODULEENTRY32 me32;
|
||||
CREATETOOLHELP32SNAPSHOT create_snap;
|
||||
CLOSETOOLHELP32SNAPSHOT close_snap;
|
||||
MODULE32 module_first, module_next;
|
||||
|
||||
if (addr == NULL) {
|
||||
union {
|
||||
int (*f) (void *, char *, int);
|
||||
void *p;
|
||||
} t = {
|
||||
win32_pathbyaddr
|
||||
};
|
||||
addr = t.p;
|
||||
}
|
||||
|
||||
dll = LoadLibrary(TEXT(DLLNAME));
|
||||
if (dll == NULL) {
|
||||
DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
create_snap = (CREATETOOLHELP32SNAPSHOT)
|
||||
GetProcAddress(dll, "CreateToolhelp32Snapshot");
|
||||
if (create_snap == NULL) {
|
||||
FreeLibrary(dll);
|
||||
DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED);
|
||||
return -1;
|
||||
}
|
||||
/* We take the rest for granted... */
|
||||
# ifdef _WIN32_WCE
|
||||
close_snap = (CLOSETOOLHELP32SNAPSHOT)
|
||||
GetProcAddress(dll, "CloseToolhelp32Snapshot");
|
||||
# else
|
||||
close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle;
|
||||
# endif
|
||||
module_first = (MODULE32) GetProcAddress(dll, "Module32First");
|
||||
module_next = (MODULE32) GetProcAddress(dll, "Module32Next");
|
||||
|
||||
/*
|
||||
* Take a snapshot of current process which includes
|
||||
* list of all involved modules.
|
||||
*/
|
||||
hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0);
|
||||
if (hModuleSnap == INVALID_HANDLE_VALUE) {
|
||||
FreeLibrary(dll);
|
||||
DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
me32.dwSize = sizeof(me32);
|
||||
|
||||
if (!(*module_first) (hModuleSnap, &me32)) {
|
||||
(*close_snap) (hModuleSnap);
|
||||
FreeLibrary(dll);
|
||||
DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Enumerate the modules to find one which includes me. */
|
||||
do {
|
||||
if ((uintptr_t) addr >= (uintptr_t) me32.modBaseAddr &&
|
||||
(uintptr_t) addr < (uintptr_t) (me32.modBaseAddr + me32.modBaseSize)) {
|
||||
(*close_snap) (hModuleSnap);
|
||||
FreeLibrary(dll);
|
||||
# ifdef _WIN32_WCE
|
||||
# if _WIN32_WCE >= 101
|
||||
return WideCharToMultiByte(CP_ACP, 0, me32.szExePath, -1,
|
||||
path, sz, NULL, NULL);
|
||||
# else
|
||||
{
|
||||
int i, len = (int)wcslen(me32.szExePath);
|
||||
if (sz <= 0)
|
||||
return len + 1;
|
||||
if (len >= sz)
|
||||
len = sz - 1;
|
||||
for (i = 0; i < len; i++)
|
||||
path[i] = (char)me32.szExePath[i];
|
||||
path[len++] = '\0';
|
||||
return len;
|
||||
}
|
||||
# endif
|
||||
# else
|
||||
{
|
||||
int len = (int)strlen(me32.szExePath);
|
||||
if (sz <= 0)
|
||||
return len + 1;
|
||||
if (len >= sz)
|
||||
len = sz - 1;
|
||||
memcpy(path, me32.szExePath, len);
|
||||
path[len++] = '\0';
|
||||
return len;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
} while ((*module_next) (hModuleSnap, &me32));
|
||||
|
||||
(*close_snap) (hModuleSnap);
|
||||
FreeLibrary(dll);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *win32_globallookup(const char *name)
|
||||
{
|
||||
HMODULE dll;
|
||||
|
||||
+5
-4
@@ -237,7 +237,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
point_conversion_form_t form;
|
||||
int y_bit;
|
||||
int y_bit, m;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
BIGNUM *x, *y, *yxi;
|
||||
size_t field_len, enc_len;
|
||||
@@ -270,7 +270,8 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
return EC_POINT_set_to_infinity(group, point);
|
||||
}
|
||||
|
||||
field_len = (EC_GROUP_get_degree(group) + 7) / 8;
|
||||
m = EC_GROUP_get_degree(group);
|
||||
field_len = (m + 7) / 8;
|
||||
enc_len =
|
||||
(form ==
|
||||
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
|
||||
@@ -295,7 +296,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
|
||||
if (!BN_bin2bn(buf + 1, field_len, x))
|
||||
goto err;
|
||||
if (BN_ucmp(x, group->field) >= 0) {
|
||||
if (BN_num_bits(x) > m) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
@@ -306,7 +307,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
} else {
|
||||
if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
|
||||
goto err;
|
||||
if (BN_ucmp(y, group->field) >= 0) {
|
||||
if (BN_num_bits(y) > m) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -204,7 +204,6 @@ int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group,
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
|
||||
@@ -1079,7 +1079,6 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r,
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
|
||||
+1
-2
@@ -378,7 +378,7 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
|
||||
|
||||
err:
|
||||
EC_POINT_free(p);
|
||||
EC_POINT_free(s);
|
||||
EC_POINT_clear_free(s);
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
@@ -948,7 +948,6 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
EC_ec_pre_comp_free(pre_comp);
|
||||
|
||||
@@ -112,8 +112,7 @@ int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_POINT_free(tmp);
|
||||
if (ctx)
|
||||
EC_POINT_clear_free(tmp);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
OPENSSL_free(buf);
|
||||
|
||||
@@ -676,7 +676,9 @@ static void felem_contract(felem out, const felem in)
|
||||
*/
|
||||
static void felem_neg(felem out, const felem in)
|
||||
{
|
||||
widefelem tmp = {0};
|
||||
widefelem tmp;
|
||||
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
felem_diff_128_64(tmp, in);
|
||||
felem_reduce(out, tmp);
|
||||
}
|
||||
|
||||
@@ -888,7 +888,6 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
|
||||
|
||||
@@ -307,7 +307,6 @@ int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
@@ -787,7 +786,6 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
|
||||
ret = 1;
|
||||
|
||||
end:
|
||||
if (ctx) /* otherwise we already called BN_CTX_end */
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
|
||||
+23
-26
@@ -525,8 +525,24 @@ static unsigned long get_error_values(int inc, int top, const char **file,
|
||||
return ERR_R_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
while (es->bottom != es->top) {
|
||||
if (es->err_flags[es->top] & ERR_FLAG_CLEAR) {
|
||||
err_clear(es, es->top);
|
||||
es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1;
|
||||
continue;
|
||||
}
|
||||
i = (es->bottom + 1) % ERR_NUM_ERRORS;
|
||||
if (es->err_flags[i] & ERR_FLAG_CLEAR) {
|
||||
es->bottom = i;
|
||||
err_clear(es, es->bottom);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (es->bottom == es->top)
|
||||
return 0;
|
||||
|
||||
if (top)
|
||||
i = es->top; /* last error */
|
||||
else
|
||||
@@ -915,25 +931,6 @@ 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;
|
||||
@@ -945,11 +942,11 @@ void err_clear_last_constant_time(int clear)
|
||||
|
||||
top = es->top;
|
||||
|
||||
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_line[top] |= 0 - clear;
|
||||
|
||||
es->top = (top + ERR_NUM_ERRORS - clear) % ERR_NUM_ERRORS;
|
||||
/*
|
||||
* Flag error as cleared but remove it elsewhere to avoid two errors
|
||||
* accessing the same error stack location, revealing timing information.
|
||||
*/
|
||||
clear = constant_time_select_int(constant_time_eq_int(clear, 0),
|
||||
0, ERR_FLAG_CLEAR);
|
||||
es->err_flags[top] |= clear;
|
||||
}
|
||||
+15
-3
@@ -396,6 +396,9 @@ CRYPTO_F_OSSL_PROVIDER_NEW:131:ossl_provider_new
|
||||
CRYPTO_F_PKEY_HMAC_INIT:123:pkey_hmac_init
|
||||
CRYPTO_F_PKEY_POLY1305_INIT:124:pkey_poly1305_init
|
||||
CRYPTO_F_PKEY_SIPHASH_INIT:125:pkey_siphash_init
|
||||
CRYPTO_F_PROVIDER_ACTIVATE:134:provider_activate
|
||||
CRYPTO_F_PROVIDER_NEW:135:provider_new
|
||||
CRYPTO_F_PROVIDER_STORE_NEW:136:provider_store_new
|
||||
CRYPTO_F_SK_RESERVE:129:sk_reserve
|
||||
CT_F_CTLOG_NEW:117:CTLOG_new
|
||||
CT_F_CTLOG_NEW_FROM_BASE64:118:CTLOG_new_from_base64
|
||||
@@ -778,7 +781,9 @@ EVP_F_EVP_CIPHER_PARAM_TO_ASN1:205:EVP_CIPHER_param_to_asn1
|
||||
EVP_F_EVP_DECRYPTFINAL_EX:101:EVP_DecryptFinal_ex
|
||||
EVP_F_EVP_DECRYPTUPDATE:166:EVP_DecryptUpdate
|
||||
EVP_F_EVP_DIGESTFINALXOF:174:EVP_DigestFinalXOF
|
||||
EVP_F_EVP_DIGESTFINAL_EX:230:EVP_DigestFinal_ex
|
||||
EVP_F_EVP_DIGESTINIT_EX:128:EVP_DigestInit_ex
|
||||
EVP_F_EVP_DIGESTUPDATE:231:EVP_DigestUpdate
|
||||
EVP_F_EVP_ENCRYPTDECRYPTUPDATE:219:evp_EncryptDecryptUpdate
|
||||
EVP_F_EVP_ENCRYPTFINAL_EX:127:EVP_EncryptFinal_ex
|
||||
EVP_F_EVP_ENCRYPTUPDATE:167:EVP_EncryptUpdate
|
||||
@@ -898,6 +903,11 @@ KDF_F_PKEY_TLS1_PRF_CTRL_STR:100:pkey_tls1_prf_ctrl_str
|
||||
KDF_F_PKEY_TLS1_PRF_DERIVE:101:pkey_tls1_prf_derive
|
||||
KDF_F_PKEY_TLS1_PRF_INIT:110:pkey_tls1_prf_init
|
||||
KDF_F_SCRYPT_SET_MEMBUF:129:scrypt_set_membuf
|
||||
KDF_F_SSKDF_CTRL_STR:134:sskdf_ctrl_str
|
||||
KDF_F_SSKDF_DERIVE:135:sskdf_derive
|
||||
KDF_F_SSKDF_MAC2CTRL:136:sskdf_mac2ctrl
|
||||
KDF_F_SSKDF_NEW:137:sskdf_new
|
||||
KDF_F_SSKDF_SIZE:138:sskdf_size
|
||||
KDF_F_TLS1_PRF_ALG:111:tls1_prf_alg
|
||||
OBJ_F_OBJ_ADD_OBJECT:105:OBJ_add_object
|
||||
OBJ_F_OBJ_ADD_SIGID:107:OBJ_add_sigid
|
||||
@@ -1215,7 +1225,6 @@ SSL_F_DO_DTLS1_WRITE:245:do_dtls1_write
|
||||
SSL_F_DO_SSL3_WRITE:104:do_ssl3_write
|
||||
SSL_F_DTLS1_BUFFER_RECORD:247:dtls1_buffer_record
|
||||
SSL_F_DTLS1_CHECK_TIMEOUT_NUM:318:dtls1_check_timeout_num
|
||||
SSL_F_DTLS1_HEARTBEAT:305:*
|
||||
SSL_F_DTLS1_HM_FRAGMENT_NEW:623:dtls1_hm_fragment_new
|
||||
SSL_F_DTLS1_PREPROCESS_FRAGMENT:288:dtls1_preprocess_fragment
|
||||
SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS:424:dtls1_process_buffered_records
|
||||
@@ -2348,6 +2357,7 @@ EVP_R_EXPECTING_A_DSA_KEY:129:expecting a dsa key
|
||||
EVP_R_EXPECTING_A_EC_KEY:142:expecting a ec key
|
||||
EVP_R_EXPECTING_A_POLY1305_KEY:164:expecting a poly1305 key
|
||||
EVP_R_EXPECTING_A_SIPHASH_KEY:175:expecting a siphash key
|
||||
EVP_R_FINAL_ERROR:188:final error
|
||||
EVP_R_FIPS_MODE_NOT_SUPPORTED:167:fips mode not supported
|
||||
EVP_R_GET_RAW_KEY_FAILED:182:get raw key failed
|
||||
EVP_R_ILLEGAL_SCRYPT_PARAMETERS:171:illegal scrypt parameters
|
||||
@@ -2366,6 +2376,7 @@ EVP_R_MEMORY_LIMIT_EXCEEDED:172:memory limit exceeded
|
||||
EVP_R_MESSAGE_DIGEST_IS_NULL:159:message digest is null
|
||||
EVP_R_METHOD_NOT_SUPPORTED:144:method not supported
|
||||
EVP_R_MISSING_PARAMETERS:103:missing parameters
|
||||
EVP_R_NOT_ABLE_TO_COPY_CTX:190:not able to copy ctx
|
||||
EVP_R_NOT_XOF_OR_INVALID_LENGTH:178:not XOF or invalid length
|
||||
EVP_R_NO_CIPHER_SET:131:no cipher set
|
||||
EVP_R_NO_DEFAULT_DIGEST:158:no default digest
|
||||
@@ -2399,9 +2410,11 @@ EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS:135:unsupported number of rounds
|
||||
EVP_R_UNSUPPORTED_PRF:125:unsupported prf
|
||||
EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM:118:unsupported private key algorithm
|
||||
EVP_R_UNSUPPORTED_SALT_TYPE:126:unsupported salt type
|
||||
EVP_R_UPDATE_ERROR:189:update error
|
||||
EVP_R_WRAP_MODE_NOT_ALLOWED:170:wrap mode not allowed
|
||||
EVP_R_WRONG_FINAL_BLOCK_LENGTH:109:wrong final block length
|
||||
KDF_R_INVALID_DIGEST:100:invalid digest
|
||||
KDF_R_INVALID_MAC_TYPE:116:invalid mac type
|
||||
KDF_R_MISSING_ITERATION_COUNT:109:missing iteration count
|
||||
KDF_R_MISSING_KEY:104:missing key
|
||||
KDF_R_MISSING_MESSAGE_DIGEST:105:missing message digest
|
||||
@@ -2414,6 +2427,7 @@ KDF_R_MISSING_SESSION_ID:113:missing session id
|
||||
KDF_R_MISSING_TYPE:114:missing type
|
||||
KDF_R_MISSING_XCGHASH:115:missing xcghash
|
||||
KDF_R_UNKNOWN_PARAMETER_TYPE:103:unknown parameter type
|
||||
KDF_R_UNSUPPORTED_MAC_TYPE:117:unsupported mac type
|
||||
KDF_R_VALUE_ERROR:108:value error
|
||||
KDF_R_VALUE_MISSING:102:value missing
|
||||
KDF_R_WRONG_OUTPUT_BUFFER_SIZE:112:wrong output buffer size
|
||||
@@ -2961,8 +2975,6 @@ SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH:303:ssl session id has bad length
|
||||
SSL_R_SSL_SESSION_ID_TOO_LONG:408:ssl session id too long
|
||||
SSL_R_SSL_SESSION_VERSION_MISMATCH:210:ssl session version mismatch
|
||||
SSL_R_STILL_IN_INIT:121:still in init
|
||||
SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT:365:peer does not accept heartbeats
|
||||
SSL_R_TLS_HEARTBEAT_PENDING:366:heartbeat request already pending
|
||||
SSL_R_TLS_ILLEGAL_EXPORTER_LABEL:367:tls illegal exporter label
|
||||
SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST:157:tls invalid ecpointformat list
|
||||
SSL_R_TOO_MANY_KEY_UPDATES:132:too many key updates
|
||||
|
||||
@@ -16,6 +16,10 @@ SOURCE[../../libcrypto]=\
|
||||
e_chacha20_poly1305.c cmeth_lib.c \
|
||||
mac_lib.c c_allm.c pkey_mac.c
|
||||
|
||||
# New design
|
||||
SOURCE[../../libcrypto]=\
|
||||
evp_fetch.c
|
||||
|
||||
INCLUDE[e_aes.o]=.. ../modes
|
||||
INCLUDE[e_aes_cbc_hmac_sha1.o]=../modes
|
||||
INCLUDE[e_aes_cbc_hmac_sha256.o]=../modes
|
||||
|
||||
+292
-5
@@ -13,6 +13,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/engine.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/provider.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
/* This call frees resources associated with the context */
|
||||
@@ -21,6 +22,24 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
|
||||
if (ctx == NULL)
|
||||
return 1;
|
||||
|
||||
if (ctx->digest == NULL || ctx->digest->prov == NULL)
|
||||
goto legacy;
|
||||
|
||||
if (ctx->provctx != NULL) {
|
||||
if (ctx->digest->freectx != NULL)
|
||||
ctx->digest->freectx(ctx->provctx);
|
||||
ctx->provctx = NULL;
|
||||
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
|
||||
}
|
||||
|
||||
if (ctx->pctx != NULL)
|
||||
goto legacy;
|
||||
|
||||
return 1;
|
||||
|
||||
/* TODO(3.0): Remove legacy code below */
|
||||
legacy:
|
||||
|
||||
/*
|
||||
* Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
|
||||
* sometimes only copies of the context are ever finalised.
|
||||
@@ -53,6 +72,23 @@ EVP_MD_CTX *EVP_MD_CTX_new(void)
|
||||
|
||||
void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
if (ctx->digest == NULL || ctx->digest->prov == NULL)
|
||||
goto legacy;
|
||||
|
||||
EVP_MD_CTX_reset(ctx);
|
||||
|
||||
EVP_MD_meth_free(ctx->fetched_digest);
|
||||
ctx->fetched_digest = NULL;
|
||||
ctx->digest = NULL;
|
||||
|
||||
OPENSSL_free(ctx);
|
||||
return;
|
||||
|
||||
/* TODO(3.0): Remove legacy code below */
|
||||
legacy:
|
||||
EVP_MD_CTX_reset(ctx);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
@@ -65,7 +101,12 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
|
||||
|
||||
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
|
||||
{
|
||||
EVP_MD *provmd;
|
||||
ENGINE *tmpimpl = NULL;
|
||||
|
||||
EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
|
||||
|
||||
/* TODO(3.0): Legacy work around code below. Remove this */
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
/*
|
||||
* Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
|
||||
@@ -76,6 +117,74 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
|
||||
if (ctx->engine && ctx->digest &&
|
||||
(type == NULL || (type->type == ctx->digest->type)))
|
||||
goto skip_to_init;
|
||||
|
||||
if (type != NULL && impl == NULL)
|
||||
tmpimpl = ENGINE_get_digest_engine(type->type);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If there are engines involved or if we're being used as part of
|
||||
* EVP_DigestSignInit then we should use legacy handling for now.
|
||||
*/
|
||||
if (ctx->engine != NULL
|
||||
|| impl != NULL
|
||||
|| tmpimpl != NULL
|
||||
|| ctx->pctx != NULL
|
||||
|| (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0) {
|
||||
if (ctx->digest == ctx->fetched_digest)
|
||||
ctx->digest = NULL;
|
||||
EVP_MD_meth_free(ctx->fetched_digest);
|
||||
ctx->fetched_digest = NULL;
|
||||
goto legacy;
|
||||
}
|
||||
|
||||
if (type->prov == NULL) {
|
||||
switch(type->type) {
|
||||
case NID_sha256:
|
||||
break;
|
||||
default:
|
||||
goto legacy;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->digest != NULL && ctx->digest->ctx_size > 0) {
|
||||
OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
|
||||
ctx->md_data = NULL;
|
||||
}
|
||||
|
||||
/* TODO(3.0): Start of non-legacy code below */
|
||||
|
||||
if (type->prov == NULL) {
|
||||
provmd = EVP_MD_fetch(NULL, OBJ_nid2sn(type->type), "");
|
||||
if (provmd == NULL) {
|
||||
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
type = provmd;
|
||||
EVP_MD_meth_free(ctx->fetched_digest);
|
||||
ctx->fetched_digest = provmd;
|
||||
}
|
||||
|
||||
ctx->digest = type;
|
||||
if (ctx->provctx == NULL) {
|
||||
ctx->provctx = ctx->digest->newctx();
|
||||
if (ctx->provctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->digest->dinit == NULL) {
|
||||
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ctx->digest->dinit(ctx->provctx);
|
||||
|
||||
/* TODO(3.0): Remove legacy code below */
|
||||
legacy:
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (type) {
|
||||
/*
|
||||
* Ensure an ENGINE left lying around from last time is cleared (the
|
||||
@@ -90,7 +199,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
|
||||
}
|
||||
} else {
|
||||
/* Ask if an ENGINE is reserved for this job */
|
||||
impl = ENGINE_get_digest_engine(type->type);
|
||||
impl = tmpimpl;
|
||||
}
|
||||
if (impl != NULL) {
|
||||
/* There's an ENGINE for this job ... (apparently) */
|
||||
@@ -150,6 +259,20 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
|
||||
|
||||
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
if (count == 0)
|
||||
return 1;
|
||||
|
||||
if (ctx->digest == NULL || ctx->digest->prov == NULL)
|
||||
goto legacy;
|
||||
|
||||
if (ctx->digest->dupdate == NULL) {
|
||||
EVPerr(EVP_F_EVP_DIGESTUPDATE, EVP_R_UPDATE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
return ctx->digest->dupdate(ctx->provctx, data, count);
|
||||
|
||||
/* TODO(3.0): Remove legacy code below */
|
||||
legacy:
|
||||
return ctx->update(ctx, data, count);
|
||||
}
|
||||
|
||||
@@ -163,14 +286,40 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
|
||||
}
|
||||
|
||||
/* The caller can assume that this removes any secret data from the context */
|
||||
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
|
||||
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
|
||||
{
|
||||
int ret;
|
||||
size_t size = 0;
|
||||
|
||||
if (ctx->digest == NULL || ctx->digest->prov == NULL)
|
||||
goto legacy;
|
||||
|
||||
if (ctx->digest->dfinal == NULL) {
|
||||
EVPerr(EVP_F_EVP_DIGESTFINAL_EX, EVP_R_FINAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ctx->digest->dfinal(ctx->provctx, md, &size);
|
||||
|
||||
if (isize != NULL) {
|
||||
if (size <= UINT_MAX) {
|
||||
*isize = (int)size;
|
||||
} else {
|
||||
EVPerr(EVP_F_EVP_DIGESTFINAL_EX, EVP_R_FINAL_ERROR);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
EVP_MD_CTX_reset(ctx);
|
||||
|
||||
return ret;
|
||||
|
||||
/* TODO(3.0): Remove legacy code below */
|
||||
legacy:
|
||||
OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
|
||||
ret = ctx->digest->final(ctx, md);
|
||||
if (size != NULL)
|
||||
*size = ctx->digest->md_size;
|
||||
if (isize != NULL)
|
||||
*isize = ctx->digest->md_size;
|
||||
if (ctx->digest->cleanup) {
|
||||
ctx->digest->cleanup(ctx);
|
||||
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
|
||||
@@ -209,10 +358,52 @@ int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
|
||||
int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
|
||||
{
|
||||
unsigned char *tmp_buf;
|
||||
if ((in == NULL) || (in->digest == NULL)) {
|
||||
|
||||
if (in == NULL || in->digest == NULL) {
|
||||
EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (in->digest->prov == NULL)
|
||||
goto legacy;
|
||||
|
||||
if (in->digest->dupctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_NOT_ABLE_TO_COPY_CTX);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_reset(out);
|
||||
if (out->fetched_digest != NULL)
|
||||
EVP_MD_meth_free(out->fetched_digest);
|
||||
*out = *in;
|
||||
/* NULL out pointers in case of error */
|
||||
out->pctx = NULL;
|
||||
out->provctx = NULL;
|
||||
|
||||
if (in->fetched_digest != NULL)
|
||||
EVP_MD_upref(in->fetched_digest);
|
||||
|
||||
out->provctx = in->digest->dupctx(in->provctx);
|
||||
if (out->provctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_NOT_ABLE_TO_COPY_CTX);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */
|
||||
EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
|
||||
if (in->pctx != NULL) {
|
||||
out->pctx = EVP_PKEY_CTX_dup(in->pctx);
|
||||
if (out->pctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_NOT_ABLE_TO_COPY_CTX);
|
||||
EVP_MD_CTX_reset(out);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
/* TODO(3.0): Remove legacy code below */
|
||||
legacy:
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
/* Make sure it's safe to copy a digest context using an ENGINE */
|
||||
if (in->engine && !ENGINE_init(in->engine)) {
|
||||
@@ -296,3 +487,99 @@ int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *evp_md_from_dispatch(int mdtype, const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov)
|
||||
{
|
||||
EVP_MD *md = NULL;
|
||||
int fncnt = 0;
|
||||
|
||||
if ((md = EVP_MD_meth_new(mdtype, NID_undef)) == NULL)
|
||||
return NULL;
|
||||
|
||||
for (; fns->function_id != 0; fns++) {
|
||||
switch (fns->function_id) {
|
||||
case OSSL_FUNC_DIGEST_NEWCTX:
|
||||
if (md->newctx != NULL)
|
||||
break;
|
||||
md->newctx = OSSL_get_OP_digest_newctx(fns);
|
||||
fncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_INIT:
|
||||
if (md->dinit != NULL)
|
||||
break;
|
||||
md->dinit = OSSL_get_OP_digest_init(fns);
|
||||
fncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_UPDDATE:
|
||||
if (md->dupdate != NULL)
|
||||
break;
|
||||
md->dupdate = OSSL_get_OP_digest_update(fns);
|
||||
fncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_FINAL:
|
||||
if (md->dfinal != NULL)
|
||||
break;
|
||||
md->dfinal = OSSL_get_OP_digest_final(fns);
|
||||
fncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_DIGEST:
|
||||
if (md->digest != NULL)
|
||||
break;
|
||||
md->digest = OSSL_get_OP_digest_digest(fns);
|
||||
/* We don't increment fnct for this as it is stand alone */
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_FREECTX:
|
||||
if (md->freectx != NULL)
|
||||
break;
|
||||
md->freectx = OSSL_get_OP_digest_freectx(fns);
|
||||
fncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_DUPCTX:
|
||||
if (md->dupctx != NULL)
|
||||
break;
|
||||
md->dupctx = OSSL_get_OP_digest_dupctx(fns);
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_SIZE:
|
||||
if (md->size != NULL)
|
||||
break;
|
||||
md->size = OSSL_get_OP_digest_size(fns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((fncnt != 0 && fncnt != 5)
|
||||
|| (fncnt == 0 && md->digest == NULL)
|
||||
|| md->size == NULL) {
|
||||
/*
|
||||
* In order to be a consistent set of functions we either need the
|
||||
* whole set of init/update/final etc functions or none of them.
|
||||
* The "digest" function can standalone. We at least need one way to
|
||||
* generate digests.
|
||||
*/
|
||||
EVP_MD_meth_free(md);
|
||||
return NULL;
|
||||
}
|
||||
md->prov = prov;
|
||||
if (prov != NULL)
|
||||
ossl_provider_upref(prov);
|
||||
|
||||
return md;
|
||||
}
|
||||
|
||||
static int evp_md_upref(void *md)
|
||||
{
|
||||
return EVP_MD_upref(md);
|
||||
}
|
||||
|
||||
static void evp_md_free(void *md)
|
||||
{
|
||||
EVP_MD_meth_free(md);
|
||||
}
|
||||
|
||||
EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
return evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
|
||||
evp_md_from_dispatch, evp_md_upref,
|
||||
evp_md_free);
|
||||
}
|
||||
+13
-1
@@ -486,6 +486,16 @@ static int aria_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aria_gcm_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, ctx);
|
||||
|
||||
if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(ctx))
|
||||
OPENSSL_free(gctx->iv);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aria_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
@@ -727,6 +737,8 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
}
|
||||
}
|
||||
|
||||
#define aria_ccm_cleanup NULL
|
||||
|
||||
#define ARIA_AUTH_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
|
||||
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
|
||||
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
|
||||
@@ -739,7 +751,7 @@ static const EVP_CIPHER aria_##keylen##_##mode = { \
|
||||
ARIA_AUTH_FLAGS|EVP_CIPH_##MODE##_MODE, \
|
||||
aria_##mode##_init_key, \
|
||||
aria_##mode##_cipher, \
|
||||
NULL, \
|
||||
aria_##mode##_cleanup, \
|
||||
sizeof(EVP_ARIA_##MODE##_CTX), \
|
||||
NULL,NULL,aria_##mode##_ctrl,NULL }; \
|
||||
const EVP_CIPHER *EVP_aria_##keylen##_##mode(void) \
|
||||
|
||||
@@ -54,7 +54,9 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
|
||||
"EVP_DecryptFinal_ex"},
|
||||
{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_DIGESTFINAL_EX, 0), "EVP_DigestFinal_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTINIT_EX, 0), "EVP_DigestInit_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTUPDATE, 0), "EVP_DigestUpdate"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTDECRYPTUPDATE, 0),
|
||||
"evp_EncryptDecryptUpdate"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0),
|
||||
@@ -219,6 +221,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
"expecting a poly1305 key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_SIPHASH_KEY),
|
||||
"expecting a siphash key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FINAL_ERROR), "final error"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FIPS_MODE_NOT_SUPPORTED),
|
||||
"fips mode not supported"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GET_RAW_KEY_FAILED), "get raw key failed"},
|
||||
@@ -246,6 +249,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_METHOD_NOT_SUPPORTED),
|
||||
"method not supported"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MISSING_PARAMETERS), "missing parameters"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NOT_ABLE_TO_COPY_CTX),
|
||||
"not able to copy ctx"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NOT_XOF_OR_INVALID_LENGTH),
|
||||
"not XOF or invalid length"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_CIPHER_SET), "no cipher set"},
|
||||
@@ -293,6 +298,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
"unsupported private key algorithm"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_SALT_TYPE),
|
||||
"unsupported salt type"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UPDATE_ERROR), "update error"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRAP_MODE_NOT_ALLOWED),
|
||||
"wrap mode not allowed"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRONG_FINAL_BLOCK_LENGTH),
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <openssl/ossl_typ.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/core.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/thread_once.h"
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/property.h"
|
||||
#include "internal/core.h"
|
||||
#include "internal/evp_int.h" /* evp_locl.h needs it */
|
||||
#include "evp_locl.h"
|
||||
|
||||
/* The OpenSSL library context index for the default method store */
|
||||
static int default_method_store_index = -1;
|
||||
|
||||
static void default_method_store_free(void *vstore)
|
||||
{
|
||||
ossl_method_store_free(vstore);
|
||||
}
|
||||
|
||||
static void *default_method_store_new(void)
|
||||
{
|
||||
return ossl_method_store_new();
|
||||
}
|
||||
|
||||
|
||||
static const OPENSSL_CTX_METHOD default_method_store_method = {
|
||||
default_method_store_new,
|
||||
default_method_store_free,
|
||||
};
|
||||
|
||||
static int default_method_store_init(void)
|
||||
{
|
||||
default_method_store_index =
|
||||
openssl_ctx_new_index(&default_method_store_method);
|
||||
|
||||
return default_method_store_index != -1;
|
||||
}
|
||||
|
||||
static CRYPTO_ONCE default_method_store_init_flag = CRYPTO_ONCE_STATIC_INIT;
|
||||
DEFINE_RUN_ONCE_STATIC(do_default_method_store_init)
|
||||
{
|
||||
return OPENSSL_init_crypto(0, NULL)
|
||||
&& default_method_store_init();
|
||||
}
|
||||
|
||||
/* Data to be passed through ossl_method_construct() */
|
||||
struct method_data_st {
|
||||
const char *name;
|
||||
int nid;
|
||||
OSSL_METHOD_CONSTRUCT_METHOD *mcm;
|
||||
void *(*method_from_dispatch)(int nid, const OSSL_DISPATCH *,
|
||||
OSSL_PROVIDER *);
|
||||
int (*refcnt_up_method)(void *method);
|
||||
void (*destruct_method)(void *method);
|
||||
};
|
||||
|
||||
/*
|
||||
* Generic routines to fetch / create EVP methods with ossl_method_construct()
|
||||
*/
|
||||
static void *alloc_tmp_method_store(void)
|
||||
{
|
||||
return ossl_method_store_new();
|
||||
}
|
||||
|
||||
static void dealloc_tmp_method_store(void *store)
|
||||
{
|
||||
if (store != NULL)
|
||||
ossl_method_store_free(store);
|
||||
}
|
||||
|
||||
static
|
||||
struct OSSL_METHOD_STORE *get_default_method_store(OPENSSL_CTX *libctx)
|
||||
{
|
||||
if (!RUN_ONCE(&default_method_store_init_flag,
|
||||
do_default_method_store_init))
|
||||
return NULL;
|
||||
return openssl_ctx_get_data(libctx, default_method_store_index);
|
||||
}
|
||||
|
||||
static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
|
||||
const char *propquery, void *data)
|
||||
{
|
||||
struct method_data_st *methdata = data;
|
||||
void *method = NULL;
|
||||
|
||||
if (store == NULL
|
||||
&& (store = get_default_method_store(libctx)) == NULL)
|
||||
return NULL;
|
||||
|
||||
(void)ossl_method_store_fetch(store, methdata->nid, propquery, &method);
|
||||
|
||||
if (method != NULL
|
||||
&& !methdata->refcnt_up_method(method)) {
|
||||
method = NULL;
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
|
||||
const char *propdef, void *method,
|
||||
void *data)
|
||||
{
|
||||
struct method_data_st *methdata = data;
|
||||
|
||||
if (store == NULL
|
||||
&& (store = get_default_method_store(libctx)) == NULL)
|
||||
return 0;
|
||||
|
||||
if (methdata->refcnt_up_method(method)
|
||||
&& ossl_method_store_add(store, methdata->nid, propdef, method,
|
||||
methdata->destruct_method))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *construct_method(const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov,
|
||||
void *data)
|
||||
{
|
||||
struct method_data_st *methdata = data;
|
||||
void *method = NULL;
|
||||
|
||||
if (methdata->nid == NID_undef) {
|
||||
/* Create a new NID for that name on the fly */
|
||||
ASN1_OBJECT tmpobj;
|
||||
|
||||
/* This is the same as OBJ_create() but without requiring a OID */
|
||||
tmpobj.nid = OBJ_new_nid(1);
|
||||
tmpobj.sn = tmpobj.ln = methdata->name;
|
||||
tmpobj.flags = ASN1_OBJECT_FLAG_DYNAMIC;
|
||||
tmpobj.length = 0;
|
||||
tmpobj.data = NULL;
|
||||
|
||||
methdata->nid = OBJ_add_object(&tmpobj);
|
||||
}
|
||||
|
||||
if (methdata->nid == NID_undef)
|
||||
return NULL;
|
||||
|
||||
method = methdata->method_from_dispatch(methdata->nid, fns, prov);
|
||||
if (method == NULL)
|
||||
return NULL;
|
||||
return method;
|
||||
}
|
||||
|
||||
static void destruct_method(void *method, void *data)
|
||||
{
|
||||
struct method_data_st *methdata = data;
|
||||
|
||||
methdata->destruct_method(method);
|
||||
}
|
||||
|
||||
void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
|
||||
const char *algorithm, const char *properties,
|
||||
void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*upref_method)(void *),
|
||||
void (*free_method)(void *))
|
||||
{
|
||||
int nid = OBJ_sn2nid(algorithm);
|
||||
void *method = NULL;
|
||||
|
||||
if (nid == NID_undef
|
||||
|| !ossl_method_store_cache_get(NULL, nid, properties, &method)) {
|
||||
OSSL_METHOD_CONSTRUCT_METHOD mcm = {
|
||||
alloc_tmp_method_store,
|
||||
dealloc_tmp_method_store,
|
||||
get_method_from_store,
|
||||
put_method_in_store,
|
||||
construct_method,
|
||||
destruct_method
|
||||
};
|
||||
struct method_data_st mcmdata;
|
||||
|
||||
mcmdata.nid = nid;
|
||||
mcmdata.mcm = &mcm;
|
||||
mcmdata.method_from_dispatch = new_method;
|
||||
mcmdata.destruct_method = free_method;
|
||||
mcmdata.refcnt_up_method = upref_method;
|
||||
mcmdata.destruct_method = free_method;
|
||||
method = ossl_method_construct(libctx, operation_id, algorithm,
|
||||
properties, 0 /* !force_cache */,
|
||||
&mcm, &mcmdata);
|
||||
ossl_method_store_cache_set(NULL, nid, properties, method);
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/provider.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
|
||||
@@ -316,6 +317,10 @@ int EVP_MD_size(const EVP_MD *md)
|
||||
EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (md->prov != NULL && md->size != NULL)
|
||||
return (int)md->size();
|
||||
|
||||
return md->md_size;
|
||||
}
|
||||
|
||||
@@ -331,6 +336,12 @@ EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type)
|
||||
if (md != NULL) {
|
||||
md->type = md_type;
|
||||
md->pkey_type = pkey_type;
|
||||
md->lock = CRYPTO_THREAD_lock_new();
|
||||
if (md->lock == NULL) {
|
||||
OPENSSL_free(md);
|
||||
return NULL;
|
||||
}
|
||||
md->refcnt = 1;
|
||||
}
|
||||
return md;
|
||||
}
|
||||
@@ -342,9 +353,27 @@ EVP_MD *EVP_MD_meth_dup(const EVP_MD *md)
|
||||
memcpy(to, md, sizeof(*to));
|
||||
return to;
|
||||
}
|
||||
|
||||
int EVP_MD_upref(EVP_MD *md)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&md->refcnt, &ref, md->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void EVP_MD_meth_free(EVP_MD *md)
|
||||
{
|
||||
if (md != NULL) {
|
||||
int i;
|
||||
|
||||
CRYPTO_DOWN_REF(&md->refcnt, &i, md->lock);
|
||||
if (i > 0)
|
||||
return;
|
||||
ossl_provider_free(md->prov);
|
||||
CRYPTO_THREAD_lock_free(md->lock);
|
||||
OPENSSL_free(md);
|
||||
}
|
||||
}
|
||||
int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize)
|
||||
{
|
||||
|
||||
+15
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -19,6 +19,10 @@ struct evp_md_ctx_st {
|
||||
EVP_PKEY_CTX *pctx;
|
||||
/* Update function: usually copied from EVP_MD */
|
||||
int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
|
||||
|
||||
/* Provider ctx */
|
||||
void *provctx;
|
||||
EVP_MD *fetched_digest;
|
||||
} /* EVP_MD_CTX */ ;
|
||||
|
||||
struct evp_cipher_ctx_st {
|
||||
@@ -76,3 +80,13 @@ typedef struct evp_pbe_st EVP_PBE_CTL;
|
||||
DEFINE_STACK_OF(EVP_PBE_CTL)
|
||||
|
||||
int is_partially_overlapping(const void *ptr1, const void *ptr2, int len);
|
||||
|
||||
#include <openssl/ossl_typ.h>
|
||||
#include <openssl/core.h>
|
||||
|
||||
void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id,
|
||||
const char *algorithm, const char *properties,
|
||||
void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*upref_method)(void *),
|
||||
void (*free_method)(void *));
|
||||
@@ -31,6 +31,7 @@ static const EVP_KDF_METHOD *standard_methods[] = {
|
||||
&tls1_prf_kdf_meth,
|
||||
&hkdf_kdf_meth,
|
||||
&sshkdf_kdf_meth,
|
||||
&ss_kdf_meth
|
||||
};
|
||||
|
||||
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_KDF_METHOD *, const EVP_KDF_METHOD *,
|
||||
|
||||
@@ -82,6 +82,8 @@ int EVP_MAC_init(EVP_MAC_CTX *ctx)
|
||||
|
||||
int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen)
|
||||
{
|
||||
if (datalen == 0)
|
||||
return 1;
|
||||
return ctx->meth->update(ctx->data, data, datalen);
|
||||
}
|
||||
|
||||
|
||||
@@ -396,6 +396,11 @@ int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
|
||||
pkey->pmeth_engine = e;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey)
|
||||
{
|
||||
return pkey->engine;
|
||||
}
|
||||
#endif
|
||||
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
|
||||
{
|
||||
|
||||
@@ -52,6 +52,10 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen,
|
||||
pass = empty;
|
||||
passlen = 0;
|
||||
}
|
||||
if (salt == NULL) {
|
||||
salt = (const unsigned char *)empty;
|
||||
saltlen = 0;
|
||||
}
|
||||
if (maxmem == 0)
|
||||
maxmem = SCRYPT_MAX_MEM;
|
||||
|
||||
|
||||
@@ -231,9 +231,9 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
int rv;
|
||||
|
||||
if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
|
||||
ctx->engine)) < 0
|
||||
ctx->engine)) <= 0
|
||||
|| (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_CIPHER,
|
||||
p2)) < 0
|
||||
p2)) <= 0
|
||||
|| !(rv = EVP_MAC_init(hctx->ctx)))
|
||||
return rv;
|
||||
}
|
||||
@@ -275,7 +275,7 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
return 0;
|
||||
break;
|
||||
case MAC_TYPE_MAC:
|
||||
if (!EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, p2, p1))
|
||||
if (EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, p2, p1) <= 0)
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
@@ -296,11 +296,11 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
(ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
|
||||
|
||||
if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
|
||||
ctx->engine)) < 0
|
||||
ctx->engine)) <= 0
|
||||
|| (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_MD,
|
||||
hctx->raw_data.md)) < 0
|
||||
hctx->raw_data.md)) <= 0
|
||||
|| (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY,
|
||||
key->data, key->length)) < 0)
|
||||
key->data, key->length)) <= 0)
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -35,6 +35,13 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The HMAC construction is not allowed to be used with the
|
||||
* extendable-output functions (XOF) shake128 and shake256.
|
||||
*/
|
||||
if ((EVP_MD_meth_get_flags(md) & EVP_MD_FLAG_XOF) != 0)
|
||||
return 0;
|
||||
|
||||
if (key != NULL) {
|
||||
reset = 1;
|
||||
j = EVP_MD_block_size(md);
|
||||
|
||||
@@ -110,8 +110,4 @@ int bn_rsa_fips186_4_derive_prime(BIGNUM *Y, BIGNUM *X, const BIGNUM *Xin,
|
||||
const BIGNUM *r1, const BIGNUM *r2, int nlen,
|
||||
const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/core_numbers.h>
|
||||
#include "internal/refcount.h"
|
||||
|
||||
/*
|
||||
@@ -169,9 +170,14 @@ extern const EVP_KDF_METHOD scrypt_kdf_meth;
|
||||
extern const EVP_KDF_METHOD tls1_prf_kdf_meth;
|
||||
extern const EVP_KDF_METHOD hkdf_kdf_meth;
|
||||
extern const EVP_KDF_METHOD sshkdf_kdf_meth;
|
||||
extern const EVP_KDF_METHOD ss_kdf_meth;
|
||||
|
||||
struct evp_md_st {
|
||||
/* nid */
|
||||
int type;
|
||||
|
||||
/* Legacy structure members */
|
||||
/* TODO(3.0): Remove these */
|
||||
int pkey_type;
|
||||
int md_size;
|
||||
unsigned long flags;
|
||||
@@ -184,6 +190,21 @@ struct evp_md_st {
|
||||
int ctx_size; /* how big does the ctx->md_data need to be */
|
||||
/* control function */
|
||||
int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
|
||||
|
||||
/* New structure members */
|
||||
/* TODO(3.0): Remove above comment when legacy has gone */
|
||||
OSSL_PROVIDER *prov;
|
||||
CRYPTO_REF_COUNT refcnt;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
OSSL_OP_digest_newctx_fn *newctx;
|
||||
OSSL_OP_digest_init_fn *dinit;
|
||||
OSSL_OP_digest_update_fn *dupdate;
|
||||
OSSL_OP_digest_final_fn *dfinal;
|
||||
OSSL_OP_digest_digest_fn *digest;
|
||||
OSSL_OP_digest_freectx_fn *freectx;
|
||||
OSSL_OP_digest_dupctx_fn *dupctx;
|
||||
OSSL_OP_digest_size_fn *size;
|
||||
|
||||
} /* EVP_MD */ ;
|
||||
|
||||
struct evp_cipher_st {
|
||||
|
||||
@@ -49,6 +49,14 @@ size_t rand_drbg_get_additional_data(RAND_POOL *pool, unsigned char **pout);
|
||||
|
||||
void rand_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out);
|
||||
|
||||
/* CRNG test entropy filter callbacks. */
|
||||
size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
|
||||
unsigned char **pout,
|
||||
int entropy, size_t min_len, size_t max_len,
|
||||
int prediction_resistance);
|
||||
void rand_crngt_cleanup_entropy(RAND_DRBG *drbg,
|
||||
unsigned char *out, size_t outlen);
|
||||
|
||||
/*
|
||||
* RAND_POOL functions
|
||||
*/
|
||||
|
||||
+2
-2
@@ -163,7 +163,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete)
|
||||
#if !defined(OPENSSL_NO_DSO) \
|
||||
&& !defined(OPENSSL_USE_NODELETE) \
|
||||
&& !defined(OPENSSL_NO_PINSHARED)
|
||||
# ifdef DSO_WIN32
|
||||
# if defined(DSO_WIN32) && !defined(_WIN32_WCE)
|
||||
{
|
||||
HMODULE handle = NULL;
|
||||
BOOL ret;
|
||||
@@ -743,7 +743,7 @@ int OPENSSL_atexit(void (*handler)(void))
|
||||
} handlersym;
|
||||
|
||||
handlersym.func = handler;
|
||||
# ifdef DSO_WIN32
|
||||
# if defined(DSO_WIN32) && !defined(_WIN32_WCE)
|
||||
{
|
||||
HMODULE handle = NULL;
|
||||
BOOL ret;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
tls1_prf.c kdf_err.c kdf_util.c hkdf.c scrypt.c pbkdf2.c sshkdf.c
|
||||
tls1_prf.c kdf_err.c kdf_util.c hkdf.c scrypt.c pbkdf2.c sshkdf.c \
|
||||
sskdf.c
|
||||
@@ -59,12 +59,18 @@ static const ERR_STRING_DATA KDF_str_functs[] = {
|
||||
"pkey_tls1_prf_derive"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_PKEY_TLS1_PRF_INIT, 0), "pkey_tls1_prf_init"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_SCRYPT_SET_MEMBUF, 0), "scrypt_set_membuf"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_CTRL_STR, 0), "sskdf_ctrl_str"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_DERIVE, 0), "sskdf_derive"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_MAC2CTRL, 0), "sskdf_mac2ctrl"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_NEW, 0), "sskdf_new"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_SSKDF_SIZE, 0), "sskdf_size"},
|
||||
{ERR_PACK(ERR_LIB_KDF, KDF_F_TLS1_PRF_ALG, 0), "tls1_prf_alg"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static const ERR_STRING_DATA KDF_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_DIGEST), "invalid digest"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_INVALID_MAC_TYPE), "invalid mac type"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_ITERATION_COUNT),
|
||||
"missing iteration count"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_KEY), "missing key"},
|
||||
@@ -80,6 +86,8 @@ static const ERR_STRING_DATA KDF_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_MISSING_XCGHASH), "missing xcghash"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_UNKNOWN_PARAMETER_TYPE),
|
||||
"unknown parameter type"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_UNSUPPORTED_MAC_TYPE),
|
||||
"unsupported mac type"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_VALUE_ERROR), "value error"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_VALUE_MISSING), "value missing"},
|
||||
{ERR_PACK(ERR_LIB_KDF, 0, KDF_R_WRONG_OUTPUT_BUFFER_SIZE),
|
||||
|
||||
@@ -0,0 +1,484 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* Refer to https://csrc.nist.gov/publications/detail/sp/800-56c/rev-1/final
|
||||
* Section 4.1.
|
||||
*
|
||||
* The Single Step KDF algorithm is given by:
|
||||
*
|
||||
* Result(0) = empty bit string (i.e., the null string).
|
||||
* For i = 1 to reps, do the following:
|
||||
* Increment counter by 1.
|
||||
* Result(i) = Result(i – 1) || H(counter || Z || FixedInfo).
|
||||
* DKM = LeftmostBits(Result(reps), L))
|
||||
*
|
||||
* NOTES:
|
||||
* Z is a shared secret required to produce the derived key material.
|
||||
* counter is a 4 byte buffer.
|
||||
* FixedInfo is a bit string containing context specific data.
|
||||
* DKM is the output derived key material.
|
||||
* L is the required size of the DKM.
|
||||
* reps = [L / H_outputBits]
|
||||
* H(x) is the auxiliary function that can be either a hash, HMAC or KMAC.
|
||||
* H_outputBits is the length of the output of the auxiliary function H(x).
|
||||
*
|
||||
* Currently there is not a comprehensive list of test vectors for this
|
||||
* algorithm, especially for H(x) = HMAC and H(x) = KMAC.
|
||||
* Test vectors for H(x) = Hash are indirectly used by CAVS KAS tests.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "kdf_local.h"
|
||||
|
||||
struct evp_kdf_impl_st {
|
||||
const EVP_MAC *mac; /* H(x) = HMAC_hash OR H(x) = KMAC */
|
||||
const EVP_MD *md; /* H(x) = hash OR when H(x) = HMAC_hash */
|
||||
unsigned char *secret;
|
||||
size_t secret_len;
|
||||
unsigned char *info;
|
||||
size_t info_len;
|
||||
unsigned char *salt;
|
||||
size_t salt_len;
|
||||
size_t out_len; /* optional KMAC parameter */
|
||||
};
|
||||
|
||||
#define SSKDF_MAX_INLEN (1<<30)
|
||||
#define SSKDF_KMAC128_DEFAULT_SALT_SIZE (168 - 4)
|
||||
#define SSKDF_KMAC256_DEFAULT_SALT_SIZE (136 - 4)
|
||||
|
||||
/* KMAC uses a Customisation string of 'KDF' */
|
||||
static const unsigned char kmac_custom_str[] = { 0x4B, 0x44, 0x46 };
|
||||
|
||||
/*
|
||||
* Refer to https://csrc.nist.gov/publications/detail/sp/800-56c/rev-1/final
|
||||
* Section 4. One-Step Key Derivation using H(x) = hash(x)
|
||||
*/
|
||||
static int SSKDF_hash_kdm(const EVP_MD *kdf_md,
|
||||
const unsigned char *z, size_t z_len,
|
||||
const unsigned char *info, size_t info_len,
|
||||
unsigned char *derived_key, size_t derived_key_len)
|
||||
{
|
||||
int ret = 0, hlen;
|
||||
size_t counter, out_len, len = derived_key_len;
|
||||
unsigned char c[4];
|
||||
unsigned char mac[EVP_MAX_MD_SIZE];
|
||||
unsigned char *out = derived_key;
|
||||
EVP_MD_CTX *ctx = NULL, *ctx_init = NULL;
|
||||
|
||||
if (z_len > SSKDF_MAX_INLEN || info_len > SSKDF_MAX_INLEN
|
||||
|| derived_key_len > SSKDF_MAX_INLEN
|
||||
|| derived_key_len == 0)
|
||||
return 0;
|
||||
|
||||
hlen = EVP_MD_size(kdf_md);
|
||||
if (hlen <= 0)
|
||||
return 0;
|
||||
out_len = (size_t)hlen;
|
||||
|
||||
ctx = EVP_MD_CTX_create();
|
||||
ctx_init = EVP_MD_CTX_create();
|
||||
if (ctx == NULL || ctx_init == NULL)
|
||||
goto end;
|
||||
|
||||
if (!EVP_DigestInit(ctx_init, kdf_md))
|
||||
goto end;
|
||||
|
||||
for (counter = 1;; counter++) {
|
||||
c[0] = (unsigned char)((counter >> 24) & 0xff);
|
||||
c[1] = (unsigned char)((counter >> 16) & 0xff);
|
||||
c[2] = (unsigned char)((counter >> 8) & 0xff);
|
||||
c[3] = (unsigned char)(counter & 0xff);
|
||||
|
||||
if (!(EVP_MD_CTX_copy_ex(ctx, ctx_init)
|
||||
&& EVP_DigestUpdate(ctx, c, sizeof(c))
|
||||
&& EVP_DigestUpdate(ctx, z, z_len)
|
||||
&& EVP_DigestUpdate(ctx, info, info_len)))
|
||||
goto end;
|
||||
if (len >= out_len) {
|
||||
if (!EVP_DigestFinal_ex(ctx, out, NULL))
|
||||
goto end;
|
||||
out += out_len;
|
||||
len -= out_len;
|
||||
if (len == 0)
|
||||
break;
|
||||
} else {
|
||||
if (!EVP_DigestFinal_ex(ctx, mac, NULL))
|
||||
goto end;
|
||||
memcpy(out, mac, len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret = 1;
|
||||
end:
|
||||
EVP_MD_CTX_destroy(ctx);
|
||||
EVP_MD_CTX_destroy(ctx_init);
|
||||
OPENSSL_cleanse(mac, sizeof(mac));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int kmac_init(EVP_MAC_CTX *ctx, const unsigned char *custom,
|
||||
size_t custom_len, size_t kmac_out_len,
|
||||
size_t derived_key_len, unsigned char **out)
|
||||
{
|
||||
/* Only KMAC has custom data - so return if not KMAC */
|
||||
if (custom == NULL)
|
||||
return 1;
|
||||
|
||||
if (EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_CUSTOM, custom, custom_len) <= 0)
|
||||
return 0;
|
||||
|
||||
/* By default only do one iteration if kmac_out_len is not specified */
|
||||
if (kmac_out_len == 0)
|
||||
kmac_out_len = derived_key_len;
|
||||
/* otherwise check the size is valid */
|
||||
else if (!(kmac_out_len == derived_key_len
|
||||
|| kmac_out_len == 20
|
||||
|| kmac_out_len == 28
|
||||
|| kmac_out_len == 32
|
||||
|| kmac_out_len == 48
|
||||
|| kmac_out_len == 64))
|
||||
return 0;
|
||||
|
||||
if (EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_SIZE, kmac_out_len) <= 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* For kmac the output buffer can be larger than EVP_MAX_MD_SIZE: so
|
||||
* alloc a buffer for this case.
|
||||
*/
|
||||
if (kmac_out_len > EVP_MAX_MD_SIZE) {
|
||||
*out = OPENSSL_zalloc(kmac_out_len);
|
||||
if (*out == NULL)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Refer to https://csrc.nist.gov/publications/detail/sp/800-56c/rev-1/final
|
||||
* Section 4. One-Step Key Derivation using MAC: i.e either
|
||||
* H(x) = HMAC-hash(salt, x) OR
|
||||
* H(x) = KMAC#(salt, x, outbits, CustomString='KDF')
|
||||
*/
|
||||
static int SSKDF_mac_kdm(const EVP_MAC *kdf_mac, const EVP_MD *hmac_md,
|
||||
const unsigned char *kmac_custom,
|
||||
size_t kmac_custom_len, size_t kmac_out_len,
|
||||
const unsigned char *salt, size_t salt_len,
|
||||
const unsigned char *z, size_t z_len,
|
||||
const unsigned char *info, size_t info_len,
|
||||
unsigned char *derived_key, size_t derived_key_len)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t counter, out_len, len;
|
||||
unsigned char c[4];
|
||||
unsigned char mac_buf[EVP_MAX_MD_SIZE];
|
||||
unsigned char *out = derived_key;
|
||||
EVP_MAC_CTX *ctx = NULL, *ctx_init = NULL;
|
||||
unsigned char *mac = mac_buf, *kmac_buffer = NULL;
|
||||
|
||||
if (z_len > SSKDF_MAX_INLEN || info_len > SSKDF_MAX_INLEN
|
||||
|| derived_key_len > SSKDF_MAX_INLEN
|
||||
|| derived_key_len == 0)
|
||||
return 0;
|
||||
|
||||
ctx = EVP_MAC_CTX_new(kdf_mac);
|
||||
ctx_init = EVP_MAC_CTX_new(kdf_mac);
|
||||
if (ctx == NULL || ctx_init == NULL)
|
||||
goto end;
|
||||
if (hmac_md != NULL &&
|
||||
EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_MD, hmac_md) <= 0)
|
||||
goto end;
|
||||
|
||||
if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_KEY, salt, salt_len) <= 0)
|
||||
goto end;
|
||||
|
||||
if (!kmac_init(ctx_init, kmac_custom, kmac_custom_len, kmac_out_len,
|
||||
derived_key_len, &kmac_buffer))
|
||||
goto end;
|
||||
if (kmac_buffer != NULL)
|
||||
mac = kmac_buffer;
|
||||
|
||||
if (!EVP_MAC_init(ctx_init))
|
||||
goto end;
|
||||
|
||||
out_len = EVP_MAC_size(ctx_init); /* output size */
|
||||
if (out_len <= 0)
|
||||
goto end;
|
||||
len = derived_key_len;
|
||||
|
||||
for (counter = 1;; counter++) {
|
||||
c[0] = (unsigned char)((counter >> 24) & 0xff);
|
||||
c[1] = (unsigned char)((counter >> 16) & 0xff);
|
||||
c[2] = (unsigned char)((counter >> 8) & 0xff);
|
||||
c[3] = (unsigned char)(counter & 0xff);
|
||||
|
||||
if (!(EVP_MAC_CTX_copy(ctx, ctx_init)
|
||||
&& EVP_MAC_update(ctx, c, sizeof(c))
|
||||
&& EVP_MAC_update(ctx, z, z_len)
|
||||
&& EVP_MAC_update(ctx, info, info_len)))
|
||||
goto end;
|
||||
if (len >= out_len) {
|
||||
if (!EVP_MAC_final(ctx, out, NULL))
|
||||
goto end;
|
||||
out += out_len;
|
||||
len -= out_len;
|
||||
if (len == 0)
|
||||
break;
|
||||
} else {
|
||||
if (!EVP_MAC_final(ctx, mac, NULL))
|
||||
goto end;
|
||||
memcpy(out, mac, len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret = 1;
|
||||
end:
|
||||
if (kmac_buffer != NULL)
|
||||
OPENSSL_clear_free(kmac_buffer, kmac_out_len);
|
||||
else
|
||||
OPENSSL_cleanse(mac_buf, sizeof(mac_buf));
|
||||
|
||||
EVP_MAC_CTX_free(ctx);
|
||||
EVP_MAC_CTX_free(ctx_init);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static EVP_KDF_IMPL *sskdf_new(void)
|
||||
{
|
||||
EVP_KDF_IMPL *impl;
|
||||
|
||||
if ((impl = OPENSSL_zalloc(sizeof(*impl))) == NULL)
|
||||
KDFerr(KDF_F_SSKDF_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return impl;
|
||||
}
|
||||
|
||||
static void sskdf_reset(EVP_KDF_IMPL *impl)
|
||||
{
|
||||
OPENSSL_clear_free(impl->secret, impl->secret_len);
|
||||
OPENSSL_clear_free(impl->info, impl->info_len);
|
||||
OPENSSL_clear_free(impl->salt, impl->salt_len);
|
||||
memset(impl, 0, sizeof(*impl));
|
||||
}
|
||||
|
||||
static void sskdf_free(EVP_KDF_IMPL *impl)
|
||||
{
|
||||
sskdf_reset(impl);
|
||||
OPENSSL_free(impl);
|
||||
}
|
||||
|
||||
static int sskdf_set_buffer(va_list args, unsigned char **out, size_t *out_len)
|
||||
{
|
||||
const unsigned char *p;
|
||||
size_t len;
|
||||
|
||||
p = va_arg(args, const unsigned char *);
|
||||
len = va_arg(args, size_t);
|
||||
if (len == 0 || p == NULL)
|
||||
return 1;
|
||||
|
||||
OPENSSL_free(*out);
|
||||
*out = OPENSSL_memdup(p, len);
|
||||
if (*out == NULL)
|
||||
return 0;
|
||||
|
||||
*out_len = len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int sskdf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
|
||||
{
|
||||
const EVP_MD *md;
|
||||
const EVP_MAC *mac;
|
||||
|
||||
switch (cmd) {
|
||||
case EVP_KDF_CTRL_SET_KEY:
|
||||
return sskdf_set_buffer(args, &impl->secret, &impl->secret_len);
|
||||
|
||||
case EVP_KDF_CTRL_SET_SSKDF_INFO:
|
||||
return sskdf_set_buffer(args, &impl->info, &impl->info_len);
|
||||
|
||||
case EVP_KDF_CTRL_SET_MD:
|
||||
md = va_arg(args, const EVP_MD *);
|
||||
if (md == NULL)
|
||||
return 0;
|
||||
|
||||
impl->md = md;
|
||||
return 1;
|
||||
|
||||
case EVP_KDF_CTRL_SET_MAC:
|
||||
mac = va_arg(args, const EVP_MAC *);
|
||||
if (mac == NULL)
|
||||
return 0;
|
||||
|
||||
impl->mac = mac;
|
||||
return 1;
|
||||
|
||||
case EVP_KDF_CTRL_SET_SALT:
|
||||
return sskdf_set_buffer(args, &impl->salt, &impl->salt_len);
|
||||
|
||||
case EVP_KDF_CTRL_SET_MAC_SIZE:
|
||||
impl->out_len = va_arg(args, size_t);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass a mac to a ctrl */
|
||||
static int sskdf_mac2ctrl(EVP_KDF_IMPL *impl,
|
||||
int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args),
|
||||
int cmd, const char *mac_name)
|
||||
{
|
||||
const EVP_MAC *mac;
|
||||
|
||||
if (mac_name == NULL || (mac = EVP_get_macbyname(mac_name)) == NULL) {
|
||||
KDFerr(KDF_F_SSKDF_MAC2CTRL, KDF_R_INVALID_MAC_TYPE);
|
||||
return 0;
|
||||
}
|
||||
return call_ctrl(ctrl, impl, cmd, mac);
|
||||
}
|
||||
|
||||
static int sskdf_ctrl_str(EVP_KDF_IMPL *impl, const char *type,
|
||||
const char *value)
|
||||
{
|
||||
if (strcmp(type, "secret") == 0 || strcmp(type, "key") == 0)
|
||||
return kdf_str2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_KEY,
|
||||
value);
|
||||
|
||||
if (strcmp(type, "hexsecret") == 0 || strcmp(type, "hexkey") == 0)
|
||||
return kdf_hex2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_KEY,
|
||||
value);
|
||||
|
||||
if (strcmp(type, "info") == 0)
|
||||
return kdf_str2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_SSKDF_INFO,
|
||||
value);
|
||||
|
||||
if (strcmp(type, "hexinfo") == 0)
|
||||
return kdf_hex2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_SSKDF_INFO,
|
||||
value);
|
||||
|
||||
if (strcmp(type, "digest") == 0)
|
||||
return kdf_md2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_MD, value);
|
||||
|
||||
if (strcmp(type, "mac") == 0)
|
||||
return sskdf_mac2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_MAC, value);
|
||||
|
||||
if (strcmp(type, "salt") == 0)
|
||||
return kdf_str2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_SALT, value);
|
||||
|
||||
if (strcmp(type, "hexsalt") == 0)
|
||||
return kdf_hex2ctrl(impl, sskdf_ctrl, EVP_KDF_CTRL_SET_SALT, value);
|
||||
|
||||
|
||||
if (strcmp(type, "maclen") == 0) {
|
||||
int val = atoi(value);
|
||||
if (val < 0) {
|
||||
KDFerr(KDF_F_SSKDF_CTRL_STR, KDF_R_VALUE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
return call_ctrl(sskdf_ctrl, impl, EVP_KDF_CTRL_SET_MAC_SIZE,
|
||||
(size_t)val);
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
static size_t sskdf_size(EVP_KDF_IMPL *impl)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (impl->md == NULL) {
|
||||
KDFerr(KDF_F_SSKDF_SIZE, KDF_R_MISSING_MESSAGE_DIGEST);
|
||||
return 0;
|
||||
}
|
||||
len = EVP_MD_size(impl->md);
|
||||
return (len <= 0) ? 0 : (size_t)len;
|
||||
}
|
||||
|
||||
static int sskdf_derive(EVP_KDF_IMPL *impl, unsigned char *key, size_t keylen)
|
||||
{
|
||||
if (impl->secret == NULL) {
|
||||
KDFerr(KDF_F_SSKDF_DERIVE, KDF_R_MISSING_SECRET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (impl->mac != NULL) {
|
||||
/* H(x) = KMAC or H(x) = HMAC */
|
||||
int ret;
|
||||
const unsigned char *custom = NULL;
|
||||
size_t custom_len = 0;
|
||||
int nid;
|
||||
int default_salt_len;
|
||||
|
||||
nid = EVP_MAC_nid(impl->mac);
|
||||
if (nid == EVP_MAC_HMAC) {
|
||||
/* H(x) = HMAC(x, salt, hash) */
|
||||
if (impl->md == NULL) {
|
||||
KDFerr(KDF_F_SSKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
|
||||
return 0;
|
||||
}
|
||||
default_salt_len = EVP_MD_block_size(impl->md);
|
||||
if (default_salt_len <= 0)
|
||||
return 0;
|
||||
} else if (nid == EVP_MAC_KMAC128 || nid == EVP_MAC_KMAC256) {
|
||||
/* H(x) = KMACzzz(x, salt, custom) */
|
||||
custom = kmac_custom_str;
|
||||
custom_len = sizeof(kmac_custom_str);
|
||||
if (nid == EVP_MAC_KMAC128)
|
||||
default_salt_len = SSKDF_KMAC128_DEFAULT_SALT_SIZE;
|
||||
else
|
||||
default_salt_len = SSKDF_KMAC256_DEFAULT_SALT_SIZE;
|
||||
} else {
|
||||
KDFerr(KDF_F_SSKDF_DERIVE, KDF_R_UNSUPPORTED_MAC_TYPE);
|
||||
return 0;
|
||||
}
|
||||
/* If no salt is set then use a default_salt of zeros */
|
||||
if (impl->salt == NULL || impl->salt_len <= 0) {
|
||||
impl->salt = OPENSSL_zalloc(default_salt_len);
|
||||
if (impl->salt == NULL) {
|
||||
KDFerr(KDF_F_SSKDF_DERIVE, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
impl->salt_len = default_salt_len;
|
||||
}
|
||||
ret = SSKDF_mac_kdm(impl->mac, impl->md,
|
||||
custom, custom_len, impl->out_len,
|
||||
impl->salt, impl->salt_len,
|
||||
impl->secret, impl->secret_len,
|
||||
impl->info, impl->info_len, key, keylen);
|
||||
return ret;
|
||||
} else {
|
||||
/* H(x) = hash */
|
||||
if (impl->md == NULL) {
|
||||
KDFerr(KDF_F_SSKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
|
||||
return 0;
|
||||
}
|
||||
return SSKDF_hash_kdm(impl->md, impl->secret, impl->secret_len,
|
||||
impl->info, impl->info_len, key, keylen);
|
||||
}
|
||||
}
|
||||
|
||||
const EVP_KDF_METHOD ss_kdf_meth = {
|
||||
EVP_KDF_SS,
|
||||
sskdf_new,
|
||||
sskdf_free,
|
||||
sskdf_reset,
|
||||
sskdf_ctrl,
|
||||
sskdf_ctrl_str,
|
||||
sskdf_size,
|
||||
sskdf_derive
|
||||
};
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
# define __MIPS_ARCH_H__
|
||||
|
||||
# if (defined(__mips_smartmips) || defined(_MIPS_ARCH_MIPS32R3) || \
|
||||
defined(_MIPS_ARCH_MIPS32R5) || defined(_MIPS_ARCH_MIPS32R6))
|
||||
defined(_MIPS_ARCH_MIPS32R5) || defined(_MIPS_ARCH_MIPS32R6)) \
|
||||
&& !defined(_MIPS_ARCH_MIPS32R2)
|
||||
# define _MIPS_ARCH_MIPS32R2
|
||||
# endif
|
||||
|
||||
@@ -166,8 +166,8 @@ int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen,
|
||||
|| (ctx->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL
|
||||
|| (ctx->mac_ctx_init = EVP_MAC_CTX_new_id(EVP_MAC_CMAC)) == NULL
|
||||
|| (ctx->mac_ctx = EVP_MAC_CTX_new_id(EVP_MAC_CMAC)) == NULL
|
||||
|| !EVP_MAC_ctrl(ctx->mac_ctx_init, EVP_MAC_CTRL_SET_CIPHER, cbc)
|
||||
|| !EVP_MAC_ctrl(ctx->mac_ctx_init, EVP_MAC_CTRL_SET_KEY, key, klen)
|
||||
|| EVP_MAC_ctrl(ctx->mac_ctx_init, EVP_MAC_CTRL_SET_CIPHER, cbc) <= 0
|
||||
|| EVP_MAC_ctrl(ctx->mac_ctx_init, EVP_MAC_CTRL_SET_KEY, key, klen) <= 0
|
||||
|| !EVP_EncryptInit_ex(ctx->cipher_ctx, ctr, NULL, key + klen, NULL)
|
||||
|| !EVP_MAC_CTX_copy(ctx->mac_ctx, ctx->mac_ctx_init)
|
||||
|| !EVP_MAC_update(ctx->mac_ctx, zero, sizeof(zero))
|
||||
|
||||
@@ -1080,7 +1080,7 @@ static const unsigned char so[7775] = {
|
||||
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75, /* [ 7766] OBJ_SM2_with_SM3 */
|
||||
};
|
||||
|
||||
#define NUM_NID 1206
|
||||
#define NUM_NID 1207
|
||||
static const ASN1_OBJECT nid_objs[NUM_NID] = {
|
||||
{"UNDEF", "undefined", NID_undef},
|
||||
{"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
|
||||
@@ -2287,10 +2287,11 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
|
||||
{"BLAKE2SMAC", "blake2smac", NID_blake2smac},
|
||||
{"SSHKDF", "sshkdf", NID_sshkdf},
|
||||
{"SM2-SM3", "SM2-with-SM3", NID_SM2_with_SM3, 8, &so[7766]},
|
||||
{"SSKDF", "sskdf", NID_sskdf},
|
||||
{"ChaCha20-Poly1305-D", "chacha20-poly1305-draft", NID_chacha20_poly1305_draft},
|
||||
};
|
||||
|
||||
#define NUM_SN 1197
|
||||
#define NUM_SN 1198
|
||||
static const unsigned int sn_objs[NUM_SN] = {
|
||||
364, /* "AD_DVCS" */
|
||||
419, /* "AES-128-CBC" */
|
||||
@@ -2413,7 +2414,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
417, /* "CSPName" */
|
||||
1019, /* "ChaCha20" */
|
||||
1018, /* "ChaCha20-Poly1305" */
|
||||
1205, /* "ChaCha20-Poly1305-D" */
|
||||
1206, /* "ChaCha20-Poly1305-D" */
|
||||
367, /* "CrlID" */
|
||||
391, /* "DC" */
|
||||
31, /* "DES-CBC" */
|
||||
@@ -2579,6 +2580,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
100, /* "SN" */
|
||||
1006, /* "SNILS" */
|
||||
1203, /* "SSHKDF" */
|
||||
1205, /* "SSKDF" */
|
||||
16, /* "ST" */
|
||||
143, /* "SXNetID" */
|
||||
1062, /* "SipHash" */
|
||||
@@ -3491,7 +3493,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
1093, /* "x509ExtAdmission" */
|
||||
};
|
||||
|
||||
#define NUM_LN 1197
|
||||
#define NUM_LN 1198
|
||||
static const unsigned int ln_objs[NUM_LN] = {
|
||||
363, /* "AD Time Stamping" */
|
||||
405, /* "ANSI X9.62" */
|
||||
@@ -3876,7 +3878,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
883, /* "certificateRevocationList" */
|
||||
1019, /* "chacha20" */
|
||||
1018, /* "chacha20-poly1305" */
|
||||
1205, /* "chacha20-poly1305-draft" */
|
||||
1206, /* "chacha20-poly1305-draft" */
|
||||
54, /* "challengePassword" */
|
||||
407, /* "characteristic-two-field" */
|
||||
395, /* "clearance" */
|
||||
@@ -4644,6 +4646,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
1133, /* "sm4-ecb" */
|
||||
1135, /* "sm4-ofb" */
|
||||
1203, /* "sshkdf" */
|
||||
1205, /* "sskdf" */
|
||||
16, /* "stateOrProvinceName" */
|
||||
660, /* "streetAddress" */
|
||||
498, /* "subtreeMaximumQuality" */
|
||||
|
||||
@@ -1202,4 +1202,5 @@ blake2bmac 1201
|
||||
blake2smac 1202
|
||||
sshkdf 1203
|
||||
SM2_with_SM3 1204
|
||||
chacha20_poly1305_draft 1205
|
||||
sskdf 1205
|
||||
chacha20_poly1305_draft 1206
|
||||
@@ -1615,6 +1615,9 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme
|
||||
# NID for SSHKDF
|
||||
: SSHKDF : sshkdf
|
||||
|
||||
# NID for SSKDF
|
||||
: SSKDF : sskdf
|
||||
|
||||
# RFC 4556
|
||||
1 3 6 1 5 2 3 : id-pkinit
|
||||
id-pkinit 4 : pkInitClientAuth : PKINIT Client Auth
|
||||
|
||||
@@ -88,7 +88,7 @@ OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
|
||||
int OCSP_id_issuer_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b)
|
||||
{
|
||||
int ret;
|
||||
ret = OBJ_cmp(a->hashAlgorithm.algorithm, b->hashAlgorithm.algorithm);
|
||||
@@ -100,7 +100,7 @@ int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
|
||||
return ASN1_OCTET_STRING_cmp(&a->issuerKeyHash, &b->issuerKeyHash);
|
||||
}
|
||||
|
||||
int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
|
||||
int OCSP_id_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b)
|
||||
{
|
||||
int ret;
|
||||
ret = OCSP_id_issuer_cmp(a, b);
|
||||
|
||||
+30
-175
@@ -41,50 +41,22 @@ static OSSL_PARAM ossl_param_construct(const char *key, unsigned int data_type,
|
||||
|
||||
int OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val)
|
||||
{
|
||||
if (val == NULL || p == NULL || p->data_type != OSSL_PARAM_INTEGER)
|
||||
return 0;
|
||||
|
||||
switch (p->data_size) {
|
||||
switch (sizeof(int)) {
|
||||
case sizeof(int32_t):
|
||||
if (sizeof(int) >= sizeof(int32_t)) {
|
||||
*val = (int)*(const int32_t *)p->data;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_get_int32(p, (int32_t *)val);
|
||||
case sizeof(int64_t):
|
||||
if (sizeof(int) >= sizeof(int64_t)) {
|
||||
*val = (int)*(const int64_t *)p->data;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_get_int64(p, (int64_t *)val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OSSL_PARAM_set_int(const OSSL_PARAM *p, int val)
|
||||
{
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
SET_RETURN_SIZE(p, 0);
|
||||
if (p->data_type != OSSL_PARAM_INTEGER)
|
||||
return 0;
|
||||
|
||||
SET_RETURN_SIZE(p, sizeof(int)); /* Minimum expected size */
|
||||
switch (p->data_size) {
|
||||
switch (sizeof(int)) {
|
||||
case sizeof(int32_t):
|
||||
if (sizeof(int32_t) >= sizeof(int)) {
|
||||
SET_RETURN_SIZE(p, sizeof(int32_t));
|
||||
*(int32_t *)p->data = (int32_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_set_int32(p, (int32_t)val);
|
||||
case sizeof(int64_t):
|
||||
if (sizeof(int64_t) >= sizeof(int)) {
|
||||
SET_RETURN_SIZE(p, sizeof(int64_t));
|
||||
*(int64_t *)p->data = (int64_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_set_int64(p, (int64_t)val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -97,52 +69,22 @@ OSSL_PARAM OSSL_PARAM_construct_int(const char *key, int *buf, size_t *rsize)
|
||||
|
||||
int OSSL_PARAM_get_uint(const OSSL_PARAM *p, unsigned int *val)
|
||||
{
|
||||
if (val == NULL
|
||||
|| p == NULL
|
||||
|| (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
|
||||
return 0;
|
||||
|
||||
switch (p->data_size) {
|
||||
switch (sizeof(unsigned int)) {
|
||||
case sizeof(uint32_t):
|
||||
if (sizeof(unsigned int) >= sizeof(uint32_t)) {
|
||||
*val = (unsigned int)*(const uint32_t *)p->data;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
|
||||
case sizeof(uint64_t):
|
||||
if (sizeof(unsigned int) >= sizeof(uint64_t)) {
|
||||
*val = (unsigned int)*(const uint64_t *)p->data;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OSSL_PARAM_set_uint(const OSSL_PARAM *p, unsigned int val)
|
||||
{
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
SET_RETURN_SIZE(p, 0);
|
||||
if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
|
||||
return 0;
|
||||
|
||||
SET_RETURN_SIZE(p, sizeof(unsigned int)); /* Minimum expected size */
|
||||
switch (p->data_size) {
|
||||
switch (sizeof(unsigned int)) {
|
||||
case sizeof(uint32_t):
|
||||
if (sizeof(uint32_t) >= sizeof(unsigned int)) {
|
||||
SET_RETURN_SIZE(p, sizeof(uint32_t));
|
||||
*(uint32_t *)p->data = (uint32_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_set_uint32(p, (uint32_t)val);
|
||||
case sizeof(uint64_t):
|
||||
if (sizeof(uint64_t) >= sizeof(unsigned int)) {
|
||||
SET_RETURN_SIZE(p, sizeof(uint64_t));
|
||||
*(uint64_t *)p->data = (uint64_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_set_uint64(p, (uint64_t)val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -156,49 +98,22 @@ OSSL_PARAM OSSL_PARAM_construct_uint(const char *key, unsigned int *buf,
|
||||
|
||||
int OSSL_PARAM_get_long(const OSSL_PARAM *p, long int *val)
|
||||
{
|
||||
if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
|
||||
return 0;
|
||||
|
||||
switch (p->data_size) {
|
||||
switch (sizeof(long int)) {
|
||||
case sizeof(int32_t):
|
||||
if (sizeof(long int) >= sizeof(int32_t)) {
|
||||
*val = (long int)*(const int32_t *)p->data;
|
||||
return 1;
|
||||
} break;
|
||||
return OSSL_PARAM_get_int32(p, (int32_t *)val);
|
||||
case sizeof(int64_t):
|
||||
if (sizeof(long int) >= sizeof(int64_t)) {
|
||||
*val = (long int)*(const int64_t *)p->data;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_get_int64(p, (int64_t *)val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OSSL_PARAM_set_long(const OSSL_PARAM *p, long int val)
|
||||
{
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
SET_RETURN_SIZE(p, 0);
|
||||
if (p->data_type != OSSL_PARAM_INTEGER)
|
||||
return 0;
|
||||
|
||||
SET_RETURN_SIZE(p, sizeof(long int)); /* Minimum expected size */
|
||||
switch (p->data_size) {
|
||||
switch (sizeof(long int)) {
|
||||
case sizeof(int32_t):
|
||||
if (sizeof(int32_t) >= sizeof(long int)) {
|
||||
SET_RETURN_SIZE(p, sizeof(int32_t));
|
||||
*(int32_t *)p->data = (int32_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_set_int32(p, (int32_t)val);
|
||||
case sizeof(int64_t):
|
||||
if (sizeof(int64_t) >= sizeof(long int)) {
|
||||
SET_RETURN_SIZE(p, sizeof(int64_t));
|
||||
*(int64_t *)p->data = (int64_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_set_int64(p, (int64_t)val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -212,52 +127,22 @@ OSSL_PARAM OSSL_PARAM_construct_long(const char *key, long int *buf,
|
||||
|
||||
int OSSL_PARAM_get_ulong(const OSSL_PARAM *p, unsigned long int *val)
|
||||
{
|
||||
if (val == NULL
|
||||
|| p == NULL
|
||||
|| (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
|
||||
return 0;
|
||||
|
||||
switch (p->data_size) {
|
||||
switch (sizeof(unsigned long int)) {
|
||||
case sizeof(uint32_t):
|
||||
if (sizeof(unsigned long int) >= sizeof(uint32_t)) {
|
||||
*val = (unsigned long int)*(const uint32_t *)p->data;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
|
||||
case sizeof(uint64_t):
|
||||
if (sizeof(unsigned long int) >= sizeof(uint64_t)) {
|
||||
*val = (unsigned long int)*(const uint64_t *)p->data;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OSSL_PARAM_set_ulong(const OSSL_PARAM *p, unsigned long int val)
|
||||
{
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
SET_RETURN_SIZE(p, 0);
|
||||
if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
|
||||
return 0;
|
||||
|
||||
SET_RETURN_SIZE(p, sizeof(unsigned long int)); /* Minimum exp size */
|
||||
switch (p->data_size) {
|
||||
switch (sizeof(unsigned long int)) {
|
||||
case sizeof(uint32_t):
|
||||
if (sizeof(uint32_t) >= sizeof(unsigned long int)) {
|
||||
SET_RETURN_SIZE(p, sizeof(uint32_t));
|
||||
*(uint32_t *)p->data = (uint32_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_set_uint32(p, (uint32_t)val);
|
||||
case sizeof(uint64_t):
|
||||
if (sizeof(uint64_t) >= sizeof(unsigned long int)) {
|
||||
SET_RETURN_SIZE(p, sizeof(uint64_t));
|
||||
*(uint64_t *)p->data = (uint64_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_set_uint64(p, (uint64_t)val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -437,52 +322,22 @@ OSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf,
|
||||
|
||||
int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val)
|
||||
{
|
||||
if (val == NULL
|
||||
|| p == NULL
|
||||
|| p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
|
||||
return 0;
|
||||
|
||||
switch (p->data_size) {
|
||||
switch (sizeof(size_t)) {
|
||||
case sizeof(uint32_t):
|
||||
if (sizeof(size_t) >= sizeof(uint32_t)) {
|
||||
*val = (size_t)*(const uint32_t *)p->data;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
|
||||
case sizeof(uint64_t):
|
||||
if (sizeof(size_t) >= sizeof(uint64_t)) {
|
||||
*val = (size_t)*(const uint64_t *)p->data;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OSSL_PARAM_set_size_t(const OSSL_PARAM *p, size_t val)
|
||||
{
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
SET_RETURN_SIZE(p, 0);
|
||||
if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
|
||||
return 0;
|
||||
|
||||
SET_RETURN_SIZE(p, sizeof(size_t)); /* Minimum expected size */
|
||||
switch (p->data_size) {
|
||||
switch (sizeof(size_t)) {
|
||||
case sizeof(uint32_t):
|
||||
if (sizeof(uint32_t) >= sizeof(size_t)) {
|
||||
SET_RETURN_SIZE(p, sizeof(uint32_t));
|
||||
*(uint32_t *)p->data = (uint32_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_set_uint32(p, (uint32_t)val);
|
||||
case sizeof(uint64_t):
|
||||
SET_RETURN_SIZE(p, sizeof(uint64_t));
|
||||
if (sizeof(uint64_t) >= sizeof(size_t)) {
|
||||
*(uint64_t *)p->data = (uint64_t)val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
return OSSL_PARAM_set_uint64(p, (uint64_t)val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,365 @@
|
||||
// ====================================================================
|
||||
// Written by Andy Polyakov, @dot-asm, initially for use in the OpenSSL
|
||||
// project.
|
||||
// ====================================================================
|
||||
//
|
||||
// Poly1305 for Itanium.
|
||||
//
|
||||
// January 2019
|
||||
//
|
||||
// Performance was reported to be ~2.1 cycles per byte on Itanium 2.
|
||||
// With exception for processors in 95xx family, which have higher
|
||||
// floating-point instructions' latencies and deliver ~2.6 cpb.
|
||||
// Comparison to compiler-generated code is not exactly fair, because
|
||||
// of different radixes. But just for reference, it was observed to be
|
||||
// >3x faster. Originally it was argued that floating-point base 2^32
|
||||
// implementation would be optimal. Upon closer look estimate for below
|
||||
// integer base 2^64 implementation turned to be approximately same on
|
||||
// Itanium 2. But floating-point code would be larger, and have higher
|
||||
// overhead, which would negatively affect small-block performance...
|
||||
|
||||
#if defined(_HPUX_SOURCE)
|
||||
# if !defined(_LP64)
|
||||
# define ADDP addp4
|
||||
# else
|
||||
# define ADDP add
|
||||
# endif
|
||||
# define RUM rum
|
||||
# define SUM sum
|
||||
#else
|
||||
# define ADDP add
|
||||
# define RUM nop
|
||||
# define SUM nop
|
||||
#endif
|
||||
|
||||
.text
|
||||
.explicit
|
||||
|
||||
.global poly1305_init#
|
||||
.proc poly1305_init#
|
||||
.align 64
|
||||
poly1305_init:
|
||||
.prologue
|
||||
.save ar.pfs,r2
|
||||
{ .mmi; alloc r2=ar.pfs,2,0,0,0
|
||||
cmp.eq p6,p7=0,r33 } // key == NULL?
|
||||
{ .mmi; ADDP r9=8,r32
|
||||
ADDP r10=16,r32
|
||||
ADDP r32=0,r32 };;
|
||||
.body
|
||||
{ .mmi; st8 [r32]=r0,24 // ctx->h0 = 0
|
||||
st8 [r9]=r0 // ctx->h1 = 0
|
||||
(p7) ADDP r8=0,r33 }
|
||||
{ .mib; st8 [r10]=r0 // ctx->h2 = 0
|
||||
(p6) mov r8=0
|
||||
(p6) br.ret.spnt b0 };;
|
||||
|
||||
{ .mmi; ADDP r9=1,r33
|
||||
ADDP r10=2,r33
|
||||
ADDP r11=3,r33 };;
|
||||
{ .mmi; ld1 r16=[r8],4 // load key, little-endian
|
||||
ld1 r17=[r9],4 }
|
||||
{ .mmi; ld1 r18=[r10],4
|
||||
ld1 r19=[r11],4 };;
|
||||
{ .mmi; ld1 r20=[r8],4
|
||||
ld1 r21=[r9],4 }
|
||||
{ .mmi; ld1 r22=[r10],4
|
||||
ld1 r23=[r11],4
|
||||
and r19=15,r19 };;
|
||||
{ .mmi; ld1 r24=[r8],4
|
||||
ld1 r25=[r9],4
|
||||
and r20=-4,r20 }
|
||||
{ .mmi; ld1 r26=[r10],4
|
||||
ld1 r27=[r11],4
|
||||
and r23=15,r23 };;
|
||||
{ .mmi; ld1 r28=[r8],4
|
||||
ld1 r29=[r9],4
|
||||
and r24=-4,r24 }
|
||||
{ .mmi; ld1 r30=[r10],4
|
||||
ld1 r31=[r11],4
|
||||
and r27=15,r27 };;
|
||||
|
||||
{ .mii; and r28=-4,r28
|
||||
dep r16=r17,r16,8,8
|
||||
dep r18=r19,r18,8,8 };;
|
||||
{ .mii; and r31=15,r31
|
||||
dep r16=r18,r16,16,16
|
||||
dep r20=r21,r20,8,8 };;
|
||||
{ .mii; dep r16=r20,r16,32,16
|
||||
dep r22=r23,r22,8,8 };;
|
||||
{ .mii; dep r16=r22,r16,48,16
|
||||
dep r24=r25,r24,8,8 };;
|
||||
{ .mii; dep r26=r27,r26,8,8
|
||||
dep r28=r29,r28,8,8 };;
|
||||
{ .mii; dep r24=r26,r24,16,16
|
||||
dep r30=r31,r30,8,8 };;
|
||||
{ .mii; st8 [r32]=r16,8 // ctx->r0
|
||||
dep r24=r28,r24,32,16;;
|
||||
dep r24=r30,r24,48,16 };;
|
||||
{ .mii; st8 [r32]=r24,8 // ctx->r1
|
||||
shr.u r25=r24,2;;
|
||||
add r25=r25,r24 };;
|
||||
{ .mib; st8 [r32]=r25 // ctx->s1
|
||||
mov r8=0
|
||||
br.ret.sptk b0 };;
|
||||
.endp poly1305_init#
|
||||
|
||||
h0=r17; h1=r18; h2=r19;
|
||||
i0=r20; i1=r21;
|
||||
HF0=f8; HF1=f9; HF2=f10;
|
||||
RF0=f11; RF1=f12; SF1=f13;
|
||||
|
||||
.global poly1305_blocks#
|
||||
.proc poly1305_blocks#
|
||||
.align 64
|
||||
poly1305_blocks:
|
||||
.prologue
|
||||
.save ar.pfs,r2
|
||||
{ .mii; alloc r2=ar.pfs,4,1,0,0
|
||||
.save ar.lc,r3
|
||||
mov r3=ar.lc
|
||||
.save pr,r36
|
||||
mov r36=pr }
|
||||
|
||||
.body
|
||||
{ .mmi; ADDP r8=0,r32
|
||||
ADDP r9=8,r32
|
||||
and r29=7,r33 };;
|
||||
{ .mmi; ld8 h0=[r8],16
|
||||
ld8 h1=[r9],16
|
||||
and r33=-8,r33 };;
|
||||
{ .mmi; ld8 h2=[r8],16
|
||||
ldf8 RF0=[r9],16
|
||||
shr.u r34=r34,4 };;
|
||||
{ .mmi; ldf8 RF1=[r8],-32
|
||||
ldf8 SF1=[r9],-32
|
||||
cmp.ltu p16,p17=1,r34 };;
|
||||
{ .mmi;
|
||||
(p16) add r34=-2,r34
|
||||
(p17) mov r34=0
|
||||
ADDP r10=0,r33 }
|
||||
{ .mii; ADDP r11=8,r33
|
||||
(p16) mov ar.ec=2
|
||||
(p17) mov ar.ec=1 };;
|
||||
{ .mib; RUM 1<<1 // go little-endian
|
||||
mov ar.lc=r34
|
||||
brp.loop.imp .Loop,.Lcend-16 }
|
||||
|
||||
{ .mmi; cmp.eq p8,p7=0,r29
|
||||
cmp.eq p9,p0=1,r29
|
||||
cmp.eq p10,p0=2,r29 }
|
||||
{ .mmi; cmp.eq p11,p0=3,r29
|
||||
cmp.eq p12,p0=4,r29
|
||||
cmp.eq p13,p0=5,r29 }
|
||||
{ .mmi; cmp.eq p14,p0=6,r29
|
||||
cmp.eq p15,p0=7,r29
|
||||
add r16=16,r10 };;
|
||||
|
||||
{ .mmb;
|
||||
(p8) ld8 i0=[r10],16 // aligned input
|
||||
(p8) ld8 i1=[r11],16
|
||||
(p8) br.cond.sptk .Loop };;
|
||||
|
||||
// align first block
|
||||
.pred.rel "mutex",p8,p9,p10,p11,p12,p13,p14,p15
|
||||
{ .mmi; (p7) ld8 r14=[r10],24
|
||||
(p7) ld8 r15=[r11],24 }
|
||||
|
||||
{ .mii; (p7) ld8 r16=[r16]
|
||||
nop.i 0;;
|
||||
(p15) shrp i0=r15,r14,56 }
|
||||
{ .mii; (p15) shrp i1=r16,r15,56
|
||||
(p14) shrp i0=r15,r14,48 }
|
||||
{ .mii; (p14) shrp i1=r16,r15,48
|
||||
(p13) shrp i0=r15,r14,40 }
|
||||
{ .mii; (p13) shrp i1=r16,r15,40
|
||||
(p12) shrp i0=r15,r14,32 }
|
||||
{ .mii; (p12) shrp i1=r16,r15,32
|
||||
(p11) shrp i0=r15,r14,24 }
|
||||
{ .mii; (p11) shrp i1=r16,r15,24
|
||||
(p10) shrp i0=r15,r14,16 }
|
||||
{ .mii; (p10) shrp i1=r16,r15,16
|
||||
(p9) shrp i0=r15,r14,8 }
|
||||
{ .mii; (p9) shrp i1=r16,r15,8
|
||||
mov r14=r16 };;
|
||||
|
||||
.Loop:
|
||||
.pred.rel "mutex",p8,p9,p10,p11,p12,p13,p14,p15
|
||||
{ .mmi; add h0=h0,i0
|
||||
add h1=h1,i1
|
||||
add h2=h2,r35 };;
|
||||
{ .mmi; setf.sig HF0=h0
|
||||
cmp.ltu p6,p0=h0,i0
|
||||
cmp.ltu p7,p0=h1,i1 };;
|
||||
{ .mmi; (p6) add h1=1,h1;;
|
||||
setf.sig HF1=h1
|
||||
(p6) cmp.eq.or p7,p0=0,h1 };;
|
||||
{ .mmi; (p7) add h2=1,h2;;
|
||||
setf.sig HF2=h2 };;
|
||||
|
||||
{ .mfi; (p16) ld8 r15=[r10],16
|
||||
xmpy.lu f32=HF0,RF0 }
|
||||
{ .mfi; (p16) ld8 r16=[r11],16
|
||||
xmpy.hu f33=HF0,RF0 }
|
||||
{ .mfi; xmpy.lu f36=HF0,RF1 }
|
||||
{ .mfi; xmpy.hu f37=HF0,RF1 };;
|
||||
{ .mfi; xmpy.lu f34=HF1,SF1
|
||||
(p15) shrp i0=r15,r14,56 }
|
||||
{ .mfi; xmpy.hu f35=HF1,SF1 }
|
||||
{ .mfi; xmpy.lu f38=HF1,RF0
|
||||
(p15) shrp i1=r16,r15,56 }
|
||||
{ .mfi; xmpy.hu f39=HF1,RF0 }
|
||||
{ .mfi; xmpy.lu f40=HF2,SF1
|
||||
(p14) shrp i0=r15,r14,48 }
|
||||
{ .mfi; xmpy.lu f41=HF2,RF0 };;
|
||||
|
||||
{ .mmi; getf.sig r22=f32
|
||||
getf.sig r23=f33
|
||||
(p14) shrp i1=r16,r15,48 }
|
||||
{ .mmi; getf.sig r24=f34
|
||||
getf.sig r25=f35
|
||||
(p13) shrp i0=r15,r14,40 }
|
||||
{ .mmi; getf.sig r26=f36
|
||||
getf.sig r27=f37
|
||||
(p13) shrp i1=r16,r15,40 }
|
||||
{ .mmi; getf.sig r28=f38
|
||||
getf.sig r29=f39
|
||||
(p12) shrp i0=r15,r14,32 }
|
||||
{ .mmi; getf.sig r30=f40
|
||||
getf.sig r31=f41 };;
|
||||
|
||||
{ .mmi; add h0=r22,r24
|
||||
add r23=r23,r25
|
||||
(p12) shrp i1=r16,r15,32 }
|
||||
{ .mmi; add h1=r26,r28
|
||||
add r27=r27,r29
|
||||
(p11) shrp i0=r15,r14,24 };;
|
||||
{ .mmi; cmp.ltu p6,p0=h0,r24
|
||||
cmp.ltu p7,p0=h1,r28
|
||||
add r23=r23,r30 };;
|
||||
{ .mmi; (p6) add r23=1,r23
|
||||
(p7) add r27=1,r27
|
||||
(p11) shrp i1=r16,r15,24 };;
|
||||
{ .mmi; add h1=h1,r23;;
|
||||
cmp.ltu p6,p7=h1,r23
|
||||
(p10) shrp i0=r15,r14,16 };;
|
||||
{ .mmi; (p6) add h2=r31,r27,1
|
||||
(p7) add h2=r31,r27
|
||||
(p10) shrp i1=r16,r15,16 };;
|
||||
|
||||
{ .mmi; (p8) mov i0=r15
|
||||
and r22=-4,h2
|
||||
shr.u r23=h2,2 };;
|
||||
{ .mmi; add r22=r22,r23
|
||||
and h2=3,h2
|
||||
(p9) shrp i0=r15,r14,8 };;
|
||||
|
||||
{ .mmi; add h0=h0,r22;;
|
||||
cmp.ltu p6,p0=h0,r22
|
||||
(p9) shrp i1=r16,r15,8 };;
|
||||
{ .mmi; (p8) mov i1=r16
|
||||
(p6) cmp.eq.unc p7,p0=-1,h1
|
||||
(p6) add h1=1,h1 };;
|
||||
{ .mmb; (p7) add h2=1,h2
|
||||
mov r14=r16
|
||||
br.ctop.sptk .Loop };;
|
||||
.Lcend:
|
||||
|
||||
{ .mii; SUM 1<<1 // back to big-endian
|
||||
mov ar.lc=r3 };;
|
||||
|
||||
{ .mmi; st8 [r8]=h0,16
|
||||
st8 [r9]=h1
|
||||
mov pr=r36,0x1ffff };;
|
||||
{ .mmb; st8 [r8]=h2
|
||||
rum 1<<5
|
||||
br.ret.sptk b0 };;
|
||||
.endp poly1305_blocks#
|
||||
|
||||
.global poly1305_emit#
|
||||
.proc poly1305_emit#
|
||||
.align 64
|
||||
poly1305_emit:
|
||||
.prologue
|
||||
.save ar.pfs,r2
|
||||
{ .mmi; alloc r2=ar.pfs,3,0,0,0
|
||||
ADDP r8=0,r32
|
||||
ADDP r9=8,r32 };;
|
||||
|
||||
.body
|
||||
{ .mmi; ld8 r16=[r8],16 // load hash
|
||||
ld8 r17=[r9]
|
||||
ADDP r10=0,r34 };;
|
||||
{ .mmi; ld8 r18=[r8]
|
||||
ld4 r24=[r10],8 // load nonce
|
||||
ADDP r11=4,r34 };;
|
||||
|
||||
{ .mmi; ld4 r25=[r11],8
|
||||
ld4 r26=[r10]
|
||||
add r20=5,r16 };;
|
||||
|
||||
{ .mmi; ld4 r27=[r11]
|
||||
cmp.ltu p6,p7=r20,r16
|
||||
shl r25=r25,32 };;
|
||||
{ .mmi;
|
||||
(p6) add r21=1,r17
|
||||
(p7) add r21=0,r17
|
||||
(p6) cmp.eq.or.andcm p6,p7=-1,r17 };;
|
||||
{ .mmi;
|
||||
(p6) add r22=1,r18
|
||||
(p7) add r22=0,r18
|
||||
shl r27=r27,32 };;
|
||||
{ .mmi; or r24=r24,r25
|
||||
or r26=r26,r27
|
||||
cmp.leu p6,p7=4,r22 };;
|
||||
{ .mmi;
|
||||
(p6) add r16=r20,r24
|
||||
(p7) add r16=r16,r24
|
||||
(p6) add r17=r21,r26 };;
|
||||
{ .mii;
|
||||
(p7) add r17=r17,r26
|
||||
cmp.ltu p6,p7=r16,r24;;
|
||||
(p6) add r17=1,r17 };;
|
||||
|
||||
{ .mmi; ADDP r8=0,r33
|
||||
ADDP r9=4,r33
|
||||
shr.u r20=r16,32 }
|
||||
{ .mmi; ADDP r10=8,r33
|
||||
ADDP r11=12,r33
|
||||
shr.u r21=r17,32 };;
|
||||
|
||||
{ .mmi; st1 [r8]=r16,1 // write mac, little-endian
|
||||
st1 [r9]=r20,1
|
||||
shr.u r16=r16,8 }
|
||||
{ .mii; st1 [r10]=r17,1
|
||||
shr.u r20=r20,8
|
||||
shr.u r17=r17,8 }
|
||||
{ .mmi; st1 [r11]=r21,1
|
||||
shr.u r21=r21,8 };;
|
||||
|
||||
{ .mmi; st1 [r8]=r16,1
|
||||
st1 [r9]=r20,1
|
||||
shr.u r16=r16,8 }
|
||||
{ .mii; st1 [r10]=r17,1
|
||||
shr.u r20=r20,8
|
||||
shr.u r17=r17,8 }
|
||||
{ .mmi; st1 [r11]=r21,1
|
||||
shr.u r21=r21,8 };;
|
||||
|
||||
{ .mmi; st1 [r8]=r16,1
|
||||
st1 [r9]=r20,1
|
||||
shr.u r16=r16,8 }
|
||||
{ .mii; st1 [r10]=r17,1
|
||||
shr.u r20=r20,8
|
||||
shr.u r17=r17,8 }
|
||||
{ .mmi; st1 [r11]=r21,1
|
||||
shr.u r21=r21,8 };;
|
||||
|
||||
{ .mmi; st1 [r8]=r16
|
||||
st1 [r9]=r20 }
|
||||
{ .mmb; st1 [r10]=r17
|
||||
st1 [r11]=r21
|
||||
br.ret.sptk b0 };;
|
||||
.endp poly1305_emit#
|
||||
|
||||
stringz "Poly1305 for IA64, CRYPTOGAMS by \@dot-asm"
|
||||
@@ -32,10 +32,20 @@
|
||||
# Copyright IBM Corp. 2019
|
||||
# Author: Patrick Steuer <patrick.steuer@de.ibm.com>
|
||||
|
||||
#
|
||||
# January 2019
|
||||
#
|
||||
# Add vector base 2^26 implementation. It's problematic to accurately
|
||||
# measure performance, because reference system is hardly idle. But
|
||||
# it's sub-cycle, i.e. less than 1 cycle per processed byte, and it's
|
||||
# >=20% faster than IBM's submission on long inputs, and much faster on
|
||||
# short ones, because calculation of key powers is postponed till we
|
||||
# know that input is long enough to justify the additional overhead.
|
||||
|
||||
use strict;
|
||||
use FindBin qw($Bin);
|
||||
use lib "$Bin/../..";
|
||||
use perlasm::s390x qw(:DEFAULT :VX AUTOLOAD LABEL);
|
||||
use perlasm::s390x qw(:DEFAULT :VX AUTOLOAD LABEL INCLUDE);
|
||||
|
||||
my $flavour = shift;
|
||||
|
||||
@@ -51,666 +61,98 @@ if ($flavour =~ /3[12]/) {
|
||||
my $output;
|
||||
while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
|
||||
|
||||
my $stdframe=16*$SIZE_T+4*8;
|
||||
my $sp="%r15";
|
||||
|
||||
# novx code path ctx layout
|
||||
# ---------------------------------
|
||||
# var value base off
|
||||
# ---------------------------------
|
||||
# u64 h[3] hash 2^64 0
|
||||
# u32 pad[2]
|
||||
# u64 r[2] key 2^64 32
|
||||
|
||||
# vx code path ctx layout
|
||||
# ---------------------------------
|
||||
# var value base off
|
||||
# ---------------------------------
|
||||
# u32 acc1[5] r^2-acc 2^26 0
|
||||
# u32 pad
|
||||
# u32 acc2[5] r-acc 2^26 24
|
||||
# u32 pad
|
||||
# u32 r1[5] r 2^26 48
|
||||
# u32 r15[5] 5*r 2^26 68
|
||||
# u32 r2[5] r^2 2^26 88
|
||||
# u32 r25[5] 5*r^2 2^26 108
|
||||
# u32 r4[5] r^4 2^26 128
|
||||
# u32 r45[5] 5*r^4 2^26 148
|
||||
my ($ctx,$inp,$len,$padbit) = map("%r$_",(2..5));
|
||||
|
||||
PERLASM_BEGIN($output);
|
||||
|
||||
INCLUDE ("s390x_arch.h");
|
||||
TEXT ();
|
||||
|
||||
################
|
||||
# static void poly1305_init(void *ctx, const unsigned char key[16])
|
||||
{
|
||||
my ($ctx,$key)=map("%r$_",(2..3));
|
||||
my ($r0,$r1,$r2)=map("%r$_",(9,11,13));
|
||||
|
||||
sub MUL_RKEY { # r*=key
|
||||
my ($d0hi,$d0lo,$d1hi,$d1lo)=map("%r$_",(4..7));
|
||||
my ($t0,$t1,$s1)=map("%r$_",(8,10,12));
|
||||
|
||||
lg ("%r0","32($ctx)");
|
||||
lg ("%r1","40($ctx)");
|
||||
|
||||
srlg ($s1,"%r1",2);
|
||||
algr ($s1,"%r1");
|
||||
|
||||
lgr ($d0lo,$r0);
|
||||
lgr ($d1lo,$r1);
|
||||
|
||||
mlgr ($d0hi,"%r0");
|
||||
lgr ($r1,$d1lo);
|
||||
mlgr ($d1hi,$s1);
|
||||
|
||||
mlgr ($t0,"%r1");
|
||||
mlgr ($t1,"%r0");
|
||||
|
||||
algr ($d0lo,$d1lo);
|
||||
lgr ($d1lo,$r2);
|
||||
alcgr ($d0hi,$d1hi);
|
||||
lghi ($d1hi,0);
|
||||
|
||||
algr ($r1,$r0);
|
||||
alcgr ($t1,$t0);
|
||||
|
||||
msgr ($d1lo,$s1);
|
||||
msgr ($r2,"%r0");
|
||||
|
||||
algr ($r1,$d1lo);
|
||||
alcgr ($t1,$d1hi);
|
||||
|
||||
algr ($r1,$d0hi);
|
||||
alcgr ($r2,$t1);
|
||||
|
||||
lghi ($r0,-4);
|
||||
ngr ($r0,$r2);
|
||||
srlg ($t0,$r2,2);
|
||||
algr ($r0,$t0);
|
||||
lghi ($t1,3);
|
||||
ngr ($r2,$t1);
|
||||
|
||||
algr ($r0,$d0lo);
|
||||
alcgr ($r1,$d1hi);
|
||||
alcgr ($r2,$d1hi);
|
||||
}
|
||||
|
||||
sub ST_R5R { # store r,5*r -> base 2^26
|
||||
my @d=map("%r$_",(4..8));
|
||||
my @off=@_;
|
||||
|
||||
lgr (@d[2],$r0);
|
||||
lr ("%r1",@d[2]);
|
||||
nilh ("%r1",1023);
|
||||
lgr (@d[3],$r1);
|
||||
lr (@d[0],"%r1");
|
||||
srlg ("%r1",@d[2],52);
|
||||
lgr (@d[4],$r2);
|
||||
srlg ("%r0",@d[2],26);
|
||||
sll (@d[4],24);
|
||||
lr (@d[2],@d[3]);
|
||||
nilh ("%r0",1023);
|
||||
sll (@d[2],12);
|
||||
lr (@d[1],"%r0");
|
||||
&or (@d[2],"%r1");
|
||||
srlg ("%r1",@d[3],40);
|
||||
nilh (@d[2],1023);
|
||||
&or (@d[4],"%r1");
|
||||
srlg (@d[3],@d[3],14);
|
||||
nilh (@d[4],1023);
|
||||
nilh (@d[3],1023);
|
||||
|
||||
stm (@d[0],@d[4],"@off[0]($ctx)");
|
||||
mhi (@d[$_],5) for (0..4);
|
||||
stm (@d[0],@d[4],"@off[1]($ctx)");
|
||||
}
|
||||
|
||||
GLOBL ("poly1305_init");
|
||||
TYPE ("poly1305_init","\@function");
|
||||
ALIGN (16);
|
||||
LABEL ("poly1305_init");
|
||||
lghi ("%r0",0);
|
||||
lghi ("%r1",-1);
|
||||
stg ("%r0","0($ctx)"); # zero hash value / acc1
|
||||
stg ("%r0","0($ctx)"); # zero hash value
|
||||
stg ("%r0","8($ctx)");
|
||||
stg ("%r0","16($ctx)");
|
||||
st ("%r0","24($ctx)"); # clear is_base2_26
|
||||
lgr ("%r5",$ctx); # reassign $ctx
|
||||
lghi ("%r2",0);
|
||||
|
||||
&{$z? \&clgr:\&clr} ($key,"%r0");
|
||||
je (".Ldone");
|
||||
&{$z? \&clgr:\&clr} ($inp,"%r0");
|
||||
je (".Lno_key");
|
||||
|
||||
lrvg ("%r4","0($key)"); # load little-endian key
|
||||
lrvg ("%r5","8($key)");
|
||||
lrvg ("%r2","0($inp)"); # load little-endian key
|
||||
lrvg ("%r3","8($inp)");
|
||||
|
||||
nihl ("%r1",0xffc0); # 0xffffffc0ffffffff
|
||||
srlg ("%r0","%r1",4); # 0x0ffffffc0fffffff
|
||||
srlg ("%r1","%r1",4);
|
||||
nill ("%r1",0xfffc); # 0x0ffffffc0ffffffc
|
||||
|
||||
ngr ("%r4","%r0");
|
||||
ngr ("%r5","%r1");
|
||||
ngr ("%r2","%r0");
|
||||
ngr ("%r3","%r1");
|
||||
|
||||
stg ("%r4","32($ctx)");
|
||||
stg ("%r5","40($ctx)");
|
||||
stmg ("%r2","%r3","32(%r5)");
|
||||
|
||||
larl ("%r1","OPENSSL_s390xcap_P");
|
||||
lg ("%r0","16(%r1)");
|
||||
tmhh ("%r0",0x4000); # check for vector facility
|
||||
jz (".Ldone");
|
||||
|
||||
larl ("%r4","poly1305_blocks_vx");
|
||||
larl ("%r5","poly1305_emit_vx");
|
||||
|
||||
&{$z? \&stmg:\&stm} ("%r6","%r13","6*$SIZE_T($sp)");
|
||||
&{$z? \&stmg:\&stm} ("%r4","%r5","4*$z+228($ctx)");
|
||||
|
||||
lg ($r0,"32($ctx)");
|
||||
lg ($r1,"40($ctx)");
|
||||
lghi ($r2,0);
|
||||
|
||||
ST_R5R (48,68); # store r,5*r
|
||||
|
||||
MUL_RKEY();
|
||||
ST_R5R (88,108); # store r^2,5*r^2
|
||||
|
||||
MUL_RKEY();
|
||||
MUL_RKEY();
|
||||
ST_R5R (128,148); # store r^4,5*r^4
|
||||
|
||||
lghi ("%r0",0);
|
||||
stg ("%r0","24($ctx)"); # zero acc2
|
||||
stg ("%r0","32($ctx)");
|
||||
stg ("%r0","40($ctx)");
|
||||
|
||||
&{$z? \&lmg:\&lm} ("%r6","%r13","6*$SIZE_T($sp)");
|
||||
srlg ("%r0","%r0",62);
|
||||
nill ("%r0",1); # extract vx bit
|
||||
lcgr ("%r0","%r0");
|
||||
larl ("%r1",".Lpoly1305_blocks");
|
||||
larl ("%r2",".Lpoly1305_blocks_vx");
|
||||
larl ("%r3",".Lpoly1305_emit");
|
||||
&{$z? \&xgr:\&xr} ("%r2","%r1"); # select between scalar and vector
|
||||
&{$z? \&ngr:\&nr} ("%r2","%r0");
|
||||
&{$z? \&xgr:\&xr} ("%r2","%r1");
|
||||
&{$z? \&stmg:\&stm} ("%r2","%r3","0(%r4)");
|
||||
lghi ("%r2",1);
|
||||
br ("%r14");
|
||||
|
||||
LABEL (".Ldone");
|
||||
lghi ("%r2",0);
|
||||
LABEL (".Lno_key");
|
||||
br ("%r14");
|
||||
SIZE ("poly1305_init",".-poly1305_init");
|
||||
}
|
||||
|
||||
# VX CODE PATH
|
||||
{
|
||||
my $frame=8*16;
|
||||
my @m01=map("%v$_",(0..4));
|
||||
my @m23=map("%v$_",(5..9));
|
||||
my @tmp=@m23;
|
||||
my @acc=map("%v$_",(10..14));
|
||||
my @r=map("%v$_",(15..19));
|
||||
my @r5=map("%v$_",(20..24));
|
||||
my $padvec="%v26";
|
||||
my $mask4="%v27";
|
||||
my @vperm=map("%v$_",(28..30));
|
||||
my $mask="%v31";
|
||||
|
||||
sub REDUCE {
|
||||
vesrlg (@tmp[0],@acc[0],26);
|
||||
vesrlg (@tmp[3],@acc[3],26);
|
||||
vn (@acc[0],@acc[0],$mask);
|
||||
vn (@acc[3],@acc[3],$mask);
|
||||
vag (@acc[1],@acc[1],@tmp[0]); # carry 0->1
|
||||
vag (@acc[4],@acc[4],@tmp[3]); # carry 3->4
|
||||
|
||||
vesrlg (@tmp[1],@acc[1],26);
|
||||
vesrlg (@tmp[4],@acc[4],26);
|
||||
vn (@acc[1],@acc[1],$mask);
|
||||
vn (@acc[4],@acc[4],$mask);
|
||||
veslg (@tmp[0],@tmp[4],2);
|
||||
vag (@tmp[4],@tmp[4],@tmp[0]); # h[4]*=5
|
||||
vag (@acc[2],@acc[2],@tmp[1]); # carry 1->2
|
||||
vag (@acc[0],@acc[0],@tmp[4]); # carry 4->0
|
||||
|
||||
vesrlg (@tmp[2],@acc[2],26);
|
||||
vesrlg (@tmp[0],@acc[0],26);
|
||||
vn (@acc[2],@acc[2],$mask);
|
||||
vn (@acc[0],@acc[0],$mask);
|
||||
vag (@acc[3],@acc[3],@tmp[2]); # carry 2->3
|
||||
vag (@acc[1],@acc[1],@tmp[0]); # carry 0->1
|
||||
|
||||
vesrlg (@tmp[3],@acc[3],26);
|
||||
vn (@acc[3],@acc[3],$mask);
|
||||
vag (@acc[4],@acc[4],@tmp[3]); # carry 3->4
|
||||
}
|
||||
|
||||
################
|
||||
# static void poly1305_blocks_vx(void *ctx, const unsigned char *inp,
|
||||
# static void poly1305_blocks(void *ctx, const unsigned char *inp,
|
||||
# size_t len, u32 padbit)
|
||||
{
|
||||
my ($ctx,$inp,$len) = map("%r$_",(2..4));
|
||||
my $padbit="%r0";
|
||||
|
||||
GLOBL ("poly1305_blocks_vx");
|
||||
TYPE ("poly1305_blocks_vx","\@function");
|
||||
ALIGN (16);
|
||||
LABEL ("poly1305_blocks_vx");
|
||||
if ($z) {
|
||||
aghi ($sp,-$frame);
|
||||
vstm ("%v8","%v15","0($sp)");
|
||||
} else {
|
||||
std ("%f4","16*$SIZE_T+2*8($sp)");
|
||||
std ("%f6","16*$SIZE_T+3*8($sp)");
|
||||
llgfr ($len,$len);
|
||||
}
|
||||
llgfr ($padbit,"%r5");
|
||||
vlef (@acc[$_],"4*$_($ctx)",1) for (0..4); # load acc1
|
||||
larl ("%r5",".Lconst");
|
||||
vlef (@acc[$_],"24+4*$_($ctx)",3) for (0..4); # load acc2
|
||||
sllg ($padbit,$padbit,24);
|
||||
vlm (@vperm[0],$mask,"0(%r5)"); # load vperm ops, mask
|
||||
vgbm ($mask4,0x0707);
|
||||
vlvgp ($padvec,$padbit,$padbit);
|
||||
|
||||
srlg ("%r1",$len,6);
|
||||
ltgr ("%r1","%r1");
|
||||
jz (".Lvx_4x_done");
|
||||
|
||||
ALIGN (16);
|
||||
LABEL (".Lvx_4x");
|
||||
vlm ("%v20","%v23","0($inp)"); # load m0,m1,m2,m3
|
||||
|
||||
# m01,m23 -> base 2^26
|
||||
|
||||
vperm (@m01[0],"%v20","%v21",@vperm[0]);
|
||||
vperm (@m23[0],"%v22","%v23",@vperm[0]);
|
||||
vperm (@m01[2],"%v20","%v21",@vperm[1]);
|
||||
vperm (@m23[2],"%v22","%v23",@vperm[1]);
|
||||
vperm (@m01[4],"%v20","%v21",@vperm[2]);
|
||||
vperm (@m23[4],"%v22","%v23",@vperm[2]);
|
||||
|
||||
vesrlg (@m01[1],@m01[0],26);
|
||||
vesrlg (@m23[1],@m23[0],26);
|
||||
vesrlg (@m01[3],@m01[2],30);
|
||||
vesrlg (@m23[3],@m23[2],30);
|
||||
vesrlg (@m01[2],@m01[2],4);
|
||||
vesrlg (@m23[2],@m23[2],4);
|
||||
|
||||
vn (@m01[4],@m01[4],$mask4);
|
||||
vn (@m23[4],@m23[4],$mask4);
|
||||
for (0..3) {
|
||||
vn (@m01[$_],@m01[$_],$mask);
|
||||
vn (@m23[$_],@m23[$_],$mask);
|
||||
}
|
||||
vaf (@m01[4],@m01[4],$padvec); # pad m01
|
||||
vaf (@m23[4],@m23[4],$padvec); # pad m23
|
||||
|
||||
# acc = acc * r^4 + m01 * r^2 + m23
|
||||
|
||||
vlrepf (@r5[$_],"4*$_+108($ctx)") for (0..4); # load 5*r^2
|
||||
vlrepf (@r[$_],"4*$_+88($ctx)") for (0..4); # load r^2
|
||||
|
||||
vmalof (@tmp[0],@m01[4],@r5[1],@m23[0]);
|
||||
vmalof (@tmp[1],@m01[4],@r5[2],@m23[1]);
|
||||
vmalof (@tmp[2],@m01[4],@r5[3],@m23[2]);
|
||||
vmalof (@tmp[3],@m01[4],@r5[4],@m23[3]);
|
||||
vmalof (@tmp[4],@m01[4],@r[0],@m23[4]);
|
||||
|
||||
vmalof (@tmp[0],@m01[3],@r5[2],@tmp[0]);
|
||||
vmalof (@tmp[1],@m01[3],@r5[3],@tmp[1]);
|
||||
vmalof (@tmp[2],@m01[3],@r5[4],@tmp[2]);
|
||||
vmalof (@tmp[3],@m01[3],@r[0],@tmp[3]);
|
||||
vmalof (@tmp[4],@m01[3],@r[1],@tmp[4]);
|
||||
|
||||
vmalof (@tmp[0],@m01[2],@r5[3],@tmp[0]);
|
||||
vmalof (@tmp[1],@m01[2],@r5[4],@tmp[1]);
|
||||
vmalof (@tmp[2],@m01[2],@r[0],@tmp[2]);
|
||||
vmalof (@tmp[3],@m01[2],@r[1],@tmp[3]);
|
||||
vmalof (@tmp[4],@m01[2],@r[2],@tmp[4]);
|
||||
|
||||
vmalof (@tmp[0],@m01[1],@r5[4],@tmp[0]);
|
||||
vmalof (@tmp[1],@m01[1],@r[0],@tmp[1]);
|
||||
vmalof (@tmp[2],@m01[1],@r[1],@tmp[2]);
|
||||
vmalof (@tmp[3],@m01[1],@r[2],@tmp[3]);
|
||||
vmalof (@tmp[4],@m01[1],@r[3],@tmp[4]);
|
||||
|
||||
vmalof (@tmp[0],@m01[0],@r[0],@tmp[0]);
|
||||
vmalof (@tmp[1],@m01[0],@r[1],@tmp[1]);
|
||||
vmalof (@tmp[2],@m01[0],@r[2],@tmp[2]);
|
||||
vmalof (@tmp[3],@m01[0],@r[3],@tmp[3]);
|
||||
vmalof (@tmp[4],@m01[0],@r[4],@tmp[4]);
|
||||
|
||||
vlrepf (@r5[$_],"4*$_+148($ctx)") for (0..4); # load 5*r^4
|
||||
vlrepf (@r[$_],"4*$_+128($ctx)") for (0..4); # load r^4
|
||||
|
||||
vmalof (@tmp[0],@acc[4],@r5[1],@tmp[0]);
|
||||
vmalof (@tmp[1],@acc[4],@r5[2],@tmp[1]);
|
||||
vmalof (@tmp[2],@acc[4],@r5[3],@tmp[2]);
|
||||
vmalof (@tmp[3],@acc[4],@r5[4],@tmp[3]);
|
||||
vmalof (@tmp[4],@acc[4],@r[0],@tmp[4]);
|
||||
|
||||
vmalof (@tmp[0],@acc[3],@r5[2],@tmp[0]);
|
||||
vmalof (@tmp[1],@acc[3],@r5[3],@tmp[1]);
|
||||
vmalof (@tmp[2],@acc[3],@r5[4],@tmp[2]);
|
||||
vmalof (@tmp[3],@acc[3],@r[0],@tmp[3]);
|
||||
vmalof (@tmp[4],@acc[3],@r[1],@tmp[4]);
|
||||
|
||||
vmalof (@tmp[0],@acc[2],@r5[3],@tmp[0]);
|
||||
vmalof (@tmp[1],@acc[2],@r5[4],@tmp[1]);
|
||||
vmalof (@tmp[2],@acc[2],@r[0],@tmp[2]);
|
||||
vmalof (@tmp[3],@acc[2],@r[1],@tmp[3]);
|
||||
vmalof (@tmp[4],@acc[2],@r[2],@tmp[4]);
|
||||
|
||||
vmalof (@tmp[0],@acc[1],@r5[4],@tmp[0]);
|
||||
vmalof (@tmp[1],@acc[1],@r[0],@tmp[1]);
|
||||
vmalof (@tmp[2],@acc[1],@r[1],@tmp[2]);
|
||||
vmalof (@tmp[3],@acc[1],@r[2],@tmp[3]);
|
||||
vmalof (@tmp[4],@acc[1],@r[3],@tmp[4]);
|
||||
|
||||
vmalof (@acc[1],@acc[0],@r[1],@tmp[1]);
|
||||
vmalof (@acc[2],@acc[0],@r[2],@tmp[2]);
|
||||
vmalof (@acc[3],@acc[0],@r[3],@tmp[3]);
|
||||
vmalof (@acc[4],@acc[0],@r[4],@tmp[4]);
|
||||
vmalof (@acc[0],@acc[0],@r[0],@tmp[0]);
|
||||
|
||||
REDUCE ();
|
||||
|
||||
la ($inp,"64($inp)");
|
||||
brctg ("%r1",".Lvx_4x");
|
||||
|
||||
ALIGN (16);
|
||||
LABEL (".Lvx_4x_done");
|
||||
tml ($len,32);
|
||||
jz (".Lvx_2x_done");
|
||||
|
||||
vlm ("%v20","%v21","0($inp)"); # load m0,m1
|
||||
|
||||
# m01 -> base 2^26
|
||||
|
||||
vperm (@m01[0],"%v20","%v21",@vperm[0]);
|
||||
vperm (@m01[2],"%v20","%v21",@vperm[1]);
|
||||
vperm (@m01[4],"%v20","%v21",@vperm[2]);
|
||||
|
||||
vesrlg (@m01[1],@m01[0],26);
|
||||
vesrlg (@m01[3],@m01[2],30);
|
||||
vesrlg (@m01[2],@m01[2],4);
|
||||
|
||||
vn (@m01[4],@m01[4],$mask4);
|
||||
vn (@m01[$_],@m01[$_],$mask) for (0..3);
|
||||
|
||||
vaf (@m01[4],@m01[4],$padvec); # pad m01
|
||||
|
||||
# acc = acc * r^2+ m01
|
||||
|
||||
vlrepf (@r5[$_],"4*$_+108($ctx)") for (0..4); # load 5*r^2
|
||||
vlrepf (@r[$_],"4*$_+88($ctx)") for (0..4); # load r^2
|
||||
|
||||
vmalof (@tmp[0],@acc[4],@r5[1],@m01[0]);
|
||||
vmalof (@tmp[1],@acc[4],@r5[2],@m01[1]);
|
||||
vmalof (@tmp[2],@acc[4],@r5[3],@m01[2]);
|
||||
vmalof (@tmp[3],@acc[4],@r5[4],@m01[3]);
|
||||
vmalof (@tmp[4],@acc[4],@r[0],@m01[4]);
|
||||
|
||||
vmalof (@tmp[0],@acc[3],@r5[2],@tmp[0]);
|
||||
vmalof (@tmp[1],@acc[3],@r5[3],@tmp[1]);
|
||||
vmalof (@tmp[2],@acc[3],@r5[4],@tmp[2]);
|
||||
vmalof (@tmp[3],@acc[3],@r[0],@tmp[3]);
|
||||
vmalof (@tmp[4],@acc[3],@r[1],@tmp[4]);
|
||||
|
||||
vmalof (@tmp[0],@acc[2],@r5[3],@tmp[0]);
|
||||
vmalof (@tmp[1],@acc[2],@r5[4],@tmp[1]);
|
||||
vmalof (@tmp[2],@acc[2],@r[0],@tmp[2]);
|
||||
vmalof (@tmp[3],@acc[2],@r[1],@tmp[3]);
|
||||
vmalof (@tmp[4],@acc[2],@r[2],@tmp[4]);
|
||||
|
||||
vmalof (@tmp[0],@acc[1],@r5[4],@tmp[0]);
|
||||
vmalof (@tmp[1],@acc[1],@r[0],@tmp[1]);
|
||||
vmalof (@tmp[2],@acc[1],@r[1],@tmp[2]);
|
||||
vmalof (@tmp[3],@acc[1],@r[2],@tmp[3]);
|
||||
vmalof (@tmp[4],@acc[1],@r[3],@tmp[4]);
|
||||
|
||||
vmalof (@acc[1],@acc[0],@r[1],@tmp[1]);
|
||||
vmalof (@acc[2],@acc[0],@r[2],@tmp[2]);
|
||||
vmalof (@acc[3],@acc[0],@r[3],@tmp[3]);
|
||||
vmalof (@acc[4],@acc[0],@r[4],@tmp[4]);
|
||||
vmalof (@acc[0],@acc[0],@r[0],@tmp[0]);
|
||||
|
||||
REDUCE ();
|
||||
|
||||
la ($inp,"32($inp)");
|
||||
|
||||
ALIGN (16);
|
||||
LABEL (".Lvx_2x_done");
|
||||
tml ($len,16);
|
||||
jz (".Lvx_done");
|
||||
|
||||
vleig ($padvec,0,0);
|
||||
|
||||
vzero ("%v20");
|
||||
vl ("%v21","0($inp)"); # load m0
|
||||
|
||||
# m0 -> base 2^26
|
||||
|
||||
vperm (@m01[0],"%v20","%v21",@vperm[0]);
|
||||
vperm (@m01[2],"%v20","%v21",@vperm[1]);
|
||||
vperm (@m01[4],"%v20","%v21",@vperm[2]);
|
||||
|
||||
vesrlg (@m01[1],@m01[0],26);
|
||||
vesrlg (@m01[3],@m01[2],30);
|
||||
vesrlg (@m01[2],@m01[2],4);
|
||||
|
||||
vn (@m01[4],@m01[4],$mask4);
|
||||
vn (@m01[$_],@m01[$_],$mask) for (0..3);
|
||||
|
||||
vaf (@m01[4],@m01[4],$padvec); # pad m0
|
||||
|
||||
# acc = acc * r + m01
|
||||
|
||||
vlrepf (@r5[$_],"4*$_+68($ctx)") for (0..4); # load 5*r
|
||||
vlrepf (@r[$_],"4*$_+48($ctx)") for (0..4); # load r
|
||||
|
||||
vmalof (@tmp[0],@acc[4],@r5[1],@m01[0]);
|
||||
vmalof (@tmp[1],@acc[4],@r5[2],@m01[1]);
|
||||
vmalof (@tmp[2],@acc[4],@r5[3],@m01[2]);
|
||||
vmalof (@tmp[3],@acc[4],@r5[4],@m01[3]);
|
||||
vmalof (@tmp[4],@acc[4],@r[0],@m01[4]);
|
||||
|
||||
vmalof (@tmp[0],@acc[3],@r5[2],@tmp[0]);
|
||||
vmalof (@tmp[1],@acc[3],@r5[3],@tmp[1]);
|
||||
vmalof (@tmp[2],@acc[3],@r5[4],@tmp[2]);
|
||||
vmalof (@tmp[3],@acc[3],@r[0],@tmp[3]);
|
||||
vmalof (@tmp[4],@acc[3],@r[1],@tmp[4]);
|
||||
|
||||
vmalof (@tmp[0],@acc[2],@r5[3],@tmp[0]);
|
||||
vmalof (@tmp[1],@acc[2],@r5[4],@tmp[1]);
|
||||
vmalof (@tmp[2],@acc[2],@r[0],@tmp[2]);
|
||||
vmalof (@tmp[3],@acc[2],@r[1],@tmp[3]);
|
||||
vmalof (@tmp[4],@acc[2],@r[2],@tmp[4]);
|
||||
|
||||
vmalof (@tmp[0],@acc[1],@r5[4],@tmp[0]);
|
||||
vmalof (@tmp[1],@acc[1],@r[0],@tmp[1]);
|
||||
vmalof (@tmp[2],@acc[1],@r[1],@tmp[2]);
|
||||
vmalof (@tmp[3],@acc[1],@r[2],@tmp[3]);
|
||||
vmalof (@tmp[4],@acc[1],@r[3],@tmp[4]);
|
||||
|
||||
vmalof (@acc[1],@acc[0],@r[1],@tmp[1]);
|
||||
vmalof (@acc[2],@acc[0],@r[2],@tmp[2]);
|
||||
vmalof (@acc[3],@acc[0],@r[3],@tmp[3]);
|
||||
vmalof (@acc[4],@acc[0],@r[4],@tmp[4]);
|
||||
vmalof (@acc[0],@acc[0],@r[0],@tmp[0]);
|
||||
|
||||
REDUCE ();
|
||||
|
||||
ALIGN (16);
|
||||
LABEL (".Lvx_done");
|
||||
vstef (@acc[$_],"4*$_($ctx)",1) for (0..4); # store acc
|
||||
vstef (@acc[$_],"24+4*$_($ctx)",3) for (0..4);
|
||||
|
||||
if ($z) {
|
||||
vlm ("%v8","%v15","0($sp)");
|
||||
la ($sp,"$frame($sp)");
|
||||
} else {
|
||||
ld ("%f4","16*$SIZE_T+2*8($sp)");
|
||||
ld ("%f6","16*$SIZE_T+3*8($sp)");
|
||||
}
|
||||
br ("%r14");
|
||||
SIZE ("poly1305_blocks_vx",".-poly1305_blocks_vx");
|
||||
}
|
||||
|
||||
################
|
||||
# static void poly1305_emit_vx(void *ctx, unsigned char mac[16],
|
||||
# const u32 nonce[4])
|
||||
{
|
||||
my ($ctx,$mac,$nonce) = map("%r$_",(2..4));
|
||||
|
||||
GLOBL ("poly1305_emit_vx");
|
||||
TYPE ("poly1305_emit_vx","\@function");
|
||||
ALIGN (16);
|
||||
LABEL ("poly1305_emit_vx");
|
||||
if ($z) {
|
||||
aghi ($sp,-$frame);
|
||||
vstm ("%v8","%v15","0($sp)");
|
||||
} else {
|
||||
std ("%f4","16*$SIZE_T+2*8($sp)");
|
||||
std ("%f6","16*$SIZE_T+3*8($sp)");
|
||||
}
|
||||
larl ("%r5",".Lconst");
|
||||
|
||||
vlef (@acc[$_],"4*$_($ctx)",1) for (0..4); # load acc1
|
||||
vlef (@acc[$_],"24+4*$_($ctx)",3) for (0..4); # load acc2
|
||||
vlef (@r5[$_],"108+4*$_($ctx)",1) for (0..4); # load 5*r^2
|
||||
vlef (@r[$_],"88+4*$_($ctx)",1) for (0..4); # load r^2
|
||||
vlef (@r5[$_],"68+4*$_($ctx)",3) for (0..4); # load 5*r
|
||||
vlef (@r[$_],"48+4*$_($ctx)",3) for (0..4); # load r
|
||||
vl ($mask,"48(%r5)"); # load mask
|
||||
|
||||
# acc = acc1 * r^2 + acc2 * r
|
||||
|
||||
vmlof (@tmp[0],@acc[4],@r5[1]);
|
||||
vmlof (@tmp[1],@acc[4],@r5[2]);
|
||||
vmlof (@tmp[2],@acc[4],@r5[3]);
|
||||
vmlof (@tmp[3],@acc[4],@r5[4]);
|
||||
vmlof (@tmp[4],@acc[4],@r[0]);
|
||||
|
||||
vmalof (@tmp[0],@acc[3],@r5[2],@tmp[0]);
|
||||
vmalof (@tmp[1],@acc[3],@r5[3],@tmp[1]);
|
||||
vmalof (@tmp[2],@acc[3],@r5[4],@tmp[2]);
|
||||
vmalof (@tmp[3],@acc[3],@r[0],@tmp[3]);
|
||||
vmalof (@tmp[4],@acc[3],@r[1],@tmp[4]);
|
||||
|
||||
vmalof (@tmp[0],@acc[2],@r5[3],@tmp[0]);
|
||||
vmalof (@tmp[1],@acc[2],@r5[4],@tmp[1]);
|
||||
vmalof (@tmp[2],@acc[2],@r[0],@tmp[2]);
|
||||
vmalof (@tmp[3],@acc[2],@r[1],@tmp[3]);
|
||||
vmalof (@tmp[4],@acc[2],@r[2],@tmp[4]);
|
||||
|
||||
vmalof (@tmp[0],@acc[1],@r5[4],@tmp[0]);
|
||||
vmalof (@tmp[1],@acc[1],@r[0],@tmp[1]);
|
||||
vmalof (@tmp[2],@acc[1],@r[1],@tmp[2]);
|
||||
vmalof (@tmp[3],@acc[1],@r[2],@tmp[3]);
|
||||
vmalof (@tmp[4],@acc[1],@r[3],@tmp[4]);
|
||||
|
||||
vmalof (@acc[1],@acc[0],@r[1],@tmp[1]);
|
||||
vmalof (@acc[2],@acc[0],@r[2],@tmp[2]);
|
||||
vmalof (@acc[3],@acc[0],@r[3],@tmp[3]);
|
||||
vmalof (@acc[4],@acc[0],@r[4],@tmp[4]);
|
||||
vmalof (@acc[0],@acc[0],@r[0],@tmp[0]);
|
||||
|
||||
vzero ("%v27");
|
||||
vsumqg (@acc[$_],@acc[$_],"%v27") for (0..4);
|
||||
|
||||
REDUCE ();
|
||||
|
||||
vesrlg (@tmp[1],@acc[1],26);
|
||||
vn (@acc[1],@acc[1],$mask);
|
||||
vag (@acc[2],@acc[2],@tmp[1]); # carry 1->2
|
||||
|
||||
vesrlg (@tmp[2],@acc[2],26);
|
||||
vn (@acc[2],@acc[2],$mask);
|
||||
vag (@acc[3],@acc[3],@tmp[2]); # carry 2->3
|
||||
|
||||
vesrlg (@tmp[3],@acc[3],26);
|
||||
vn (@acc[3],@acc[3],$mask);
|
||||
vag (@acc[4],@acc[4],@tmp[3]); # carry 3->4
|
||||
|
||||
# acc -> base 2^64
|
||||
vleib ("%v30",6*8,7);
|
||||
vleib ("%v29",13*8,7);
|
||||
vleib ("%v28",3*8,7);
|
||||
|
||||
veslg (@acc[1],@acc[1],26);
|
||||
veslg (@acc[3],@acc[3],26);
|
||||
vo (@acc[0],@acc[0],@acc[1]);
|
||||
vo (@acc[2],@acc[2],@acc[3]);
|
||||
|
||||
veslg (@acc[2],@acc[2],4);
|
||||
vslb (@acc[2],@acc[2],"%v30"); # <<52
|
||||
vo (@acc[0],@acc[0],@acc[2]);
|
||||
|
||||
vslb (@tmp[4],@acc[4],"%v29"); # <<104
|
||||
vo (@acc[0],@acc[0],@tmp[4]);
|
||||
|
||||
vsrlb (@acc[1],@acc[4],"%v28"); # >>24
|
||||
|
||||
# acc %= 2^130-5
|
||||
vone ("%v26");
|
||||
vleig ("%v27",5,1);
|
||||
vone ("%v29");
|
||||
vleig ("%v26",-4,1);
|
||||
|
||||
vaq (@tmp[0],@acc[0],"%v27");
|
||||
vaccq (@tmp[1],@acc[0],"%v27");
|
||||
|
||||
vaq (@tmp[1],@tmp[1],"%v26");
|
||||
vaccq (@tmp[1],@tmp[1],@acc[1]);
|
||||
|
||||
vaq (@tmp[1],@tmp[1],"%v29");
|
||||
|
||||
vn (@tmp[2],@tmp[1],@acc[0]);
|
||||
vnc (@tmp[3],@tmp[0],@tmp[1]);
|
||||
vo (@acc[0],@tmp[2],@tmp[3]);
|
||||
|
||||
# acc += nonce
|
||||
vl (@vperm[0],"64(%r5)");
|
||||
vlef (@tmp[0],"4*$_($nonce)",3-$_) for (0..3);
|
||||
|
||||
vaq (@acc[0],@acc[0],@tmp[0]);
|
||||
|
||||
vperm (@acc[0],@acc[0],@acc[0],@vperm[0]);
|
||||
vst (@acc[0],"0($mac)"); # store mac
|
||||
|
||||
if ($z) {
|
||||
vlm ("%v8","%v15","0($sp)");
|
||||
la ($sp,"$frame($sp)");
|
||||
} else {
|
||||
ld ("%f4","16*$SIZE_T+2*8($sp)");
|
||||
ld ("%f6","16*$SIZE_T+3*8($sp)");
|
||||
}
|
||||
br ("%r14");
|
||||
SIZE ("poly1305_emit_vx",".-poly1305_emit_vx");
|
||||
}
|
||||
}
|
||||
|
||||
# NOVX CODE PATH
|
||||
{
|
||||
################
|
||||
# static void poly1305_blocks(void *ctx, const unsigned char *inp, size_t len,
|
||||
# u32 padbit)
|
||||
{
|
||||
my ($ctx,$inp,$len,$padbit) = map("%r$_",(2..5));
|
||||
|
||||
my ($d0hi,$d0lo,$d1hi,$d1lo,$t0,$h0,$t1,$h1,$h2) = map("%r$_",(6..14));
|
||||
my ($r0,$r1,$s1) = map("%r$_",(0..2));
|
||||
|
||||
GLOBL ("poly1305_blocks");
|
||||
TYPE ("poly1305_blocks","\@function");
|
||||
ALIGN (16);
|
||||
LABEL ("poly1305_blocks");
|
||||
$z? srlg ($len,$len,4) :srl ($len,4);
|
||||
lghi ("%r0",0);
|
||||
&{$z? \&clgr:\&clr} ($len,"%r0");
|
||||
je (".Lno_data");
|
||||
LABEL (".Lpoly1305_blocks");
|
||||
&{$z? \<gr:\<r} ("%r0",$len);
|
||||
jz (".Lno_data");
|
||||
|
||||
&{$z? \&stmg:\&stm} ("%r6","%r14","6*$SIZE_T($sp)");
|
||||
|
||||
llgfr ($padbit,$padbit); # clear upper half, much needed with
|
||||
# non-64-bit ABI
|
||||
lg ($r0,"32($ctx)"); # load key
|
||||
lg ($r1,"40($ctx)");
|
||||
|
||||
lg ($h0,"0($ctx)"); # load hash value
|
||||
lg ($h1,"8($ctx)");
|
||||
lg ($h2,"16($ctx)");
|
||||
|
||||
LABEL (".Lpoly1305_blocks_entry");
|
||||
if ($z) {
|
||||
srlg ($len,$len,4);
|
||||
} else {
|
||||
srl ($len,4);
|
||||
}
|
||||
llgfr ($padbit,$padbit); # clear upper half, much needed with
|
||||
# non-64-bit ABI
|
||||
lg ($r0,"32($ctx)"); # load key
|
||||
lg ($r1,"40($ctx)");
|
||||
|
||||
&{$z? \&stg:\&st} ($ctx,"2*$SIZE_T($sp)"); # off-load $ctx
|
||||
srlg ($s1,$r1,2);
|
||||
algr ($s1,$r1); # s1 = r1 + r1>>2
|
||||
@@ -724,6 +166,7 @@ LABEL (".Loop");
|
||||
|
||||
algr ($d0lo,$h0); # accumulate input
|
||||
alcgr ($d1lo,$h1);
|
||||
alcgr ($h2,$padbit);
|
||||
|
||||
lgr ($h0,$d0lo);
|
||||
mlgr ($d0hi,$r0); # h0*r0 -> $d0hi:$d0lo
|
||||
@@ -732,7 +175,6 @@ LABEL (".Loop");
|
||||
|
||||
mlgr ($t0,$r1); # h0*r1 -> $t0:$h0
|
||||
mlgr ($t1,$r0); # h1*r0 -> $t1:$h1
|
||||
alcgr ($h2,$padbit);
|
||||
|
||||
algr ($d0lo,$d1lo);
|
||||
lgr ($d1lo,$h2);
|
||||
@@ -776,25 +218,718 @@ LABEL (".Lno_data");
|
||||
SIZE ("poly1305_blocks",".-poly1305_blocks");
|
||||
}
|
||||
|
||||
################
|
||||
# static void poly1305_blocks_vx(void *ctx, const unsigned char *inp,
|
||||
# size_t len, u32 padbit)
|
||||
{
|
||||
my ($H0, $H1, $H2, $H3, $H4) = map("%v$_",(0..4));
|
||||
my ($I0, $I1, $I2, $I3, $I4) = map("%v$_",(5..9));
|
||||
my ($R0, $R1, $S1, $R2, $S2) = map("%v$_",(10..14));
|
||||
my ($R3, $S3, $R4, $S4) = map("%v$_",(15..18));
|
||||
my ($ACC0, $ACC1, $ACC2, $ACC3, $ACC4) = map("%v$_",(19..23));
|
||||
my ($T1, $T2, $T3, $T4) = map("%v$_",(24..27));
|
||||
my ($mask26,$bswaplo,$bswaphi,$bswapmi) = map("%v$_",(28..31));
|
||||
|
||||
my ($d2,$d0,$h0,$d1,$h1,$h2)=map("%r$_",(9..14));
|
||||
|
||||
TYPE ("poly1305_blocks_vx","\@function");
|
||||
ALIGN (16);
|
||||
LABEL ("poly1305_blocks_vx");
|
||||
LABEL (".Lpoly1305_blocks_vx");
|
||||
&{$z? \&clgfi:\&clfi} ($len,128);
|
||||
jhe ("__poly1305_blocks_vx");
|
||||
|
||||
&{$z? \&stmg:\&stm} ("%r6","%r14","6*$SIZE_T($sp)");
|
||||
|
||||
lg ($d0,"0($ctx)");
|
||||
lg ($d1,"8($ctx)");
|
||||
lg ($d2,"16($ctx)");
|
||||
|
||||
llgfr ("%r0",$d0); # base 2^26 -> base 2^64
|
||||
srlg ($h0,$d0,32);
|
||||
llgfr ("%r1",$d1);
|
||||
srlg ($h1,$d1,32);
|
||||
srlg ($h2,$d2,32);
|
||||
|
||||
sllg ("%r0","%r0",26);
|
||||
algr ($h0,"%r0");
|
||||
sllg ("%r0",$h1,52);
|
||||
srlg ($h1,$h1,12);
|
||||
sllg ("%r1","%r1",14);
|
||||
algr ($h0,"%r0");
|
||||
alcgr ($h1,"%r1");
|
||||
sllg ("%r0",$h2,40);
|
||||
srlg ($h2,$h2,24);
|
||||
lghi ("%r1",0);
|
||||
algr ($h1,"%r0");
|
||||
alcgr ($h2,"%r1");
|
||||
|
||||
llgf ("%r0","24($ctx)"); # is_base2_26
|
||||
lcgr ("%r0","%r0");
|
||||
|
||||
xgr ($h0,$d0); # choose between radixes
|
||||
xgr ($h1,$d1);
|
||||
xgr ($h2,$d2);
|
||||
ngr ($h0,"%r0");
|
||||
ngr ($h1,"%r0");
|
||||
ngr ($h2,"%r0");
|
||||
xgr ($h0,$d0);
|
||||
xgr ($h1,$d1);
|
||||
xgr ($h2,$d2);
|
||||
|
||||
lhi ("%r0",0);
|
||||
st ("%r0","24($ctx)"); # clear is_base2_26
|
||||
|
||||
j (".Lpoly1305_blocks_entry");
|
||||
SIZE ("poly1305_blocks_vx",".-poly1305_blocks_vx");
|
||||
|
||||
TYPE ("__poly1305_mul","\@function");
|
||||
ALIGN (16);
|
||||
LABEL ("__poly1305_mul");
|
||||
vmlof ($ACC0,$H0,$R0);
|
||||
vmlof ($ACC1,$H0,$R1);
|
||||
vmlof ($ACC2,$H0,$R2);
|
||||
vmlof ($ACC3,$H0,$R3);
|
||||
vmlof ($ACC4,$H0,$R4);
|
||||
|
||||
vmalof ($ACC0,$H1,$S4,$ACC0);
|
||||
vmalof ($ACC1,$H1,$R0,$ACC1);
|
||||
vmalof ($ACC2,$H1,$R1,$ACC2);
|
||||
vmalof ($ACC3,$H1,$R2,$ACC3);
|
||||
vmalof ($ACC4,$H1,$R3,$ACC4);
|
||||
|
||||
vmalof ($ACC0,$H2,$S3,$ACC0);
|
||||
vmalof ($ACC1,$H2,$S4,$ACC1);
|
||||
vmalof ($ACC2,$H2,$R0,$ACC2);
|
||||
vmalof ($ACC3,$H2,$R1,$ACC3);
|
||||
vmalof ($ACC4,$H2,$R2,$ACC4);
|
||||
|
||||
vmalof ($ACC0,$H3,$S2,$ACC0);
|
||||
vmalof ($ACC1,$H3,$S3,$ACC1);
|
||||
vmalof ($ACC2,$H3,$S4,$ACC2);
|
||||
vmalof ($ACC3,$H3,$R0,$ACC3);
|
||||
vmalof ($ACC4,$H3,$R1,$ACC4);
|
||||
|
||||
vmalof ($ACC0,$H4,$S1,$ACC0);
|
||||
vmalof ($ACC1,$H4,$S2,$ACC1);
|
||||
vmalof ($ACC2,$H4,$S3,$ACC2);
|
||||
vmalof ($ACC3,$H4,$S4,$ACC3);
|
||||
vmalof ($ACC4,$H4,$R0,$ACC4);
|
||||
|
||||
################################################################
|
||||
# lazy reduction
|
||||
|
||||
vesrlg ($H4,$ACC3,26);
|
||||
vesrlg ($H1,$ACC0,26);
|
||||
vn ($H3,$ACC3,$mask26);
|
||||
vn ($H0,$ACC0,$mask26);
|
||||
vag ($H4,$H4,$ACC4); # h3 -> h4
|
||||
vag ($H1,$H1,$ACC1); # h0 -> h1
|
||||
|
||||
vesrlg ($ACC4,$H4,26);
|
||||
vesrlg ($ACC1,$H1,26);
|
||||
vn ($H4,$H4,$mask26);
|
||||
vn ($H1,$H1,$mask26);
|
||||
vag ($H0,$H0,$ACC4);
|
||||
vag ($H2,$ACC2,$ACC1); # h1 -> h2
|
||||
|
||||
veslg ($ACC4,$ACC4,2); # <<2
|
||||
vesrlg ($ACC2,$H2,26);
|
||||
vn ($H2,$H2,$mask26);
|
||||
vag ($H0,$H0,$ACC4); # h4 -> h0
|
||||
vag ($H3,$H3,$ACC2); # h2 -> h3
|
||||
|
||||
vesrlg ($ACC0,$H0,26);
|
||||
vesrlg ($ACC3,$H3,26);
|
||||
vn ($H0,$H0,$mask26);
|
||||
vn ($H3,$H3,$mask26);
|
||||
vag ($H1,$H1,$ACC0); # h0 -> h1
|
||||
vag ($H4,$H4,$ACC3); # h3 -> h4
|
||||
br ("%r14");
|
||||
SIZE ("__poly1305_mul",".-__poly1305_mul");
|
||||
|
||||
TYPE ("__poly1305_blocks_vx","\@function");
|
||||
ALIGN (16);
|
||||
LABEL ("__poly1305_blocks_vx");
|
||||
&{$z? \&lgr:\&lr} ("%r0",$sp);
|
||||
&{$z? \&stmg:\&stm} ("%r10","%r15","10*$SIZE_T($sp)");
|
||||
if (!$z) {
|
||||
std ("%f4","16*$SIZE_T+2*8($sp)");
|
||||
std ("%f6","16*$SIZE_T+3*8($sp)");
|
||||
ahi ($sp,-$stdframe);
|
||||
st ("%r0","0($sp)"); # back-chain
|
||||
|
||||
llgfr ($len,$len); # so that srlg works on $len
|
||||
} else {
|
||||
aghi ($sp,"-($stdframe+8*8)");
|
||||
stg ("%r0","0($sp)"); # back-chain
|
||||
|
||||
std ("%f8","$stdframe+0*8($sp)");
|
||||
std ("%f9","$stdframe+1*8($sp)");
|
||||
std ("%f10","$stdframe+2*8($sp)");
|
||||
std ("%f11","$stdframe+3*8($sp)");
|
||||
std ("%f12","$stdframe+4*8($sp)");
|
||||
std ("%f13","$stdframe+5*8($sp)");
|
||||
std ("%f14","$stdframe+6*8($sp)");
|
||||
std ("%f15","$stdframe+7*8($sp)");
|
||||
}
|
||||
larl ("%r1",".Lconst");
|
||||
vgmg ($mask26,38,63);
|
||||
vlm ($bswaplo,$bswapmi,"16(%r1)");
|
||||
|
||||
< ("%r0","24($ctx)"); # is_base2_26?
|
||||
jnz (".Lskip_init");
|
||||
|
||||
lg ($h0,"32($ctx)"); # load key base 2^64
|
||||
lg ($h1,"40($ctx)");
|
||||
|
||||
risbg ($d0,$h0,38,0x80+63,38); # base 2^64 -> 2^26
|
||||
srlg ($d1,$h0,52);
|
||||
risbg ($h0,$h0,38,0x80+63,0);
|
||||
vlvgg ($R0,$h0,0);
|
||||
risbg ($d1,$h1,38,51,12);
|
||||
vlvgg ($R1,$d0,0);
|
||||
risbg ($d0,$h1,38,63,50);
|
||||
vlvgg ($R2,$d1,0);
|
||||
srlg ($d1,$h1,40);
|
||||
vlvgg ($R3,$d0,0);
|
||||
vlvgg ($R4,$d1,0);
|
||||
|
||||
veslg ($S1,$R1,2);
|
||||
veslg ($S2,$R2,2);
|
||||
veslg ($S3,$R3,2);
|
||||
veslg ($S4,$R4,2);
|
||||
vlr ($H0,$R0);
|
||||
vlr ($H1,$R1);
|
||||
vlr ($H2,$R2);
|
||||
vlr ($H3,$R3);
|
||||
vlr ($H4,$R4);
|
||||
vag ($S1,$S1,$R1); # * 5
|
||||
vag ($S2,$S2,$R2);
|
||||
vag ($S3,$S3,$R3);
|
||||
vag ($S4,$S4,$R4);
|
||||
|
||||
brasl ("%r14","__poly1305_mul"); # r^1:- * r^1:-
|
||||
|
||||
vpdi ($R0,$H0,$R0,0); # r^2:r^1
|
||||
vpdi ($R1,$H1,$R1,0);
|
||||
vpdi ($R2,$H2,$R2,0);
|
||||
vpdi ($R3,$H3,$R3,0);
|
||||
vpdi ($R4,$H4,$R4,0);
|
||||
vpdi ($H0,$H0,$H0,0); # r^2:r^2
|
||||
vpdi ($H1,$H1,$H1,0);
|
||||
vpdi ($H2,$H2,$H2,0);
|
||||
vpdi ($H3,$H3,$H3,0);
|
||||
vpdi ($H4,$H4,$H4,0);
|
||||
veslg ($S1,$R1,2);
|
||||
veslg ($S2,$R2,2);
|
||||
veslg ($S3,$R3,2);
|
||||
veslg ($S4,$R4,2);
|
||||
vag ($S1,$S1,$R1); # * 5
|
||||
vag ($S2,$S2,$R2);
|
||||
vag ($S3,$S3,$R3);
|
||||
vag ($S4,$S4,$R4);
|
||||
|
||||
brasl ("%r14,__poly1305_mul"); # r^2:r^2 * r^2:r^1
|
||||
|
||||
vl ($I0,"0(%r1)"); # borrow $I0
|
||||
vperm ($R0,$R0,$H0,$I0); # r^2:r^4:r^1:r^3
|
||||
vperm ($R1,$R1,$H1,$I0);
|
||||
vperm ($R2,$R2,$H2,$I0);
|
||||
vperm ($R3,$R3,$H3,$I0);
|
||||
vperm ($R4,$R4,$H4,$I0);
|
||||
veslf ($S1,$R1,2);
|
||||
veslf ($S2,$R2,2);
|
||||
veslf ($S3,$R3,2);
|
||||
veslf ($S4,$R4,2);
|
||||
vaf ($S1,$S1,$R1); # * 5
|
||||
vaf ($S2,$S2,$R2);
|
||||
vaf ($S3,$S3,$R3);
|
||||
vaf ($S4,$S4,$R4);
|
||||
|
||||
lg ($h0,"0($ctx)"); # load hash base 2^64
|
||||
lg ($h1,"8($ctx)");
|
||||
lg ($h2,"16($ctx)");
|
||||
|
||||
vzero ($H0);
|
||||
vzero ($H1);
|
||||
vzero ($H2);
|
||||
vzero ($H3);
|
||||
vzero ($H4);
|
||||
|
||||
risbg ($d0,$h0,38,0x80+63,38); # base 2^64 -> 2^26
|
||||
srlg ($d1,$h0,52);
|
||||
risbg ($h0,$h0,38,0x80+63,0);
|
||||
vlvgg ($H0,$h0,0);
|
||||
risbg ($d1,$h1,38,51,12);
|
||||
vlvgg ($H1,$d0,0);
|
||||
risbg ($d0,$h1,38,63,50);
|
||||
vlvgg ($H2,$d1,0);
|
||||
srlg ($d1,$h1,40);
|
||||
vlvgg ($H3,$d0,0);
|
||||
risbg ($d1,$h2,37,39,24);
|
||||
vlvgg ($H4,$d1,0);
|
||||
|
||||
lhi ("%r0",1);
|
||||
st ("%r0","24($ctx)"); # set is_base2_26
|
||||
|
||||
vstm ($R0,$S4,"48($ctx)"); # save key schedule base 2^26
|
||||
|
||||
vpdi ($R0,$R0,$R0,0); # broadcast r^2:r^4
|
||||
vpdi ($R1,$R1,$R1,0);
|
||||
vpdi ($S1,$S1,$S1,0);
|
||||
vpdi ($R2,$R2,$R2,0);
|
||||
vpdi ($S2,$S2,$S2,0);
|
||||
vpdi ($R3,$R3,$R3,0);
|
||||
vpdi ($S3,$S3,$S3,0);
|
||||
vpdi ($R4,$R4,$R4,0);
|
||||
vpdi ($S4,$S4,$S4,0);
|
||||
|
||||
j (".Loaded_hash");
|
||||
|
||||
ALIGN (16);
|
||||
LABEL (".Lskip_init");
|
||||
vllezf ($H0,"0($ctx)"); # load hash base 2^26
|
||||
vllezf ($H1,"4($ctx)");
|
||||
vllezf ($H2,"8($ctx)");
|
||||
vllezf ($H3,"12($ctx)");
|
||||
vllezf ($H4,"16($ctx)");
|
||||
|
||||
vlrepg ($R0,"0x30($ctx)"); # broadcast r^2:r^4
|
||||
vlrepg ($R1,"0x40($ctx)");
|
||||
vlrepg ($S1,"0x50($ctx)");
|
||||
vlrepg ($R2,"0x60($ctx)");
|
||||
vlrepg ($S2,"0x70($ctx)");
|
||||
vlrepg ($R3,"0x80($ctx)");
|
||||
vlrepg ($S3,"0x90($ctx)");
|
||||
vlrepg ($R4,"0xa0($ctx)");
|
||||
vlrepg ($S4,"0xb0($ctx)");
|
||||
|
||||
LABEL (".Loaded_hash");
|
||||
vzero ($I1);
|
||||
vzero ($I3);
|
||||
|
||||
vlm ($T1,$T4,"0x00($inp)"); # load first input block
|
||||
la ($inp,"0x40($inp)");
|
||||
vgmg ($mask26,6,31);
|
||||
vgmf ($I4,5,5); # padbit<<2
|
||||
|
||||
vperm ($I0,$T3,$T4,$bswaplo);
|
||||
vperm ($I2,$T3,$T4,$bswapmi);
|
||||
vperm ($T3,$T3,$T4,$bswaphi);
|
||||
|
||||
verimg ($I1,$I0,$mask26,6); # >>26
|
||||
veslg ($I0,$I0,32);
|
||||
veslg ($I2,$I2,28); # >>4
|
||||
verimg ($I3,$T3,$mask26,18); # >>14
|
||||
verimg ($I4,$T3,$mask26,58); # >>38
|
||||
vn ($I0,$I0,$mask26);
|
||||
vn ($I2,$I2,$mask26);
|
||||
vesrlf ($I4,$I4,2); # >>2
|
||||
|
||||
vgmg ($mask26,38,63);
|
||||
vperm ($T3,$T1,$T2,$bswaplo);
|
||||
vperm ($T4,$T1,$T2,$bswaphi);
|
||||
vperm ($T2,$T1,$T2,$bswapmi);
|
||||
|
||||
verimg ($I0,$T3,$mask26,0);
|
||||
verimg ($I1,$T3,$mask26,38); # >>26
|
||||
verimg ($I2,$T2,$mask26,60); # >>4
|
||||
verimg ($I3,$T4,$mask26,50); # >>14
|
||||
vesrlg ($T4,$T4,40);
|
||||
vo ($I4,$I4,$T4);
|
||||
|
||||
srlg ("%r0",$len,6);
|
||||
&{$z? \&aghi:\&ahi} ("%r0",-1);
|
||||
|
||||
ALIGN (16);
|
||||
LABEL (".Loop_vx");
|
||||
vmlef ($ACC0,$I0,$R0);
|
||||
vmlef ($ACC1,$I0,$R1);
|
||||
vmlef ($ACC2,$I0,$R2);
|
||||
vmlef ($ACC3,$I0,$R3);
|
||||
vmlef ($ACC4,$I0,$R4);
|
||||
|
||||
vmalef ($ACC0,$I1,$S4,$ACC0);
|
||||
vmalef ($ACC1,$I1,$R0,$ACC1);
|
||||
vmalef ($ACC2,$I1,$R1,$ACC2);
|
||||
vmalef ($ACC3,$I1,$R2,$ACC3);
|
||||
vmalef ($ACC4,$I1,$R3,$ACC4);
|
||||
|
||||
vaf ($H2,$H2,$I2);
|
||||
vaf ($H0,$H0,$I0);
|
||||
vaf ($H3,$H3,$I3);
|
||||
vaf ($H1,$H1,$I1);
|
||||
vaf ($H4,$H4,$I4);
|
||||
|
||||
vmalef ($ACC0,$I2,$S3,$ACC0);
|
||||
vmalef ($ACC1,$I2,$S4,$ACC1);
|
||||
vmalef ($ACC2,$I2,$R0,$ACC2);
|
||||
vmalef ($ACC3,$I2,$R1,$ACC3);
|
||||
vmalef ($ACC4,$I2,$R2,$ACC4);
|
||||
|
||||
vlm ($T1,$T4,"0x00($inp)"); # load next input block
|
||||
la ($inp,"0x40($inp)");
|
||||
vgmg ($mask26,6,31);
|
||||
|
||||
vmalef ($ACC0,$I3,$S2,$ACC0);
|
||||
vmalef ($ACC1,$I3,$S3,$ACC1);
|
||||
vmalef ($ACC2,$I3,$S4,$ACC2);
|
||||
vmalef ($ACC3,$I3,$R0,$ACC3);
|
||||
vmalef ($ACC4,$I3,$R1,$ACC4);
|
||||
|
||||
vperm ($I0,$T3,$T4,$bswaplo);
|
||||
vperm ($I2,$T3,$T4,$bswapmi);
|
||||
vperm ($T3,$T3,$T4,$bswaphi);
|
||||
|
||||
vmalef ($ACC0,$I4,$S1,$ACC0);
|
||||
vmalef ($ACC1,$I4,$S2,$ACC1);
|
||||
vmalef ($ACC2,$I4,$S3,$ACC2);
|
||||
vmalef ($ACC3,$I4,$S4,$ACC3);
|
||||
vmalef ($ACC4,$I4,$R0,$ACC4);
|
||||
|
||||
verimg ($I1,$I0,$mask26,6); # >>26
|
||||
veslg ($I0,$I0,32);
|
||||
veslg ($I2,$I2,28); # >>4
|
||||
verimg ($I3,$T3,$mask26,18); # >>14
|
||||
|
||||
vmalof ($ACC0,$H0,$R0,$ACC0);
|
||||
vmalof ($ACC1,$H0,$R1,$ACC1);
|
||||
vmalof ($ACC2,$H0,$R2,$ACC2);
|
||||
vmalof ($ACC3,$H0,$R3,$ACC3);
|
||||
vmalof ($ACC4,$H0,$R4,$ACC4);
|
||||
|
||||
vgmf ($I4,5,5); # padbit<<2
|
||||
verimg ($I4,$T3,$mask26,58); # >>38
|
||||
vn ($I0,$I0,$mask26);
|
||||
vn ($I2,$I2,$mask26);
|
||||
vesrlf ($I4,$I4,2); # >>2
|
||||
|
||||
vmalof ($ACC0,$H1,$S4,$ACC0);
|
||||
vmalof ($ACC1,$H1,$R0,$ACC1);
|
||||
vmalof ($ACC2,$H1,$R1,$ACC2);
|
||||
vmalof ($ACC3,$H1,$R2,$ACC3);
|
||||
vmalof ($ACC4,$H1,$R3,$ACC4);
|
||||
|
||||
vgmg ($mask26,38,63);
|
||||
vperm ($T3,$T1,$T2,$bswaplo);
|
||||
vperm ($T4,$T1,$T2,$bswaphi);
|
||||
vperm ($T2,$T1,$T2,$bswapmi);
|
||||
|
||||
vmalof ($ACC0,$H2,$S3,$ACC0);
|
||||
vmalof ($ACC1,$H2,$S4,$ACC1);
|
||||
vmalof ($ACC2,$H2,$R0,$ACC2);
|
||||
vmalof ($ACC3,$H2,$R1,$ACC3);
|
||||
vmalof ($ACC4,$H2,$R2,$ACC4);
|
||||
|
||||
verimg ($I0,$T3,$mask26,0);
|
||||
verimg ($I1,$T3,$mask26,38); # >>26
|
||||
verimg ($I2,$T2,$mask26,60); # >>4
|
||||
|
||||
vmalof ($ACC0,$H3,$S2,$ACC0);
|
||||
vmalof ($ACC1,$H3,$S3,$ACC1);
|
||||
vmalof ($ACC2,$H3,$S4,$ACC2);
|
||||
vmalof ($ACC3,$H3,$R0,$ACC3);
|
||||
vmalof ($ACC4,$H3,$R1,$ACC4);
|
||||
|
||||
verimg ($I3,$T4,$mask26,50); # >>14
|
||||
vesrlg ($T4,$T4,40);
|
||||
vo ($I4,$I4,$T4);
|
||||
|
||||
vmalof ($ACC0,$H4,$S1,$ACC0);
|
||||
vmalof ($ACC1,$H4,$S2,$ACC1);
|
||||
vmalof ($ACC2,$H4,$S3,$ACC2);
|
||||
vmalof ($ACC3,$H4,$S4,$ACC3);
|
||||
vmalof ($ACC4,$H4,$R0,$ACC4);
|
||||
|
||||
################################################################
|
||||
# lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
|
||||
# and P. Schwabe
|
||||
|
||||
vesrlg ($H4,$ACC3,26);
|
||||
vesrlg ($H1,$ACC0,26);
|
||||
vn ($H3,$ACC3,$mask26);
|
||||
vn ($H0,$ACC0,$mask26);
|
||||
vag ($H4,$H4,$ACC4); # h3 -> h4
|
||||
vag ($H1,$H1,$ACC1); # h0 -> h1
|
||||
|
||||
vesrlg ($ACC4,$H4,26);
|
||||
vesrlg ($ACC1,$H1,26);
|
||||
vn ($H4,$H4,$mask26);
|
||||
vn ($H1,$H1,$mask26);
|
||||
vag ($H0,$H0,$ACC4);
|
||||
vag ($H2,$ACC2,$ACC1); # h1 -> h2
|
||||
|
||||
veslg ($ACC4,$ACC4,2); # <<2
|
||||
vesrlg ($ACC2,$H2,26);
|
||||
vn ($H2,$H2,$mask26);
|
||||
vag ($H0,$H0,$ACC4); # h4 -> h0
|
||||
vag ($H3,$H3,$ACC2); # h2 -> h3
|
||||
|
||||
vesrlg ($ACC0,$H0,26);
|
||||
vesrlg ($ACC3,$H3,26);
|
||||
vn ($H0,$H0,$mask26);
|
||||
vn ($H3,$H3,$mask26);
|
||||
vag ($H1,$H1,$ACC0); # h0 -> h1
|
||||
vag ($H4,$H4,$ACC3); # h3 -> h4
|
||||
|
||||
&{$z? \&brctg:\&brct} ("%r0",".Loop_vx");
|
||||
|
||||
vlm ($R0,$S4,"48($ctx)"); # load all powers
|
||||
|
||||
lghi ("%r0",0x30);
|
||||
&{$z? \&lcgr:\&lcr} ($len,$len);
|
||||
&{$z? \&ngr:\&nr} ($len,"%r0");
|
||||
&{$z? \&slgr:\&slr} ($inp,$len);
|
||||
|
||||
LABEL (".Last");
|
||||
vmlef ($ACC0,$I0,$R0);
|
||||
vmlef ($ACC1,$I0,$R1);
|
||||
vmlef ($ACC2,$I0,$R2);
|
||||
vmlef ($ACC3,$I0,$R3);
|
||||
vmlef ($ACC4,$I0,$R4);
|
||||
|
||||
vmalef ($ACC0,$I1,$S4,$ACC0);
|
||||
vmalef ($ACC1,$I1,$R0,$ACC1);
|
||||
vmalef ($ACC2,$I1,$R1,$ACC2);
|
||||
vmalef ($ACC3,$I1,$R2,$ACC3);
|
||||
vmalef ($ACC4,$I1,$R3,$ACC4);
|
||||
|
||||
vaf ($H0,$H0,$I0);
|
||||
vaf ($H1,$H1,$I1);
|
||||
vaf ($H2,$H2,$I2);
|
||||
vaf ($H3,$H3,$I3);
|
||||
vaf ($H4,$H4,$I4);
|
||||
|
||||
vmalef ($ACC0,$I2,$S3,$ACC0);
|
||||
vmalef ($ACC1,$I2,$S4,$ACC1);
|
||||
vmalef ($ACC2,$I2,$R0,$ACC2);
|
||||
vmalef ($ACC3,$I2,$R1,$ACC3);
|
||||
vmalef ($ACC4,$I2,$R2,$ACC4);
|
||||
|
||||
vmalef ($ACC0,$I3,$S2,$ACC0);
|
||||
vmalef ($ACC1,$I3,$S3,$ACC1);
|
||||
vmalef ($ACC2,$I3,$S4,$ACC2);
|
||||
vmalef ($ACC3,$I3,$R0,$ACC3);
|
||||
vmalef ($ACC4,$I3,$R1,$ACC4);
|
||||
|
||||
vmalef ($ACC0,$I4,$S1,$ACC0);
|
||||
vmalef ($ACC1,$I4,$S2,$ACC1);
|
||||
vmalef ($ACC2,$I4,$S3,$ACC2);
|
||||
vmalef ($ACC3,$I4,$S4,$ACC3);
|
||||
vmalef ($ACC4,$I4,$R0,$ACC4);
|
||||
|
||||
vmalof ($ACC0,$H0,$R0,$ACC0);
|
||||
vmalof ($ACC1,$H0,$R1,$ACC1);
|
||||
vmalof ($ACC2,$H0,$R2,$ACC2);
|
||||
vmalof ($ACC3,$H0,$R3,$ACC3);
|
||||
vmalof ($ACC4,$H0,$R4,$ACC4);
|
||||
|
||||
vmalof ($ACC0,$H1,$S4,$ACC0);
|
||||
vmalof ($ACC1,$H1,$R0,$ACC1);
|
||||
vmalof ($ACC2,$H1,$R1,$ACC2);
|
||||
vmalof ($ACC3,$H1,$R2,$ACC3);
|
||||
vmalof ($ACC4,$H1,$R3,$ACC4);
|
||||
|
||||
vmalof ($ACC0,$H2,$S3,$ACC0);
|
||||
vmalof ($ACC1,$H2,$S4,$ACC1);
|
||||
vmalof ($ACC2,$H2,$R0,$ACC2);
|
||||
vmalof ($ACC3,$H2,$R1,$ACC3);
|
||||
vmalof ($ACC4,$H2,$R2,$ACC4);
|
||||
|
||||
vmalof ($ACC0,$H3,$S2,$ACC0);
|
||||
vmalof ($ACC1,$H3,$S3,$ACC1);
|
||||
vmalof ($ACC2,$H3,$S4,$ACC2);
|
||||
vmalof ($ACC3,$H3,$R0,$ACC3);
|
||||
vmalof ($ACC4,$H3,$R1,$ACC4);
|
||||
|
||||
vmalof ($ACC0,$H4,$S1,$ACC0);
|
||||
vmalof ($ACC1,$H4,$S2,$ACC1);
|
||||
vmalof ($ACC2,$H4,$S3,$ACC2);
|
||||
vmalof ($ACC3,$H4,$S4,$ACC3);
|
||||
vmalof ($ACC4,$H4,$R0,$ACC4);
|
||||
|
||||
################################################################
|
||||
# horizontal addition
|
||||
|
||||
vzero ($H0);
|
||||
vsumqg ($ACC0,$ACC0,$H0);
|
||||
vsumqg ($ACC1,$ACC1,$H0);
|
||||
vsumqg ($ACC2,$ACC2,$H0);
|
||||
vsumqg ($ACC3,$ACC3,$H0);
|
||||
vsumqg ($ACC4,$ACC4,$H0);
|
||||
|
||||
################################################################
|
||||
# lazy reduction
|
||||
|
||||
vesrlg ($H4,$ACC3,26);
|
||||
vesrlg ($H1,$ACC0,26);
|
||||
vn ($H3,$ACC3,$mask26);
|
||||
vn ($H0,$ACC0,$mask26);
|
||||
vag ($H4,$H4,$ACC4); # h3 -> h4
|
||||
vag ($H1,$H1,$ACC1); # h0 -> h1
|
||||
|
||||
vesrlg ($ACC4,$H4,26);
|
||||
vesrlg ($ACC1,$H1,26);
|
||||
vn ($H4,$H4,$mask26);
|
||||
vn ($H1,$H1,$mask26);
|
||||
vag ($H0,$H0,$ACC4);
|
||||
vag ($H2,$ACC2,$ACC1); # h1 -> h2
|
||||
|
||||
veslg ($ACC4,$ACC4,2); # <<2
|
||||
vesrlg ($ACC2,$H2,26);
|
||||
vn ($H2,$H2,$mask26);
|
||||
vag ($H0,$H0,$ACC4); # h4 -> h0
|
||||
vag ($H3,$H3,$ACC2); # h2 -> h3
|
||||
|
||||
vesrlg ($ACC0,$H0,26);
|
||||
vesrlg ($ACC3,$H3,26);
|
||||
vn ($H0,$H0,$mask26);
|
||||
vn ($H3,$H3,$mask26);
|
||||
vag ($H1,$H1,$ACC0); # h0 -> h1
|
||||
vag ($H4,$H4,$ACC3); # h3 -> h4
|
||||
|
||||
&{$z? \&clgfi:\&clfi} ($len,0);
|
||||
je (".Ldone");
|
||||
|
||||
vlm ($T1,$T4,"0x00($inp)"); # load last partial block
|
||||
vgmg ($mask26,6,31);
|
||||
vgmf ($I4,5,5); # padbit<<2
|
||||
|
||||
vperm ($I0,$T3,$T4,$bswaplo);
|
||||
vperm ($I2,$T3,$T4,$bswapmi);
|
||||
vperm ($T3,$T3,$T4,$bswaphi);
|
||||
|
||||
vl ($ACC0,"0x30($len,%r1)"); # borrow $ACC0,1
|
||||
vl ($ACC1,"0x60($len,%r1)");
|
||||
|
||||
verimg ($I1,$I0,$mask26,6); # >>26
|
||||
veslg ($I0,$I0,32);
|
||||
veslg ($I2,$I2,28); # >>4
|
||||
verimg ($I3,$T3,$mask26,18); # >>14
|
||||
verimg ($I4,$T3,$mask26,58); # >>38
|
||||
vn ($I0,$I0,$mask26);
|
||||
vn ($I2,$I2,$mask26);
|
||||
vesrlf ($I4,$I4,2); # >>2
|
||||
|
||||
vgmg ($mask26,38,63);
|
||||
vperm ($T3,$T1,$T2,$bswaplo);
|
||||
vperm ($T4,$T1,$T2,$bswaphi);
|
||||
vperm ($T2,$T1,$T2,$bswapmi);
|
||||
|
||||
verimg ($I0,$T3,$mask26,0);
|
||||
verimg ($I1,$T3,$mask26,38); # >>26
|
||||
verimg ($I2,$T2,$mask26,60); # >>4
|
||||
verimg ($I3,$T4,$mask26,50); # >>14
|
||||
vesrlg ($T4,$T4,40);
|
||||
vo ($I4,$I4,$T4);
|
||||
|
||||
vperm ($H0,$H0,$H0,$ACC0); # move hash to right lane
|
||||
vn ($I0,$I0,$ACC1); # mask redundant lane[s]
|
||||
vperm ($H1,$H1,$H1,$ACC0);
|
||||
vn ($I1,$I1,$ACC1);
|
||||
vperm ($H2,$H2,$H2,$ACC0);
|
||||
vn ($I2,$I2,$ACC1);
|
||||
vperm ($H3,$H3,$H3,$ACC0);
|
||||
vn ($I3,$I3,$ACC1);
|
||||
vperm ($H4,$H4,$H4,$ACC0);
|
||||
vn ($I4,$I4,$ACC1);
|
||||
|
||||
vaf ($I0,$I0,$H0); # accumulate hash
|
||||
vzero ($H0); # wipe hash value
|
||||
vaf ($I1,$I1,$H1);
|
||||
vzero ($H1);
|
||||
vaf ($I2,$I2,$H2);
|
||||
vzero ($H2);
|
||||
vaf ($I3,$I3,$H3);
|
||||
vzero ($H3);
|
||||
vaf ($I4,$I4,$H4);
|
||||
vzero ($H4);
|
||||
|
||||
&{$z? \&lghi:\&lhi} ($len,0);
|
||||
j (".Last");
|
||||
# I don't bother to tell apart cases when only one multiplication
|
||||
# pass is sufficient, because I argue that mispredicted branch
|
||||
# penalties are comparable to overhead of sometimes redundant
|
||||
# multiplication pass...
|
||||
|
||||
LABEL (".Ldone");
|
||||
vstef ($H0,"0($ctx)",3); # store hash base 2^26
|
||||
vstef ($H1,"4($ctx)",3);
|
||||
vstef ($H2,"8($ctx)",3);
|
||||
vstef ($H3,"12($ctx)",3);
|
||||
vstef ($H4,"16($ctx)",3);
|
||||
|
||||
if ($z) {
|
||||
ld ("%f8","$stdframe+0*8($sp)");
|
||||
ld ("%f9","$stdframe+1*8($sp)");
|
||||
ld ("%f10","$stdframe+2*8($sp)");
|
||||
ld ("%f11","$stdframe+3*8($sp)");
|
||||
ld ("%f12","$stdframe+4*8($sp)");
|
||||
ld ("%f13","$stdframe+5*8($sp)");
|
||||
ld ("%f14","$stdframe+6*8($sp)");
|
||||
ld ("%f15","$stdframe+7*8($sp)");
|
||||
&{$z? \&lmg:\&lm} ("%r10","%r15","$stdframe+8*8+10*$SIZE_T($sp)");
|
||||
} else {
|
||||
ld ("%f4","$stdframe+16*$SIZE_T+2*8($sp)");
|
||||
ld ("%f6","$stdframe+16*$SIZE_T+3*8($sp)");
|
||||
&{$z? \&lmg:\&lm} ("%r10","%r15","$stdframe+10*$SIZE_T($sp)");
|
||||
}
|
||||
br ("%r14");
|
||||
SIZE ("__poly1305_blocks_vx",".-__poly1305_blocks_vx");
|
||||
}
|
||||
|
||||
################
|
||||
# static void poly1305_emit(void *ctx, unsigned char mac[16],
|
||||
# const u32 nonce[4])
|
||||
{
|
||||
my ($ctx,$mac,$nonce) = map("%r$_",(2..4));
|
||||
my ($h0,$h1,$h2,$d0,$d1)=map("%r$_",(5..9));
|
||||
my ($mac,$nonce)=($inp,$len);
|
||||
my ($h0,$h1,$h2,$d0,$d1,$d2)=map("%r$_",(5..10));
|
||||
|
||||
GLOBL ("poly1305_emit");
|
||||
TYPE ("poly1305_emit","\@function");
|
||||
ALIGN (16);
|
||||
LABEL ("poly1305_emit");
|
||||
&{$z? \&stmg:\&stm} ("%r6","%r9","6*$SIZE_T($sp)");
|
||||
LABEL (".Lpoly1305_emit");
|
||||
&{$z? \&stmg:\&stm} ("%r6","%r10","6*$SIZE_T($sp)");
|
||||
|
||||
lg ($h0,"0($ctx)");
|
||||
lg ($h1,"8($ctx)");
|
||||
lg ($h2,"16($ctx)");
|
||||
lg ($d0,"0($ctx)");
|
||||
lg ($d1,"8($ctx)");
|
||||
lg ($d2,"16($ctx)");
|
||||
|
||||
llgfr ("%r0",$d0); # base 2^26 -> base 2^64
|
||||
srlg ($h0,$d0,32);
|
||||
llgfr ("%r1",$d1);
|
||||
srlg ($h1,$d1,32);
|
||||
srlg ($h2,$d2,32);
|
||||
|
||||
sllg ("%r0","%r0",26);
|
||||
algr ($h0,"%r0");
|
||||
sllg ("%r0",$h1,52);
|
||||
srlg ($h1,$h1,12);
|
||||
sllg ("%r1","%r1",14);
|
||||
algr ($h0,"%r0");
|
||||
alcgr ($h1,"%r1");
|
||||
sllg ("%r0",$h2,40);
|
||||
srlg ($h2,$h2,24);
|
||||
lghi ("%r1",0);
|
||||
algr ($h1,"%r0");
|
||||
alcgr ($h2,"%r1");
|
||||
|
||||
llgf ("%r0","24($ctx)"); # is_base2_26
|
||||
lcgr ("%r0","%r0");
|
||||
|
||||
xgr ($h0,$d0); # choose between radixes
|
||||
xgr ($h1,$d1);
|
||||
xgr ($h2,$d2);
|
||||
ngr ($h0,"%r0");
|
||||
ngr ($h1,"%r0");
|
||||
ngr ($h2,"%r0");
|
||||
xgr ($h0,$d0);
|
||||
xgr ($h1,$d1);
|
||||
xgr ($h2,$d2);
|
||||
|
||||
lghi ("%r0",5);
|
||||
lghi ("%r1",0);
|
||||
lgr ($d0,$h0);
|
||||
lgr ($d1,$h1);
|
||||
|
||||
@@ -804,18 +939,16 @@ LABEL ("poly1305_emit");
|
||||
|
||||
srlg ($h2,$h2,2); # did it borrow/carry?
|
||||
slgr ("%r1",$h2); # 0-$h2>>2
|
||||
lg ($h2,"0($nonce)"); # load nonce
|
||||
lghi ("%r0",-1);
|
||||
lg ($d2,"0($nonce)"); # load nonce
|
||||
lg ($ctx,"8($nonce)");
|
||||
xgr ("%r0","%r1"); # ~%r1
|
||||
|
||||
xgr ($h0,$d0);
|
||||
xgr ($h1,$d1);
|
||||
ngr ($h0,"%r1");
|
||||
ngr ($d0,"%r0");
|
||||
ngr ($h1,"%r1");
|
||||
ngr ($d1,"%r0");
|
||||
ogr ($h0,$d0);
|
||||
rllg ($d0,$h2,32); # flip nonce words
|
||||
ogr ($h1,$d1);
|
||||
xgr ($h0,$d0);
|
||||
rllg ($d0,$d2,32); # flip nonce words
|
||||
xgr ($h1,$d1);
|
||||
rllg ($d1,$ctx,32);
|
||||
|
||||
algr ($h0,$d0); # accumulate nonce
|
||||
@@ -824,20 +957,28 @@ LABEL ("poly1305_emit");
|
||||
strvg ($h0,"0($mac)"); # write little-endian result
|
||||
strvg ($h1,"8($mac)");
|
||||
|
||||
&{$z? \&lmg:\&lm} ("%r6","%r9","6*$SIZE_T($sp)");
|
||||
&{$z? \&lmg:\&lm} ("%r6","%r10","6*$SIZE_T($sp)");
|
||||
br ("%r14");
|
||||
SIZE ("poly1305_emit",".-poly1305_emit");
|
||||
}
|
||||
}
|
||||
|
||||
################
|
||||
|
||||
ALIGN (128);
|
||||
ALIGN (16);
|
||||
LABEL (".Lconst");
|
||||
LONG (0x00060504,0x03020100,0x00161514,0x13121110); # vperm op[m[1],m[0]]
|
||||
LONG (0x000c0b0a,0x09080706,0x001c1b1a,0x19181716); # vperm op[m[3],m[2]]
|
||||
LONG (0x00000000,0x000f0e0d,0x00000000,0x001f1e1d); # vperm op[ - ,m[4]]
|
||||
LONG (0x00000000,0x03ffffff,0x00000000,0x03ffffff); # [0,2^26-1,0,2^26-1]
|
||||
LONG (0x0f0e0d0c,0x0b0a0908,0x07060504,0x03020100); # vperm op endian
|
||||
LONG (0x04050607,0x14151617,0x0c0d0e0f,0x1c1d1e1f); # merge odd
|
||||
LONG (0x07060504,0x03020100,0x17161514,0x13121110); # byte swap masks
|
||||
LONG (0x0f0e0d0c,0x0b0a0908,0x1f1e1d1c,0x1b1a1918);
|
||||
LONG (0x00000000,0x09080706,0x00000000,0x19181716);
|
||||
|
||||
LONG (0x00000000,0x00000000,0x00000000,0x0c0d0e0f); # magic tail masks
|
||||
LONG (0x0c0d0e0f,0x00000000,0x00000000,0x00000000);
|
||||
LONG (0x00000000,0x00000000,0x0c0d0e0f,0x00000000);
|
||||
|
||||
LONG (0xffffffff,0x00000000,0xffffffff,0xffffffff);
|
||||
LONG (0xffffffff,0x00000000,0xffffffff,0x00000000);
|
||||
LONG (0x00000000,0x00000000,0xffffffff,0x00000000);
|
||||
|
||||
STRING ("\"Poly1305 for s390x, CRYPTOGAMS by <appro\@openssl.org>\"");
|
||||
|
||||
PERLASM_END();
|
||||
@@ -18,4 +18,5 @@ INCLUDE[poly1305-armv8.o]=..
|
||||
GENERATE[poly1305-mips.S]=asm/poly1305-mips.pl $(PERLASM_SCHEME)
|
||||
INCLUDE[poly1305-mips.o]=..
|
||||
GENERATE[poly1305-c64xplus.S]=asm/poly1305-c64xplus.pl $(PERLASM_SCHEME)
|
||||
INCLUDE[poly1305-s390x.o]=..
|
||||
GENERATE[poly1305-s390x.S]=asm/poly1305-s390x.pl $(PERLASM_SCHEME)
|
||||
+175
-37
@@ -11,9 +11,14 @@
|
||||
#include <openssl/core_numbers.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/nelem.h"
|
||||
#include "internal/thread_once.h"
|
||||
#include "internal/provider.h"
|
||||
#include "internal/refcount.h"
|
||||
#include "provider_local.h"
|
||||
|
||||
static OSSL_PROVIDER *provider_new(const char *name,
|
||||
OSSL_provider_init_fn *init_function);
|
||||
|
||||
/*-
|
||||
* Provider Object structure
|
||||
@@ -25,6 +30,7 @@ struct provider_store_st; /* Forward declaration */
|
||||
struct ossl_provider_st {
|
||||
/* Flag bits */
|
||||
unsigned int flag_initialized:1;
|
||||
unsigned int flag_fallback:1;
|
||||
|
||||
/* OpenSSL library side data */
|
||||
CRYPTO_REF_COUNT refcnt;
|
||||
@@ -32,6 +38,7 @@ struct ossl_provider_st {
|
||||
char *name;
|
||||
DSO *module;
|
||||
OSSL_provider_init_fn *init_function;
|
||||
struct provider_store_st *store; /* The store this instance belongs to */
|
||||
|
||||
/* Provider side functions */
|
||||
OSSL_provider_teardown_fn *teardown;
|
||||
@@ -58,6 +65,7 @@ static int ossl_provider_cmp(const OSSL_PROVIDER * const *a,
|
||||
struct provider_store_st {
|
||||
STACK_OF(OSSL_PROVIDER) *providers;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
unsigned int use_fallbacks:1;
|
||||
};
|
||||
static int provider_store_index = -1;
|
||||
|
||||
@@ -75,13 +83,37 @@ static void provider_store_free(void *vstore)
|
||||
static void *provider_store_new(void)
|
||||
{
|
||||
struct provider_store_st *store = OPENSSL_zalloc(sizeof(*store));
|
||||
const struct predefined_providers_st *p = NULL;
|
||||
|
||||
if (store == NULL
|
||||
|| (store->providers = sk_OSSL_PROVIDER_new(ossl_provider_cmp)) == NULL
|
||||
|| (store->lock = CRYPTO_THREAD_lock_new()) == NULL) {
|
||||
provider_store_free(store);
|
||||
store = NULL;
|
||||
return NULL;
|
||||
}
|
||||
store->use_fallbacks = 1;
|
||||
|
||||
for (p = predefined_providers; p->name != NULL; p++) {
|
||||
OSSL_PROVIDER *prov = NULL;
|
||||
|
||||
/*
|
||||
* We use the internal constructor directly here,
|
||||
* otherwise we get a call loop
|
||||
*/
|
||||
prov = provider_new(p->name, p->init);
|
||||
|
||||
if (prov == NULL
|
||||
|| sk_OSSL_PROVIDER_push(store->providers, prov) == 0) {
|
||||
ossl_provider_free(prov);
|
||||
provider_store_free(store);
|
||||
CRYPTOerr(CRYPTO_F_PROVIDER_STORE_NEW, ERR_R_INTERNAL_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
prov->store = store;
|
||||
if(p->is_fallback)
|
||||
ossl_provider_set_fallback(prov);
|
||||
}
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
@@ -112,20 +144,6 @@ static struct provider_store_st *get_provider_store(OPENSSL_CTX *libctx)
|
||||
return store;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Provider Object methods
|
||||
* =======================
|
||||
*/
|
||||
|
||||
int ossl_provider_upref(OSSL_PROVIDER *prov)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock);
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* Finder, constructor and destructor */
|
||||
OSSL_PROVIDER *ossl_provider_find(OPENSSL_CTX *libctx, const char *name)
|
||||
{
|
||||
struct provider_store_st *store = NULL;
|
||||
@@ -147,6 +165,39 @@ OSSL_PROVIDER *ossl_provider_find(OPENSSL_CTX *libctx, const char *name)
|
||||
return prov;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Provider Object methods
|
||||
* =======================
|
||||
*/
|
||||
|
||||
static OSSL_PROVIDER *provider_new(const char *name,
|
||||
OSSL_provider_init_fn *init_function)
|
||||
{
|
||||
OSSL_PROVIDER *prov = NULL;
|
||||
|
||||
if ((prov = OPENSSL_zalloc(sizeof(*prov))) == NULL
|
||||
#ifndef HAVE_ATOMICS
|
||||
|| (prov->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL
|
||||
#endif
|
||||
|| !ossl_provider_upref(prov) /* +1 One reference to be returned */
|
||||
|| (prov->name = OPENSSL_strdup(name)) == NULL) {
|
||||
ossl_provider_free(prov);
|
||||
CRYPTOerr(CRYPTO_F_PROVIDER_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prov->init_function = init_function;
|
||||
return prov;
|
||||
}
|
||||
|
||||
int ossl_provider_upref(OSSL_PROVIDER *prov)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock);
|
||||
return ref;
|
||||
}
|
||||
|
||||
OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name,
|
||||
OSSL_provider_init_fn *init_function)
|
||||
{
|
||||
@@ -164,18 +215,9 @@ OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((prov = OPENSSL_zalloc(sizeof(*prov))) == NULL
|
||||
#ifndef HAVE_ATOMICS
|
||||
|| (prov->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL
|
||||
#endif
|
||||
|| !ossl_provider_upref(prov) /* +1 One reference to be returned */
|
||||
|| (prov->name = OPENSSL_strdup(name)) == NULL) {
|
||||
ossl_provider_free(prov);
|
||||
CRYPTOerr(CRYPTO_F_OSSL_PROVIDER_NEW, ERR_R_MALLOC_FAILURE);
|
||||
/* provider_new() generates an error, so no need here */
|
||||
if ((prov = provider_new(name, init_function)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prov->init_function = init_function;
|
||||
|
||||
CRYPTO_THREAD_write_lock(store->lock);
|
||||
if (!ossl_provider_upref(prov)) { /* +1 One reference for the store */
|
||||
@@ -185,6 +227,8 @@ OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name,
|
||||
ossl_provider_free(prov); /* -1 Store reference */
|
||||
ossl_provider_free(prov); /* -1 Reference that was to be returned */
|
||||
prov = NULL;
|
||||
} else {
|
||||
prov->store = store;
|
||||
}
|
||||
CRYPTO_THREAD_unlock(store->lock);
|
||||
|
||||
@@ -207,11 +251,13 @@ void ossl_provider_free(OSSL_PROVIDER *prov)
|
||||
CRYPTO_DOWN_REF(&prov->refcnt, &ref, prov->refcnt_lock);
|
||||
|
||||
/*
|
||||
* When the refcount drops down to one, there is only one reference,
|
||||
* the store.
|
||||
* When the refcount drops below two, the store is the only
|
||||
* possible reference, or it has already been taken away from
|
||||
* the store (this may happen if a provider was activated
|
||||
* because it's a fallback, but isn't currently used)
|
||||
* When that happens, the provider is inactivated.
|
||||
*/
|
||||
if (ref == 1 && prov->flag_initialized) {
|
||||
if (ref < 2 && prov->flag_initialized) {
|
||||
if (prov->teardown != NULL)
|
||||
prov->teardown();
|
||||
prov->flag_initialized = 0;
|
||||
@@ -246,7 +292,12 @@ void ossl_provider_free(OSSL_PROVIDER *prov)
|
||||
*/
|
||||
static const OSSL_DISPATCH *core_dispatch; /* Define further down */
|
||||
|
||||
int ossl_provider_activate(OSSL_PROVIDER *prov)
|
||||
/*
|
||||
* Internal version that doesn't affect the store flags, and thereby avoid
|
||||
* locking. Direct callers must remember to set the store flags when
|
||||
* appropriate
|
||||
*/
|
||||
static int provider_activate(OSSL_PROVIDER *prov)
|
||||
{
|
||||
const OSSL_DISPATCH *provider_dispatch = NULL;
|
||||
|
||||
@@ -295,7 +346,7 @@ int ossl_provider_activate(OSSL_PROVIDER *prov)
|
||||
|
||||
if (prov->init_function == NULL
|
||||
|| !prov->init_function(prov, core_dispatch, &provider_dispatch)) {
|
||||
CRYPTOerr(CRYPTO_F_OSSL_PROVIDER_ACTIVATE, ERR_R_INIT_FAIL);
|
||||
CRYPTOerr(CRYPTO_F_PROVIDER_ACTIVATE, ERR_R_INIT_FAIL);
|
||||
ERR_add_error_data(2, "name=", prov->name);
|
||||
DSO_free(prov->module);
|
||||
prov->module = NULL;
|
||||
@@ -329,6 +380,46 @@ int ossl_provider_activate(OSSL_PROVIDER *prov)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ossl_provider_activate(OSSL_PROVIDER *prov)
|
||||
{
|
||||
if (provider_activate(prov)) {
|
||||
CRYPTO_THREAD_write_lock(prov->store->lock);
|
||||
prov->store->use_fallbacks = 0;
|
||||
CRYPTO_THREAD_unlock(prov->store->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int provider_forall_loaded(struct provider_store_st *store,
|
||||
int *found_activated,
|
||||
int (*cb)(OSSL_PROVIDER *provider,
|
||||
void *cbdata),
|
||||
void *cbdata)
|
||||
{
|
||||
int i;
|
||||
int ret = 1;
|
||||
int num_provs = sk_OSSL_PROVIDER_num(store->providers);
|
||||
|
||||
if (found_activated != NULL)
|
||||
*found_activated = 0;
|
||||
for (i = 0; i < num_provs; i++) {
|
||||
OSSL_PROVIDER *prov =
|
||||
sk_OSSL_PROVIDER_value(store->providers, i);
|
||||
|
||||
if (prov->flag_initialized) {
|
||||
if (found_activated != NULL)
|
||||
*found_activated = 1;
|
||||
if (!(ret = cb(prov, cbdata)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ossl_provider_forall_loaded(OPENSSL_CTX *ctx,
|
||||
int (*cb)(OSSL_PROVIDER *provider,
|
||||
void *cbdata),
|
||||
@@ -339,13 +430,50 @@ int ossl_provider_forall_loaded(OPENSSL_CTX *ctx,
|
||||
struct provider_store_st *store = get_provider_store(ctx);
|
||||
|
||||
if (store != NULL) {
|
||||
CRYPTO_THREAD_read_lock(store->lock);
|
||||
for (i = 0; i < sk_OSSL_PROVIDER_num(store->providers); i++) {
|
||||
OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(store->providers, i);
|
||||
int found_activated = 0;
|
||||
|
||||
if (prov->flag_initialized
|
||||
&& !(ret = cb(prov, cbdata)))
|
||||
break;
|
||||
CRYPTO_THREAD_read_lock(store->lock);
|
||||
ret = provider_forall_loaded(store, &found_activated, cb, cbdata);
|
||||
|
||||
/*
|
||||
* If there's nothing activated ever in this store, try to activate
|
||||
* all fallbacks.
|
||||
*/
|
||||
if (!found_activated && store->use_fallbacks) {
|
||||
int num_provs = sk_OSSL_PROVIDER_num(store->providers);
|
||||
int activated_fallback_count = 0;
|
||||
|
||||
for (i = 0; i < num_provs; i++) {
|
||||
OSSL_PROVIDER *prov =
|
||||
sk_OSSL_PROVIDER_value(store->providers, i);
|
||||
|
||||
/*
|
||||
* Note that we don't care if the activation succeeds or
|
||||
* not. If it doesn't succeed, then the next loop will
|
||||
* fail anyway.
|
||||
*/
|
||||
if (prov->flag_fallback) {
|
||||
activated_fallback_count++;
|
||||
provider_activate(prov);
|
||||
}
|
||||
}
|
||||
|
||||
if (activated_fallback_count > 0) {
|
||||
/*
|
||||
* We assume that all fallbacks have been added to the store
|
||||
* before any fallback is activated.
|
||||
* TODO: We may have to reconsider this, IF we find ourselves
|
||||
* adding fallbacks after any previous fallback has been
|
||||
* activated.
|
||||
*/
|
||||
store->use_fallbacks = 0;
|
||||
|
||||
/*
|
||||
* Now that we've activated available fallbacks, try a
|
||||
* second sweep
|
||||
*/
|
||||
ret = provider_forall_loaded(store, NULL, cb, cbdata);
|
||||
}
|
||||
}
|
||||
CRYPTO_THREAD_unlock(store->lock);
|
||||
}
|
||||
@@ -353,6 +481,16 @@ int ossl_provider_forall_loaded(OPENSSL_CTX *ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Setters of Provider Object data */
|
||||
int ossl_provider_set_fallback(OSSL_PROVIDER *prov)
|
||||
{
|
||||
if (prov == NULL)
|
||||
return 0;
|
||||
|
||||
prov->flag_fallback = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Getters of Provider Object data */
|
||||
const char *ossl_provider_name(OSSL_PROVIDER *prov)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/core.h>
|
||||
|
||||
struct predefined_providers_st {
|
||||
const char *name;
|
||||
OSSL_provider_init_fn *init;
|
||||
unsigned int is_fallback:1;
|
||||
};
|
||||
|
||||
extern const struct predefined_providers_st predefined_providers[];
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/core.h>
|
||||
#include "provider_local.h"
|
||||
|
||||
OSSL_provider_init_fn ossl_default_provider_init;
|
||||
|
||||
const struct predefined_providers_st predefined_providers[] = {
|
||||
{ "default", ossl_default_provider_init, 1 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
randfile.c rand_lib.c rand_err.c rand_egd.c \
|
||||
randfile.c rand_lib.c rand_err.c rand_crng_test.c rand_egd.c \
|
||||
rand_win.c rand_unix.c rand_vms.c drbg_lib.c drbg_ctr.c \
|
||||
drbg_hash.c drbg_hmac.c
|
||||
|
||||
@@ -67,7 +67,7 @@ static CRYPTO_THREAD_LOCAL private_drbg;
|
||||
|
||||
|
||||
/* NIST SP 800-90A DRBG recommends the use of a personalization string. */
|
||||
static const char ossl_pers_string[] = "OpenSSL NIST SP 800-90A DRBG";
|
||||
static const char ossl_pers_string[] = DRBG_DEFAULT_PERS_STRING;
|
||||
|
||||
static CRYPTO_ONCE rand_drbg_init = CRYPTO_ONCE_STATIC_INIT;
|
||||
|
||||
@@ -241,8 +241,8 @@ static RAND_DRBG *rand_drbg_new(int secure,
|
||||
unsigned int flags,
|
||||
RAND_DRBG *parent)
|
||||
{
|
||||
RAND_DRBG *drbg = secure ?
|
||||
OPENSSL_secure_zalloc(sizeof(*drbg)) : OPENSSL_zalloc(sizeof(*drbg));
|
||||
RAND_DRBG *drbg = secure ? OPENSSL_secure_zalloc(sizeof(*drbg))
|
||||
: OPENSSL_zalloc(sizeof(*drbg));
|
||||
|
||||
if (drbg == NULL) {
|
||||
RANDerr(RAND_F_RAND_DRBG_NEW, ERR_R_MALLOC_FAILURE);
|
||||
@@ -254,8 +254,13 @@ static RAND_DRBG *rand_drbg_new(int secure,
|
||||
drbg->parent = parent;
|
||||
|
||||
if (parent == NULL) {
|
||||
#ifdef FIPS_MODE
|
||||
drbg->get_entropy = rand_crngt_get_entropy;
|
||||
drbg->cleanup_entropy = rand_crngt_cleanup_entropy;
|
||||
#else
|
||||
drbg->get_entropy = rand_drbg_get_entropy;
|
||||
drbg->cleanup_entropy = rand_drbg_cleanup_entropy;
|
||||
#endif
|
||||
#ifndef RAND_DRBG_GET_RANDOM_NONCE
|
||||
drbg->get_nonce = rand_drbg_get_nonce;
|
||||
drbg->cleanup_nonce = rand_drbg_cleanup_nonce;
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* Implementation of the FIPS 140-2 section 4.9.2 Conditional Tests.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "internal/rand_int.h"
|
||||
#include "internal/thread_once.h"
|
||||
#include "rand_lcl.h"
|
||||
|
||||
static RAND_POOL *crngt_pool;
|
||||
static unsigned char *crngt_prev;
|
||||
|
||||
int (*crngt_get_entropy)(unsigned char *) = &rand_crngt_get_entropy_cb;
|
||||
|
||||
int rand_crngt_get_entropy_cb(unsigned char *buf)
|
||||
{
|
||||
size_t n;
|
||||
unsigned char *p;
|
||||
|
||||
while ((n = rand_pool_acquire_entropy(crngt_pool)) != 0)
|
||||
if (n >= CRNGT_BUFSIZ) {
|
||||
p = rand_pool_detach(crngt_pool);
|
||||
memcpy(crngt_prev, p, CRNGT_BUFSIZ);
|
||||
rand_pool_reattach(crngt_pool, p);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
void rand_crngt_cleanup(void)
|
||||
{
|
||||
rand_pool_free(crngt_pool);
|
||||
OPENSSL_secure_free(crngt_prev);
|
||||
crngt_pool = NULL;
|
||||
crngt_prev = NULL;
|
||||
}
|
||||
|
||||
int rand_crngt_init(void)
|
||||
{
|
||||
if ((crngt_pool = rand_pool_new(0, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL)
|
||||
return 0;
|
||||
if ((crngt_prev = OPENSSL_secure_malloc(CRNGT_BUFSIZ)) != NULL
|
||||
&& crngt_get_entropy(crngt_prev))
|
||||
return 1;
|
||||
rand_crngt_cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CRYPTO_ONCE rand_crngt_init_flag = CRYPTO_ONCE_STATIC_INIT;
|
||||
DEFINE_RUN_ONCE_STATIC(do_rand_crngt_init)
|
||||
{
|
||||
return OPENSSL_init_crypto(0, NULL)
|
||||
&& rand_crngt_init()
|
||||
&& OPENSSL_atexit(&rand_crngt_cleanup);
|
||||
}
|
||||
|
||||
int rand_crngt_single_init(void)
|
||||
{
|
||||
return RUN_ONCE(&rand_crngt_init_flag, do_rand_crngt_init);
|
||||
}
|
||||
|
||||
size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
|
||||
unsigned char **pout,
|
||||
int entropy, size_t min_len, size_t max_len,
|
||||
int prediction_resistance)
|
||||
{
|
||||
unsigned char buf[CRNGT_BUFSIZ];
|
||||
RAND_POOL *pool;
|
||||
size_t q, r = 0, s, t = 0;
|
||||
int attempts = 3;
|
||||
|
||||
if (!RUN_ONCE(&rand_crngt_init_flag, do_rand_crngt_init))
|
||||
return 0;
|
||||
|
||||
if ((pool = rand_pool_new(entropy, min_len, max_len)) == NULL)
|
||||
return 0;
|
||||
|
||||
while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) {
|
||||
s = q > sizeof(buf) ? sizeof(buf) : q;
|
||||
if (!crngt_get_entropy(buf)
|
||||
|| memcmp(crngt_prev, buf, CRNGT_BUFSIZ) == 0
|
||||
|| !rand_pool_add(pool, buf, s, s * 8))
|
||||
goto err;
|
||||
memcpy(crngt_prev, buf, CRNGT_BUFSIZ);
|
||||
t += s;
|
||||
attempts++;
|
||||
}
|
||||
r = t;
|
||||
*pout = rand_pool_detach(pool);
|
||||
err:
|
||||
rand_pool_free(pool);
|
||||
return r;
|
||||
}
|
||||
|
||||
void rand_crngt_cleanup_entropy(RAND_DRBG *drbg,
|
||||
unsigned char *out, size_t outlen)
|
||||
{
|
||||
OPENSSL_secure_clear_free(out, outlen);
|
||||
}
|
||||
+27
-2
@@ -33,7 +33,15 @@
|
||||
# define MASTER_RESEED_TIME_INTERVAL (60*60) /* 1 hour */
|
||||
# define SLAVE_RESEED_TIME_INTERVAL (7*60) /* 7 minutes */
|
||||
|
||||
|
||||
/*
|
||||
* The number of bytes that constitutes an atomic lump of entropy with respect
|
||||
* to the FIPS 140-2 section 4.9.2 Conditional Tests. The size is somewhat
|
||||
* arbitrary, the smaller the value, the less entropy is consumed on first
|
||||
* read but the higher the probability of the test failing by accident.
|
||||
*
|
||||
* The value is in bytes.
|
||||
*/
|
||||
#define CRNGT_BUFSIZ 16
|
||||
|
||||
/*
|
||||
* Maximum input size for the DRBG (entropy, nonce, personalization string)
|
||||
@@ -44,7 +52,8 @@
|
||||
*/
|
||||
# define DRBG_MAX_LENGTH INT32_MAX
|
||||
|
||||
|
||||
/* The default nonce */
|
||||
# define DRBG_DEFAULT_PERS_STRING "OpenSSL NIST SP 800-90A DRBG"
|
||||
|
||||
/*
|
||||
* Maximum allocation size for RANDOM_POOL buffers
|
||||
@@ -321,4 +330,20 @@ int drbg_ctr_init(RAND_DRBG *drbg);
|
||||
int drbg_hash_init(RAND_DRBG *drbg);
|
||||
int drbg_hmac_init(RAND_DRBG *drbg);
|
||||
|
||||
/*
|
||||
* Entropy call back for the FIPS 140-2 section 4.9.2 Conditional Tests.
|
||||
* These need to be exposed for the unit tests.
|
||||
*/
|
||||
int rand_crngt_get_entropy_cb(unsigned char *buf);
|
||||
extern int (*crngt_get_entropy)(unsigned char *);
|
||||
int rand_crngt_init(void);
|
||||
void rand_crngt_cleanup(void);
|
||||
|
||||
/*
|
||||
* Expose the run once initialisation function for the unit tests because.
|
||||
* they need to restart from scratch to validate the first block is skipped
|
||||
* properly.
|
||||
*/
|
||||
int rand_crngt_single_init(void);
|
||||
|
||||
#endif
|
||||
@@ -137,7 +137,7 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
||||
size_t entropy_available = 0;
|
||||
RAND_POOL *pool;
|
||||
|
||||
if (drbg->parent && drbg->strength > drbg->parent->strength) {
|
||||
if (drbg->parent != NULL && drbg->strength > drbg->parent->strength) {
|
||||
/*
|
||||
* We currently don't support the algorithm from NIST SP 800-90C
|
||||
* 10.1.2 to use a weaker DRBG as source
|
||||
@@ -155,7 +155,7 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (drbg->parent) {
|
||||
if (drbg->parent != NULL) {
|
||||
size_t bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
|
||||
unsigned char *buffer = rand_pool_add_begin(pool, bytes_needed);
|
||||
|
||||
@@ -235,8 +235,9 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg,
|
||||
struct {
|
||||
void * instance;
|
||||
int count;
|
||||
} data = { 0 };
|
||||
} data;
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
pool = rand_pool_new(0, min_len, max_len);
|
||||
if (pool == NULL)
|
||||
return 0;
|
||||
@@ -402,7 +403,7 @@ int RAND_poll(void)
|
||||
} else {
|
||||
/* fill random pool and seed the current legacy RNG */
|
||||
pool = rand_pool_new(RAND_DRBG_STRENGTH,
|
||||
RAND_DRBG_STRENGTH / 8,
|
||||
(RAND_DRBG_STRENGTH + 7) / 8,
|
||||
RAND_POOL_MAX_LENGTH);
|
||||
if (pool == NULL)
|
||||
return 0;
|
||||
@@ -689,7 +690,7 @@ unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len)
|
||||
|
||||
if (pool->buffer == NULL) {
|
||||
RANDerr(RAND_F_RAND_POOL_ADD_BEGIN, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pool->buffer + pool->len;
|
||||
|
||||
@@ -615,7 +615,10 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
|
||||
pid_t pid;
|
||||
CRYPTO_THREAD_ID tid;
|
||||
uint64_t time;
|
||||
} data = { 0 };
|
||||
} data;
|
||||
|
||||
/* Erase the entire structure including any padding */
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
/*
|
||||
* Add process id, thread id, and a high resolution timestamp to
|
||||
@@ -634,7 +637,10 @@ int rand_pool_add_additional_data(RAND_POOL *pool)
|
||||
struct {
|
||||
CRYPTO_THREAD_ID tid;
|
||||
uint64_t time;
|
||||
} data = { 0 };
|
||||
} data;
|
||||
|
||||
/* Erase the entire structure including any padding */
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
/*
|
||||
* Add some noise from the thread id and a high resolution timer.
|
||||
|
||||
@@ -475,7 +475,10 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
|
||||
pid_t pid;
|
||||
CRYPTO_THREAD_ID tid;
|
||||
uint64_t time;
|
||||
} data = { 0 };
|
||||
} data;
|
||||
|
||||
/* Erase the entire structure including any padding */
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
/*
|
||||
* Add process id, thread id, and a high resolution timestamp
|
||||
@@ -499,7 +502,10 @@ int rand_pool_add_additional_data(RAND_POOL *pool)
|
||||
struct {
|
||||
CRYPTO_THREAD_ID tid;
|
||||
uint64_t time;
|
||||
} data = { 0 };
|
||||
} data;
|
||||
|
||||
/* Erase the entire structure including any padding */
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
/*
|
||||
* Add some noise from the thread id and a high resolution timer.
|
||||
|
||||
@@ -125,7 +125,10 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
|
||||
DWORD pid;
|
||||
DWORD tid;
|
||||
FILETIME time;
|
||||
} data = { 0 };
|
||||
} data;
|
||||
|
||||
/* Erase the entire structure including any padding */
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
/*
|
||||
* Add process id, thread id, and a high resolution timestamp to
|
||||
@@ -144,7 +147,10 @@ int rand_pool_add_additional_data(RAND_POOL *pool)
|
||||
struct {
|
||||
DWORD tid;
|
||||
LARGE_INTEGER time;
|
||||
} data = { 0 };
|
||||
} data;
|
||||
|
||||
/* Erase the entire structure including any padding */
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
/*
|
||||
* Add some noise from the thread id and a high resolution timer.
|
||||
|
||||
@@ -254,7 +254,7 @@ const char *RAND_file_name(char *buf, size_t size)
|
||||
size_t len;
|
||||
int use_randfile = 1;
|
||||
|
||||
#if defined(_WIN32) && defined(CP_UTF8)
|
||||
#if defined(_WIN32) && defined(CP_UTF8) && !defined(_WIN32_WCE)
|
||||
DWORD envlen;
|
||||
WCHAR *var;
|
||||
|
||||
|
||||
@@ -447,7 +447,7 @@ static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
|
||||
RSA_PSS_PARAMS_free(pss);
|
||||
if (!rv)
|
||||
return 0;
|
||||
} else if (!sig && BIO_puts(bp, "\n") <= 0) {
|
||||
} else if (BIO_puts(bp, "\n") <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if (sig)
|
||||
|
||||
@@ -393,7 +393,6 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
|
||||
RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN);
|
||||
ok = 0;
|
||||
}
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
return ok;
|
||||
|
||||
+16
-16
@@ -234,25 +234,25 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
|
||||
good &= constant_time_ge(tlen, mlen);
|
||||
|
||||
/*
|
||||
* Even though we can't fake result's length, we can pretend copying
|
||||
* |tlen| bytes where |mlen| bytes would be real. Last |tlen| of |dblen|
|
||||
* bytes are viewed as circular buffer with start at |tlen|-|mlen'|,
|
||||
* where |mlen'| is "saturated" |mlen| value. Deducing information
|
||||
* about failure or |mlen| would take attacker's ability to observe
|
||||
* memory access pattern with byte granularity *as it occurs*. It
|
||||
* should be noted that failure is indistinguishable from normal
|
||||
* operation if |tlen| is fixed by protocol.
|
||||
* Move the result in-place by |dblen|-|mdlen|-1-|mlen| bytes to the left.
|
||||
* Then if |good| move |mlen| bytes from |db|+|mdlen|+1 to |to|.
|
||||
* Otherwise leave |to| unchanged.
|
||||
* Copy the memory back in a way that does not reveal the size of
|
||||
* the data being copied via a timing side channel. This requires copying
|
||||
* parts of the buffer multiple times based on the bits set in the real
|
||||
* length. Clear bits do a non-copy with identical access pattern.
|
||||
* The loop below has overall complexity of O(N*log(N)).
|
||||
*/
|
||||
tlen = constant_time_select_int(constant_time_lt(dblen - mdlen - 1, tlen),
|
||||
dblen - mdlen - 1, tlen);
|
||||
msg_index = constant_time_select_int(good, msg_index, dblen - tlen);
|
||||
mlen = dblen - msg_index;
|
||||
for (mask = good, i = 0; i < tlen; i++) {
|
||||
unsigned int equals = constant_time_eq(msg_index, dblen);
|
||||
|
||||
msg_index -= tlen & equals; /* rewind at EOF */
|
||||
mask &= ~equals; /* mask = 0 at EOF */
|
||||
to[i] = constant_time_select_8(mask, db[msg_index++], to[i]);
|
||||
for (msg_index = 1; msg_index < dblen - mdlen - 1; msg_index <<= 1) {
|
||||
mask = ~constant_time_eq(msg_index & (dblen - mdlen - 1 - mlen), 0);
|
||||
for (i = mdlen + 1; i < dblen - msg_index; i++)
|
||||
db[i] = constant_time_select_8(mask, db[i + msg_index], db[i]);
|
||||
}
|
||||
for (i = 0; i < tlen; i++) {
|
||||
mask = good & constant_time_lt(i, mlen);
|
||||
to[i] = constant_time_select_8(mask, db[i + mdlen + 1], to[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -148,7 +148,6 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from,
|
||||
*/
|
||||
r = BN_bn2binpad(ret, to, num);
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
OPENSSL_clear_free(buf, num);
|
||||
@@ -354,7 +353,6 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from,
|
||||
*/
|
||||
r = BN_bn2binpad(res, to, num);
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
OPENSSL_clear_free(buf, num);
|
||||
@@ -481,10 +479,9 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
|
||||
goto err;
|
||||
}
|
||||
RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED);
|
||||
err_clear_last_constant_time(r >= 0);
|
||||
err_clear_last_constant_time(1 & ~constant_time_msb(r));
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
OPENSSL_clear_free(buf, num);
|
||||
@@ -581,7 +578,6 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from,
|
||||
RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_PADDING_CHECK_FAILED);
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
OPENSSL_clear_free(buf, num);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user