Latest update

This commit is contained in:
2019-04-01 00:21:15 +09:00
parent c03e0c45f8
commit 48ec086472
209 changed files with 7552 additions and 2495 deletions
+19
View File
@@ -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]
+2
View File
@@ -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 => {
+20 -26
View File
@@ -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
+7 -2
View File
@@ -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
-2
View File
@@ -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",
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
-8
View File
@@ -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
View File
@@ -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) {
+4
View File
@@ -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
View File
@@ -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
View File
@@ -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
+2 -2
View File
@@ -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:
+6
View File
@@ -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;
+1 -1
View File
@@ -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.
+1
View File
@@ -258,6 +258,7 @@ $data=<<EOF;
# .text section
.machine "any"
.text
#
# NOTE: The following label name should be changed to
+2
View File
@@ -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--;
+2
View File
@@ -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);
-1
View File
@@ -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
View File
@@ -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]=\
+292
View File
@@ -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;
+1
View File
@@ -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)
+1 -1
View File
@@ -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) {
+1
View File
@@ -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
View File
@@ -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;
+5
View File
@@ -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}
};
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+5 -9
View File
@@ -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;
}
-2
View File
@@ -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;
}
-2
View File
@@ -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;
}
+2
View File
@@ -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);
}
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
-1
View File
@@ -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;
-1
View File
@@ -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
View File
@@ -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);
+1 -2
View File
@@ -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);
+3 -1
View File
@@ -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);
}
-1
View File
@@ -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);
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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
+4
View File
@@ -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
View File
@@ -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
View File
@@ -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) \
+6
View File
@@ -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),
+197
View File
@@ -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;
}
+29
View File
@@ -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
View File
@@ -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 *));
+1
View File
@@ -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 *,
+2
View File
@@ -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);
}
+5
View File
@@ -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)
{
+4
View File
@@ -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;
+6 -6
View File
@@ -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;
+7
View File
@@ -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);
-4
View File
@@ -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
+21
View File
@@ -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 {
+8
View File
@@ -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
View File
@@ -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;
+2 -1
View File
@@ -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
+8
View File
@@ -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),
+484
View File
@@ -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
View File
@@ -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
+2 -2
View File
@@ -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))
+8 -5
View File
@@ -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" */
+2 -1
View File
@@ -1202,4 +1202,5 @@ blake2bmac 1201
blake2smac 1202
sshkdf 1203
SM2_with_SM3 1204
chacha20_poly1305_draft 1205
sskdf 1205
chacha20_poly1305_draft 1206
+3
View File
@@ -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
+2 -2
View File
@@ -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
View File
@@ -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;
}
+365
View File
@@ -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"
+775 -634
View File
@@ -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? \&ltgr:\&ltr} ("%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)");
&lt ("%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();
+1
View File
@@ -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
View File
@@ -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)
{
+18
View File
@@ -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[];
+18
View File
@@ -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 -1
View File
@@ -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
+8 -3
View File
@@ -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;
+109
View File
@@ -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
View File
@@ -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
+6 -5
View File
@@ -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;
+8 -2
View File
@@ -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.
+8 -2
View File
@@ -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.
+8 -2
View File
@@ -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.
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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)
-1
View File
@@ -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
View File
@@ -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]);
}
/*
+1 -5
View File
@@ -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